i386.md revision 117404
190286Sobrien;; GCC machine description for IA-32 and x86-64.
2117404Skan;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3117404Skan;; 2001, 2002, 2003
490286Sobrien;; Free Software Foundation, Inc.
518334Speter;; Mostly by William Schelter.
690286Sobrien;; x86_64 support added by Jan Hubicka
790286Sobrien;;
818334Speter;; This file is part of GNU CC.
990286Sobrien;;
1018334Speter;; GNU CC is free software; you can redistribute it and/or modify
1118334Speter;; it under the terms of the GNU General Public License as published by
1218334Speter;; the Free Software Foundation; either version 2, or (at your option)
1318334Speter;; any later version.
1490286Sobrien;;
1518334Speter;; GNU CC is distributed in the hope that it will be useful,
1618334Speter;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1718334Speter;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1818334Speter;; GNU General Public License for more details.
1990286Sobrien;;
2018334Speter;; You should have received a copy of the GNU General Public License
2118334Speter;; along with GNU CC; see the file COPYING.  If not, write to
2218334Speter;; the Free Software Foundation, 59 Temple Place - Suite 330,
2390286Sobrien;; Boston, MA 02111-1307, USA.  */
2490286Sobrien;;
2518334Speter;; The original PO technology requires these to be ordered by speed,
2618334Speter;; so that assigner will pick the fastest.
2790286Sobrien;;
2818334Speter;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
2990286Sobrien;;
3018334Speter;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
3118334Speter;; updates for most instructions.
3290286Sobrien;;
3318334Speter;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
3418334Speter;; constraint letters.
3590286Sobrien;;
3690286Sobrien;; The special asm out single letter directives following a '%' are:
3718334Speter;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
3818334Speter;;     operands[1].
3918334Speter;; 'L' Print the opcode suffix for a 32-bit integer opcode.
4018334Speter;; 'W' Print the opcode suffix for a 16-bit integer opcode.
4118334Speter;; 'B' Print the opcode suffix for an 8-bit integer opcode.
4250650Sobrien;; 'Q' Print the opcode suffix for a 64-bit float opcode.
4318334Speter;; 'S' Print the opcode suffix for a 32-bit float opcode.
4418334Speter;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
4518334Speter;; 'J' Print the appropriate jump operand.
4690286Sobrien;;
4718334Speter;; 'b' Print the QImode name of the register for the indicated operand.
4818334Speter;;     %b0 would print %al if operands[0] is reg 0.
4918334Speter;; 'w' Likewise, print the HImode name of the register.
5018334Speter;; 'k' Likewise, print the SImode name of the register.
5118334Speter;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
5218334Speter;; 'y' Print "st(0)" instead of "st" as a register.
53117404Skan
5418334Speter;; UNSPEC usage:
5590286Sobrien
56117404Skan(define_constants
57117404Skan  [; Relocation specifiers
58117404Skan   (UNSPEC_GOT			0)
59117404Skan   (UNSPEC_GOTOFF		1)
60117404Skan   (UNSPEC_GOTPCREL		2)
61117404Skan   (UNSPEC_GOTTPOFF		3)
62117404Skan   (UNSPEC_TPOFF		4)
63117404Skan   (UNSPEC_NTPOFF		5)
64117404Skan   (UNSPEC_DTPOFF		6)
65117404Skan   (UNSPEC_GOTNTPOFF		7)
66117404Skan   (UNSPEC_INDNTPOFF		8)
6790286Sobrien
68117404Skan   ; Prologue support
69117404Skan   (UNSPEC_STACK_PROBE		10)
70117404Skan   (UNSPEC_STACK_ALLOC		11)
71117404Skan   (UNSPEC_SET_GOT		12)
72117404Skan   (UNSPEC_SSE_PROLOGUE_SAVE	13)
73117404Skan
74117404Skan   ; TLS support
75117404Skan   (UNSPEC_TP			15)
76117404Skan   (UNSPEC_TLS_GD		16)
77117404Skan   (UNSPEC_TLS_LD_BASE		17)
78117404Skan
79117404Skan   ; Other random patterns
80117404Skan   (UNSPEC_SCAS			20)
81117404Skan   (UNSPEC_SIN			21)
82117404Skan   (UNSPEC_COS			22)
83117404Skan   (UNSPEC_BSF			23)
84117404Skan   (UNSPEC_FNSTSW		24)
85117404Skan   (UNSPEC_SAHF			25)
86117404Skan   (UNSPEC_FSTCW		26)
87117404Skan   (UNSPEC_ADD_CARRY		27)
88117404Skan   (UNSPEC_FLDCW		28)
89117404Skan
90117404Skan   ; For SSE/MMX support:
91117404Skan   (UNSPEC_FIX			30)
92117404Skan   (UNSPEC_MASKMOV		32)
93117404Skan   (UNSPEC_MOVMSK		33)
94117404Skan   (UNSPEC_MOVNT		34)
95117404Skan   (UNSPEC_MOVA			38)
96117404Skan   (UNSPEC_MOVU			39)
97117404Skan   (UNSPEC_SHUFFLE		41)
98117404Skan   (UNSPEC_RCP			42)
99117404Skan   (UNSPEC_RSQRT		43)
100117404Skan   (UNSPEC_SFENCE		44)
101117404Skan   (UNSPEC_NOP			45)	; prevents combiner cleverness
102117404Skan   (UNSPEC_PAVGUSB		49)
103117404Skan   (UNSPEC_PFRCP		50)
104117404Skan   (UNSPEC_PFRCPIT1		51)
105117404Skan   (UNSPEC_PFRCPIT2		52)
106117404Skan   (UNSPEC_PFRSQRT		53)
107117404Skan   (UNSPEC_PFRSQIT1		54)
108117404Skan   (UNSPEC_PSHUFLW		55)
109117404Skan   (UNSPEC_PSHUFHW		56)
110117404Skan   (UNSPEC_MFENCE		59)
111117404Skan   (UNSPEC_LFENCE		60)
112117404Skan   (UNSPEC_PSADBW		61)
113117404Skan  ])
114117404Skan
115117404Skan(define_constants
116117404Skan  [(UNSPECV_BLOCKAGE		0)
117117404Skan   (UNSPECV_EH_RETURN		13)
118117404Skan   (UNSPECV_EMMS		31)
119117404Skan   (UNSPECV_LDMXCSR		37)
120117404Skan   (UNSPECV_STMXCSR		40)
121117404Skan   (UNSPECV_FEMMS		46)
122117404Skan   (UNSPECV_CLFLUSH		57)
123117404Skan  ])
124117404Skan
12590286Sobrien;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
12690286Sobrien;; from i386.c.
12790286Sobrien
12890286Sobrien;; In C guard expressions, put expressions which may be compile-time
12990286Sobrien;; constants first.  This allows for better optimization.  For
13090286Sobrien;; example, write "TARGET_64BIT && reload_completed", not
13190286Sobrien;; "reload_completed && TARGET_64BIT".
13290286Sobrien
13318334Speter
13490286Sobrien;; Processor type.  This attribute must exactly match the processor_type
13590286Sobrien;; enumeration in i386.h.
13690286Sobrien(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
13790286Sobrien  (const (symbol_ref "ix86_cpu")))
13850650Sobrien
13990286Sobrien;; A basic instruction type.  Refinements due to arguments to be
14090286Sobrien;; provided in other attributes.
14152296Sobrien(define_attr "type"
142117404Skan  "other,multi,
143117404Skan   alu,alu1,negnot,imov,imovx,lea,
144117404Skan   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
145117404Skan   icmp,test,ibr,setcc,icmov,
146117404Skan   push,pop,call,callv,
147117404Skan   str,cld,
148117404Skan   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
149117404Skan   sselog,sseiadd,sseishft,sseimul,
150117404Skan   sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
151117404Skan   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
15290286Sobrien  (const_string "other"))
15350650Sobrien
15490286Sobrien;; Main data type used by the insn
155117404Skan(define_attr "mode"
156117404Skan  "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI,V4SF,V2DF,V2SF"
15790286Sobrien  (const_string "unknown"))
15852296Sobrien
159117404Skan;; The CPU unit operations uses.
160117404Skan(define_attr "unit" "integer,i387,sse,mmx,unknown"
161117404Skan  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
162117404Skan	   (const_string "i387")
163117404Skan	 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
164117404Skan			  sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv")
165117404Skan	   (const_string "sse")
166117404Skan	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
167117404Skan	   (const_string "mmx")
168117404Skan	 (eq_attr "type" "other")
169117404Skan	   (const_string "unknown")]
170117404Skan	 (const_string "integer")))
17152296Sobrien
17290286Sobrien;; The (bounding maximum) length of an instruction immediate.
17390286Sobrien(define_attr "length_immediate" ""
174117404Skan  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv")
17590286Sobrien	   (const_int 0)
176117404Skan	 (eq_attr "unit" "i387,sse,mmx")
17790286Sobrien	   (const_int 0)
178117404Skan	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
179117404Skan			  imul,icmp,push,pop")
18090286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
18190286Sobrien	 (eq_attr "type" "imov,test")
18290286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
18390286Sobrien	 (eq_attr "type" "call")
18490286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
18590286Sobrien	     (const_int 4)
18690286Sobrien	     (const_int 0))
18790286Sobrien	 (eq_attr "type" "callv")
18890286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
18990286Sobrien	     (const_int 4)
19090286Sobrien	     (const_int 0))
191117404Skan	 ;; We don't know the size before shorten_branches.  Expect
192117404Skan	 ;; the instruction to fit for better scheduling.
19390286Sobrien	 (eq_attr "type" "ibr")
194117404Skan	   (const_int 1)
19590286Sobrien	 ]
196117404Skan	 (symbol_ref "/* Update immediate_length and other attributes! */
197117404Skan		      abort(),1")))
19852296Sobrien
19990286Sobrien;; The (bounding maximum) length of an instruction address.
20090286Sobrien(define_attr "length_address" ""
20190286Sobrien  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
20290286Sobrien	   (const_int 0)
20390286Sobrien	 (and (eq_attr "type" "call")
204117404Skan	      (match_operand 0 "constant_call_address_operand" ""))
20590286Sobrien	     (const_int 0)
20690286Sobrien	 (and (eq_attr "type" "callv")
20790286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
20890286Sobrien	     (const_int 0)
20990286Sobrien	 ]
21090286Sobrien	 (symbol_ref "ix86_attr_length_address_default (insn)")))
21152296Sobrien
21290286Sobrien;; Set when length prefix is used.
21390286Sobrien(define_attr "prefix_data16" ""
214117404Skan  (if_then_else (ior (eq_attr "mode" "HI")
215117404Skan		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
21690286Sobrien    (const_int 1)
21790286Sobrien    (const_int 0)))
21852296Sobrien
21990286Sobrien;; Set when string REP prefix is used.
220117404Skan(define_attr "prefix_rep" "" 
221117404Skan  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
222117404Skan    (const_int 1)
223117404Skan    (const_int 0)))
22452296Sobrien
22590286Sobrien;; Set when 0f opcode prefix is used.
22690286Sobrien(define_attr "prefix_0f" ""
227117404Skan  (if_then_else 
228117404Skan    (eq_attr "type" 
229117404Skan             "imovx,setcc,icmov,
230117404Skan              sselog,sseiadd,sseishft,sseimul,
231117404Skan              sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
232117404Skan              mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
23390286Sobrien    (const_int 1)
23490286Sobrien    (const_int 0)))
23552296Sobrien
23690286Sobrien;; Set when modrm byte is used.
23790286Sobrien(define_attr "modrm" ""
23890286Sobrien  (cond [(eq_attr "type" "str,cld")
23990286Sobrien	   (const_int 0)
240117404Skan	 (eq_attr "unit" "i387")
24190286Sobrien	   (const_int 0)
24290286Sobrien         (and (eq_attr "type" "incdec")
24390286Sobrien	      (ior (match_operand:SI 1 "register_operand" "")
24490286Sobrien		   (match_operand:HI 1 "register_operand" "")))
24590286Sobrien	   (const_int 0)
24690286Sobrien	 (and (eq_attr "type" "push")
24790286Sobrien	      (not (match_operand 1 "memory_operand" "")))
24890286Sobrien	   (const_int 0)
24990286Sobrien	 (and (eq_attr "type" "pop")
25090286Sobrien	      (not (match_operand 0 "memory_operand" "")))
25190286Sobrien	   (const_int 0)
25290286Sobrien	 (and (eq_attr "type" "imov")
25390286Sobrien	      (and (match_operand 0 "register_operand" "")
25490286Sobrien	           (match_operand 1 "immediate_operand" "")))
25590286Sobrien	   (const_int 0)
256117404Skan	 (and (eq_attr "type" "call")
257117404Skan	      (match_operand 0 "constant_call_address_operand" ""))
258117404Skan	     (const_int 0)
259117404Skan	 (and (eq_attr "type" "callv")
260117404Skan	      (match_operand 1 "constant_call_address_operand" ""))
261117404Skan	     (const_int 0)
26290286Sobrien	 ]
26390286Sobrien	 (const_int 1)))
26490286Sobrien
26590286Sobrien;; The (bounding maximum) length of an instruction in bytes.
26690286Sobrien;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
26790286Sobrien;; to split it and compute proper length as for other insns.
26890286Sobrien(define_attr "length" ""
26990286Sobrien  (cond [(eq_attr "type" "other,multi,fistp")
27090286Sobrien	   (const_int 16)
271117404Skan	 (eq_attr "type" "fcmp")
272117404Skan	   (const_int 4)
273117404Skan	 (eq_attr "unit" "i387")
274117404Skan	   (plus (const_int 2)
275117404Skan		 (plus (attr "prefix_data16")
276117404Skan		       (attr "length_address")))]
27790286Sobrien	 (plus (plus (attr "modrm")
27890286Sobrien		     (plus (attr "prefix_0f")
279117404Skan			   (const_int 1)))
28090286Sobrien	       (plus (attr "prefix_rep")
28190286Sobrien		     (plus (attr "prefix_data16")
28290286Sobrien			   (plus (attr "length_immediate")
28390286Sobrien				 (attr "length_address")))))))
28490286Sobrien
28590286Sobrien;; The `memory' attribute is `none' if no memory is referenced, `load' or
28690286Sobrien;; `store' if there is a simple memory reference therein, or `unknown'
28790286Sobrien;; if the instruction is complex.
28890286Sobrien
28990286Sobrien(define_attr "memory" "none,load,store,both,unknown"
29090286Sobrien  (cond [(eq_attr "type" "other,multi,str")
29190286Sobrien	   (const_string "unknown")
29290286Sobrien	 (eq_attr "type" "lea,fcmov,fpspc,cld")
29390286Sobrien	   (const_string "none")
29490286Sobrien	 (eq_attr "type" "fistp")
29590286Sobrien	   (const_string "both")
29690286Sobrien	 (eq_attr "type" "push")
29790286Sobrien	   (if_then_else (match_operand 1 "memory_operand" "")
29890286Sobrien	     (const_string "both")
29990286Sobrien	     (const_string "store"))
30090286Sobrien	 (eq_attr "type" "pop,setcc")
30190286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
30290286Sobrien	     (const_string "both")
30390286Sobrien	     (const_string "load"))
304117404Skan	 (eq_attr "type" "icmp,test,ssecmp,mmxcmp,fcmp")
30590286Sobrien	   (if_then_else (ior (match_operand 0 "memory_operand" "")
30690286Sobrien			      (match_operand 1 "memory_operand" ""))
30790286Sobrien	     (const_string "load")
30890286Sobrien	     (const_string "none"))
30990286Sobrien	 (eq_attr "type" "ibr")
31090286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
31190286Sobrien	     (const_string "load")
31290286Sobrien	     (const_string "none"))
31390286Sobrien	 (eq_attr "type" "call")
31490286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
31590286Sobrien	     (const_string "none")
31690286Sobrien	     (const_string "load"))
31790286Sobrien	 (eq_attr "type" "callv")
31890286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
31990286Sobrien	     (const_string "none")
32090286Sobrien	     (const_string "load"))
32190286Sobrien	 (and (eq_attr "type" "alu1,negnot")
32290286Sobrien	      (match_operand 1 "memory_operand" ""))
32390286Sobrien	   (const_string "both")
32490286Sobrien	 (and (match_operand 0 "memory_operand" "")
32590286Sobrien	      (match_operand 1 "memory_operand" ""))
32690286Sobrien	   (const_string "both")
32790286Sobrien	 (match_operand 0 "memory_operand" "")
32890286Sobrien	   (const_string "store")
32990286Sobrien	 (match_operand 1 "memory_operand" "")
33090286Sobrien	   (const_string "load")
331117404Skan	 (and (eq_attr "type"
332117404Skan		 "!alu1,negnot,
333117404Skan		   imov,imovx,icmp,test,
334117404Skan		   fmov,fcmp,fsgn,
335117404Skan		   sse,ssemov,ssecmp,ssecvt,
336117404Skan		   mmx,mmxmov,mmxcmp,mmxcvt")
33790286Sobrien	      (match_operand 2 "memory_operand" ""))
33890286Sobrien	   (const_string "load")
33990286Sobrien	 (and (eq_attr "type" "icmov")
34090286Sobrien	      (match_operand 3 "memory_operand" ""))
34190286Sobrien	   (const_string "load")
34290286Sobrien	]
34352296Sobrien	(const_string "none")))
34452296Sobrien
34590286Sobrien;; Indicates if an instruction has both an immediate and a displacement.
34650650Sobrien
34790286Sobrien(define_attr "imm_disp" "false,true,unknown"
34890286Sobrien  (cond [(eq_attr "type" "other,multi")
34990286Sobrien	   (const_string "unknown")
350117404Skan	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
35190286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
35290286Sobrien		   (match_operand 1 "immediate_operand" "")))
35390286Sobrien	   (const_string "true")
354117404Skan	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
35590286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
35690286Sobrien		   (match_operand 2 "immediate_operand" "")))
35790286Sobrien	   (const_string "true")
35890286Sobrien	]
35990286Sobrien	(const_string "false")))
36050650Sobrien
36190286Sobrien;; Indicates if an FP operation has an integer source.
36250650Sobrien
36390286Sobrien(define_attr "fp_int_src" "false,true"
36490286Sobrien  (const_string "false"))
36550650Sobrien
36690286Sobrien;; Describe a user's asm statement.
36790286Sobrien(define_asm_attributes
36890286Sobrien  [(set_attr "length" "128")
36990286Sobrien   (set_attr "type" "multi")])
37090286Sobrien
371117404Skan(include "pentium.md")
372117404Skan(include "ppro.md")
373117404Skan(include "k6.md")
374117404Skan(include "athlon.md")
37590286Sobrien
37690286Sobrien;; Compare instructions.
37790286Sobrien
37890286Sobrien;; All compare insns have expanders that save the operands away without
37990286Sobrien;; actually generating RTL.  The bCOND or sCOND (emitted immediately
38090286Sobrien;; after the cmp) will actually emit the cmpM.
38190286Sobrien
38290286Sobrien(define_expand "cmpdi"
38390286Sobrien  [(set (reg:CC 17)
38490286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
38590286Sobrien		    (match_operand:DI 1 "x86_64_general_operand" "")))]
38690286Sobrien  ""
38718334Speter{
38890286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
38990286Sobrien    operands[0] = force_reg (DImode, operands[0]);
39090286Sobrien  ix86_compare_op0 = operands[0];
39190286Sobrien  ix86_compare_op1 = operands[1];
39218334Speter  DONE;
39390286Sobrien})
39418334Speter
39518334Speter(define_expand "cmpsi"
39690286Sobrien  [(set (reg:CC 17)
39790286Sobrien	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
39890286Sobrien		    (match_operand:SI 1 "general_operand" "")))]
39918334Speter  ""
40018334Speter{
40118334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
40218334Speter    operands[0] = force_reg (SImode, operands[0]);
40390286Sobrien  ix86_compare_op0 = operands[0];
40490286Sobrien  ix86_compare_op1 = operands[1];
40518334Speter  DONE;
40690286Sobrien})
40718334Speter
40818334Speter(define_expand "cmphi"
40990286Sobrien  [(set (reg:CC 17)
41090286Sobrien	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
41190286Sobrien		    (match_operand:HI 1 "general_operand" "")))]
41218334Speter  ""
41318334Speter{
41418334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
41518334Speter    operands[0] = force_reg (HImode, operands[0]);
41690286Sobrien  ix86_compare_op0 = operands[0];
41790286Sobrien  ix86_compare_op1 = operands[1];
41818334Speter  DONE;
41990286Sobrien})
42018334Speter
42118334Speter(define_expand "cmpqi"
42290286Sobrien  [(set (reg:CC 17)
42390286Sobrien	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
42490286Sobrien		    (match_operand:QI 1 "general_operand" "")))]
42590286Sobrien  "TARGET_QIMODE_MATH"
42618334Speter{
42718334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
42818334Speter    operands[0] = force_reg (QImode, operands[0]);
42990286Sobrien  ix86_compare_op0 = operands[0];
43090286Sobrien  ix86_compare_op1 = operands[1];
43118334Speter  DONE;
43290286Sobrien})
43318334Speter
43490286Sobrien(define_insn "cmpdi_ccno_1_rex64"
43590286Sobrien  [(set (reg 17)
43690286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
43790286Sobrien		 (match_operand:DI 1 "const0_operand" "n,n")))]
43890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
43990286Sobrien  "@
44090286Sobrien   test{q}\t{%0, %0|%0, %0}
44190286Sobrien   cmp{q}\t{%1, %0|%0, %1}"
44290286Sobrien  [(set_attr "type" "test,icmp")
44390286Sobrien   (set_attr "length_immediate" "0,1")
44490286Sobrien   (set_attr "mode" "DI")])
44518334Speter
44690286Sobrien(define_insn "*cmpdi_minus_1_rex64"
44790286Sobrien  [(set (reg 17)
44890286Sobrien	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
44990286Sobrien			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
45090286Sobrien		 (const_int 0)))]
45190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
45290286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
45390286Sobrien  [(set_attr "type" "icmp")
45490286Sobrien   (set_attr "mode" "DI")])
45518334Speter
45690286Sobrien(define_expand "cmpdi_1_rex64"
45790286Sobrien  [(set (reg:CC 17)
45890286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
45990286Sobrien		    (match_operand:DI 1 "general_operand" "")))]
46090286Sobrien  "TARGET_64BIT"
46190286Sobrien  "")
46218334Speter
46390286Sobrien(define_insn "cmpdi_1_insn_rex64"
46490286Sobrien  [(set (reg 17)
46590286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
46690286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
46790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
46890286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
46990286Sobrien  [(set_attr "type" "icmp")
47090286Sobrien   (set_attr "mode" "DI")])
47150650Sobrien
47218334Speter
47390286Sobrien(define_insn "*cmpsi_ccno_1"
47490286Sobrien  [(set (reg 17)
47590286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
47690286Sobrien		 (match_operand:SI 1 "const0_operand" "n,n")))]
47790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
47890286Sobrien  "@
47990286Sobrien   test{l}\t{%0, %0|%0, %0}
48090286Sobrien   cmp{l}\t{%1, %0|%0, %1}"
48190286Sobrien  [(set_attr "type" "test,icmp")
48290286Sobrien   (set_attr "length_immediate" "0,1")
48390286Sobrien   (set_attr "mode" "SI")])
48450650Sobrien
48590286Sobrien(define_insn "*cmpsi_minus_1"
48690286Sobrien  [(set (reg 17)
48790286Sobrien	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
48890286Sobrien			   (match_operand:SI 1 "general_operand" "ri,mr"))
48990286Sobrien		 (const_int 0)))]
49090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
49190286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
49290286Sobrien  [(set_attr "type" "icmp")
49390286Sobrien   (set_attr "mode" "SI")])
49418334Speter
49590286Sobrien(define_expand "cmpsi_1"
49690286Sobrien  [(set (reg:CC 17)
49790286Sobrien	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
49890286Sobrien		    (match_operand:SI 1 "general_operand" "ri,mr")))]
49990286Sobrien  ""
50090286Sobrien  "")
50118334Speter
50290286Sobrien(define_insn "*cmpsi_1_insn"
50390286Sobrien  [(set (reg 17)
50490286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
50590286Sobrien		 (match_operand:SI 1 "general_operand" "ri,mr")))]
50690286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
50790286Sobrien    && ix86_match_ccmode (insn, CCmode)"
50890286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
50990286Sobrien  [(set_attr "type" "icmp")
51090286Sobrien   (set_attr "mode" "SI")])
51118334Speter
51290286Sobrien(define_insn "*cmphi_ccno_1"
51390286Sobrien  [(set (reg 17)
51490286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
51590286Sobrien		 (match_operand:HI 1 "const0_operand" "n,n")))]
51690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
51790286Sobrien  "@
51890286Sobrien   test{w}\t{%0, %0|%0, %0}
51990286Sobrien   cmp{w}\t{%1, %0|%0, %1}"
52090286Sobrien  [(set_attr "type" "test,icmp")
52190286Sobrien   (set_attr "length_immediate" "0,1")
52290286Sobrien   (set_attr "mode" "HI")])
52318334Speter
52490286Sobrien(define_insn "*cmphi_minus_1"
52590286Sobrien  [(set (reg 17)
52690286Sobrien	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
52790286Sobrien			   (match_operand:HI 1 "general_operand" "ri,mr"))
52890286Sobrien		 (const_int 0)))]
52990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
53090286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
53190286Sobrien  [(set_attr "type" "icmp")
53290286Sobrien   (set_attr "mode" "HI")])
53350650Sobrien
53490286Sobrien(define_insn "*cmphi_1"
53590286Sobrien  [(set (reg 17)
53690286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
53790286Sobrien		 (match_operand:HI 1 "general_operand" "ri,mr")))]
53890286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
53990286Sobrien   && ix86_match_ccmode (insn, CCmode)"
54090286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
54190286Sobrien  [(set_attr "type" "icmp")
54290286Sobrien   (set_attr "mode" "HI")])
54318334Speter
54490286Sobrien(define_insn "*cmpqi_ccno_1"
54590286Sobrien  [(set (reg 17)
54690286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
54790286Sobrien		 (match_operand:QI 1 "const0_operand" "n,n")))]
54890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
54990286Sobrien  "@
55090286Sobrien   test{b}\t{%0, %0|%0, %0}
55190286Sobrien   cmp{b}\t{$0, %0|%0, 0}"
55290286Sobrien  [(set_attr "type" "test,icmp")
55390286Sobrien   (set_attr "length_immediate" "0,1")
55490286Sobrien   (set_attr "mode" "QI")])
55518334Speter
55690286Sobrien(define_insn "*cmpqi_1"
55790286Sobrien  [(set (reg 17)
55890286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
55990286Sobrien		 (match_operand:QI 1 "general_operand" "qi,mq")))]
56090286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
56190286Sobrien    && ix86_match_ccmode (insn, CCmode)"
56290286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
56390286Sobrien  [(set_attr "type" "icmp")
56490286Sobrien   (set_attr "mode" "QI")])
56518334Speter
56690286Sobrien(define_insn "*cmpqi_minus_1"
56790286Sobrien  [(set (reg 17)
56890286Sobrien	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
56990286Sobrien			   (match_operand:QI 1 "general_operand" "qi,mq"))
57090286Sobrien		 (const_int 0)))]
57190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
57290286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
57390286Sobrien  [(set_attr "type" "icmp")
57490286Sobrien   (set_attr "mode" "QI")])
57518334Speter
57690286Sobrien(define_insn "*cmpqi_ext_1"
57790286Sobrien  [(set (reg 17)
57890286Sobrien	(compare
57990286Sobrien	  (match_operand:QI 0 "general_operand" "Qm")
58090286Sobrien	  (subreg:QI
58190286Sobrien	    (zero_extract:SI
58290286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
58390286Sobrien	      (const_int 8)
58490286Sobrien	      (const_int 8)) 0)))]
58590286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
58690286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
58790286Sobrien  [(set_attr "type" "icmp")
58890286Sobrien   (set_attr "mode" "QI")])
58990286Sobrien
59090286Sobrien(define_insn "*cmpqi_ext_1_rex64"
59190286Sobrien  [(set (reg 17)
59290286Sobrien	(compare
59390286Sobrien	  (match_operand:QI 0 "register_operand" "Q")
59490286Sobrien	  (subreg:QI
59590286Sobrien	    (zero_extract:SI
59690286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
59790286Sobrien	      (const_int 8)
59890286Sobrien	      (const_int 8)) 0)))]
59990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
60090286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
60190286Sobrien  [(set_attr "type" "icmp")
60290286Sobrien   (set_attr "mode" "QI")])
60390286Sobrien
60490286Sobrien(define_insn "*cmpqi_ext_2"
60590286Sobrien  [(set (reg 17)
60690286Sobrien	(compare
60790286Sobrien	  (subreg:QI
60890286Sobrien	    (zero_extract:SI
60990286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
61090286Sobrien	      (const_int 8)
61190286Sobrien	      (const_int 8)) 0)
61290286Sobrien	  (match_operand:QI 1 "const0_operand" "n")))]
61390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
61490286Sobrien  "test{b}\t%h0, %h0"
61590286Sobrien  [(set_attr "type" "test")
61690286Sobrien   (set_attr "length_immediate" "0")
61790286Sobrien   (set_attr "mode" "QI")])
61890286Sobrien
61990286Sobrien(define_expand "cmpqi_ext_3"
62090286Sobrien  [(set (reg:CC 17)
62190286Sobrien	(compare:CC
62290286Sobrien	  (subreg:QI
62390286Sobrien	    (zero_extract:SI
62490286Sobrien	      (match_operand 0 "ext_register_operand" "")
62590286Sobrien	      (const_int 8)
62690286Sobrien	      (const_int 8)) 0)
62790286Sobrien	  (match_operand:QI 1 "general_operand" "")))]
62890286Sobrien  ""
62990286Sobrien  "")
63090286Sobrien
63190286Sobrien(define_insn "cmpqi_ext_3_insn"
63290286Sobrien  [(set (reg 17)
63390286Sobrien	(compare
63490286Sobrien	  (subreg:QI
63590286Sobrien	    (zero_extract:SI
63690286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
63790286Sobrien	      (const_int 8)
63890286Sobrien	      (const_int 8)) 0)
63990286Sobrien	  (match_operand:QI 1 "general_operand" "Qmn")))]
64090286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
64190286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
64290286Sobrien  [(set_attr "type" "icmp")
64390286Sobrien   (set_attr "mode" "QI")])
64490286Sobrien
64590286Sobrien(define_insn "cmpqi_ext_3_insn_rex64"
64690286Sobrien  [(set (reg 17)
64790286Sobrien	(compare
64890286Sobrien	  (subreg:QI
64990286Sobrien	    (zero_extract:SI
65090286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
65190286Sobrien	      (const_int 8)
65290286Sobrien	      (const_int 8)) 0)
65390286Sobrien	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
65490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
65590286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
65690286Sobrien  [(set_attr "type" "icmp")
65790286Sobrien   (set_attr "mode" "QI")])
65890286Sobrien
65990286Sobrien(define_insn "*cmpqi_ext_4"
66090286Sobrien  [(set (reg 17)
66190286Sobrien	(compare
66290286Sobrien	  (subreg:QI
66390286Sobrien	    (zero_extract:SI
66490286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
66590286Sobrien	      (const_int 8)
66690286Sobrien	      (const_int 8)) 0)
66790286Sobrien	  (subreg:QI
66890286Sobrien	    (zero_extract:SI
66990286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
67090286Sobrien	      (const_int 8)
67190286Sobrien	      (const_int 8)) 0)))]
67290286Sobrien  "ix86_match_ccmode (insn, CCmode)"
67390286Sobrien  "cmp{b}\t{%h1, %h0|%h0, %h1}"
67490286Sobrien  [(set_attr "type" "icmp")
67590286Sobrien   (set_attr "mode" "QI")])
67690286Sobrien
67790286Sobrien;; These implement float point compares.
67890286Sobrien;; %%% See if we can get away with VOIDmode operands on the actual insns,
67990286Sobrien;; which would allow mix and match FP modes on the compares.  Which is what
68090286Sobrien;; the old patterns did, but with many more of them.
68190286Sobrien
68218334Speter(define_expand "cmpxf"
68390286Sobrien  [(set (reg:CC 17)
68490286Sobrien	(compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
68590286Sobrien		    (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
68690286Sobrien  "!TARGET_64BIT && TARGET_80387"
68790286Sobrien{
68890286Sobrien  ix86_compare_op0 = operands[0];
68990286Sobrien  ix86_compare_op1 = operands[1];
69090286Sobrien  DONE;
69190286Sobrien})
69290286Sobrien
69390286Sobrien(define_expand "cmptf"
69490286Sobrien  [(set (reg:CC 17)
69590286Sobrien	(compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
69690286Sobrien		    (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
69718334Speter  "TARGET_80387"
69818334Speter{
69990286Sobrien  ix86_compare_op0 = operands[0];
70090286Sobrien  ix86_compare_op1 = operands[1];
70118334Speter  DONE;
70290286Sobrien})
70318334Speter
70418334Speter(define_expand "cmpdf"
70590286Sobrien  [(set (reg:CC 17)
70690286Sobrien	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
70790286Sobrien		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
70890286Sobrien  "TARGET_80387 || TARGET_SSE2"
70918334Speter{
71090286Sobrien  ix86_compare_op0 = operands[0];
71190286Sobrien  ix86_compare_op1 = operands[1];
71218334Speter  DONE;
71390286Sobrien})
71418334Speter
71518334Speter(define_expand "cmpsf"
71690286Sobrien  [(set (reg:CC 17)
71790286Sobrien	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
71890286Sobrien		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
71990286Sobrien  "TARGET_80387 || TARGET_SSE"
72018334Speter{
72190286Sobrien  ix86_compare_op0 = operands[0];
72290286Sobrien  ix86_compare_op1 = operands[1];
72318334Speter  DONE;
72490286Sobrien})
72518334Speter
72690286Sobrien;; FP compares, step 1:
72790286Sobrien;; Set the FP condition codes.
72890286Sobrien;;
72990286Sobrien;; CCFPmode	compare with exceptions
73090286Sobrien;; CCFPUmode	compare with no exceptions
73118334Speter
73290286Sobrien;; %%% It is an unfortunate fact that ftst has no non-popping variant,
73390286Sobrien;; and that fp moves clobber the condition codes, and that there is
73490286Sobrien;; currently no way to describe this fact to reg-stack.  So there are
73590286Sobrien;; no splitters yet for this.
73618334Speter
73790286Sobrien;; %%% YIKES!  This scheme does not retain a strong connection between 
73890286Sobrien;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
73990286Sobrien;; work!  Only allow tos/mem with tos in op 0.
74090286Sobrien;;
74190286Sobrien;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
74290286Sobrien;; things aren't as bad as they sound...
74390286Sobrien
74490286Sobrien(define_insn "*cmpfp_0"
74590286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
74690286Sobrien	(unspec:HI
74790286Sobrien	  [(compare:CCFP (match_operand 1 "register_operand" "f")
748117404Skan		         (match_operand 2 "const0_operand" "X"))]
749117404Skan	  UNSPEC_FNSTSW))]
75090286Sobrien  "TARGET_80387
75190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
75290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
75390286Sobrien{
75490286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
75590286Sobrien    return "ftst\;fnstsw\t%0\;fstp\t%y0";
75690286Sobrien  else
75790286Sobrien    return "ftst\;fnstsw\t%0";
75890286Sobrien}
75990286Sobrien  [(set_attr "type" "multi")
76090286Sobrien   (set_attr "mode" "unknownfp")])
76190286Sobrien
76290286Sobrien;; We may not use "#" to split and emit these, since the REG_DEAD notes
76390286Sobrien;; used to manage the reg stack popping would not be preserved.
76490286Sobrien
76590286Sobrien(define_insn "*cmpfp_2_sf"
76690286Sobrien  [(set (reg:CCFP 18)
76790286Sobrien	(compare:CCFP
76890286Sobrien	  (match_operand:SF 0 "register_operand" "f")
76990286Sobrien	  (match_operand:SF 1 "nonimmediate_operand" "fm")))]
77018334Speter  "TARGET_80387"
77190286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
77290286Sobrien  [(set_attr "type" "fcmp")
77390286Sobrien   (set_attr "mode" "SF")])
77418334Speter
77590286Sobrien(define_insn "*cmpfp_2_sf_1"
77690286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
77790286Sobrien	(unspec:HI
77890286Sobrien	  [(compare:CCFP
77990286Sobrien	     (match_operand:SF 1 "register_operand" "f")
780117404Skan	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
781117404Skan	  UNSPEC_FNSTSW))]
78218334Speter  "TARGET_80387"
78390286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
78490286Sobrien  [(set_attr "type" "fcmp")
78590286Sobrien   (set_attr "mode" "SF")])
78618334Speter
78790286Sobrien(define_insn "*cmpfp_2_df"
78890286Sobrien  [(set (reg:CCFP 18)
78990286Sobrien	(compare:CCFP
79090286Sobrien	  (match_operand:DF 0 "register_operand" "f")
79190286Sobrien	  (match_operand:DF 1 "nonimmediate_operand" "fm")))]
79218334Speter  "TARGET_80387"
79390286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
79490286Sobrien  [(set_attr "type" "fcmp")
79590286Sobrien   (set_attr "mode" "DF")])
79618334Speter
79790286Sobrien(define_insn "*cmpfp_2_df_1"
79890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
79990286Sobrien	(unspec:HI
80090286Sobrien	  [(compare:CCFP
80190286Sobrien	     (match_operand:DF 1 "register_operand" "f")
802117404Skan	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
803117404Skan	  UNSPEC_FNSTSW))]
80418334Speter  "TARGET_80387"
80590286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
80690286Sobrien  [(set_attr "type" "multi")
80790286Sobrien   (set_attr "mode" "DF")])
80818334Speter
80990286Sobrien(define_insn "*cmpfp_2_xf"
81090286Sobrien  [(set (reg:CCFP 18)
81190286Sobrien	(compare:CCFP
81290286Sobrien	  (match_operand:XF 0 "register_operand" "f")
81390286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
81490286Sobrien  "!TARGET_64BIT && TARGET_80387"
81590286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
81690286Sobrien  [(set_attr "type" "fcmp")
81790286Sobrien   (set_attr "mode" "XF")])
81818334Speter
81990286Sobrien(define_insn "*cmpfp_2_tf"
82090286Sobrien  [(set (reg:CCFP 18)
82190286Sobrien	(compare:CCFP
82290286Sobrien	  (match_operand:TF 0 "register_operand" "f")
82390286Sobrien	  (match_operand:TF 1 "register_operand" "f")))]
82490286Sobrien  "TARGET_80387"
82590286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
82690286Sobrien  [(set_attr "type" "fcmp")
82790286Sobrien   (set_attr "mode" "XF")])
82818334Speter
82990286Sobrien(define_insn "*cmpfp_2_xf_1"
83090286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
83190286Sobrien	(unspec:HI
83290286Sobrien	  [(compare:CCFP
83390286Sobrien	     (match_operand:XF 1 "register_operand" "f")
834117404Skan	     (match_operand:XF 2 "register_operand" "f"))]
835117404Skan	  UNSPEC_FNSTSW))]
83690286Sobrien  "!TARGET_64BIT && TARGET_80387"
83790286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
83890286Sobrien  [(set_attr "type" "multi")
83990286Sobrien   (set_attr "mode" "XF")])
84018334Speter
84190286Sobrien(define_insn "*cmpfp_2_tf_1"
84290286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
84390286Sobrien	(unspec:HI
84490286Sobrien	  [(compare:CCFP
84590286Sobrien	     (match_operand:TF 1 "register_operand" "f")
846117404Skan	     (match_operand:TF 2 "register_operand" "f"))]
847117404Skan	  UNSPEC_FNSTSW))]
84890286Sobrien  "TARGET_80387"
84990286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
85090286Sobrien  [(set_attr "type" "multi")
85190286Sobrien   (set_attr "mode" "XF")])
85218334Speter
85390286Sobrien(define_insn "*cmpfp_2u"
85490286Sobrien  [(set (reg:CCFPU 18)
85590286Sobrien	(compare:CCFPU
85690286Sobrien	  (match_operand 0 "register_operand" "f")
85790286Sobrien	  (match_operand 1 "register_operand" "f")))]
85890286Sobrien  "TARGET_80387
85990286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
86090286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
86190286Sobrien  "* return output_fp_compare (insn, operands, 0, 1);"
86290286Sobrien  [(set_attr "type" "fcmp")
86390286Sobrien   (set_attr "mode" "unknownfp")])
86418334Speter
86590286Sobrien(define_insn "*cmpfp_2u_1"
86690286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
86790286Sobrien	(unspec:HI
86890286Sobrien	  [(compare:CCFPU
86990286Sobrien	     (match_operand 1 "register_operand" "f")
870117404Skan	     (match_operand 2 "register_operand" "f"))]
871117404Skan	  UNSPEC_FNSTSW))]
87290286Sobrien  "TARGET_80387
87390286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
87490286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
87590286Sobrien  "* return output_fp_compare (insn, operands, 2, 1);"
87690286Sobrien  [(set_attr "type" "multi")
87790286Sobrien   (set_attr "mode" "unknownfp")])
87818334Speter
87990286Sobrien;; Patterns to match the SImode-in-memory ficom instructions.
88090286Sobrien;;
88190286Sobrien;; %%% Play games with accepting gp registers, as otherwise we have to
88290286Sobrien;; force them to memory during rtl generation, which is no good.  We
88390286Sobrien;; can get rid of this once we teach reload to do memory input reloads 
88490286Sobrien;; via pushes.
88518334Speter
88690286Sobrien(define_insn "*ficom_1"
88790286Sobrien  [(set (reg:CCFP 18)
88890286Sobrien	(compare:CCFP
88990286Sobrien	  (match_operand 0 "register_operand" "f,f")
89090286Sobrien	  (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
89190286Sobrien  "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
89290286Sobrien   && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
89390286Sobrien  "#")
89418334Speter
89590286Sobrien;; Split the not-really-implemented gp register case into a
89690286Sobrien;; push-op-pop sequence.
89790286Sobrien;;
89890286Sobrien;; %%% This is most efficient, but am I gonna get in trouble
89990286Sobrien;; for separating cc0_setter and cc0_user?
90018334Speter
90190286Sobrien(define_split
90290286Sobrien  [(set (reg:CCFP 18)
90390286Sobrien	(compare:CCFP
90490286Sobrien	  (match_operand:SF 0 "register_operand" "")
90590286Sobrien	  (float (match_operand:SI 1 "register_operand" ""))))]
90690286Sobrien  "0 && TARGET_80387 && reload_completed"
90790286Sobrien  [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
90890286Sobrien   (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
90990286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
91090286Sobrien              (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
91190286Sobrien  "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
91290286Sobrien   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
91318334Speter
91490286Sobrien;; FP compares, step 2
91590286Sobrien;; Move the fpsw to ax.
91618334Speter
91790286Sobrien(define_insn "x86_fnstsw_1"
91890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
919117404Skan	(unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
92090286Sobrien  "TARGET_80387"
92190286Sobrien  "fnstsw\t%0"
92290286Sobrien  [(set_attr "length" "2")
92390286Sobrien   (set_attr "mode" "SI")
924117404Skan   (set_attr "unit" "i387")
92590286Sobrien   (set_attr "ppro_uops" "few")])
92618334Speter
92790286Sobrien;; FP compares, step 3
92890286Sobrien;; Get ax into flags, general case.
92950650Sobrien
93090286Sobrien(define_insn "x86_sahf_1"
93190286Sobrien  [(set (reg:CC 17)
932117404Skan	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
93390286Sobrien  "!TARGET_64BIT"
93490286Sobrien  "sahf"
93590286Sobrien  [(set_attr "length" "1")
93690286Sobrien   (set_attr "athlon_decode" "vector")
93790286Sobrien   (set_attr "mode" "SI")
93890286Sobrien   (set_attr "ppro_uops" "one")])
93918334Speter
94090286Sobrien;; Pentium Pro can do steps 1 through 3 in one go.
94118334Speter
94290286Sobrien(define_insn "*cmpfp_i"
94390286Sobrien  [(set (reg:CCFP 17)
94490286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f")
94590286Sobrien		      (match_operand 1 "register_operand" "f")))]
94690286Sobrien  "TARGET_80387 && TARGET_CMOVE
94790286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
94890286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
94990286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
95090286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
95190286Sobrien  [(set_attr "type" "fcmp")
95290286Sobrien   (set_attr "mode" "unknownfp")
95390286Sobrien   (set_attr "athlon_decode" "vector")])
95418334Speter
95590286Sobrien(define_insn "*cmpfp_i_sse"
95690286Sobrien  [(set (reg:CCFP 17)
95790286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
95890286Sobrien		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
95990286Sobrien  "TARGET_80387
96090286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
96190286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
96290286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
963117404Skan  [(set_attr "type" "fcmp,ssecmp")
96490286Sobrien   (set_attr "mode" "unknownfp")
96590286Sobrien   (set_attr "athlon_decode" "vector")])
96618334Speter
96790286Sobrien(define_insn "*cmpfp_i_sse_only"
96890286Sobrien  [(set (reg:CCFP 17)
96990286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "x")
97090286Sobrien		      (match_operand 1 "nonimmediate_operand" "xm")))]
97190286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
97290286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
97390286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
974117404Skan  [(set_attr "type" "ssecmp")
97590286Sobrien   (set_attr "mode" "unknownfp")
97690286Sobrien   (set_attr "athlon_decode" "vector")])
97718334Speter
97890286Sobrien(define_insn "*cmpfp_iu"
97990286Sobrien  [(set (reg:CCFPU 17)
98090286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f")
98190286Sobrien		       (match_operand 1 "register_operand" "f")))]
98290286Sobrien  "TARGET_80387 && TARGET_CMOVE
98390286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
98490286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
98590286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
98690286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
98790286Sobrien  [(set_attr "type" "fcmp")
98890286Sobrien   (set_attr "mode" "unknownfp")
98990286Sobrien   (set_attr "athlon_decode" "vector")])
99018334Speter
99190286Sobrien(define_insn "*cmpfp_iu_sse"
99290286Sobrien  [(set (reg:CCFPU 17)
99390286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
99490286Sobrien		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
99590286Sobrien  "TARGET_80387
99690286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
99790286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
99890286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
999117404Skan  [(set_attr "type" "fcmp,ssecmp")
100090286Sobrien   (set_attr "mode" "unknownfp")
100190286Sobrien   (set_attr "athlon_decode" "vector")])
100250650Sobrien
100390286Sobrien(define_insn "*cmpfp_iu_sse_only"
100490286Sobrien  [(set (reg:CCFPU 17)
100590286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "x")
100690286Sobrien		       (match_operand 1 "nonimmediate_operand" "xm")))]
100790286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
100890286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
100990286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
1010117404Skan  [(set_attr "type" "ssecmp")
101190286Sobrien   (set_attr "mode" "unknownfp")
101290286Sobrien   (set_attr "athlon_decode" "vector")])
101390286Sobrien
101490286Sobrien;; Move instructions.
101518334Speter
101618334Speter;; General case of fullword move.
101718334Speter
101818334Speter(define_expand "movsi"
101990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
102018334Speter	(match_operand:SI 1 "general_operand" ""))]
102118334Speter  ""
102290286Sobrien  "ix86_expand_move (SImode, operands); DONE;")
102318334Speter
102490286Sobrien;; Push/pop instructions.  They are separate since autoinc/dec is not a
102590286Sobrien;; general_operand.
102690286Sobrien;;
102790286Sobrien;; %%% We don't use a post-inc memory reference because x86 is not a 
102890286Sobrien;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
102990286Sobrien;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
103090286Sobrien;; targets without our curiosities, and it is just as easy to represent
103190286Sobrien;; this differently.
103218334Speter
103390286Sobrien(define_insn "*pushsi2"
103490286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
103590286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
103690286Sobrien  "!TARGET_64BIT"
103790286Sobrien  "push{l}\t%1"
103890286Sobrien  [(set_attr "type" "push")
103990286Sobrien   (set_attr "mode" "SI")])
104018334Speter
104190286Sobrien;; For 64BIT abi we always round up to 8 bytes.
104290286Sobrien(define_insn "*pushsi2_rex64"
104390286Sobrien  [(set (match_operand:SI 0 "push_operand" "=X")
104490286Sobrien	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
104590286Sobrien  "TARGET_64BIT"
104690286Sobrien  "push{q}\t%q1"
104790286Sobrien  [(set_attr "type" "push")
104890286Sobrien   (set_attr "mode" "SI")])
104918334Speter
105090286Sobrien(define_insn "*pushsi2_prologue"
105190286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
105290286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
105390286Sobrien   (clobber (mem:BLK (scratch)))]
105490286Sobrien  "!TARGET_64BIT"
105590286Sobrien  "push{l}\t%1"
105690286Sobrien  [(set_attr "type" "push")
105790286Sobrien   (set_attr "mode" "SI")])
105852296Sobrien
105990286Sobrien(define_insn "*popsi1_epilogue"
106090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
106190286Sobrien	(mem:SI (reg:SI 7)))
106290286Sobrien   (set (reg:SI 7)
106390286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))
106490286Sobrien   (clobber (mem:BLK (scratch)))]
106590286Sobrien  "!TARGET_64BIT"
106690286Sobrien  "pop{l}\t%0"
106790286Sobrien  [(set_attr "type" "pop")
106890286Sobrien   (set_attr "mode" "SI")])
106918334Speter
107090286Sobrien(define_insn "popsi1"
107190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
107290286Sobrien	(mem:SI (reg:SI 7)))
107390286Sobrien   (set (reg:SI 7)
107490286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))]
107590286Sobrien  "!TARGET_64BIT"
107690286Sobrien  "pop{l}\t%0"
107790286Sobrien  [(set_attr "type" "pop")
107890286Sobrien   (set_attr "mode" "SI")])
107918334Speter
108090286Sobrien(define_insn "*movsi_xor"
108190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
108290286Sobrien	(match_operand:SI 1 "const0_operand" "i"))
108390286Sobrien   (clobber (reg:CC 17))]
108490286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
108590286Sobrien  "xor{l}\t{%0, %0|%0, %0}"
108690286Sobrien  [(set_attr "type" "alu1")
108790286Sobrien   (set_attr "mode" "SI")
108890286Sobrien   (set_attr "length_immediate" "0")])
108918334Speter
109090286Sobrien(define_insn "*movsi_or"
109190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
109290286Sobrien	(match_operand:SI 1 "immediate_operand" "i"))
109390286Sobrien   (clobber (reg:CC 17))]
109490286Sobrien  "reload_completed && GET_CODE (operands[1]) == CONST_INT
109590286Sobrien   && INTVAL (operands[1]) == -1
109690286Sobrien   && (TARGET_PENTIUM || optimize_size)"
109790286Sobrien{
109890286Sobrien  operands[1] = constm1_rtx;
109990286Sobrien  return "or{l}\t{%1, %0|%0, %1}";
110090286Sobrien}
110190286Sobrien  [(set_attr "type" "alu1")
110290286Sobrien   (set_attr "mode" "SI")
110390286Sobrien   (set_attr "length_immediate" "1")])
110418334Speter
110590286Sobrien(define_insn "*movsi_1"
1106117404Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!*Y,!rm")
1107117404Skan	(match_operand:SI 1 "general_operand" "rinm,rin,rm,*y,*y,*Y,rm,*Y"))]
110890286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
110950650Sobrien{
111090286Sobrien  switch (get_attr_type (insn))
111190286Sobrien    {
1112117404Skan    case TYPE_SSEMOV:
1113117404Skan      if (get_attr_mode (insn) == MODE_TI)
111490286Sobrien        return "movdqa\t{%1, %0|%0, %1}";
111590286Sobrien      return "movd\t{%1, %0|%0, %1}";
111652296Sobrien
1117117404Skan    case TYPE_MMXMOV:
1118117404Skan      if (get_attr_mode (insn) == MODE_DI)
111996294Sobrien	return "movq\t{%1, %0|%0, %1}";
112090286Sobrien      return "movd\t{%1, %0|%0, %1}";
112152296Sobrien
112290286Sobrien    case TYPE_LEA:
112390286Sobrien      return "lea{l}\t{%1, %0|%0, %1}";
112418334Speter
112590286Sobrien    default:
1126117404Skan      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
112790286Sobrien	abort();
112890286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
112990286Sobrien    }
113090286Sobrien}
113190286Sobrien  [(set (attr "type")
1132117404Skan     (cond [(eq_attr "alternative" "2,3,4")
1133117404Skan	      (const_string "mmxmov")
1134117404Skan	    (eq_attr "alternative" "5,6,7")
1135117404Skan	      (const_string "ssemov")
113690286Sobrien	    (and (ne (symbol_ref "flag_pic") (const_int 0))
113790286Sobrien		 (match_operand:SI 1 "symbolic_operand" ""))
113890286Sobrien	      (const_string "lea")
113990286Sobrien	   ]
114090286Sobrien	   (const_string "imov")))
1141117404Skan   (set_attr "mode" "SI,SI,SI,SI,DI,TI,SI,SI")])
114250650Sobrien
114390286Sobrien;; Stores and loads of ax to arbitary constant address.
114490286Sobrien;; We fake an second form of instruction to force reload to load address
114590286Sobrien;; into register when rax is not available
114690286Sobrien(define_insn "*movabssi_1_rex64"
1147117404Skan  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1148117404Skan	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1149117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
115090286Sobrien  "@
115190286Sobrien   movabs{l}\t{%1, %P0|%P0, %1}
1152117404Skan   mov{l}\t{%1, %a0|%a0, %1}"
115390286Sobrien  [(set_attr "type" "imov")
1154117404Skan   (set_attr "modrm" "0,*")
1155117404Skan   (set_attr "length_address" "8,0")
1156117404Skan   (set_attr "length_immediate" "0,*")
115790286Sobrien   (set_attr "memory" "store")
115890286Sobrien   (set_attr "mode" "SI")])
115950650Sobrien
116090286Sobrien(define_insn "*movabssi_2_rex64"
116190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a,r")
116290286Sobrien        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1163117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
116490286Sobrien  "@
116590286Sobrien   movabs{l}\t{%P1, %0|%0, %P1}
116690286Sobrien   mov{l}\t{%a1, %0|%0, %a1}"
116790286Sobrien  [(set_attr "type" "imov")
116890286Sobrien   (set_attr "modrm" "0,*")
116990286Sobrien   (set_attr "length_address" "8,0")
117090286Sobrien   (set_attr "length_immediate" "0")
117190286Sobrien   (set_attr "memory" "load")
117290286Sobrien   (set_attr "mode" "SI")])
117390286Sobrien
117490286Sobrien(define_insn "*swapsi"
117590286Sobrien  [(set (match_operand:SI 0 "register_operand" "+r")
117690286Sobrien	(match_operand:SI 1 "register_operand" "+r"))
117790286Sobrien   (set (match_dup 1)
117890286Sobrien	(match_dup 0))]
117950650Sobrien  ""
118090286Sobrien  "xchg{l}\t%1, %0"
118190286Sobrien  [(set_attr "type" "imov")
118290286Sobrien   (set_attr "pent_pair" "np")
118390286Sobrien   (set_attr "athlon_decode" "vector")
118490286Sobrien   (set_attr "mode" "SI")
118590286Sobrien   (set_attr "modrm" "0")
118690286Sobrien   (set_attr "ppro_uops" "few")])
118718334Speter
118890286Sobrien(define_expand "movhi"
118990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
119090286Sobrien        (match_operand:HI 1 "general_operand" ""))]
119190286Sobrien  ""
119290286Sobrien  "ix86_expand_move (HImode, operands); DONE;")
119318334Speter
119490286Sobrien(define_insn "*pushhi2"
119590286Sobrien  [(set (match_operand:HI 0 "push_operand" "=<,<")
119690286Sobrien	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
119790286Sobrien  "!TARGET_64BIT"
119890286Sobrien  "@
119990286Sobrien   push{w}\t{|WORD PTR }%1
120090286Sobrien   push{w}\t%1"
120190286Sobrien  [(set_attr "type" "push")
120290286Sobrien   (set_attr "mode" "HI")])
120318334Speter
120490286Sobrien;; For 64BIT abi we always round up to 8 bytes.
120590286Sobrien(define_insn "*pushhi2_rex64"
120690286Sobrien  [(set (match_operand:HI 0 "push_operand" "=X")
120790286Sobrien	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
120890286Sobrien  "TARGET_64BIT"
120990286Sobrien  "push{q}\t%q1"
121090286Sobrien  [(set_attr "type" "push")
121190286Sobrien   (set_attr "mode" "QI")])
121290286Sobrien
121390286Sobrien(define_insn "*movhi_1"
1214117404Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1215117404Skan	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
121690286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
121718334Speter{
121890286Sobrien  switch (get_attr_type (insn))
121918334Speter    {
122090286Sobrien    case TYPE_IMOVX:
122190286Sobrien      /* movzwl is faster than movw on p2 due to partial word stalls,
122290286Sobrien	 though not as fast as an aligned movl.  */
122390286Sobrien      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
122490286Sobrien    default:
122590286Sobrien      if (get_attr_mode (insn) == MODE_SI)
122690286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
122790286Sobrien      else
122890286Sobrien        return "mov{w}\t{%1, %0|%0, %1}";
122918334Speter    }
123090286Sobrien}
123190286Sobrien  [(set (attr "type")
1232117404Skan     (cond [(and (eq_attr "alternative" "0")
123390286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
123490286Sobrien			  (const_int 0))
123590286Sobrien		      (eq (symbol_ref "TARGET_HIMODE_MATH")
123690286Sobrien			  (const_int 0))))
123790286Sobrien	      (const_string "imov")
1238117404Skan	    (and (eq_attr "alternative" "1,2")
123990286Sobrien		 (match_operand:HI 1 "aligned_operand" ""))
124090286Sobrien	      (const_string "imov")
124190286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
124290286Sobrien		     (const_int 0))
1243117404Skan		 (eq_attr "alternative" "0,2"))
124490286Sobrien	      (const_string "imovx")
124590286Sobrien	   ]
124690286Sobrien	   (const_string "imov")))
124790286Sobrien    (set (attr "mode")
124890286Sobrien      (cond [(eq_attr "type" "imovx")
124990286Sobrien	       (const_string "SI")
1250117404Skan	     (and (eq_attr "alternative" "1,2")
125190286Sobrien		  (match_operand:HI 1 "aligned_operand" ""))
125290286Sobrien	       (const_string "SI")
1253117404Skan	     (and (eq_attr "alternative" "0")
125490286Sobrien		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
125590286Sobrien			   (const_int 0))
125690286Sobrien		       (eq (symbol_ref "TARGET_HIMODE_MATH")
125790286Sobrien			   (const_int 0))))
125890286Sobrien	       (const_string "SI")
125990286Sobrien	    ]
1260117404Skan	    (const_string "HI")))])
126118334Speter
126290286Sobrien;; Stores and loads of ax to arbitary constant address.
126390286Sobrien;; We fake an second form of instruction to force reload to load address
126490286Sobrien;; into register when rax is not available
126590286Sobrien(define_insn "*movabshi_1_rex64"
1266117404Skan  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1267117404Skan	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1268117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
126990286Sobrien  "@
127090286Sobrien   movabs{w}\t{%1, %P0|%P0, %1}
1271117404Skan   mov{w}\t{%1, %a0|%a0, %1}"
127290286Sobrien  [(set_attr "type" "imov")
1273117404Skan   (set_attr "modrm" "0,*")
1274117404Skan   (set_attr "length_address" "8,0")
1275117404Skan   (set_attr "length_immediate" "0,*")
127690286Sobrien   (set_attr "memory" "store")
127790286Sobrien   (set_attr "mode" "HI")])
127818334Speter
127990286Sobrien(define_insn "*movabshi_2_rex64"
128090286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a,r")
128190286Sobrien        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1282117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
128390286Sobrien  "@
128490286Sobrien   movabs{w}\t{%P1, %0|%0, %P1}
128590286Sobrien   mov{w}\t{%a1, %0|%0, %a1}"
128690286Sobrien  [(set_attr "type" "imov")
128790286Sobrien   (set_attr "modrm" "0,*")
128890286Sobrien   (set_attr "length_address" "8,0")
128990286Sobrien   (set_attr "length_immediate" "0")
129090286Sobrien   (set_attr "memory" "load")
129190286Sobrien   (set_attr "mode" "HI")])
129218334Speter
129390286Sobrien(define_insn "*swaphi_1"
129490286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
129590286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
129690286Sobrien   (set (match_dup 1)
129790286Sobrien	(match_dup 0))]
129890286Sobrien  "TARGET_PARTIAL_REG_STALL"
129990286Sobrien  "xchg{w}\t%1, %0"
130090286Sobrien  [(set_attr "type" "imov")
130190286Sobrien   (set_attr "pent_pair" "np")
130290286Sobrien   (set_attr "mode" "HI")
130390286Sobrien   (set_attr "modrm" "0")
130490286Sobrien   (set_attr "ppro_uops" "few")])
130518334Speter
130690286Sobrien(define_insn "*swaphi_2"
130790286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
130890286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
130990286Sobrien   (set (match_dup 1)
131090286Sobrien	(match_dup 0))]
131190286Sobrien  "! TARGET_PARTIAL_REG_STALL"
131290286Sobrien  "xchg{l}\t%k1, %k0"
131390286Sobrien  [(set_attr "type" "imov")
131490286Sobrien   (set_attr "pent_pair" "np")
131590286Sobrien   (set_attr "mode" "SI")
131690286Sobrien   (set_attr "modrm" "0")
131790286Sobrien   (set_attr "ppro_uops" "few")])
131818334Speter
131918334Speter(define_expand "movstricthi"
132090286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
132118334Speter	(match_operand:HI 1 "general_operand" ""))]
132290286Sobrien  "! TARGET_PARTIAL_REG_STALL || optimize_size"
132318334Speter{
132418334Speter  /* Don't generate memory->memory moves, go through a register */
132590286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
132690286Sobrien    operands[1] = force_reg (HImode, operands[1]);
132790286Sobrien})
132818334Speter
132990286Sobrien(define_insn "*movstricthi_1"
133090286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
133190286Sobrien	(match_operand:HI 1 "general_operand" "rn,m"))]
133290286Sobrien  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
133390286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
133490286Sobrien  "mov{w}\t{%1, %0|%0, %1}"
133590286Sobrien  [(set_attr "type" "imov")
133690286Sobrien   (set_attr "mode" "HI")])
133752296Sobrien
133890286Sobrien(define_insn "*movstricthi_xor"
133990286Sobrien  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
134090286Sobrien	(match_operand:HI 1 "const0_operand" "i"))
134190286Sobrien   (clobber (reg:CC 17))]
134290286Sobrien  "reload_completed
134390286Sobrien   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
134490286Sobrien  "xor{w}\t{%0, %0|%0, %0}"
134590286Sobrien  [(set_attr "type" "alu1")
134690286Sobrien   (set_attr "mode" "HI")
134790286Sobrien   (set_attr "length_immediate" "0")])
134852296Sobrien
134990286Sobrien(define_expand "movqi"
135090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
135190286Sobrien	(match_operand:QI 1 "general_operand" ""))]
135290286Sobrien  ""
135390286Sobrien  "ix86_expand_move (QImode, operands); DONE;")
135418334Speter
135590286Sobrien;; emit_push_insn when it calls move_by_pieces requires an insn to
135690286Sobrien;; "push a byte".  But actually we use pushw, which has the effect
135790286Sobrien;; of rounding the amount pushed up to a halfword.
135818334Speter
135990286Sobrien(define_insn "*pushqi2"
136090286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X,X")
136190286Sobrien	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
136290286Sobrien  "!TARGET_64BIT"
136390286Sobrien  "@
136490286Sobrien   push{w}\t{|word ptr }%1
136590286Sobrien   push{w}\t%w1"
136690286Sobrien  [(set_attr "type" "push")
136790286Sobrien   (set_attr "mode" "HI")])
136818334Speter
136990286Sobrien;; For 64BIT abi we always round up to 8 bytes.
137090286Sobrien(define_insn "*pushqi2_rex64"
137190286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X")
1372102802Skan	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
137390286Sobrien  "TARGET_64BIT"
137490286Sobrien  "push{q}\t%q1"
137590286Sobrien  [(set_attr "type" "push")
137690286Sobrien   (set_attr "mode" "QI")])
137790286Sobrien
137890286Sobrien;; Situation is quite tricky about when to choose full sized (SImode) move
137990286Sobrien;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
138090286Sobrien;; partial register dependency machines (such as AMD Athlon), where QImode
138190286Sobrien;; moves issue extra dependency and for partial register stalls machines
138290286Sobrien;; that don't use QImode patterns (and QImode move cause stall on the next
138390286Sobrien;; instruction).
138490286Sobrien;;
138590286Sobrien;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
138690286Sobrien;; register stall machines with, where we use QImode instructions, since
138790286Sobrien;; partial register stall can be caused there.  Then we use movzx.
138890286Sobrien(define_insn "*movqi_1"
138990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
139090286Sobrien	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
139190286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
139290286Sobrien{
139390286Sobrien  switch (get_attr_type (insn))
139490286Sobrien    {
139590286Sobrien    case TYPE_IMOVX:
139690286Sobrien      if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
139790286Sobrien	abort ();
139890286Sobrien      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
139990286Sobrien    default:
140090286Sobrien      if (get_attr_mode (insn) == MODE_SI)
140190286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
140290286Sobrien      else
140390286Sobrien        return "mov{b}\t{%1, %0|%0, %1}";
140490286Sobrien    }
140590286Sobrien}
140690286Sobrien  [(set (attr "type")
140790286Sobrien     (cond [(and (eq_attr "alternative" "3")
140890286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
140990286Sobrien			  (const_int 0))
141090286Sobrien		      (eq (symbol_ref "TARGET_QIMODE_MATH")
141190286Sobrien			  (const_int 0))))
141290286Sobrien	      (const_string "imov")
141390286Sobrien	    (eq_attr "alternative" "3,5")
141490286Sobrien	      (const_string "imovx")
141590286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
141690286Sobrien		     (const_int 0))
141790286Sobrien		 (eq_attr "alternative" "2"))
141890286Sobrien	      (const_string "imovx")
141990286Sobrien	   ]
142090286Sobrien	   (const_string "imov")))
142190286Sobrien   (set (attr "mode")
142290286Sobrien      (cond [(eq_attr "alternative" "3,4,5")
142390286Sobrien	       (const_string "SI")
142490286Sobrien	     (eq_attr "alternative" "6")
142590286Sobrien	       (const_string "QI")
142690286Sobrien	     (eq_attr "type" "imovx")
142790286Sobrien	       (const_string "SI")
142890286Sobrien	     (and (eq_attr "type" "imov")
142990286Sobrien		  (and (eq_attr "alternative" "0,1,2")
143090286Sobrien		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
143190286Sobrien			   (const_int 0))))
143290286Sobrien	       (const_string "SI")
143390286Sobrien	     ;; Avoid partial register stalls when not using QImode arithmetic
143490286Sobrien	     (and (eq_attr "type" "imov")
143590286Sobrien		  (and (eq_attr "alternative" "0,1,2")
143690286Sobrien		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
143790286Sobrien				(const_int 0))
143890286Sobrien			    (eq (symbol_ref "TARGET_QIMODE_MATH")
143990286Sobrien				(const_int 0)))))
144090286Sobrien	       (const_string "SI")
144190286Sobrien	   ]
144290286Sobrien	   (const_string "QI")))])
144390286Sobrien
144490286Sobrien(define_expand "reload_outqi"
144590286Sobrien  [(parallel [(match_operand:QI 0 "" "=m")
144690286Sobrien              (match_operand:QI 1 "register_operand" "r")
144790286Sobrien              (match_operand:QI 2 "register_operand" "=&q")])]
144818334Speter  ""
144990286Sobrien{
145090286Sobrien  rtx op0, op1, op2;
145190286Sobrien  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
145218334Speter
145390286Sobrien  if (reg_overlap_mentioned_p (op2, op0))
145490286Sobrien    abort ();
145590286Sobrien  if (! q_regs_operand (op1, QImode))
145690286Sobrien    {
145790286Sobrien      emit_insn (gen_movqi (op2, op1));
145890286Sobrien      op1 = op2;
145990286Sobrien    }
146090286Sobrien  emit_insn (gen_movqi (op0, op1));
146190286Sobrien  DONE;
146290286Sobrien})
146390286Sobrien
146490286Sobrien(define_insn "*swapqi"
146590286Sobrien  [(set (match_operand:QI 0 "register_operand" "+r")
146690286Sobrien	(match_operand:QI 1 "register_operand" "+r"))
146790286Sobrien   (set (match_dup 1)
146890286Sobrien	(match_dup 0))]
146950650Sobrien  ""
147090286Sobrien  "xchg{b}\t%1, %0"
147190286Sobrien  [(set_attr "type" "imov")
147290286Sobrien   (set_attr "pent_pair" "np")
147390286Sobrien   (set_attr "mode" "QI")
147490286Sobrien   (set_attr "modrm" "0")
147590286Sobrien   (set_attr "ppro_uops" "few")])
147690286Sobrien
147790286Sobrien(define_expand "movstrictqi"
147890286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
147990286Sobrien	(match_operand:QI 1 "general_operand" ""))]
1480117404Skan  "! TARGET_PARTIAL_REG_STALL || optimize_size"
148118334Speter{
148290286Sobrien  /* Don't generate memory->memory moves, go through a register.  */
148390286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
148490286Sobrien    operands[1] = force_reg (QImode, operands[1]);
148590286Sobrien})
148618334Speter
148790286Sobrien(define_insn "*movstrictqi_1"
148890286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
148990286Sobrien	(match_operand:QI 1 "general_operand" "*qn,m"))]
1490117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
149190286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
149290286Sobrien  "mov{b}\t{%1, %0|%0, %1}"
149390286Sobrien  [(set_attr "type" "imov")
149490286Sobrien   (set_attr "mode" "QI")])
149518334Speter
149690286Sobrien(define_insn "*movstrictqi_xor"
149790286Sobrien  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
149890286Sobrien	(match_operand:QI 1 "const0_operand" "i"))
149990286Sobrien   (clobber (reg:CC 17))]
150090286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
150190286Sobrien  "xor{b}\t{%0, %0|%0, %0}"
150290286Sobrien  [(set_attr "type" "alu1")
150390286Sobrien   (set_attr "mode" "QI")
150490286Sobrien   (set_attr "length_immediate" "0")])
150518334Speter
150690286Sobrien(define_insn "*movsi_extv_1"
150790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
150890286Sobrien	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
150990286Sobrien			 (const_int 8)
151090286Sobrien			 (const_int 8)))]
151118334Speter  ""
151290286Sobrien  "movs{bl|x}\t{%h1, %0|%0, %h1}"
151390286Sobrien  [(set_attr "type" "imovx")
151490286Sobrien   (set_attr "mode" "SI")])
151590286Sobrien
151690286Sobrien(define_insn "*movhi_extv_1"
151790286Sobrien  [(set (match_operand:HI 0 "register_operand" "=R")
151890286Sobrien	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
151990286Sobrien			 (const_int 8)
152090286Sobrien			 (const_int 8)))]
152190286Sobrien  ""
152290286Sobrien  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
152390286Sobrien  [(set_attr "type" "imovx")
152490286Sobrien   (set_attr "mode" "SI")])
152590286Sobrien
152690286Sobrien(define_insn "*movqi_extv_1"
152790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
152890286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
152990286Sobrien                         (const_int 8)
153090286Sobrien                         (const_int 8)))]
153190286Sobrien  "!TARGET_64BIT"
153218334Speter{
153390286Sobrien  switch (get_attr_type (insn))
153418334Speter    {
153590286Sobrien    case TYPE_IMOVX:
153690286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
153790286Sobrien    default:
153890286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
153918334Speter    }
154090286Sobrien}
154190286Sobrien  [(set (attr "type")
154290286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
154390286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
154490286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
154590286Sobrien				 (const_int 0))))
154690286Sobrien	(const_string "imovx")
154790286Sobrien	(const_string "imov")))
154890286Sobrien   (set (attr "mode")
154990286Sobrien     (if_then_else (eq_attr "type" "imovx")
155090286Sobrien	(const_string "SI")
155190286Sobrien	(const_string "QI")))])
155218334Speter
155390286Sobrien(define_insn "*movqi_extv_1_rex64"
155490286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
155590286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
155690286Sobrien                         (const_int 8)
155790286Sobrien                         (const_int 8)))]
155890286Sobrien  "TARGET_64BIT"
155918334Speter{
156090286Sobrien  switch (get_attr_type (insn))
156150650Sobrien    {
156290286Sobrien    case TYPE_IMOVX:
156390286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
156490286Sobrien    default:
156590286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
156650650Sobrien    }
156790286Sobrien}
156890286Sobrien  [(set (attr "type")
156990286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
157090286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
157190286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
157290286Sobrien				 (const_int 0))))
157390286Sobrien	(const_string "imovx")
157490286Sobrien	(const_string "imov")))
157590286Sobrien   (set (attr "mode")
157690286Sobrien     (if_then_else (eq_attr "type" "imovx")
157790286Sobrien	(const_string "SI")
157890286Sobrien	(const_string "QI")))])
157918334Speter
158090286Sobrien;; Stores and loads of ax to arbitary constant address.
158190286Sobrien;; We fake an second form of instruction to force reload to load address
158290286Sobrien;; into register when rax is not available
158390286Sobrien(define_insn "*movabsqi_1_rex64"
1584117404Skan  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1585117404Skan	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1586117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
158790286Sobrien  "@
158890286Sobrien   movabs{b}\t{%1, %P0|%P0, %1}
1589117404Skan   mov{b}\t{%1, %a0|%a0, %1}"
159090286Sobrien  [(set_attr "type" "imov")
1591117404Skan   (set_attr "modrm" "0,*")
1592117404Skan   (set_attr "length_address" "8,0")
1593117404Skan   (set_attr "length_immediate" "0,*")
159490286Sobrien   (set_attr "memory" "store")
159590286Sobrien   (set_attr "mode" "QI")])
159618334Speter
159790286Sobrien(define_insn "*movabsqi_2_rex64"
159890286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a,r")
159990286Sobrien        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1600117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
160190286Sobrien  "@
160290286Sobrien   movabs{b}\t{%P1, %0|%0, %P1}
160390286Sobrien   mov{b}\t{%a1, %0|%0, %a1}"
160490286Sobrien  [(set_attr "type" "imov")
160590286Sobrien   (set_attr "modrm" "0,*")
160690286Sobrien   (set_attr "length_address" "8,0")
160790286Sobrien   (set_attr "length_immediate" "0")
160890286Sobrien   (set_attr "memory" "load")
160990286Sobrien   (set_attr "mode" "QI")])
161018334Speter
161190286Sobrien(define_insn "*movsi_extzv_1"
161290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
161390286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
161490286Sobrien			 (const_int 8)
161590286Sobrien			 (const_int 8)))]
161690286Sobrien  ""
161790286Sobrien  "movz{bl|x}\t{%h1, %0|%0, %h1}"
161890286Sobrien  [(set_attr "type" "imovx")
161990286Sobrien   (set_attr "mode" "SI")])
162018334Speter
162190286Sobrien(define_insn "*movqi_extzv_2"
162290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
162390286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
162490286Sobrien				    (const_int 8)
162590286Sobrien				    (const_int 8)) 0))]
162690286Sobrien  "!TARGET_64BIT"
162718334Speter{
162890286Sobrien  switch (get_attr_type (insn))
162918334Speter    {
163090286Sobrien    case TYPE_IMOVX:
163190286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
163290286Sobrien    default:
163390286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
163418334Speter    }
163590286Sobrien}
163690286Sobrien  [(set (attr "type")
163790286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
163890286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
163990286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
164090286Sobrien				 (const_int 0))))
164190286Sobrien	(const_string "imovx")
164290286Sobrien	(const_string "imov")))
164390286Sobrien   (set (attr "mode")
164490286Sobrien     (if_then_else (eq_attr "type" "imovx")
164590286Sobrien	(const_string "SI")
164690286Sobrien	(const_string "QI")))])
164718334Speter
164890286Sobrien(define_insn "*movqi_extzv_2_rex64"
164990286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
165090286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
165190286Sobrien				    (const_int 8)
165290286Sobrien				    (const_int 8)) 0))]
165390286Sobrien  "TARGET_64BIT"
165418334Speter{
165590286Sobrien  switch (get_attr_type (insn))
165690286Sobrien    {
165790286Sobrien    case TYPE_IMOVX:
165890286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
165990286Sobrien    default:
166090286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
166190286Sobrien    }
166290286Sobrien}
166390286Sobrien  [(set (attr "type")
166490286Sobrien     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
166590286Sobrien			(ne (symbol_ref "TARGET_MOVX")
166690286Sobrien			    (const_int 0)))
166790286Sobrien	(const_string "imovx")
166890286Sobrien	(const_string "imov")))
166990286Sobrien   (set (attr "mode")
167090286Sobrien     (if_then_else (eq_attr "type" "imovx")
167190286Sobrien	(const_string "SI")
167290286Sobrien	(const_string "QI")))])
167318334Speter
167490286Sobrien(define_insn "movsi_insv_1"
167590286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
167690286Sobrien			 (const_int 8)
167790286Sobrien			 (const_int 8))
167890286Sobrien	(match_operand:SI 1 "general_operand" "Qmn"))]
167990286Sobrien  "!TARGET_64BIT"
168090286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
168190286Sobrien  [(set_attr "type" "imov")
168290286Sobrien   (set_attr "mode" "QI")])
168352296Sobrien
168490286Sobrien(define_insn "*movsi_insv_1_rex64"
168590286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
168690286Sobrien			 (const_int 8)
168790286Sobrien			 (const_int 8))
168890286Sobrien	(match_operand:SI 1 "nonmemory_operand" "Qn"))]
168990286Sobrien  "TARGET_64BIT"
169090286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
169190286Sobrien  [(set_attr "type" "imov")
169290286Sobrien   (set_attr "mode" "QI")])
169318334Speter
169490286Sobrien(define_insn "*movqi_insv_2"
169590286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
169690286Sobrien			 (const_int 8)
169790286Sobrien			 (const_int 8))
169890286Sobrien	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
169990286Sobrien			     (const_int 8))
170090286Sobrien		(const_int 255)))]
170190286Sobrien  ""
170290286Sobrien  "mov{b}\t{%h1, %h0|%h0, %h1}"
170390286Sobrien  [(set_attr "type" "imov")
170490286Sobrien   (set_attr "mode" "QI")])
170518334Speter
170690286Sobrien(define_expand "movdi"
170790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
170890286Sobrien	(match_operand:DI 1 "general_operand" ""))]
170990286Sobrien  ""
171090286Sobrien  "ix86_expand_move (DImode, operands); DONE;")
171118334Speter
171290286Sobrien(define_insn "*pushdi"
171390286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
171490286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
171590286Sobrien  "!TARGET_64BIT"
171690286Sobrien  "#")
171790286Sobrien
171890286Sobrien(define_insn "pushdi2_rex64"
171990286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<,!<")
172090286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
172190286Sobrien  "TARGET_64BIT"
172290286Sobrien  "@
172390286Sobrien   push{q}\t%1
172490286Sobrien   #"
172590286Sobrien  [(set_attr "type" "push,multi")
172690286Sobrien   (set_attr "mode" "DI")])
172790286Sobrien
172890286Sobrien;; Convert impossible pushes of immediate to existing instructions.
172990286Sobrien;; First try to get scratch register and go through it.  In case this
173090286Sobrien;; fails, push sign extended lower part first and then overwrite
173190286Sobrien;; upper part by 32bit move.
173290286Sobrien(define_peephole2
173390286Sobrien  [(match_scratch:DI 2 "r")
173490286Sobrien   (set (match_operand:DI 0 "push_operand" "")
173590286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
173690286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
173790286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
173890286Sobrien  [(set (match_dup 2) (match_dup 1))
173990286Sobrien   (set (match_dup 0) (match_dup 2))]
174090286Sobrien  "")
174190286Sobrien
174290286Sobrien;; We need to define this as both peepholer and splitter for case
174390286Sobrien;; peephole2 pass is not run.
174490286Sobrien(define_peephole2
174590286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
174690286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
174790286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
174890286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
174990286Sobrien  [(set (match_dup 0) (match_dup 1))
175090286Sobrien   (set (match_dup 2) (match_dup 3))]
175190286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
175290286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
175390286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
175490286Sobrien						    GEN_INT (4)));
175590286Sobrien  ")
175690286Sobrien
175790286Sobrien(define_split
175890286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
175990286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
176090286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
176190286Sobrien   && !symbolic_operand (operands[1], DImode)
176290286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
176390286Sobrien  [(set (match_dup 0) (match_dup 1))
176490286Sobrien   (set (match_dup 2) (match_dup 3))]
176590286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
176690286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
176790286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
176890286Sobrien						    GEN_INT (4)));
176990286Sobrien  ")
177090286Sobrien
177190286Sobrien(define_insn "*pushdi2_prologue_rex64"
177290286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
177390286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
177490286Sobrien   (clobber (mem:BLK (scratch)))]
177590286Sobrien  "TARGET_64BIT"
177690286Sobrien  "push{q}\t%1"
177790286Sobrien  [(set_attr "type" "push")
177890286Sobrien   (set_attr "mode" "DI")])
177990286Sobrien
178090286Sobrien(define_insn "*popdi1_epilogue_rex64"
178190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
178290286Sobrien	(mem:DI (reg:DI 7)))
178390286Sobrien   (set (reg:DI 7)
178490286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))
178590286Sobrien   (clobber (mem:BLK (scratch)))]
178690286Sobrien  "TARGET_64BIT"
178790286Sobrien  "pop{q}\t%0"
178890286Sobrien  [(set_attr "type" "pop")
178990286Sobrien   (set_attr "mode" "DI")])
179090286Sobrien
179190286Sobrien(define_insn "popdi1"
179290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
179390286Sobrien	(mem:DI (reg:DI 7)))
179490286Sobrien   (set (reg:DI 7)
179590286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))]
179690286Sobrien  "TARGET_64BIT"
179790286Sobrien  "pop{q}\t%0"
179890286Sobrien  [(set_attr "type" "pop")
179990286Sobrien   (set_attr "mode" "DI")])
180090286Sobrien
180190286Sobrien(define_insn "*movdi_xor_rex64"
180290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
180390286Sobrien	(match_operand:DI 1 "const0_operand" "i"))
180490286Sobrien   (clobber (reg:CC 17))]
180590286Sobrien  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
180690286Sobrien   && reload_completed"
180790286Sobrien  "xor{l}\t{%k0, %k0|%k0, %k0}"
180890286Sobrien  [(set_attr "type" "alu1")
180990286Sobrien   (set_attr "mode" "SI")
181090286Sobrien   (set_attr "length_immediate" "0")])
181190286Sobrien
181290286Sobrien(define_insn "*movdi_or_rex64"
181390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
181490286Sobrien	(match_operand:DI 1 "const_int_operand" "i"))
181590286Sobrien   (clobber (reg:CC 17))]
181690286Sobrien  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
181790286Sobrien   && reload_completed
181890286Sobrien   && GET_CODE (operands[1]) == CONST_INT
181990286Sobrien   && INTVAL (operands[1]) == -1"
182018334Speter{
182190286Sobrien  operands[1] = constm1_rtx;
182290286Sobrien  return "or{q}\t{%1, %0|%0, %1}";
182390286Sobrien}
182490286Sobrien  [(set_attr "type" "alu1")
182590286Sobrien   (set_attr "mode" "DI")
182690286Sobrien   (set_attr "length_immediate" "1")])
182718334Speter
182890286Sobrien(define_insn "*movdi_2"
182996294Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
183090286Sobrien	(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
183190286Sobrien  "!TARGET_64BIT
183290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
183390286Sobrien  "@
183490286Sobrien   #
183590286Sobrien   #
183690286Sobrien   movq\t{%1, %0|%0, %1}
183790286Sobrien   movq\t{%1, %0|%0, %1}
183890286Sobrien   movq\t{%1, %0|%0, %1}
183990286Sobrien   movdqa\t{%1, %0|%0, %1}
184090286Sobrien   movq\t{%1, %0|%0, %1}"
1841117404Skan  [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
184290286Sobrien   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
184318334Speter
184490286Sobrien(define_split
184590286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
184690286Sobrien        (match_operand:DI 1 "general_operand" ""))]
184790286Sobrien  "!TARGET_64BIT && reload_completed
184890286Sobrien   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
184990286Sobrien  [(const_int 0)]
185090286Sobrien  "ix86_split_long_move (operands); DONE;")
185118334Speter
185290286Sobrien;; %%% This multiword shite has got to go.
185390286Sobrien(define_split
185490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
185590286Sobrien        (match_operand:DI 1 "general_operand" ""))]
185690286Sobrien  "!TARGET_64BIT && reload_completed
185790286Sobrien   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
185890286Sobrien   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
185990286Sobrien  [(const_int 0)]
186090286Sobrien  "ix86_split_long_move (operands); DONE;")
186118334Speter
186290286Sobrien(define_insn "*movdi_1_rex64"
186390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
186490286Sobrien	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
186590286Sobrien  "TARGET_64BIT
186690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
186790286Sobrien{
186890286Sobrien  switch (get_attr_type (insn))
186990286Sobrien    {
1870117404Skan    case TYPE_SSEMOV:
187190286Sobrien      if (register_operand (operands[0], DImode)
187290286Sobrien	  && register_operand (operands[1], DImode))
187390286Sobrien	  return "movdqa\t{%1, %0|%0, %1}";
187490286Sobrien      /* FALLTHRU */
1875117404Skan    case TYPE_MMXMOV:
187690286Sobrien      return "movq\t{%1, %0|%0, %1}";
187790286Sobrien    case TYPE_MULTI:
187890286Sobrien      return "#";
187990286Sobrien    case TYPE_LEA:
188090286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
188190286Sobrien    default:
1882117404Skan      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
188390286Sobrien	abort ();
188490286Sobrien      if (get_attr_mode (insn) == MODE_SI)
188590286Sobrien	return "mov{l}\t{%k1, %k0|%k0, %k1}";
188690286Sobrien      else if (which_alternative == 2)
188790286Sobrien	return "movabs{q}\t{%1, %0|%0, %1}";
188818334Speter      else
188990286Sobrien	return "mov{q}\t{%1, %0|%0, %1}";
189018334Speter    }
189190286Sobrien}
189290286Sobrien  [(set (attr "type")
189390286Sobrien     (cond [(eq_attr "alternative" "5,6")
1894117404Skan	      (const_string "mmxmov")
1895117404Skan	    (eq_attr "alternative" "7,8,9")
1896117404Skan	      (const_string "ssemov")
189790286Sobrien	    (eq_attr "alternative" "4")
189890286Sobrien	      (const_string "multi")
189990286Sobrien 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
190090286Sobrien		 (match_operand:DI 1 "symbolic_operand" ""))
190190286Sobrien	      (const_string "lea")
190290286Sobrien	   ]
190390286Sobrien	   (const_string "imov")))
190490286Sobrien   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
190590286Sobrien   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
190690286Sobrien   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
190750650Sobrien
190890286Sobrien;; Stores and loads of ax to arbitary constant address.
190990286Sobrien;; We fake an second form of instruction to force reload to load address
191090286Sobrien;; into register when rax is not available
191190286Sobrien(define_insn "*movabsdi_1_rex64"
1912102802Skan  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1913102802Skan	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
1914117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
191590286Sobrien  "@
191690286Sobrien   movabs{q}\t{%1, %P0|%P0, %1}
1917102802Skan   mov{q}\t{%1, %a0|%a0, %1}"
191890286Sobrien  [(set_attr "type" "imov")
1919102802Skan   (set_attr "modrm" "0,*")
1920102802Skan   (set_attr "length_address" "8,0")
1921102802Skan   (set_attr "length_immediate" "0,*")
192290286Sobrien   (set_attr "memory" "store")
192390286Sobrien   (set_attr "mode" "DI")])
192418334Speter
192590286Sobrien(define_insn "*movabsdi_2_rex64"
192690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a,r")
192790286Sobrien        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1928117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
192990286Sobrien  "@
193090286Sobrien   movabs{q}\t{%P1, %0|%0, %P1}
193190286Sobrien   mov{q}\t{%a1, %0|%0, %a1}"
193290286Sobrien  [(set_attr "type" "imov")
193390286Sobrien   (set_attr "modrm" "0,*")
193490286Sobrien   (set_attr "length_address" "8,0")
193590286Sobrien   (set_attr "length_immediate" "0")
193690286Sobrien   (set_attr "memory" "load")
193790286Sobrien   (set_attr "mode" "DI")])
193890286Sobrien
193990286Sobrien;; Convert impossible stores of immediate to existing instructions.
194090286Sobrien;; First try to get scratch register and go through it.  In case this
194190286Sobrien;; fails, move by 32bit parts.
194290286Sobrien(define_peephole2
194390286Sobrien  [(match_scratch:DI 2 "r")
194490286Sobrien   (set (match_operand:DI 0 "memory_operand" "")
194590286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
194690286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
194790286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
194890286Sobrien  [(set (match_dup 2) (match_dup 1))
194990286Sobrien   (set (match_dup 0) (match_dup 2))]
195052296Sobrien  "")
195150650Sobrien
195290286Sobrien;; We need to define this as both peepholer and splitter for case
195390286Sobrien;; peephole2 pass is not run.
195490286Sobrien(define_peephole2
195590286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
195690286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
195790286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
195890286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
195990286Sobrien  [(set (match_dup 2) (match_dup 3))
196090286Sobrien   (set (match_dup 4) (match_dup 5))]
196190286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
196290286Sobrien
196390286Sobrien(define_split
196490286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
196590286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
196690286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
196790286Sobrien   && !symbolic_operand (operands[1], DImode)
196890286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
196990286Sobrien  [(set (match_dup 2) (match_dup 3))
197090286Sobrien   (set (match_dup 4) (match_dup 5))]
197190286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
197290286Sobrien
197390286Sobrien(define_insn "*swapdi_rex64"
197490286Sobrien  [(set (match_operand:DI 0 "register_operand" "+r")
197590286Sobrien	(match_operand:DI 1 "register_operand" "+r"))
197690286Sobrien   (set (match_dup 1)
197790286Sobrien	(match_dup 0))]
197890286Sobrien  "TARGET_64BIT"
197990286Sobrien  "xchg{q}\t%1, %0"
198090286Sobrien  [(set_attr "type" "imov")
198190286Sobrien   (set_attr "pent_pair" "np")
198290286Sobrien   (set_attr "athlon_decode" "vector")
198390286Sobrien   (set_attr "mode" "DI")
198490286Sobrien   (set_attr "modrm" "0")
198590286Sobrien   (set_attr "ppro_uops" "few")])
198690286Sobrien
198790286Sobrien  
198850650Sobrien(define_expand "movsf"
198990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
199050650Sobrien	(match_operand:SF 1 "general_operand" ""))]
199118334Speter  ""
199290286Sobrien  "ix86_expand_move (SFmode, operands); DONE;")
199390286Sobrien
199490286Sobrien(define_insn "*pushsf"
199590286Sobrien  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
199690286Sobrien	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
199790286Sobrien  "!TARGET_64BIT"
199818334Speter{
199990286Sobrien  switch (which_alternative)
200018334Speter    {
200190286Sobrien    case 0:
200290286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
200390286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
200490286Sobrien      operands[2] = stack_pointer_rtx;
200590286Sobrien      operands[3] = GEN_INT (4);
200690286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
200790286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
200890286Sobrien      else
200990286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
201018334Speter
201190286Sobrien    case 1:
201290286Sobrien      return "push{l}\t%1";
201390286Sobrien    case 2:
201490286Sobrien      return "#";
201590286Sobrien
201690286Sobrien    default:
201790286Sobrien      abort ();
201818334Speter    }
201990286Sobrien}
202090286Sobrien  [(set_attr "type" "multi,push,multi")
202190286Sobrien   (set_attr "mode" "SF,SI,SF")])
202218334Speter
202390286Sobrien(define_insn "*pushsf_rex64"
202490286Sobrien  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
202590286Sobrien	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
202690286Sobrien  "TARGET_64BIT"
202718334Speter{
202890286Sobrien  switch (which_alternative)
202990286Sobrien    {
203090286Sobrien    case 0:
203190286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
203290286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
203390286Sobrien      operands[2] = stack_pointer_rtx;
203490286Sobrien      operands[3] = GEN_INT (8);
203590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
203690286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
203790286Sobrien      else
203890286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
203918334Speter
204090286Sobrien    case 1:
204190286Sobrien      return "push{q}\t%q1";
204218334Speter
204390286Sobrien    case 2:
204490286Sobrien      return "#";
204590286Sobrien
204690286Sobrien    default:
204790286Sobrien      abort ();
204818334Speter    }
204990286Sobrien}
205090286Sobrien  [(set_attr "type" "multi,push,multi")
205190286Sobrien   (set_attr "mode" "SF,DI,SF")])
205218334Speter
205390286Sobrien(define_split
205490286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
205590286Sobrien	(match_operand:SF 1 "memory_operand" ""))]
205690286Sobrien  "reload_completed
205790286Sobrien   && GET_CODE (operands[1]) == MEM
205890286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
205990286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
206090286Sobrien  [(set (match_dup 0)
206190286Sobrien	(match_dup 1))]
206290286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
206318334Speter
206490286Sobrien
206590286Sobrien;; %%% Kill this when call knows how to work this out.
206690286Sobrien(define_split
206790286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
2068117404Skan	(match_operand:SF 1 "any_fp_register_operand" ""))]
2069117404Skan  "!TARGET_64BIT"
207090286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
207190286Sobrien   (set (mem:SF (reg:SI 7)) (match_dup 1))])
207290286Sobrien
207390286Sobrien(define_split
207490286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
2075117404Skan	(match_operand:SF 1 "any_fp_register_operand" ""))]
2076117404Skan  "TARGET_64BIT"
207790286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
207890286Sobrien   (set (mem:SF (reg:DI 7)) (match_dup 1))])
207990286Sobrien
208090286Sobrien(define_insn "*movsf_1"
208196294Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2082117404Skan	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
208390286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
208490286Sobrien   && (reload_in_progress || reload_completed
208590286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
208690286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
208790286Sobrien       || memory_operand (operands[0], SFmode))" 
208890286Sobrien{
208990286Sobrien  switch (which_alternative)
209018334Speter    {
209190286Sobrien    case 0:
209290286Sobrien      if (REG_P (operands[1])
209390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
209490286Sobrien        return "fstp\t%y0";
209590286Sobrien      else if (STACK_TOP_P (operands[0]))
209690286Sobrien        return "fld%z1\t%y1";
209718334Speter      else
209890286Sobrien        return "fst\t%y0";
209918334Speter
210090286Sobrien    case 1:
210190286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
210290286Sobrien        return "fstp%z0\t%y0";
210390286Sobrien      else
210490286Sobrien        return "fst%z0\t%y0";
210518334Speter
210690286Sobrien    case 2:
210790286Sobrien      switch (standard_80387_constant_p (operands[1]))
210890286Sobrien        {
210990286Sobrien        case 1:
211090286Sobrien	  return "fldz";
211190286Sobrien	case 2:
211290286Sobrien	  return "fld1";
211390286Sobrien	}
211490286Sobrien      abort();
211518334Speter
211690286Sobrien    case 3:
211790286Sobrien    case 4:
211890286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
211990286Sobrien    case 5:
2120117404Skan      if (TARGET_SSE2 && !TARGET_ATHLON)
212196294Sobrien	return "pxor\t%0, %0";
212296294Sobrien      else
212396294Sobrien	return "xorps\t%0, %0";
212490286Sobrien    case 6:
212590286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
212690286Sobrien	return "movaps\t{%1, %0|%0, %1}";
212790286Sobrien      else
212890286Sobrien	return "movss\t{%1, %0|%0, %1}";
212990286Sobrien    case 7:
213090286Sobrien    case 8:
213190286Sobrien      return "movss\t{%1, %0|%0, %1}";
213218334Speter
213396294Sobrien    case 9:
213496294Sobrien    case 10:
213596294Sobrien      return "movd\t{%1, %0|%0, %1}";
213696294Sobrien
213796294Sobrien    case 11:
213896294Sobrien      return "movq\t{%1, %0|%0, %1}";
213996294Sobrien
214090286Sobrien    default:
214190286Sobrien      abort();
214290286Sobrien    }
214390286Sobrien}
2144117404Skan  [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
214596294Sobrien   (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
214618334Speter
214790286Sobrien(define_insn "*swapsf"
214890286Sobrien  [(set (match_operand:SF 0 "register_operand" "+f")
214990286Sobrien	(match_operand:SF 1 "register_operand" "+f"))
215018334Speter   (set (match_dup 1)
215118334Speter	(match_dup 0))]
215290286Sobrien  "reload_completed || !TARGET_SSE"
215318334Speter{
215418334Speter  if (STACK_TOP_P (operands[0]))
215590286Sobrien    return "fxch\t%1";
215618334Speter  else
215790286Sobrien    return "fxch\t%0";
215890286Sobrien}
215990286Sobrien  [(set_attr "type" "fxch")
216090286Sobrien   (set_attr "mode" "SF")])
216118334Speter
216290286Sobrien(define_expand "movdf"
216390286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
216490286Sobrien	(match_operand:DF 1 "general_operand" ""))]
216590286Sobrien  ""
216690286Sobrien  "ix86_expand_move (DFmode, operands); DONE;")
216752296Sobrien
216890286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
216990286Sobrien;; Size of pushdf using integer insturctions is 2+2*memory operand size
217090286Sobrien;; On the average, pushdf using integers can be still shorter.  Allow this
217190286Sobrien;; pattern for optimize_size too.
217290286Sobrien
217390286Sobrien(define_insn "*pushdf_nointeger"
217490286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
217590286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
217690286Sobrien  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
217718334Speter{
217890286Sobrien  switch (which_alternative)
217918334Speter    {
218090286Sobrien    case 0:
218190286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
218290286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
218390286Sobrien      operands[2] = stack_pointer_rtx;
218490286Sobrien      operands[3] = GEN_INT (8);
218590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
218690286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
218790286Sobrien      else
218890286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
218918334Speter
219090286Sobrien    case 1:
219190286Sobrien    case 2:
219290286Sobrien    case 3:
219390286Sobrien      return "#";
219418334Speter
219590286Sobrien    default:
219690286Sobrien      abort ();
219790286Sobrien    }
219890286Sobrien}
219990286Sobrien  [(set_attr "type" "multi")
220090286Sobrien   (set_attr "mode" "DF,SI,SI,DF")])
220118334Speter
220290286Sobrien(define_insn "*pushdf_integer"
220390286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
220490286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
220590286Sobrien  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
220690286Sobrien{
220790286Sobrien  switch (which_alternative)
220890286Sobrien    {
220990286Sobrien    case 0:
221090286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
221190286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
221290286Sobrien      operands[2] = stack_pointer_rtx;
221390286Sobrien      operands[3] = GEN_INT (8);
221490286Sobrien      if (TARGET_64BIT)
221590286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
221690286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
221790286Sobrien	else
221890286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
221918334Speter      else
222090286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
222190286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
222290286Sobrien	else
222390286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
222418334Speter
222550650Sobrien
222690286Sobrien    case 1:
222790286Sobrien    case 2:
222890286Sobrien      return "#";
222950650Sobrien
223090286Sobrien    default:
223190286Sobrien      abort ();
223290286Sobrien    }
223390286Sobrien}
223490286Sobrien  [(set_attr "type" "multi")
223590286Sobrien   (set_attr "mode" "DF,SI,DF")])
223618334Speter
223790286Sobrien;; %%% Kill this when call knows how to work this out.
223852296Sobrien(define_split
223952296Sobrien  [(set (match_operand:DF 0 "push_operand" "")
2240117404Skan	(match_operand:DF 1 "any_fp_register_operand" ""))]
2241117404Skan  "!TARGET_64BIT && reload_completed"
224290286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
224390286Sobrien   (set (mem:DF (reg:SI 7)) (match_dup 1))]
224452296Sobrien  "")
224550650Sobrien
224690286Sobrien(define_split
224790286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
2248117404Skan	(match_operand:DF 1 "any_fp_register_operand" ""))]
2249117404Skan  "TARGET_64BIT && reload_completed"
225090286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
225190286Sobrien   (set (mem:DF (reg:DI 7)) (match_dup 1))]
225290286Sobrien  "")
225390286Sobrien
225490286Sobrien(define_split
225590286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
225650650Sobrien	(match_operand:DF 1 "general_operand" ""))]
225790286Sobrien  "reload_completed"
225890286Sobrien  [(const_int 0)]
225990286Sobrien  "ix86_split_long_move (operands); DONE;")
226090286Sobrien
226190286Sobrien;; Moving is usually shorter when only FP registers are used. This separate
226290286Sobrien;; movdf pattern avoids the use of integer registers for FP operations
226390286Sobrien;; when optimizing for size.
226490286Sobrien
226590286Sobrien(define_insn "*movdf_nointeger"
226690286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2267117404Skan	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
226890286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
226990286Sobrien   && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
227090286Sobrien   && (reload_in_progress || reload_completed
227190286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
227290286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
227390286Sobrien       || memory_operand (operands[0], DFmode))" 
227418334Speter{
227590286Sobrien  switch (which_alternative)
227618334Speter    {
227790286Sobrien    case 0:
227890286Sobrien      if (REG_P (operands[1])
227990286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
228090286Sobrien        return "fstp\t%y0";
228190286Sobrien      else if (STACK_TOP_P (operands[0]))
228290286Sobrien        return "fld%z1\t%y1";
228390286Sobrien      else
228490286Sobrien        return "fst\t%y0";
228518334Speter
228690286Sobrien    case 1:
228790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
228890286Sobrien        return "fstp%z0\t%y0";
228990286Sobrien      else
229090286Sobrien        return "fst%z0\t%y0";
229118334Speter
229290286Sobrien    case 2:
229390286Sobrien      switch (standard_80387_constant_p (operands[1]))
229490286Sobrien        {
229590286Sobrien        case 1:
229690286Sobrien	  return "fldz";
229790286Sobrien	case 2:
229890286Sobrien	  return "fld1";
229990286Sobrien	}
230090286Sobrien      abort();
230118334Speter
230290286Sobrien    case 3:
230390286Sobrien    case 4:
230490286Sobrien      return "#";
230590286Sobrien    case 5:
2306117404Skan      if (TARGET_ATHLON)
2307117404Skan        return "xorpd\t%0, %0";
2308117404Skan      else
2309117404Skan        return "pxor\t%0, %0";
231090286Sobrien    case 6:
231190286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
231290286Sobrien	return "movapd\t{%1, %0|%0, %1}";
231390286Sobrien      else
231490286Sobrien	return "movsd\t{%1, %0|%0, %1}";
231590286Sobrien    case 7:
231690286Sobrien    case 8:
231790286Sobrien        return "movsd\t{%1, %0|%0, %1}";
231818334Speter
231990286Sobrien    default:
232090286Sobrien      abort();
232118334Speter    }
232290286Sobrien}
2323117404Skan  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
232490286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
232518334Speter
232690286Sobrien(define_insn "*movdf_integer"
232790286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2328117404Skan	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
232990286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
233090286Sobrien   && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
233190286Sobrien   && (reload_in_progress || reload_completed
233290286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
233390286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
233490286Sobrien       || memory_operand (operands[0], DFmode))" 
233590286Sobrien{
233690286Sobrien  switch (which_alternative)
233718334Speter    {
233890286Sobrien    case 0:
233990286Sobrien      if (REG_P (operands[1])
234090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
234190286Sobrien        return "fstp\t%y0";
234290286Sobrien      else if (STACK_TOP_P (operands[0]))
234390286Sobrien        return "fld%z1\t%y1";
234418334Speter      else
234590286Sobrien        return "fst\t%y0";
234618334Speter
234790286Sobrien    case 1:
234890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
234990286Sobrien        return "fstp%z0\t%y0";
235090286Sobrien      else
235190286Sobrien        return "fst%z0\t%y0";
235218334Speter
235390286Sobrien    case 2:
235490286Sobrien      switch (standard_80387_constant_p (operands[1]))
235590286Sobrien        {
235690286Sobrien        case 1:
235790286Sobrien	  return "fldz";
235890286Sobrien	case 2:
235990286Sobrien	  return "fld1";
236090286Sobrien	}
236190286Sobrien      abort();
236218334Speter
236390286Sobrien    case 3:
236490286Sobrien    case 4:
236590286Sobrien      return "#";
236618334Speter
236790286Sobrien    case 5:
2368117404Skan      if (TARGET_ATHLON)
2369117404Skan        return "xorpd\t%0, %0";
2370117404Skan      else
2371117404Skan        return "pxor\t%0, %0";
237290286Sobrien    case 6:
237390286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
237490286Sobrien	return "movapd\t{%1, %0|%0, %1}";
237590286Sobrien      else
237690286Sobrien	return "movsd\t{%1, %0|%0, %1}";
237790286Sobrien    case 7:
237890286Sobrien    case 8:
237990286Sobrien      return "movsd\t{%1, %0|%0, %1}";
238018334Speter
238190286Sobrien    default:
238290286Sobrien      abort();
238390286Sobrien    }
238490286Sobrien}
2385117404Skan  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
238690286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
238718334Speter
238890286Sobrien(define_split
238990286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
239090286Sobrien	(match_operand:DF 1 "general_operand" ""))]
239190286Sobrien  "reload_completed
239290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
239390286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
239490286Sobrien	 (GET_CODE (operands[0]) == SUBREG
239590286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
239690286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
239790286Sobrien	 (GET_CODE (operands[1]) == SUBREG
239890286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
239990286Sobrien  [(const_int 0)]
240090286Sobrien  "ix86_split_long_move (operands); DONE;")
240150650Sobrien
240290286Sobrien(define_insn "*swapdf"
240390286Sobrien  [(set (match_operand:DF 0 "register_operand" "+f")
240490286Sobrien	(match_operand:DF 1 "register_operand" "+f"))
240518334Speter   (set (match_dup 1)
240618334Speter	(match_dup 0))]
240790286Sobrien  "reload_completed || !TARGET_SSE2"
240818334Speter{
240918334Speter  if (STACK_TOP_P (operands[0]))
241090286Sobrien    return "fxch\t%1";
241118334Speter  else
241290286Sobrien    return "fxch\t%0";
241390286Sobrien}
241490286Sobrien  [(set_attr "type" "fxch")
241590286Sobrien   (set_attr "mode" "DF")])
241618334Speter
241790286Sobrien(define_expand "movxf"
241890286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
241990286Sobrien	(match_operand:XF 1 "general_operand" ""))]
242090286Sobrien  "!TARGET_64BIT"
242190286Sobrien  "ix86_expand_move (XFmode, operands); DONE;")
242290286Sobrien
242390286Sobrien(define_expand "movtf"
242490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
242590286Sobrien	(match_operand:TF 1 "general_operand" ""))]
242690286Sobrien  ""
242790286Sobrien  "ix86_expand_move (TFmode, operands); DONE;")
242890286Sobrien
242990286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
243090286Sobrien;; Size of pushdf using integer insturctions is 3+3*memory operand size
243190286Sobrien;; Pushing using integer instructions is longer except for constants
243290286Sobrien;; and direct memory references.
243390286Sobrien;; (assuming that any given constant is pushed only once, but this ought to be
243490286Sobrien;;  handled elsewhere).
243590286Sobrien
243690286Sobrien(define_insn "*pushxf_nointeger"
243790286Sobrien  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
243890286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
243990286Sobrien  "!TARGET_64BIT && optimize_size"
244018334Speter{
244190286Sobrien  switch (which_alternative)
244218334Speter    {
244390286Sobrien    case 0:
244490286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
244590286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
244690286Sobrien      operands[2] = stack_pointer_rtx;
244790286Sobrien      operands[3] = GEN_INT (12);
244890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
244990286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
245090286Sobrien      else
245190286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
245218334Speter
245390286Sobrien    case 1:
245490286Sobrien    case 2:
245590286Sobrien      return "#";
245618334Speter
245790286Sobrien    default:
245890286Sobrien      abort ();
245990286Sobrien    }
246090286Sobrien}
246190286Sobrien  [(set_attr "type" "multi")
246290286Sobrien   (set_attr "mode" "XF,SI,SI")])
246350650Sobrien
246490286Sobrien(define_insn "*pushtf_nointeger"
246590286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
246690286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
246790286Sobrien  "optimize_size"
246890286Sobrien{
246990286Sobrien  switch (which_alternative)
247090286Sobrien    {
247190286Sobrien    case 0:
247290286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
247390286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
247490286Sobrien      operands[2] = stack_pointer_rtx;
247590286Sobrien      operands[3] = GEN_INT (16);
247690286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
247790286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
247890286Sobrien      else
247990286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
248018334Speter
248190286Sobrien    case 1:
248290286Sobrien    case 2:
248390286Sobrien      return "#";
248490286Sobrien
248590286Sobrien    default:
248690286Sobrien      abort ();
248718334Speter    }
248890286Sobrien}
248990286Sobrien  [(set_attr "type" "multi")
249090286Sobrien   (set_attr "mode" "XF,SI,SI")])
249150650Sobrien
249290286Sobrien(define_insn "*pushxf_integer"
249390286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<,<")
249490286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
249590286Sobrien  "!TARGET_64BIT && !optimize_size"
249690286Sobrien{
249790286Sobrien  switch (which_alternative)
249890286Sobrien    {
249990286Sobrien    case 0:
250090286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
250190286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
250290286Sobrien      operands[2] = stack_pointer_rtx;
250390286Sobrien      operands[3] = GEN_INT (12);
250490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
250590286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
250690286Sobrien      else
250790286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
250850650Sobrien
250990286Sobrien    case 1:
251090286Sobrien      return "#";
251118334Speter
251290286Sobrien    default:
251390286Sobrien      abort ();
251490286Sobrien    }
251590286Sobrien}
251690286Sobrien  [(set_attr "type" "multi")
251790286Sobrien   (set_attr "mode" "XF,SI")])
251890286Sobrien
251990286Sobrien(define_insn "*pushtf_integer"
252090286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<")
252190286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
252290286Sobrien  "!optimize_size"
252390286Sobrien{
252490286Sobrien  switch (which_alternative)
252590286Sobrien    {
252690286Sobrien    case 0:
252790286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
252890286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
252990286Sobrien      operands[2] = stack_pointer_rtx;
253090286Sobrien      operands[3] = GEN_INT (16);
253190286Sobrien      if (TARGET_64BIT)
253290286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
253390286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
253490286Sobrien	else
253590286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
253690286Sobrien      else
253790286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
253890286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
253990286Sobrien	else
254090286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
254190286Sobrien
254290286Sobrien    case 1:
254390286Sobrien      return "#";
254490286Sobrien
254590286Sobrien    default:
254690286Sobrien      abort ();
254790286Sobrien    }
254890286Sobrien}
254990286Sobrien  [(set_attr "type" "multi")
255090286Sobrien   (set_attr "mode" "XF,SI")])
255190286Sobrien
255252296Sobrien(define_split
255390286Sobrien  [(set (match_operand 0 "push_operand" "")
255490286Sobrien	(match_operand 1 "general_operand" ""))]
255590286Sobrien  "reload_completed
255690286Sobrien   && (GET_MODE (operands[0]) == XFmode
255790286Sobrien       || GET_MODE (operands[0]) == TFmode
255890286Sobrien       || GET_MODE (operands[0]) == DFmode)
2559117404Skan   && !ANY_FP_REG_P (operands[1])"
256090286Sobrien  [(const_int 0)]
256190286Sobrien  "ix86_split_long_move (operands); DONE;")
256290286Sobrien
256390286Sobrien(define_split
256452296Sobrien  [(set (match_operand:XF 0 "push_operand" "")
2565117404Skan	(match_operand:XF 1 "any_fp_register_operand" ""))]
2566117404Skan  "!TARGET_64BIT"
256790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
256890286Sobrien   (set (mem:XF (reg:SI 7)) (match_dup 1))])
256950650Sobrien
257090286Sobrien(define_split
257190286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
2572117404Skan	(match_operand:TF 1 "any_fp_register_operand" ""))]
2573117404Skan  "!TARGET_64BIT"
257490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
257590286Sobrien   (set (mem:TF (reg:SI 7)) (match_dup 1))])
257690286Sobrien
257790286Sobrien(define_split
257890286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
2579117404Skan	(match_operand:TF 1 "any_fp_register_operand" ""))]
2580117404Skan  "TARGET_64BIT"
258190286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
258290286Sobrien   (set (mem:TF (reg:DI 7)) (match_dup 1))])
258390286Sobrien
258490286Sobrien;; Do not use integer registers when optimizing for size
258590286Sobrien(define_insn "*movxf_nointeger"
258690286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
258790286Sobrien	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
258890286Sobrien  "!TARGET_64BIT
258990286Sobrien   && optimize_size
259090286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
259190286Sobrien   && (reload_in_progress || reload_completed
259290286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
259390286Sobrien       || memory_operand (operands[0], XFmode))" 
259418334Speter{
259590286Sobrien  switch (which_alternative)
259618334Speter    {
259790286Sobrien    case 0:
259890286Sobrien      if (REG_P (operands[1])
259990286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
260090286Sobrien        return "fstp\t%y0";
260190286Sobrien      else if (STACK_TOP_P (operands[0]))
260290286Sobrien        return "fld%z1\t%y1";
260390286Sobrien      else
260490286Sobrien        return "fst\t%y0";
260590286Sobrien
260690286Sobrien    case 1:
260790286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
260890286Sobrien	 we need one, follow the store with a load.  */
260990286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
261090286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
261190286Sobrien      else
261290286Sobrien        return "fstp%z0\t%y0";
261390286Sobrien
261490286Sobrien    case 2:
261590286Sobrien      switch (standard_80387_constant_p (operands[1]))
261690286Sobrien        {
261790286Sobrien        case 1:
261890286Sobrien	  return "fldz";
261990286Sobrien	case 2:
262090286Sobrien	  return "fld1";
262190286Sobrien	}
262290286Sobrien      break;
262390286Sobrien
262490286Sobrien    case 3: case 4:
262590286Sobrien      return "#";
262650650Sobrien    }
262790286Sobrien  abort();
262890286Sobrien}
262990286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
263090286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
263118334Speter
263290286Sobrien(define_insn "*movtf_nointeger"
263390286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
263490286Sobrien	(match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
263590286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
263690286Sobrien   && optimize_size
263790286Sobrien   && (reload_in_progress || reload_completed
263890286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
263990286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
264090286Sobrien       || memory_operand (operands[0], TFmode))" 
264190286Sobrien{
264290286Sobrien  switch (which_alternative)
264350650Sobrien    {
264490286Sobrien    case 0:
264590286Sobrien      if (REG_P (operands[1])
264690286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
264790286Sobrien        return "fstp\t%y0";
264890286Sobrien      else if (STACK_TOP_P (operands[0]))
264990286Sobrien        return "fld%z1\t%y1";
265090286Sobrien      else
265190286Sobrien        return "fst\t%y0";
265218334Speter
265390286Sobrien    case 1:
265490286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
265590286Sobrien	 we need one, follow the store with a load.  */
265690286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
265790286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
265890286Sobrien      else
265990286Sobrien        return "fstp%z0\t%y0";
266018334Speter
266190286Sobrien    case 2:
266290286Sobrien      switch (standard_80387_constant_p (operands[1]))
266390286Sobrien        {
266490286Sobrien        case 1:
266590286Sobrien	  return "fldz";
266690286Sobrien	case 2:
266790286Sobrien	  return "fld1";
266890286Sobrien	}
266990286Sobrien      break;
267018334Speter
267190286Sobrien    case 3: case 4:
267290286Sobrien      return "#";
267390286Sobrien    }
267490286Sobrien  abort();
267590286Sobrien}
267690286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
267790286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
267818334Speter
267990286Sobrien(define_insn "*movxf_integer"
268090286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
268190286Sobrien	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
268290286Sobrien  "!TARGET_64BIT
268390286Sobrien   && !optimize_size
268490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
268590286Sobrien   && (reload_in_progress || reload_completed
268690286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
268790286Sobrien       || memory_operand (operands[0], XFmode))" 
268890286Sobrien{
268990286Sobrien  switch (which_alternative)
269018334Speter    {
269190286Sobrien    case 0:
269290286Sobrien      if (REG_P (operands[1])
269390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
269490286Sobrien        return "fstp\t%y0";
269590286Sobrien      else if (STACK_TOP_P (operands[0]))
269690286Sobrien        return "fld%z1\t%y1";
269718334Speter      else
269890286Sobrien        return "fst\t%y0";
269918334Speter
270090286Sobrien    case 1:
270190286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
270290286Sobrien	 we need one, follow the store with a load.  */
270390286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
270490286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
270590286Sobrien      else
270690286Sobrien        return "fstp%z0\t%y0";
270718334Speter
270890286Sobrien    case 2:
270990286Sobrien      switch (standard_80387_constant_p (operands[1]))
271090286Sobrien        {
271190286Sobrien        case 1:
271290286Sobrien	  return "fldz";
271390286Sobrien	case 2:
271490286Sobrien	  return "fld1";
271590286Sobrien	}
271690286Sobrien      break;
271718334Speter
271890286Sobrien    case 3: case 4:
271990286Sobrien      return "#";
272018334Speter    }
272190286Sobrien  abort();
272290286Sobrien}
272390286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
272490286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
272518334Speter
272690286Sobrien(define_insn "*movtf_integer"
272790286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
272890286Sobrien	(match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
272990286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
273090286Sobrien   && !optimize_size
273190286Sobrien   && (reload_in_progress || reload_completed
273290286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
273390286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
273490286Sobrien       || memory_operand (operands[0], TFmode))" 
273590286Sobrien{
273690286Sobrien  switch (which_alternative)
273790286Sobrien    {
273890286Sobrien    case 0:
273990286Sobrien      if (REG_P (operands[1])
274090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
274190286Sobrien        return "fstp\t%y0";
274290286Sobrien      else if (STACK_TOP_P (operands[0]))
274390286Sobrien        return "fld%z1\t%y1";
274490286Sobrien      else
274590286Sobrien        return "fst\t%y0";
274618334Speter
274790286Sobrien    case 1:
274890286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
274990286Sobrien	 we need one, follow the store with a load.  */
275090286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
275190286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
275290286Sobrien      else
275390286Sobrien        return "fstp%z0\t%y0";
275418334Speter
275590286Sobrien    case 2:
275690286Sobrien      switch (standard_80387_constant_p (operands[1]))
275790286Sobrien        {
275890286Sobrien        case 1:
275990286Sobrien	  return "fldz";
276090286Sobrien	case 2:
276190286Sobrien	  return "fld1";
276290286Sobrien	}
276390286Sobrien      break;
276418334Speter
276590286Sobrien    case 3: case 4:
276690286Sobrien      return "#";
276790286Sobrien    }
276890286Sobrien  abort();
276990286Sobrien}
277090286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
277190286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
277218334Speter
277390286Sobrien(define_split
277490286Sobrien  [(set (match_operand 0 "nonimmediate_operand" "")
277590286Sobrien	(match_operand 1 "general_operand" ""))]
277690286Sobrien  "reload_completed
277790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
277890286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
277990286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
278090286Sobrien	 (GET_CODE (operands[0]) == SUBREG
278190286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
278290286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
278390286Sobrien	 (GET_CODE (operands[1]) == SUBREG
278490286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
278590286Sobrien  [(const_int 0)]
278690286Sobrien  "ix86_split_long_move (operands); DONE;")
278718334Speter
278890286Sobrien(define_split
278990286Sobrien  [(set (match_operand 0 "register_operand" "")
279090286Sobrien	(match_operand 1 "memory_operand" ""))]
279190286Sobrien  "reload_completed
279290286Sobrien   && GET_CODE (operands[1]) == MEM
279390286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
279490286Sobrien       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
279590286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
279690286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
279790286Sobrien   && (!(SSE_REG_P (operands[0]) || 
279890286Sobrien	 (GET_CODE (operands[0]) == SUBREG
279990286Sobrien	  && SSE_REG_P (SUBREG_REG (operands[0]))))
280090286Sobrien       || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
280190286Sobrien   && (!(FP_REG_P (operands[0]) || 
280290286Sobrien	 (GET_CODE (operands[0]) == SUBREG
280390286Sobrien	  && FP_REG_P (SUBREG_REG (operands[0]))))
280490286Sobrien       || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
280590286Sobrien  [(set (match_dup 0)
280690286Sobrien	(match_dup 1))]
280790286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
280890286Sobrien
280990286Sobrien(define_insn "swapxf"
281090286Sobrien  [(set (match_operand:XF 0 "register_operand" "+f")
281190286Sobrien	(match_operand:XF 1 "register_operand" "+f"))
281218334Speter   (set (match_dup 1)
281318334Speter	(match_dup 0))]
281418334Speter  ""
281518334Speter{
281618334Speter  if (STACK_TOP_P (operands[0]))
281790286Sobrien    return "fxch\t%1";
281818334Speter  else
281990286Sobrien    return "fxch\t%0";
282090286Sobrien}
282190286Sobrien  [(set_attr "type" "fxch")
282290286Sobrien   (set_attr "mode" "XF")])
282318334Speter
282490286Sobrien(define_insn "swaptf"
282590286Sobrien  [(set (match_operand:TF 0 "register_operand" "+f")
282690286Sobrien	(match_operand:TF 1 "register_operand" "+f"))
282790286Sobrien   (set (match_dup 1)
282890286Sobrien	(match_dup 0))]
282918334Speter  ""
283018334Speter{
283190286Sobrien  if (STACK_TOP_P (operands[0]))
283290286Sobrien    return "fxch\t%1";
283390286Sobrien  else
283490286Sobrien    return "fxch\t%0";
283590286Sobrien}
283690286Sobrien  [(set_attr "type" "fxch")
283790286Sobrien   (set_attr "mode" "XF")])
283818334Speter
283990286Sobrien;; Zero extension instructions
284018334Speter
284152296Sobrien(define_expand "zero_extendhisi2"
284252296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
284390286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
284452296Sobrien  ""
284590286Sobrien{
284690286Sobrien  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
284718334Speter    {
284890286Sobrien      operands[1] = force_reg (HImode, operands[1]);
284990286Sobrien      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
285090286Sobrien      DONE;
285118334Speter    }
285290286Sobrien})
285318334Speter
285490286Sobrien(define_insn "zero_extendhisi2_and"
285590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
285690286Sobrien     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
285790286Sobrien   (clobber (reg:CC 17))]
285890286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
285990286Sobrien  "#"
286090286Sobrien  [(set_attr "type" "alu1")
286190286Sobrien   (set_attr "mode" "SI")])
286250650Sobrien
286350650Sobrien(define_split
286450650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
286590286Sobrien	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
286690286Sobrien   (clobber (reg:CC 17))]
286790286Sobrien  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
286890286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
286990286Sobrien	      (clobber (reg:CC 17))])]
287090286Sobrien  "")
287150650Sobrien
287290286Sobrien(define_insn "*zero_extendhisi2_movzwl"
287390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
287490286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
287590286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
287690286Sobrien  "movz{wl|x}\t{%1, %0|%0, %1}"
287790286Sobrien  [(set_attr "type" "imovx")
287890286Sobrien   (set_attr "mode" "SI")])
287950650Sobrien
288052296Sobrien(define_expand "zero_extendqihi2"
288190286Sobrien  [(parallel
288290286Sobrien    [(set (match_operand:HI 0 "register_operand" "")
288390286Sobrien       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
288490286Sobrien     (clobber (reg:CC 17))])]
288552296Sobrien  ""
288652296Sobrien  "")
288752296Sobrien
288890286Sobrien(define_insn "*zero_extendqihi2_and"
288990286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
289090286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
289190286Sobrien   (clobber (reg:CC 17))]
289290286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
289390286Sobrien  "#"
289490286Sobrien  [(set_attr "type" "alu1")
289590286Sobrien   (set_attr "mode" "HI")])
289652296Sobrien
289790286Sobrien(define_insn "*zero_extendqihi2_movzbw_and"
289890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
289990286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
290090286Sobrien   (clobber (reg:CC 17))]
290190286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
290290286Sobrien  "#"
290390286Sobrien  [(set_attr "type" "imovx,alu1")
290490286Sobrien   (set_attr "mode" "HI")])
290552296Sobrien
290690286Sobrien(define_insn "*zero_extendqihi2_movzbw"
290790286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r")
290890286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
290990286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
291090286Sobrien  "movz{bw|x}\t{%1, %0|%0, %1}"
291190286Sobrien  [(set_attr "type" "imovx")
291290286Sobrien   (set_attr "mode" "HI")])
291350650Sobrien
291490286Sobrien;; For the movzbw case strip only the clobber
291550650Sobrien(define_split
291650650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
291790286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
291890286Sobrien   (clobber (reg:CC 17))]
291990286Sobrien  "reload_completed 
292090286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
292190286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
292290286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
292390286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
292450650Sobrien
292590286Sobrien;; When source and destination does not overlap, clear destination
292690286Sobrien;; first and then do the movb
292750650Sobrien(define_split
292850650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
292990286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
293090286Sobrien   (clobber (reg:CC 17))]
293190286Sobrien  "reload_completed
293290286Sobrien   && ANY_QI_REG_P (operands[0])
293390286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
293490286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
293590286Sobrien  [(set (match_dup 0) (const_int 0))
293690286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
293790286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
293850650Sobrien
293990286Sobrien;; Rest is handled by single and.
294050650Sobrien(define_split
294150650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
294290286Sobrien	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
294390286Sobrien   (clobber (reg:CC 17))]
294490286Sobrien  "reload_completed
294590286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
294690286Sobrien  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
294790286Sobrien	      (clobber (reg:CC 17))])]
294890286Sobrien  "")
294950650Sobrien
295052296Sobrien(define_expand "zero_extendqisi2"
295190286Sobrien  [(parallel
295290286Sobrien    [(set (match_operand:SI 0 "register_operand" "")
295390286Sobrien       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
295490286Sobrien     (clobber (reg:CC 17))])]
295552296Sobrien  ""
295652296Sobrien  "")
295752296Sobrien
295890286Sobrien(define_insn "*zero_extendqisi2_and"
295990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
296090286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
296190286Sobrien   (clobber (reg:CC 17))]
296290286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
296390286Sobrien  "#"
296490286Sobrien  [(set_attr "type" "alu1")
296590286Sobrien   (set_attr "mode" "SI")])
296652296Sobrien
296790286Sobrien(define_insn "*zero_extendqisi2_movzbw_and"
296890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
296990286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
297090286Sobrien   (clobber (reg:CC 17))]
297190286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
297290286Sobrien  "#"
297390286Sobrien  [(set_attr "type" "imovx,alu1")
297490286Sobrien   (set_attr "mode" "SI")])
297550650Sobrien
297690286Sobrien(define_insn "*zero_extendqisi2_movzbw"
297790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
297890286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
297990286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
298090286Sobrien  "movz{bl|x}\t{%1, %0|%0, %1}"
298190286Sobrien  [(set_attr "type" "imovx")
298290286Sobrien   (set_attr "mode" "SI")])
298318334Speter
298490286Sobrien;; For the movzbl case strip only the clobber
298550650Sobrien(define_split
298650650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
298790286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
298890286Sobrien   (clobber (reg:CC 17))]
298990286Sobrien  "reload_completed 
299090286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
299190286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
299290286Sobrien  [(set (match_dup 0)
299390286Sobrien	(zero_extend:SI (match_dup 1)))])
299450650Sobrien
299590286Sobrien;; When source and destination does not overlap, clear destination
299690286Sobrien;; first and then do the movb
299750650Sobrien(define_split
299850650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
299990286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
300090286Sobrien   (clobber (reg:CC 17))]
300190286Sobrien  "reload_completed
300290286Sobrien   && ANY_QI_REG_P (operands[0])
300390286Sobrien   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
300490286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
300590286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
300690286Sobrien  [(set (match_dup 0) (const_int 0))
300790286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
300890286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
300950650Sobrien
301090286Sobrien;; Rest is handled by single and.
301150650Sobrien(define_split
301250650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
301390286Sobrien	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
301490286Sobrien   (clobber (reg:CC 17))]
301590286Sobrien  "reload_completed
301690286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
301790286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
301890286Sobrien	      (clobber (reg:CC 17))])]
301990286Sobrien  "")
302050650Sobrien
302190286Sobrien;; %%% Kill me once multi-word ops are sane.
302290286Sobrien(define_expand "zero_extendsidi2"
302390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
302490286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
302518334Speter  ""
302690286Sobrien  "if (!TARGET_64BIT)
302790286Sobrien     {
302890286Sobrien       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
302990286Sobrien       DONE;
303090286Sobrien     }
303190286Sobrien  ")
303250650Sobrien
303390286Sobrien(define_insn "zero_extendsidi2_32"
303490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
303590286Sobrien	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
303690286Sobrien   (clobber (reg:CC 17))]
303790286Sobrien  "!TARGET_64BIT"
303890286Sobrien  "#"
303990286Sobrien  [(set_attr "mode" "SI")])
304090286Sobrien
304190286Sobrien(define_insn "zero_extendsidi2_rex64"
304290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
304390286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
304490286Sobrien  "TARGET_64BIT"
304590286Sobrien  "@
304690286Sobrien   mov\t{%k1, %k0|%k0, %k1}
304790286Sobrien   #"
304890286Sobrien  [(set_attr "type" "imovx,imov")
304990286Sobrien   (set_attr "mode" "SI,DI")])
305090286Sobrien
305190286Sobrien(define_split
305290286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
305390286Sobrien     (zero_extend:DI (match_dup 0)))]
305490286Sobrien  "TARGET_64BIT"
305590286Sobrien  [(set (match_dup 4) (const_int 0))]
305690286Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
305790286Sobrien
305852296Sobrien(define_split 
305952296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
306090286Sobrien	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
306190286Sobrien   (clobber (reg:CC 17))]
306290286Sobrien  "!TARGET_64BIT && reload_completed
306390286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
306452296Sobrien  [(set (match_dup 4) (const_int 0))]
306552296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
306650650Sobrien
306752296Sobrien(define_split 
306852296Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
306990286Sobrien	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
307090286Sobrien   (clobber (reg:CC 17))]
307190286Sobrien  "!TARGET_64BIT && reload_completed"
307252296Sobrien  [(set (match_dup 3) (match_dup 1))
307352296Sobrien   (set (match_dup 4) (const_int 0))]
307452296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
307590286Sobrien
307690286Sobrien(define_insn "zero_extendhidi2"
307790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
307890286Sobrien     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
307990286Sobrien  "TARGET_64BIT"
308090286Sobrien  "@
308190286Sobrien   movz{wl|x}\t{%1, %k0|%k0, %1} 
308290286Sobrien   movz{wq|x}\t{%1, %0|%0, %1}"
308390286Sobrien  [(set_attr "type" "imovx")
308490286Sobrien   (set_attr "mode" "SI,DI")])
308590286Sobrien
308690286Sobrien(define_insn "zero_extendqidi2"
308790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
308890286Sobrien     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
308990286Sobrien  "TARGET_64BIT"
309090286Sobrien  "@
309190286Sobrien   movz{bl|x}\t{%1, %k0|%k0, %1} 
309290286Sobrien   movz{bq|x}\t{%1, %0|%0, %1}"
309390286Sobrien  [(set_attr "type" "imovx")
309490286Sobrien   (set_attr "mode" "SI,DI")])
309518334Speter
309690286Sobrien;; Sign extension instructions
309718334Speter
309890286Sobrien(define_expand "extendsidi2"
309990286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
310090286Sobrien		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
310190286Sobrien	      (clobber (reg:CC 17))
310290286Sobrien	      (clobber (match_scratch:SI 2 ""))])]
310390286Sobrien  ""
310490286Sobrien{
310590286Sobrien  if (TARGET_64BIT)
310690286Sobrien    {
310790286Sobrien      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
310890286Sobrien      DONE;
310990286Sobrien    }
311090286Sobrien})
311190286Sobrien
311290286Sobrien(define_insn "*extendsidi2_1"
311390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
311490286Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
311590286Sobrien   (clobber (reg:CC 17))
311652296Sobrien   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
311790286Sobrien  "!TARGET_64BIT"
311852296Sobrien  "#")
311952296Sobrien
312090286Sobrien(define_insn "extendsidi2_rex64"
312190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
312290286Sobrien	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
312390286Sobrien  "TARGET_64BIT"
312490286Sobrien  "@
312590286Sobrien   {cltq|cdqe}
312690286Sobrien   movs{lq|x}\t{%1,%0|%0, %1}"
312790286Sobrien  [(set_attr "type" "imovx")
312890286Sobrien   (set_attr "mode" "DI")
312990286Sobrien   (set_attr "prefix_0f" "0")
313090286Sobrien   (set_attr "modrm" "0,1")])
313190286Sobrien
313290286Sobrien(define_insn "extendhidi2"
313390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
313490286Sobrien	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
313590286Sobrien  "TARGET_64BIT"
313690286Sobrien  "movs{wq|x}\t{%1,%0|%0, %1}"
313790286Sobrien  [(set_attr "type" "imovx")
313890286Sobrien   (set_attr "mode" "DI")])
313990286Sobrien
314090286Sobrien(define_insn "extendqidi2"
314190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
314290286Sobrien	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
314390286Sobrien  "TARGET_64BIT"
314490286Sobrien  "movs{bq|x}\t{%1,%0|%0, %1}"
314590286Sobrien   [(set_attr "type" "imovx")
314690286Sobrien    (set_attr "mode" "DI")])
314790286Sobrien
314852296Sobrien;; Extend to memory case when source register does die.
314952296Sobrien(define_split 
315052296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
315152296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
315290286Sobrien   (clobber (reg:CC 17))
315352296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
315490286Sobrien  "(reload_completed
315552296Sobrien    && dead_or_set_p (insn, operands[1])
315652296Sobrien    && !reg_mentioned_p (operands[1], operands[0]))"
315752296Sobrien  [(set (match_dup 3) (match_dup 1))
315890286Sobrien   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
315990286Sobrien	      (clobber (reg:CC 17))])
316052296Sobrien   (set (match_dup 4) (match_dup 1))]
316152296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
316252296Sobrien
316352296Sobrien;; Extend to memory case when source register does not die.
316452296Sobrien(define_split 
316552296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
316652296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
316790286Sobrien   (clobber (reg:CC 17))
316852296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
316990286Sobrien  "reload_completed"
317052296Sobrien  [(const_int 0)]
317118334Speter{
317252296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
317352296Sobrien
317452296Sobrien  emit_move_insn (operands[3], operands[1]);
317552296Sobrien
317652296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
317752296Sobrien  if (true_regnum (operands[1]) == 0
317852296Sobrien      && true_regnum (operands[2]) == 1
317990286Sobrien      && (optimize_size || TARGET_USE_CLTD))
318018334Speter    {
318190286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
318218334Speter    }
318352296Sobrien  else
318452296Sobrien    {
318552296Sobrien      emit_move_insn (operands[2], operands[1]);
318690286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
318752296Sobrien    }
318852296Sobrien  emit_move_insn (operands[4], operands[2]);
318952296Sobrien  DONE;
319090286Sobrien})
319118334Speter
319252296Sobrien;; Extend to register case.  Optimize case where source and destination
319352296Sobrien;; registers match and cases where we can use cltd.
319452296Sobrien(define_split 
319552296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
319652296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
319790286Sobrien   (clobber (reg:CC 17))
319852296Sobrien   (clobber (match_scratch:SI 2 ""))]
319952296Sobrien  "reload_completed"
320052296Sobrien  [(const_int 0)]
320152296Sobrien{
320252296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
320318334Speter
320452296Sobrien  if (true_regnum (operands[3]) != true_regnum (operands[1]))
320552296Sobrien    emit_move_insn (operands[3], operands[1]);
320652296Sobrien
320752296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
320852296Sobrien  if (true_regnum (operands[3]) == 0
320990286Sobrien      && (optimize_size || TARGET_USE_CLTD))
321052296Sobrien    {
321190286Sobrien      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
321252296Sobrien      DONE;
321352296Sobrien    }
321452296Sobrien
321552296Sobrien  if (true_regnum (operands[4]) != true_regnum (operands[1]))
321652296Sobrien    emit_move_insn (operands[4], operands[1]);
321752296Sobrien
321890286Sobrien  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
321952296Sobrien  DONE;
322090286Sobrien})
322118334Speter
322218334Speter(define_insn "extendhisi2"
322390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=*a,r")
322490286Sobrien	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
322518334Speter  ""
322618334Speter{
322790286Sobrien  switch (get_attr_prefix_0f (insn))
322890286Sobrien    {
322990286Sobrien    case 0:
323090286Sobrien      return "{cwtl|cwde}";
323190286Sobrien    default:
323290286Sobrien      return "movs{wl|x}\t{%1,%0|%0, %1}";
323390286Sobrien    }
323490286Sobrien}
323590286Sobrien  [(set_attr "type" "imovx")
323690286Sobrien   (set_attr "mode" "SI")
323790286Sobrien   (set (attr "prefix_0f")
323890286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
323990286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
324090286Sobrien			(eq_attr "alternative" "0"))
324190286Sobrien	(const_string "0")
324290286Sobrien	(const_string "1")))
324390286Sobrien   (set (attr "modrm")
324490286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
324590286Sobrien	(const_string "0")
324690286Sobrien	(const_string "1")))])
324718334Speter
324890286Sobrien(define_insn "*extendhisi2_zext"
324990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
325090286Sobrien	(zero_extend:DI
325190286Sobrien	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
325290286Sobrien  "TARGET_64BIT"
325390286Sobrien{
325490286Sobrien  switch (get_attr_prefix_0f (insn))
325590286Sobrien    {
325690286Sobrien    case 0:
325790286Sobrien      return "{cwtl|cwde}";
325890286Sobrien    default:
325990286Sobrien      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
326090286Sobrien    }
326190286Sobrien}
326290286Sobrien  [(set_attr "type" "imovx")
326390286Sobrien   (set_attr "mode" "SI")
326490286Sobrien   (set (attr "prefix_0f")
326590286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
326690286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
326790286Sobrien			(eq_attr "alternative" "0"))
326890286Sobrien	(const_string "0")
326990286Sobrien	(const_string "1")))
327090286Sobrien   (set (attr "modrm")
327190286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
327290286Sobrien	(const_string "0")
327390286Sobrien	(const_string "1")))])
327418334Speter
327518334Speter(define_insn "extendqihi2"
327690286Sobrien  [(set (match_operand:HI 0 "register_operand" "=*a,r")
327790286Sobrien	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
327818334Speter  ""
327918334Speter{
328090286Sobrien  switch (get_attr_prefix_0f (insn))
328190286Sobrien    {
328290286Sobrien    case 0:
328390286Sobrien      return "{cbtw|cbw}";
328490286Sobrien    default:
328590286Sobrien      return "movs{bw|x}\t{%1,%0|%0, %1}";
328690286Sobrien    }
328790286Sobrien}
328890286Sobrien  [(set_attr "type" "imovx")
328990286Sobrien   (set_attr "mode" "HI")
329090286Sobrien   (set (attr "prefix_0f")
329190286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
329290286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
329390286Sobrien			(eq_attr "alternative" "0"))
329490286Sobrien	(const_string "0")
329590286Sobrien	(const_string "1")))
329690286Sobrien   (set (attr "modrm")
329790286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
329890286Sobrien	(const_string "0")
329990286Sobrien	(const_string "1")))])
330018334Speter
330118334Speter(define_insn "extendqisi2"
330250650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
330350650Sobrien	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
330418334Speter  ""
330590286Sobrien  "movs{bl|x}\t{%1,%0|%0, %1}"
330690286Sobrien   [(set_attr "type" "imovx")
330790286Sobrien    (set_attr "mode" "SI")])
330850650Sobrien
330990286Sobrien(define_insn "*extendqisi2_zext"
331090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
331190286Sobrien	(zero_extend:DI
331290286Sobrien	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
331390286Sobrien  "TARGET_64BIT"
331490286Sobrien  "movs{bl|x}\t{%1,%k0|%k0, %1}"
331590286Sobrien   [(set_attr "type" "imovx")
331690286Sobrien    (set_attr "mode" "SI")])
331718334Speter
331890286Sobrien;; Conversions between float and double.
331950650Sobrien
332090286Sobrien;; These are all no-ops in the model used for the 80387.  So just
332190286Sobrien;; emit moves.
332250650Sobrien
332390286Sobrien;; %%% Kill these when call knows how to work out a DFmode push earlier. 
332490286Sobrien(define_insn "*dummy_extendsfdf2"
332590286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<")
332690286Sobrien	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
332790286Sobrien  "0"
332890286Sobrien  "#")
332950650Sobrien
333090286Sobrien(define_split
333190286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
3332117404Skan	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3333117404Skan  "!TARGET_64BIT"
333490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
333590286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
333650650Sobrien
333790286Sobrien(define_split
333890286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
3339117404Skan	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3340117404Skan  "TARGET_64BIT"
334190286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
334290286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
334350650Sobrien
334490286Sobrien(define_insn "*dummy_extendsfxf2"
334590286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
334690286Sobrien	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
334790286Sobrien  "0"
334890286Sobrien  "#")
334950650Sobrien
335090286Sobrien(define_split
335190286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
3352117404Skan	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3353117404Skan  "!TARGET_64BIT"
335490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
335590286Sobrien   (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
335650650Sobrien
335790286Sobrien(define_insn "*dummy_extendsftf2"
335890286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
335990286Sobrien	(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
336090286Sobrien  "0"
336190286Sobrien  "#")
336250650Sobrien
336390286Sobrien(define_split
336490286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
3365117404Skan	(float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3366117404Skan  "!TARGET_64BIT"
336790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
336890286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
336950650Sobrien
337090286Sobrien(define_split
337190286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
3372117404Skan	(float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3373117404Skan  "TARGET_64BIT"
337490286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
337590286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
337618334Speter
337790286Sobrien(define_insn "*dummy_extenddfxf2"
337890286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
337990286Sobrien	(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
338090286Sobrien  "0"
338190286Sobrien  "#")
338252296Sobrien
338390286Sobrien(define_split
338490286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
3385117404Skan	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3386117404Skan  "!TARGET_64BIT"
338790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
338890286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
338952296Sobrien
339090286Sobrien(define_insn "*dummy_extenddftf2"
339190286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
339290286Sobrien	(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
339390286Sobrien  "0"
339490286Sobrien  "#")
339518334Speter
339652296Sobrien(define_split
339790286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
3398117404Skan	(float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3399117404Skan  "!TARGET_64BIT"
340090286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
340190286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
340218334Speter
340352296Sobrien(define_split
340490286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
3405117404Skan	(float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3406117404Skan  "TARGET_64BIT"
340790286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
340890286Sobrien   (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
340918334Speter
341090286Sobrien(define_expand "extendsfdf2"
341152296Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3412117404Skan        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
341390286Sobrien  "TARGET_80387 || TARGET_SSE2"
341452296Sobrien{
3415117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3416117404Skan     are LEGITIMATE_CONSTANT_P.  */
3417117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3418117404Skan    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
341990286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
342090286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
342190286Sobrien})
342218334Speter
342390286Sobrien(define_insn "*extendsfdf2_1"
342490286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
342590286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
342690286Sobrien  "(TARGET_80387 || TARGET_SSE2)
342790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
342852296Sobrien{
342990286Sobrien  switch (which_alternative)
343090286Sobrien    {
343190286Sobrien    case 0:
343290286Sobrien      if (REG_P (operands[1])
343390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
343490286Sobrien        return "fstp\t%y0";
343590286Sobrien      else if (STACK_TOP_P (operands[0]))
343690286Sobrien        return "fld%z1\t%y1";
343790286Sobrien      else
343890286Sobrien        return "fst\t%y0";
343952296Sobrien
344090286Sobrien    case 1:
344190286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
344290286Sobrien        return "fstp%z0\t%y0";
344318334Speter
344490286Sobrien      else
344590286Sobrien        return "fst%z0\t%y0";
344690286Sobrien    case 2:
344790286Sobrien      return "cvtss2sd\t{%1, %0|%0, %1}";
344818334Speter
344990286Sobrien    default:
345090286Sobrien      abort ();
345190286Sobrien    }
345290286Sobrien}
3453117404Skan  [(set_attr "type" "fmov,fmov,ssecvt")
345490286Sobrien   (set_attr "mode" "SF,XF,DF")])
345518334Speter
345690286Sobrien(define_insn "*extendsfdf2_1_sse_only"
345790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
345890286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
345990286Sobrien  "!TARGET_80387 && TARGET_SSE2
346090286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
346190286Sobrien  "cvtss2sd\t{%1, %0|%0, %1}"
3462117404Skan  [(set_attr "type" "ssecvt")
346390286Sobrien   (set_attr "mode" "DF")])
346418334Speter
346590286Sobrien(define_expand "extendsfxf2"
346652296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3467117404Skan        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
346890286Sobrien  "!TARGET_64BIT && TARGET_80387"
346990286Sobrien{
3470117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3471117404Skan     are LEGITIMATE_CONSTANT_P.  */
3472117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3473117404Skan    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
347490286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
347590286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
347690286Sobrien})
347718334Speter
347890286Sobrien(define_insn "*extendsfxf2_1"
347952296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
348090286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
348190286Sobrien  "!TARGET_64BIT && TARGET_80387
348290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
348352296Sobrien{
348490286Sobrien  switch (which_alternative)
348590286Sobrien    {
348690286Sobrien    case 0:
348790286Sobrien      if (REG_P (operands[1])
348890286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
348990286Sobrien        return "fstp\t%y0";
349090286Sobrien      else if (STACK_TOP_P (operands[0]))
349190286Sobrien        return "fld%z1\t%y1";
349290286Sobrien      else
349390286Sobrien        return "fst\t%y0";
349418334Speter
349590286Sobrien    case 1:
349690286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
349790286Sobrien	 we need one, follow the store with a load.  */
349890286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
349990286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
350090286Sobrien      else
350190286Sobrien        return "fstp%z0\t%y0";
350290286Sobrien
350390286Sobrien    default:
350490286Sobrien      abort ();
350590286Sobrien    }
350690286Sobrien}
350790286Sobrien  [(set_attr "type" "fmov")
350890286Sobrien   (set_attr "mode" "SF,XF")])
350990286Sobrien
351090286Sobrien(define_expand "extendsftf2"
351190286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
3512117404Skan        (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
351352296Sobrien  "TARGET_80387"
351452296Sobrien{
3515117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3516117404Skan     are LEGITIMATE_CONSTANT_P.  */
3517117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3518117404Skan    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
351952296Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
352052296Sobrien    operands[1] = force_reg (SFmode, operands[1]);
352190286Sobrien})
352252296Sobrien
352390286Sobrien(define_insn "*extendsftf2_1"
352490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
352590286Sobrien        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
352690286Sobrien  "TARGET_80387
352790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
352818334Speter{
352990286Sobrien  switch (which_alternative)
353090286Sobrien    {
353190286Sobrien    case 0:
353290286Sobrien      if (REG_P (operands[1])
353390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
353490286Sobrien        return "fstp\t%y0";
353590286Sobrien      else if (STACK_TOP_P (operands[0]))
353690286Sobrien        return "fld%z1\t%y1";
353790286Sobrien      else
353890286Sobrien        return "fst\t%y0";
353918334Speter
354090286Sobrien    case 1:
354190286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
354290286Sobrien	 we need one, follow the store with a load.  */
354390286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
354490286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
354590286Sobrien      else
354690286Sobrien        return "fstp%z0\t%y0";
354718334Speter
354890286Sobrien    default:
354990286Sobrien      abort ();
355090286Sobrien    }
355190286Sobrien}
355290286Sobrien  [(set_attr "type" "fmov")
355390286Sobrien   (set_attr "mode" "SF,XF")])
355418334Speter
355590286Sobrien(define_expand "extenddfxf2"
355652296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557117404Skan        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
355890286Sobrien  "!TARGET_64BIT && TARGET_80387"
355990286Sobrien{
3560117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3561117404Skan     are LEGITIMATE_CONSTANT_P.  */
3562117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563117404Skan    operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
356490286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
356590286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
356690286Sobrien})
356718334Speter
356890286Sobrien(define_insn "*extenddfxf2_1"
356952296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
357090286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
357190286Sobrien  "!TARGET_64BIT && TARGET_80387
357290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
357352296Sobrien{
357490286Sobrien  switch (which_alternative)
357590286Sobrien    {
357690286Sobrien    case 0:
357790286Sobrien      if (REG_P (operands[1])
357890286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
357990286Sobrien        return "fstp\t%y0";
358090286Sobrien      else if (STACK_TOP_P (operands[0]))
358190286Sobrien        return "fld%z1\t%y1";
358290286Sobrien      else
358390286Sobrien        return "fst\t%y0";
358418334Speter
358590286Sobrien    case 1:
358690286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
358790286Sobrien	 we need one, follow the store with a load.  */
358890286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
358990286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
359090286Sobrien      else
359190286Sobrien        return "fstp%z0\t%y0";
359290286Sobrien
359390286Sobrien    default:
359490286Sobrien      abort ();
359590286Sobrien    }
359690286Sobrien}
359790286Sobrien  [(set_attr "type" "fmov")
359890286Sobrien   (set_attr "mode" "DF,XF")])
359990286Sobrien
360090286Sobrien(define_expand "extenddftf2"
360190286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
3602117404Skan        (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
360390286Sobrien  "TARGET_80387"
360490286Sobrien{
3605117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3606117404Skan     are LEGITIMATE_CONSTANT_P.  */
3607117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608117404Skan    operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
360990286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
361090286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
361190286Sobrien})
361290286Sobrien
361390286Sobrien(define_insn "*extenddftf2_1"
361490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
361590286Sobrien        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
361690286Sobrien  "TARGET_80387
361790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
361890286Sobrien{
361990286Sobrien  switch (which_alternative)
362090286Sobrien    {
362190286Sobrien    case 0:
362290286Sobrien      if (REG_P (operands[1])
362390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
362490286Sobrien        return "fstp\t%y0";
362590286Sobrien      else if (STACK_TOP_P (operands[0]))
362690286Sobrien        return "fld%z1\t%y1";
362790286Sobrien      else
362890286Sobrien        return "fst\t%y0";
362990286Sobrien
363090286Sobrien    case 1:
363190286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
363290286Sobrien	 we need one, follow the store with a load.  */
363390286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
363490286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
363590286Sobrien      else
363690286Sobrien        return "fstp%z0\t%y0";
363790286Sobrien
363890286Sobrien    default:
363990286Sobrien      abort ();
364090286Sobrien    }
364190286Sobrien}
364290286Sobrien  [(set_attr "type" "fmov")
364390286Sobrien   (set_attr "mode" "DF,XF")])
364490286Sobrien
364590286Sobrien;; %%% This seems bad bad news.
364690286Sobrien;; This cannot output into an f-reg because there is no way to be sure
364790286Sobrien;; of truncating in that case.  Otherwise this is just like a simple move
364890286Sobrien;; insn.  So we pretend we can output to a reg in order to get better
364990286Sobrien;; register preferencing, but we really use a stack slot.
365090286Sobrien
365118334Speter(define_expand "truncdfsf2"
365218334Speter  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
365318334Speter		   (float_truncate:SF
365418334Speter		    (match_operand:DF 1 "register_operand" "")))
365518334Speter	      (clobber (match_dup 2))])]
365690286Sobrien  "TARGET_80387 || TARGET_SSE2"
365718334Speter  "
365890286Sobrien   if (TARGET_80387)
365990286Sobrien     operands[2] = assign_386_stack_local (SFmode, 0);
366090286Sobrien   else
366190286Sobrien     {
366290286Sobrien	emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
366390286Sobrien	DONE;
366490286Sobrien     }
366590286Sobrien")
366690286Sobrien
366790286Sobrien(define_insn "*truncdfsf2_1"
366890286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
366990286Sobrien	(float_truncate:SF
367090286Sobrien	 (match_operand:DF 1 "register_operand" "f,f,f,f")))
367190286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
367290286Sobrien  "TARGET_80387 && !TARGET_SSE2"
367318334Speter{
367490286Sobrien  switch (which_alternative)
367590286Sobrien    {
367690286Sobrien    case 0:
367790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
367890286Sobrien	return "fstp%z0\t%y0";
367990286Sobrien      else
368090286Sobrien	return "fst%z0\t%y0";
368190286Sobrien    default:
368290286Sobrien      abort ();
368390286Sobrien    }
368490286Sobrien}
368590286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
368690286Sobrien   (set_attr "mode" "SF,SF,SF,SF")])
368718334Speter
368890286Sobrien(define_insn "*truncdfsf2_1_sse"
368990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
369018334Speter	(float_truncate:SF
369190286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
369290286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
369390286Sobrien  "TARGET_80387 && TARGET_SSE2"
369418334Speter{
369590286Sobrien  switch (which_alternative)
369690286Sobrien    {
369790286Sobrien    case 0:
369890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
369990286Sobrien	return "fstp%z0\t%y0";
370090286Sobrien      else
370190286Sobrien	return "fst%z0\t%y0";
370290286Sobrien    case 4:
370390286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
370490286Sobrien    default:
370590286Sobrien      abort ();
370690286Sobrien    }
370790286Sobrien}
3708117404Skan  [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
370990286Sobrien   (set_attr "mode" "SF,SF,SF,SF,DF")])
371018334Speter
371190286Sobrien(define_insn "*truncdfsf2_2"
371290286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
371390286Sobrien	(float_truncate:SF
371490286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
371590286Sobrien  "TARGET_80387 && TARGET_SSE2
371690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
371790286Sobrien{
371890286Sobrien  switch (which_alternative)
371990286Sobrien    {
372090286Sobrien    case 0:
372190286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
372290286Sobrien    case 1:
372390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
372490286Sobrien	return "fstp%z0\t%y0";
372590286Sobrien      else
372690286Sobrien	return "fst%z0\t%y0";
372790286Sobrien    default:
372890286Sobrien      abort ();
372990286Sobrien    }
373090286Sobrien}
3731117404Skan  [(set_attr "type" "ssecvt,fmov")
373290286Sobrien   (set_attr "mode" "DF,SF")])
373352296Sobrien
373490286Sobrien(define_insn "truncdfsf2_3"
373590286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
373690286Sobrien	(float_truncate:SF
373790286Sobrien	 (match_operand:DF 1 "register_operand" "f")))]
373890286Sobrien  "TARGET_80387"
373990286Sobrien{
374090286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
374190286Sobrien    return "fstp%z0\t%y0";
374218334Speter  else
374390286Sobrien    return "fst%z0\t%y0";
374490286Sobrien}
374590286Sobrien  [(set_attr "type" "fmov")
374690286Sobrien   (set_attr "mode" "SF")])
374718334Speter
374890286Sobrien(define_insn "truncdfsf2_sse_only"
374990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=Y")
375090286Sobrien	(float_truncate:SF
375190286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
375290286Sobrien  "!TARGET_80387 && TARGET_SSE2"
375390286Sobrien  "cvtsd2ss\t{%1, %0|%0, %1}"
3754117404Skan  [(set_attr "type" "ssecvt")
375590286Sobrien   (set_attr "mode" "DF")])
375652296Sobrien
375752296Sobrien(define_split
375890286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
375990286Sobrien	(float_truncate:SF
376090286Sobrien	 (match_operand:DF 1 "register_operand" "")))
376152296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
376290286Sobrien  "TARGET_80387"
376390286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
376452296Sobrien  "")
376552296Sobrien
376652296Sobrien(define_split
376790286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
376890286Sobrien	(float_truncate:SF
376990286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "")))
377090286Sobrien   (clobber (match_operand 2 "" ""))]
377190286Sobrien  "TARGET_80387 && reload_completed
377290286Sobrien   && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
377390286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
377490286Sobrien  "")
377590286Sobrien
377690286Sobrien(define_split
377790286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
377890286Sobrien	(float_truncate:SF
3779117404Skan	 (match_operand:DF 1 "fp_register_operand" "")))
378052296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
3781117404Skan  "TARGET_80387 && reload_completed"
378290286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
378390286Sobrien   (set (match_dup 0) (match_dup 2))]
378452296Sobrien  "")
378552296Sobrien
378690286Sobrien(define_expand "truncxfsf2"
378790286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
378890286Sobrien		   (float_truncate:SF
378990286Sobrien		    (match_operand:XF 1 "register_operand" "")))
379090286Sobrien	      (clobber (match_dup 2))])]
379190286Sobrien  "!TARGET_64BIT && TARGET_80387"
379290286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
379352296Sobrien
379490286Sobrien(define_insn "*truncxfsf2_1"
379590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
379690286Sobrien	(float_truncate:SF
379790286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
379890286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
379990286Sobrien  "!TARGET_64BIT && TARGET_80387"
380090286Sobrien{
380190286Sobrien  switch (which_alternative)
380290286Sobrien    {
380390286Sobrien    case 0:
380490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
380590286Sobrien	return "fstp%z0\t%y0";
380690286Sobrien      else
380790286Sobrien	return "fst%z0\t%y0";
380890286Sobrien    default:
380990286Sobrien      abort();
381090286Sobrien    }
381190286Sobrien}
381290286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
381390286Sobrien   (set_attr "mode" "SF")])
381490286Sobrien
381590286Sobrien(define_insn "*truncxfsf2_2"
381652296Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
381790286Sobrien	(float_truncate:SF
381890286Sobrien	 (match_operand:XF 1 "register_operand" "f")))]
381990286Sobrien  "!TARGET_64BIT && TARGET_80387"
382018334Speter{
382190286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
382290286Sobrien    return "fstp%z0\t%y0";
382318334Speter  else
382490286Sobrien    return "fst%z0\t%y0";
382590286Sobrien}
382690286Sobrien  [(set_attr "type" "fmov")
382790286Sobrien   (set_attr "mode" "SF")])
382852296Sobrien
382990286Sobrien(define_split
383090286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
383190286Sobrien	(float_truncate:SF
383290286Sobrien	 (match_operand:XF 1 "register_operand" "")))
383390286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
383490286Sobrien  "TARGET_80387"
383590286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
383690286Sobrien  "")
383790286Sobrien
383890286Sobrien(define_split
383990286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
384090286Sobrien	(float_truncate:SF
384190286Sobrien	 (match_operand:XF 1 "register_operand" "")))
384290286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
384390286Sobrien  "TARGET_80387 && reload_completed"
384490286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
384590286Sobrien   (set (match_dup 0) (match_dup 2))]
384690286Sobrien  "")
384790286Sobrien
384890286Sobrien(define_expand "trunctfsf2"
384952296Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
385052296Sobrien		   (float_truncate:SF
385190286Sobrien		    (match_operand:TF 1 "register_operand" "")))
385252296Sobrien	      (clobber (match_dup 2))])]
385352296Sobrien  "TARGET_80387"
385490286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
385590286Sobrien
385690286Sobrien(define_insn "*trunctfsf2_1"
385790286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
385890286Sobrien	(float_truncate:SF
385990286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
386090286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
386190286Sobrien  "TARGET_80387"
386252296Sobrien{
386390286Sobrien  switch (which_alternative)
386490286Sobrien    {
386590286Sobrien    case 0:
386690286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
386790286Sobrien	return "fstp%z0\t%y0";
386890286Sobrien      else
386990286Sobrien	return "fst%z0\t%y0";
387090286Sobrien    default:
387190286Sobrien      abort();
387290286Sobrien    }
387390286Sobrien}
387490286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
387590286Sobrien   (set_attr "mode" "SF")])
387618334Speter
387790286Sobrien(define_insn "*trunctfsf2_2"
387890286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
387952296Sobrien	(float_truncate:SF
388090286Sobrien	 (match_operand:TF 1 "register_operand" "f")))]
388118334Speter  "TARGET_80387"
388218334Speter{
388390286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
388490286Sobrien    return "fstp%z0\t%y0";
388518334Speter  else
388690286Sobrien    return "fst%z0\t%y0";
388790286Sobrien}
388890286Sobrien  [(set_attr "type" "fmov")
388990286Sobrien   (set_attr "mode" "SF")])
389018334Speter
389152296Sobrien(define_split
389290286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
389390286Sobrien	(float_truncate:SF
389490286Sobrien	 (match_operand:TF 1 "register_operand" "")))
389552296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
389690286Sobrien  "TARGET_80387"
389790286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
389852296Sobrien  "")
389952296Sobrien
390052296Sobrien(define_split
390190286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
390290286Sobrien	(float_truncate:SF
390390286Sobrien	 (match_operand:TF 1 "register_operand" "")))
390452296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
390552296Sobrien  "TARGET_80387 && reload_completed"
390690286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
390790286Sobrien   (set (match_dup 0) (match_dup 2))]
390852296Sobrien  "")
390952296Sobrien
391018334Speter
391152296Sobrien(define_expand "truncxfdf2"
391252296Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
391352296Sobrien		   (float_truncate:DF
391452296Sobrien		    (match_operand:XF 1 "register_operand" "")))
391552296Sobrien	      (clobber (match_dup 2))])]
391690286Sobrien  "!TARGET_64BIT && TARGET_80387"
391790286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
391818334Speter
391990286Sobrien(define_insn "*truncxfdf2_1"
392090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
392152296Sobrien	(float_truncate:DF
392290286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
392390286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
392490286Sobrien  "!TARGET_64BIT && TARGET_80387"
392518334Speter{
392690286Sobrien  switch (which_alternative)
392752296Sobrien    {
392890286Sobrien    case 0:
392990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
393090286Sobrien	return "fstp%z0\t%y0";
393190286Sobrien      else
393290286Sobrien	return "fst%z0\t%y0";
393390286Sobrien    default:
393490286Sobrien      abort();
393552296Sobrien    }
393690286Sobrien  abort ();
393790286Sobrien}
393890286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
393990286Sobrien   (set_attr "mode" "DF")])
394052296Sobrien
394190286Sobrien(define_insn "*truncxfdf2_2"
394290286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
394390286Sobrien	(float_truncate:DF
394490286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
394590286Sobrien  "!TARGET_64BIT && TARGET_80387"
394690286Sobrien{
394790286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
394890286Sobrien    return "fstp%z0\t%y0";
394990286Sobrien  else
395090286Sobrien    return "fst%z0\t%y0";
395190286Sobrien}
395290286Sobrien  [(set_attr "type" "fmov")
395390286Sobrien   (set_attr "mode" "DF")])
395452296Sobrien
395552296Sobrien(define_split
395690286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
395790286Sobrien	(float_truncate:DF
395890286Sobrien	 (match_operand:XF 1 "register_operand" "")))
395952296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
396090286Sobrien  "TARGET_80387"
396190286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
396252296Sobrien  "")
396352296Sobrien
396452296Sobrien(define_split
396590286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
396690286Sobrien	(float_truncate:DF
396790286Sobrien	 (match_operand:XF 1 "register_operand" "")))
396852296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
396952296Sobrien  "TARGET_80387 && reload_completed"
397090286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
397190286Sobrien   (set (match_dup 0) (match_dup 2))]
397252296Sobrien  "")
397352296Sobrien
397490286Sobrien(define_expand "trunctfdf2"
397590286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
397690286Sobrien		   (float_truncate:DF
397790286Sobrien		    (match_operand:TF 1 "register_operand" "")))
397890286Sobrien	      (clobber (match_dup 2))])]
397918334Speter  "TARGET_80387"
398090286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
398118334Speter
398290286Sobrien(define_insn "*trunctfdf2_1"
398390286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
398490286Sobrien	(float_truncate:DF
398590286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
398690286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
398718334Speter  "TARGET_80387"
398818334Speter{
398990286Sobrien  switch (which_alternative)
399090286Sobrien    {
399190286Sobrien    case 0:
399290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
399390286Sobrien	return "fstp%z0\t%y0";
399490286Sobrien      else
399590286Sobrien	return "fst%z0\t%y0";
399690286Sobrien    default:
399790286Sobrien      abort();
399890286Sobrien    }
399990286Sobrien  abort ();
400090286Sobrien}
400190286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
400290286Sobrien   (set_attr "mode" "DF")])
400318334Speter
400490286Sobrien	(define_insn "*trunctfdf2_2"
400590286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
400690286Sobrien	(float_truncate:DF
400790286Sobrien	  (match_operand:TF 1 "register_operand" "f")))]
400852296Sobrien  "TARGET_80387"
400918334Speter{
401090286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
401190286Sobrien    return "fstp%z0\t%y0";
401290286Sobrien  else
401390286Sobrien    return "fst%z0\t%y0";
401490286Sobrien}
401590286Sobrien  [(set_attr "type" "fmov")
401690286Sobrien   (set_attr "mode" "DF")])
401718334Speter
401890286Sobrien(define_split
401990286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
402090286Sobrien	(float_truncate:DF
402190286Sobrien	 (match_operand:TF 1 "register_operand" "")))
402290286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
402318334Speter  "TARGET_80387"
402490286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
402590286Sobrien  "")
402618334Speter
402790286Sobrien(define_split
402890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
402990286Sobrien	(float_truncate:DF
403090286Sobrien	 (match_operand:TF 1 "register_operand" "")))
403190286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
403290286Sobrien  "TARGET_80387 && reload_completed"
403390286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
403490286Sobrien   (set (match_dup 0) (match_dup 2))]
403590286Sobrien  "")
403618334Speter
403790286Sobrien
403890286Sobrien;; %%% Break up all these bad boys.
403990286Sobrien
404090286Sobrien;; Signed conversion to DImode.
404190286Sobrien
404290286Sobrien(define_expand "fix_truncxfdi2"
404390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
404490286Sobrien        (fix:DI (match_operand:XF 1 "register_operand" "")))]
404590286Sobrien  "!TARGET_64BIT && TARGET_80387"
404690286Sobrien  "")
404790286Sobrien
404890286Sobrien(define_expand "fix_trunctfdi2"
404990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
405090286Sobrien	(fix:DI (match_operand:TF 1 "register_operand" "")))]
405118334Speter  "TARGET_80387"
405290286Sobrien  "")
405318334Speter
405452296Sobrien(define_expand "fix_truncdfdi2"
405590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
405690286Sobrien        (fix:DI (match_operand:DF 1 "register_operand" "")))]
405790286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
405818334Speter{
405990286Sobrien  if (TARGET_64BIT && TARGET_SSE2)
406090286Sobrien   {
406190286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
406290286Sobrien     emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
406390286Sobrien     if (out != operands[0])
406490286Sobrien	emit_move_insn (operands[0], out);
406590286Sobrien     DONE;
406690286Sobrien   }
406790286Sobrien})
406818334Speter
406990286Sobrien(define_expand "fix_truncsfdi2"
407090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
407190286Sobrien	(fix:DI (match_operand:SF 1 "register_operand" "")))]
407290286Sobrien  "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
407390286Sobrien{
407490286Sobrien  if (TARGET_SSE && TARGET_64BIT)
407590286Sobrien   {
407690286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
407790286Sobrien     emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
407890286Sobrien     if (out != operands[0])
407990286Sobrien	emit_move_insn (operands[0], out);
408090286Sobrien     DONE;
408190286Sobrien   }
408290286Sobrien})
408352296Sobrien
408490286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
408590286Sobrien;; of the machinery.
408690286Sobrien(define_insn_and_split "*fix_truncdi_1"
408790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
408890286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))]
408990286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
409090286Sobrien   && !reload_completed && !reload_in_progress
409190286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
409290286Sobrien  "#"
409390286Sobrien  "&& 1"
409490286Sobrien  [(const_int 0)]
409590286Sobrien{
409690286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
409790286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
409890286Sobrien  if (memory_operand (operands[0], VOIDmode))
409990286Sobrien    emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
410090286Sobrien				       operands[2], operands[3]));
410190286Sobrien  else
410290286Sobrien    {
410390286Sobrien      operands[4] = assign_386_stack_local (DImode, 0);
410490286Sobrien      emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
410590286Sobrien					   operands[2], operands[3],
410690286Sobrien					   operands[4]));
410790286Sobrien    }
410890286Sobrien  DONE;
410990286Sobrien}
411090286Sobrien  [(set_attr "type" "fistp")])
411190286Sobrien
411290286Sobrien(define_insn "fix_truncdi_nomemory"
411390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
411490286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))
411590286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
411690286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
411790286Sobrien   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
411890286Sobrien   (clobber (match_scratch:DF 5 "=&1f,&1f"))]
411990286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
412090286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
412190286Sobrien  "#"
412290286Sobrien  [(set_attr "type" "fistp")])
412390286Sobrien
412490286Sobrien(define_insn "fix_truncdi_memory"
412590286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
412690286Sobrien	(fix:DI (match_operand 1 "register_operand" "f")))
412790286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
412890286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))
412990286Sobrien   (clobber (match_scratch:DF 4 "=&1f"))]
413090286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
413190286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
413290286Sobrien  "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
413390286Sobrien  [(set_attr "type" "fistp")])
413490286Sobrien
413590286Sobrien(define_split 
413690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
413790286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
413890286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
413990286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
414090286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
414190286Sobrien   (clobber (match_scratch 5 ""))]
414290286Sobrien  "reload_completed"
414390286Sobrien  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
414490286Sobrien	      (use (match_dup 2))
414590286Sobrien	      (use (match_dup 3))
414690286Sobrien	      (clobber (match_dup 5))])
414790286Sobrien   (set (match_dup 0) (match_dup 4))]
414890286Sobrien  "")
414990286Sobrien
415090286Sobrien(define_split 
415190286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
415290286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
415390286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
415490286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
415590286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
415690286Sobrien   (clobber (match_scratch 5 ""))]
415790286Sobrien  "reload_completed"
415890286Sobrien  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
415990286Sobrien	      (use (match_dup 2))
416090286Sobrien	      (use (match_dup 3))
416190286Sobrien	      (clobber (match_dup 5))])]
416290286Sobrien  "")
416390286Sobrien
416490286Sobrien;; When SSE available, it is always faster to use it!
416590286Sobrien(define_insn "fix_truncsfdi_sse"
416690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
416790286Sobrien	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
416890286Sobrien  "TARGET_64BIT && TARGET_SSE"
416990286Sobrien  "cvttss2si{q}\t{%1, %0|%0, %1}"
4170117404Skan  [(set_attr "type" "ssecvt")])
417190286Sobrien
417290286Sobrien(define_insn "fix_truncdfdi_sse"
417390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
417490286Sobrien	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
417590286Sobrien  "TARGET_64BIT && TARGET_SSE2"
417690286Sobrien  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4177117404Skan  [(set_attr "type" "ssecvt")])
417890286Sobrien
417990286Sobrien;; Signed conversion to SImode.
418090286Sobrien
418152296Sobrien(define_expand "fix_truncxfsi2"
418290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
418390286Sobrien	(fix:SI (match_operand:XF 1 "register_operand" "")))]
418490286Sobrien  "!TARGET_64BIT && TARGET_80387"
418590286Sobrien  "")
418690286Sobrien
418790286Sobrien(define_expand "fix_trunctfsi2"
418890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
418990286Sobrien	(fix:SI (match_operand:TF 1 "register_operand" "")))]
419018334Speter  "TARGET_80387"
419190286Sobrien  "")
419290286Sobrien
419390286Sobrien(define_expand "fix_truncdfsi2"
419490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
419590286Sobrien	(fix:SI (match_operand:DF 1 "register_operand" "")))]
419690286Sobrien  "TARGET_80387 || TARGET_SSE2"
419718334Speter{
419890286Sobrien  if (TARGET_SSE2)
419990286Sobrien   {
420090286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
420190286Sobrien     emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
420290286Sobrien     if (out != operands[0])
420390286Sobrien	emit_move_insn (operands[0], out);
420490286Sobrien     DONE;
420590286Sobrien   }
420690286Sobrien})
420718334Speter
420890286Sobrien(define_expand "fix_truncsfsi2"
420990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
421090286Sobrien	(fix:SI (match_operand:SF 1 "register_operand" "")))]
421190286Sobrien  "TARGET_80387 || TARGET_SSE"
421290286Sobrien{
421390286Sobrien  if (TARGET_SSE)
421490286Sobrien   {
421590286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
421690286Sobrien     emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
421790286Sobrien     if (out != operands[0])
421890286Sobrien	emit_move_insn (operands[0], out);
421990286Sobrien     DONE;
422090286Sobrien   }
422190286Sobrien})
422252296Sobrien
422390286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
422490286Sobrien;; of the machinery.
422590286Sobrien(define_insn_and_split "*fix_truncsi_1"
422690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
422790286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))]
422890286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
422990286Sobrien   && !reload_completed && !reload_in_progress
423090286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
423190286Sobrien  "#"
423290286Sobrien  "&& 1"
423390286Sobrien  [(const_int 0)]
423418334Speter{
423590286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
423690286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
423790286Sobrien  if (memory_operand (operands[0], VOIDmode))
423890286Sobrien    emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
423990286Sobrien				       operands[2], operands[3]));
424090286Sobrien  else
424190286Sobrien    {
424290286Sobrien      operands[4] = assign_386_stack_local (SImode, 0);
424390286Sobrien      emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
424490286Sobrien					   operands[2], operands[3],
424590286Sobrien					   operands[4]));
424690286Sobrien    }
424790286Sobrien  DONE;
424890286Sobrien}
424990286Sobrien  [(set_attr "type" "fistp")])
425018334Speter
425190286Sobrien(define_insn "fix_truncsi_nomemory"
425290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
425390286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))
425490286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
425590286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
425690286Sobrien   (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
425790286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
425890286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
425990286Sobrien  "#"
426090286Sobrien  [(set_attr "type" "fistp")])
426190286Sobrien
426290286Sobrien(define_insn "fix_truncsi_memory"
426390286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
426490286Sobrien	(fix:SI (match_operand 1 "register_operand" "f")))
426590286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
426690286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
426790286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
426890286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
426952296Sobrien  "* return output_fix_trunc (insn, operands);"
427090286Sobrien  [(set_attr "type" "fistp")])
427118334Speter
427290286Sobrien;; When SSE available, it is always faster to use it!
427390286Sobrien(define_insn "fix_truncsfsi_sse"
427490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
427590286Sobrien	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
427690286Sobrien  "TARGET_SSE"
427790286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
4278117404Skan  [(set_attr "type" "ssecvt")])
427952296Sobrien
428090286Sobrien(define_insn "fix_truncdfsi_sse"
428190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
428290286Sobrien	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
428390286Sobrien  "TARGET_SSE2"
428490286Sobrien  "cvttsd2si\t{%1, %0|%0, %1}"
4285117404Skan  [(set_attr "type" "ssecvt")])
428652296Sobrien
428790286Sobrien(define_split 
428890286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
428990286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
429090286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
429190286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
429290286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
429390286Sobrien  "reload_completed"
429490286Sobrien  [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
429590286Sobrien	      (use (match_dup 2))
429690286Sobrien	      (use (match_dup 3))])
429790286Sobrien   (set (match_dup 0) (match_dup 4))]
429890286Sobrien  "")
429918334Speter
430090286Sobrien(define_split 
430190286Sobrien  [(set (match_operand:SI 0 "memory_operand" "")
430290286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
430390286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
430490286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
430590286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
430690286Sobrien  "reload_completed"
430790286Sobrien  [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
430890286Sobrien	      (use (match_dup 2))
430990286Sobrien	      (use (match_dup 3))])]
431052296Sobrien  "")
431152296Sobrien
431290286Sobrien;; Signed conversion to HImode.
431390286Sobrien
431490286Sobrien(define_expand "fix_truncxfhi2"
431590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
431690286Sobrien        (fix:HI (match_operand:XF 1 "register_operand" "")))]
431790286Sobrien  "!TARGET_64BIT && TARGET_80387"
431852296Sobrien  "")
431952296Sobrien
432090286Sobrien(define_expand "fix_trunctfhi2"
432190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
432290286Sobrien	(fix:HI (match_operand:TF 1 "register_operand" "")))]
432318334Speter  "TARGET_80387"
432490286Sobrien  "")
432518334Speter
432690286Sobrien(define_expand "fix_truncdfhi2"
432790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
432890286Sobrien	(fix:HI (match_operand:DF 1 "register_operand" "")))]
432990286Sobrien  "TARGET_80387 && !TARGET_SSE2"
433090286Sobrien  "")
433118334Speter
433290286Sobrien(define_expand "fix_truncsfhi2"
433390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
433490286Sobrien	(fix:HI (match_operand:SF 1 "register_operand" "")))]
433590286Sobrien  "TARGET_80387 && !TARGET_SSE"
433690286Sobrien  "")
433752296Sobrien
433890286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
433990286Sobrien;; of the machinery.
434090286Sobrien(define_insn_and_split "*fix_trunchi_1"
434190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
434290286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))]
434390286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
434490286Sobrien   && !reload_completed && !reload_in_progress
434590286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
434690286Sobrien  "#"
434790286Sobrien  ""
434890286Sobrien  [(const_int 0)]
434990286Sobrien{
435090286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
435190286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
435290286Sobrien  if (memory_operand (operands[0], VOIDmode))
435390286Sobrien    emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
435490286Sobrien				       operands[2], operands[3]));
435590286Sobrien  else
435690286Sobrien    {
435790286Sobrien      operands[4] = assign_386_stack_local (HImode, 0);
435890286Sobrien      emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
435990286Sobrien					   operands[2], operands[3],
436090286Sobrien					   operands[4]));
436190286Sobrien    }
436290286Sobrien  DONE;
436390286Sobrien}
436490286Sobrien  [(set_attr "type" "fistp")])
436590286Sobrien
436690286Sobrien(define_insn "fix_trunchi_nomemory"
436790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
436890286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))
436990286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
437090286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
437190286Sobrien   (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
437290286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
437390286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
437490286Sobrien  "#"
437590286Sobrien  [(set_attr "type" "fistp")])
437690286Sobrien
437790286Sobrien(define_insn "fix_trunchi_memory"
437890286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
437990286Sobrien	(fix:HI (match_operand 1 "register_operand" "f")))
438090286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
438190286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
438290286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
438390286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
438490286Sobrien  "* return output_fix_trunc (insn, operands);"
438590286Sobrien  [(set_attr "type" "fistp")])
438690286Sobrien
438790286Sobrien(define_split 
438890286Sobrien  [(set (match_operand:HI 0 "memory_operand" "")
438990286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
439090286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
439190286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
439290286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
439390286Sobrien  "reload_completed"
439490286Sobrien  [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
439590286Sobrien	      (use (match_dup 2))
439690286Sobrien	      (use (match_dup 3))])]
439718334Speter  "")
439818334Speter
439990286Sobrien(define_split 
440090286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
440190286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
440290286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
440390286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
440490286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
440590286Sobrien  "reload_completed"
440690286Sobrien  [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
440790286Sobrien	      (use (match_dup 2))
440890286Sobrien	      (use (match_dup 3))
440990286Sobrien	      (clobber (match_dup 4))])
441090286Sobrien   (set (match_dup 0) (match_dup 4))]
441152296Sobrien  "")
441252296Sobrien
441390286Sobrien;; %% Not used yet.
441490286Sobrien(define_insn "x86_fnstcw_1"
441590286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
4416117404Skan	(unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
441752296Sobrien  "TARGET_80387"
441890286Sobrien  "fnstcw\t%0"
441990286Sobrien  [(set_attr "length" "2")
442090286Sobrien   (set_attr "mode" "HI")
4421117404Skan   (set_attr "unit" "i387")
442290286Sobrien   (set_attr "ppro_uops" "few")])
442352296Sobrien
442490286Sobrien(define_insn "x86_fldcw_1"
442590286Sobrien  [(set (reg:HI 18)
4426117404Skan	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
442752296Sobrien  "TARGET_80387"
442890286Sobrien  "fldcw\t%0"
442990286Sobrien  [(set_attr "length" "2")
443090286Sobrien   (set_attr "mode" "HI")
4431117404Skan   (set_attr "unit" "i387")
443290286Sobrien   (set_attr "athlon_decode" "vector")
443390286Sobrien   (set_attr "ppro_uops" "few")])
443490286Sobrien
443590286Sobrien;; Conversion between fixed point and floating point.
443652296Sobrien
443790286Sobrien;; Even though we only accept memory inputs, the backend _really_
443890286Sobrien;; wants to be able to do this between registers.
443990286Sobrien
444090286Sobrien(define_insn "floathisf2"
444152296Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
444290286Sobrien	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
444390286Sobrien  "TARGET_80387 && !TARGET_SSE"
444490286Sobrien  "@
444590286Sobrien   fild%z1\t%1
444690286Sobrien   #"
444790286Sobrien  [(set_attr "type" "fmov,multi")
444890286Sobrien   (set_attr "mode" "SF")
444990286Sobrien   (set_attr "fp_int_src" "true")])
445052296Sobrien
445190286Sobrien(define_expand "floatsisf2"
445218334Speter  [(set (match_operand:SF 0 "register_operand" "")
445390286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
445490286Sobrien  "TARGET_SSE || TARGET_80387"
445518334Speter  "")
445618334Speter
445790286Sobrien(define_insn "*floatsisf2_i387"
445890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
445990286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
446090286Sobrien  "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
446190286Sobrien  "@
446290286Sobrien   fild%z1\t%1
446390286Sobrien   #
446490286Sobrien   cvtsi2ss\t{%1, %0|%0, %1}"
4465117404Skan  [(set_attr "type" "fmov,multi,ssecvt")
446690286Sobrien   (set_attr "mode" "SF")
446790286Sobrien   (set_attr "fp_int_src" "true")])
446890286Sobrien
446990286Sobrien(define_insn "*floatsisf2_sse"
447090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
447190286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
447290286Sobrien  "TARGET_SSE"
447390286Sobrien  "cvtsi2ss\t{%1, %0|%0, %1}"
4474117404Skan  [(set_attr "type" "ssecvt")
447590286Sobrien   (set_attr "mode" "SF")
447690286Sobrien   (set_attr "fp_int_src" "true")])
447790286Sobrien
447890286Sobrien(define_expand "floatdisf2"
447952296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
448090286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
448190286Sobrien  "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
448252296Sobrien  "")
448352296Sobrien
448490286Sobrien(define_insn "*floatdisf2_i387_only"
448590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f")
448690286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
448790286Sobrien  "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
448890286Sobrien  "@
448990286Sobrien   fild%z1\t%1
449090286Sobrien   #"
449190286Sobrien  [(set_attr "type" "fmov,multi")
449290286Sobrien   (set_attr "mode" "SF")
449390286Sobrien   (set_attr "fp_int_src" "true")])
449452296Sobrien
449590286Sobrien(define_insn "*floatdisf2_i387"
449690286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
449790286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
449890286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
449990286Sobrien  "@
450090286Sobrien   fild%z1\t%1
450190286Sobrien   #
450290286Sobrien   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503117404Skan  [(set_attr "type" "fmov,multi,ssecvt")
450490286Sobrien   (set_attr "mode" "SF")
450590286Sobrien   (set_attr "fp_int_src" "true")])
450652296Sobrien
450790286Sobrien(define_insn "*floatdisf2_sse"
450890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
450990286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
451090286Sobrien  "TARGET_64BIT && TARGET_SSE"
451190286Sobrien  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4512117404Skan  [(set_attr "type" "ssecvt")
451390286Sobrien   (set_attr "mode" "SF")
451490286Sobrien   (set_attr "fp_int_src" "true")])
451590286Sobrien
451690286Sobrien(define_insn "floathidf2"
451752296Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
451890286Sobrien	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
451990286Sobrien  "TARGET_80387 && !TARGET_SSE2"
452090286Sobrien  "@
452190286Sobrien   fild%z1\t%1
452290286Sobrien   #"
452390286Sobrien  [(set_attr "type" "fmov,multi")
452490286Sobrien   (set_attr "mode" "DF")
452590286Sobrien   (set_attr "fp_int_src" "true")])
452652296Sobrien
452790286Sobrien(define_expand "floatsidf2"
452818334Speter  [(set (match_operand:DF 0 "register_operand" "")
452990286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
453096294Sobrien  "TARGET_80387 || TARGET_SSE2"
453152296Sobrien  "")
453252296Sobrien
453390286Sobrien(define_insn "*floatsidf2_i387"
453490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
453590286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
453690286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
453790286Sobrien  "@
453890286Sobrien   fild%z1\t%1
453990286Sobrien   #
454090286Sobrien   cvtsi2sd\t{%1, %0|%0, %1}"
4541117404Skan  [(set_attr "type" "fmov,multi,ssecvt")
454290286Sobrien   (set_attr "mode" "DF")
454390286Sobrien   (set_attr "fp_int_src" "true")])
454490286Sobrien
454590286Sobrien(define_insn "*floatsidf2_sse"
454690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
454790286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
454890286Sobrien  "TARGET_SSE2"
454990286Sobrien  "cvtsi2sd\t{%1, %0|%0, %1}"
4550117404Skan  [(set_attr "type" "ssecvt")
455190286Sobrien   (set_attr "mode" "DF")
455290286Sobrien   (set_attr "fp_int_src" "true")])
455390286Sobrien
455490286Sobrien(define_expand "floatdidf2"
455552296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
455690286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
455790286Sobrien  "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
455852296Sobrien  "")
455952296Sobrien
456090286Sobrien(define_insn "*floatdidf2_i387_only"
456190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f")
456290286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
456390286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
456490286Sobrien  "@
456590286Sobrien   fild%z1\t%1
456690286Sobrien   #"
456790286Sobrien  [(set_attr "type" "fmov,multi")
456890286Sobrien   (set_attr "mode" "DF")
456990286Sobrien   (set_attr "fp_int_src" "true")])
457090286Sobrien
457190286Sobrien(define_insn "*floatdidf2_i387"
457290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
457390286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
457490286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
457590286Sobrien  "@
457690286Sobrien   fild%z1\t%1
457790286Sobrien   #
457890286Sobrien   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4579117404Skan  [(set_attr "type" "fmov,multi,ssecvt")
458090286Sobrien   (set_attr "mode" "DF")
458190286Sobrien   (set_attr "fp_int_src" "true")])
458290286Sobrien
458390286Sobrien(define_insn "*floatdidf2_sse"
458490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
458590286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
458690286Sobrien  "TARGET_SSE2"
458790286Sobrien  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4588117404Skan  [(set_attr "type" "ssecvt")
458990286Sobrien   (set_attr "mode" "DF")
459090286Sobrien   (set_attr "fp_int_src" "true")])
459190286Sobrien
459290286Sobrien(define_insn "floathixf2"
459390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
459490286Sobrien	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
459590286Sobrien  "!TARGET_64BIT && TARGET_80387"
459690286Sobrien  "@
459790286Sobrien   fild%z1\t%1
459890286Sobrien   #"
459990286Sobrien  [(set_attr "type" "fmov,multi")
460090286Sobrien   (set_attr "mode" "XF")
460190286Sobrien   (set_attr "fp_int_src" "true")])
460290286Sobrien
460390286Sobrien(define_insn "floathitf2"
460490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
460590286Sobrien	(float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
460618334Speter  "TARGET_80387"
460790286Sobrien  "@
460890286Sobrien   fild%z1\t%1
460990286Sobrien   #"
461090286Sobrien  [(set_attr "type" "fmov,multi")
461190286Sobrien   (set_attr "mode" "XF")
461290286Sobrien   (set_attr "fp_int_src" "true")])
461352296Sobrien
461490286Sobrien(define_insn "floatsixf2"
461590286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
461690286Sobrien	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
461790286Sobrien  "!TARGET_64BIT && TARGET_80387"
461890286Sobrien  "@
461990286Sobrien   fild%z1\t%1
462090286Sobrien   #"
462190286Sobrien  [(set_attr "type" "fmov,multi")
462290286Sobrien   (set_attr "mode" "XF")
462390286Sobrien   (set_attr "fp_int_src" "true")])
462490286Sobrien
462590286Sobrien(define_insn "floatsitf2"
462690286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
462790286Sobrien	(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
462852296Sobrien  "TARGET_80387"
462990286Sobrien  "@
463090286Sobrien   fild%z1\t%1
463190286Sobrien   #"
463290286Sobrien  [(set_attr "type" "fmov,multi")
463390286Sobrien   (set_attr "mode" "XF")
463490286Sobrien   (set_attr "fp_int_src" "true")])
463552296Sobrien
463690286Sobrien(define_insn "floatdixf2"
463790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
463890286Sobrien	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
463990286Sobrien  "!TARGET_64BIT && TARGET_80387"
464090286Sobrien  "@
464190286Sobrien   fild%z1\t%1
464290286Sobrien   #"
464390286Sobrien  [(set_attr "type" "fmov,multi")
464490286Sobrien   (set_attr "mode" "XF")
464590286Sobrien   (set_attr "fp_int_src" "true")])
464690286Sobrien
464790286Sobrien(define_insn "floatditf2"
464890286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
464990286Sobrien	(float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
465052296Sobrien  "TARGET_80387"
465190286Sobrien  "@
465290286Sobrien   fild%z1\t%1
465390286Sobrien   #"
465490286Sobrien  [(set_attr "type" "fmov,multi")
465590286Sobrien   (set_attr "mode" "XF")
465690286Sobrien   (set_attr "fp_int_src" "true")])
465752296Sobrien
465890286Sobrien;; %%% Kill these when reload knows how to do it.
465952296Sobrien(define_split
4660117404Skan  [(set (match_operand 0 "fp_register_operand" "")
466190286Sobrien	(float (match_operand 1 "register_operand" "")))]
4662117404Skan  "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
466390286Sobrien  [(const_int 0)]
466490286Sobrien{
466590286Sobrien  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
466690286Sobrien  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
466790286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
466890286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
466990286Sobrien  DONE;
467090286Sobrien})
467190286Sobrien
467290286Sobrien;; Add instructions
467318334Speter
467490286Sobrien;; %%% splits for addsidi3
467590286Sobrien;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
467690286Sobrien;	(plus:DI (match_operand:DI 1 "general_operand" "")
467790286Sobrien;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
467852296Sobrien
467990286Sobrien(define_expand "adddi3"
468090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
468190286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
468290286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "")))
468390286Sobrien   (clobber (reg:CC 17))]
468490286Sobrien  ""
468590286Sobrien  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
468652296Sobrien
468790286Sobrien(define_insn "*adddi3_1"
468890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
468990286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
469090286Sobrien		 (match_operand:DI 2 "general_operand" "roiF,riF")))
469190286Sobrien   (clobber (reg:CC 17))]
4692107605Sobrien  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
469352296Sobrien  "#")
469452296Sobrien
469552296Sobrien(define_split
469690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
469790286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
469890286Sobrien		 (match_operand:DI 2 "general_operand" "")))
469990286Sobrien   (clobber (reg:CC 17))]
470090286Sobrien  "!TARGET_64BIT && reload_completed"
4701117404Skan  [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4702117404Skan					  UNSPEC_ADD_CARRY))
470390286Sobrien	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
470490286Sobrien   (parallel [(set (match_dup 3)
470590286Sobrien		   (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
470690286Sobrien				     (match_dup 4))
470790286Sobrien			    (match_dup 5)))
470890286Sobrien	      (clobber (reg:CC 17))])]
470990286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
471090286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
471190286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
471218334Speter
471390286Sobrien(define_insn "*adddi3_carry_rex64"
471490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
471590286Sobrien	  (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
471690286Sobrien			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
471790286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
471890286Sobrien   (clobber (reg:CC 17))]
471990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
472090286Sobrien  "adc{q}\t{%2, %0|%0, %2}"
472190286Sobrien  [(set_attr "type" "alu")
472290286Sobrien   (set_attr "pent_pair" "pu")
472390286Sobrien   (set_attr "mode" "DI")
472490286Sobrien   (set_attr "ppro_uops" "few")])
472552296Sobrien
472690286Sobrien(define_insn "*adddi3_cc_rex64"
4727117404Skan  [(set (reg:CC 17)
4728117404Skan	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4729117404Skan		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4730117404Skan		   UNSPEC_ADD_CARRY))
473190286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
473290286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
473390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
473490286Sobrien  "add{q}\t{%2, %0|%0, %2}"
473590286Sobrien  [(set_attr "type" "alu")
473690286Sobrien   (set_attr "mode" "DI")])
473752296Sobrien
473890286Sobrien(define_insn "*addsi3_carry"
473990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
474090286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
474190286Sobrien			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
474290286Sobrien		   (match_operand:SI 2 "general_operand" "ri,rm")))
474390286Sobrien   (clobber (reg:CC 17))]
474490286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
474590286Sobrien  "adc{l}\t{%2, %0|%0, %2}"
474690286Sobrien  [(set_attr "type" "alu")
474790286Sobrien   (set_attr "pent_pair" "pu")
474890286Sobrien   (set_attr "mode" "SI")
474990286Sobrien   (set_attr "ppro_uops" "few")])
475052296Sobrien
475190286Sobrien(define_insn "*addsi3_carry_zext"
475290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
475390286Sobrien	  (zero_extend:DI 
475490286Sobrien	    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
475590286Sobrien			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
475690286Sobrien		     (match_operand:SI 2 "general_operand" "rim"))))
475790286Sobrien   (clobber (reg:CC 17))]
475890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
475990286Sobrien  "adc{l}\t{%2, %k0|%k0, %2}"
476090286Sobrien  [(set_attr "type" "alu")
476190286Sobrien   (set_attr "pent_pair" "pu")
476290286Sobrien   (set_attr "mode" "SI")
476390286Sobrien   (set_attr "ppro_uops" "few")])
476452296Sobrien
476590286Sobrien(define_insn "*addsi3_cc"
4766117404Skan  [(set (reg:CC 17)
4767117404Skan	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4768117404Skan		    (match_operand:SI 2 "general_operand" "ri,rm")]
4769117404Skan		   UNSPEC_ADD_CARRY))
477090286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
477190286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
477290286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
477390286Sobrien  "add{l}\t{%2, %0|%0, %2}"
477490286Sobrien  [(set_attr "type" "alu")
477590286Sobrien   (set_attr "mode" "SI")])
477618334Speter
477790286Sobrien(define_insn "addqi3_cc"
4778117404Skan  [(set (reg:CC 17)
4779117404Skan	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4780117404Skan		    (match_operand:QI 2 "general_operand" "qi,qm")]
4781117404Skan		   UNSPEC_ADD_CARRY))
478290286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
478390286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
478490286Sobrien  "ix86_binary_operator_ok (PLUS, QImode, operands)"
478590286Sobrien  "add{b}\t{%2, %0|%0, %2}"
478690286Sobrien  [(set_attr "type" "alu")
478790286Sobrien   (set_attr "mode" "QI")])
478818334Speter
478990286Sobrien(define_expand "addsi3"
479090286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
479190286Sobrien		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
479290286Sobrien			    (match_operand:SI 2 "general_operand" "")))
479390286Sobrien	      (clobber (reg:CC 17))])]
479490286Sobrien  ""
479590286Sobrien  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
479618334Speter
479790286Sobrien(define_insn "*lea_1"
479890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
479990286Sobrien	(match_operand:SI 1 "address_operand" "p"))]
480090286Sobrien  "!TARGET_64BIT"
480190286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
480290286Sobrien  [(set_attr "type" "lea")
480390286Sobrien   (set_attr "mode" "SI")])
480418334Speter
480590286Sobrien(define_insn "*lea_1_rex64"
480690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
480790286Sobrien	(subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
480890286Sobrien  "TARGET_64BIT"
480990286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
481090286Sobrien  [(set_attr "type" "lea")
481190286Sobrien   (set_attr "mode" "SI")])
481218334Speter
481390286Sobrien(define_insn "*lea_1_zext"
481490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
481590286Sobrien	(zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
481690286Sobrien  "TARGET_64BIT"
481790286Sobrien  "lea{l}\t{%a1, %k0|%k0, %a1}"
481890286Sobrien  [(set_attr "type" "lea")
481990286Sobrien   (set_attr "mode" "SI")])
482090286Sobrien
482190286Sobrien(define_insn "*lea_2_rex64"
482290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
482390286Sobrien	(match_operand:DI 1 "address_operand" "p"))]
482490286Sobrien  "TARGET_64BIT"
482590286Sobrien  "lea{q}\t{%a1, %0|%0, %a1}"
482690286Sobrien  [(set_attr "type" "lea")
482790286Sobrien   (set_attr "mode" "DI")])
482890286Sobrien
482990286Sobrien;; The lea patterns for non-Pmodes needs to be matched by several
483090286Sobrien;; insns converted to real lea by splitters.
483190286Sobrien
483290286Sobrien(define_insn_and_split "*lea_general_1"
483390286Sobrien  [(set (match_operand 0 "register_operand" "=r")
4834117404Skan	(plus (plus (match_operand 1 "index_register_operand" "r")
483590286Sobrien		    (match_operand 2 "register_operand" "r"))
483690286Sobrien	      (match_operand 3 "immediate_operand" "i")))]
483790286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
483890286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
483990286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
484090286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
484190286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[2])
484290286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
484390286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
484490286Sobrien  "#"
484590286Sobrien  "&& reload_completed"
484690286Sobrien  [(const_int 0)]
484790286Sobrien{
484890286Sobrien  rtx pat;
484990286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
485090286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
485190286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
485290286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
485390286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
485490286Sobrien  		      operands[3]);
485590286Sobrien  if (Pmode != SImode)
485690286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
485790286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
485890286Sobrien  DONE;
485990286Sobrien}
486090286Sobrien  [(set_attr "type" "lea")
486190286Sobrien   (set_attr "mode" "SI")])
486290286Sobrien
486390286Sobrien(define_insn_and_split "*lea_general_1_zext"
486490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
486590286Sobrien	(zero_extend:DI
4866117404Skan	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
486790286Sobrien			    (match_operand:SI 2 "register_operand" "r"))
486890286Sobrien		   (match_operand:SI 3 "immediate_operand" "i"))))]
486990286Sobrien  "TARGET_64BIT"
487090286Sobrien  "#"
487190286Sobrien  "&& reload_completed"
487252296Sobrien  [(set (match_dup 0)
487390286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
487490286Sobrien						     (match_dup 2))
487590286Sobrien					    (match_dup 3)) 0)))]
487690286Sobrien{
487790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
487890286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
487990286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
488090286Sobrien}
488190286Sobrien  [(set_attr "type" "lea")
488290286Sobrien   (set_attr "mode" "SI")])
488352296Sobrien
488490286Sobrien(define_insn_and_split "*lea_general_2"
488590286Sobrien  [(set (match_operand 0 "register_operand" "=r")
4886117404Skan	(plus (mult (match_operand 1 "index_register_operand" "r")
488790286Sobrien		    (match_operand 2 "const248_operand" "i"))
488890286Sobrien	      (match_operand 3 "nonmemory_operand" "ri")))]
488990286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
489090286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
489190286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
489290286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
489390286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
489490286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
489590286Sobrien  "#"
489690286Sobrien  "&& reload_completed"
489790286Sobrien  [(const_int 0)]
489890286Sobrien{
489990286Sobrien  rtx pat;
490090286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
490190286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
490290286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
490390286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
490490286Sobrien  		      operands[3]);
490590286Sobrien  if (Pmode != SImode)
490690286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
490790286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
490890286Sobrien  DONE;
490990286Sobrien}
491090286Sobrien  [(set_attr "type" "lea")
491190286Sobrien   (set_attr "mode" "SI")])
491252296Sobrien
491390286Sobrien(define_insn_and_split "*lea_general_2_zext"
491490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
491590286Sobrien	(zero_extend:DI
4916117404Skan	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
491790286Sobrien			    (match_operand:SI 2 "const248_operand" "n"))
491890286Sobrien		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
491990286Sobrien  "TARGET_64BIT"
492090286Sobrien  "#"
492190286Sobrien  "&& reload_completed"
492290286Sobrien  [(set (match_dup 0)
492390286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
492490286Sobrien						     (match_dup 2))
492590286Sobrien					    (match_dup 3)) 0)))]
492690286Sobrien{
492790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
492890286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
492990286Sobrien}
493090286Sobrien  [(set_attr "type" "lea")
493190286Sobrien   (set_attr "mode" "SI")])
493218334Speter
493390286Sobrien(define_insn_and_split "*lea_general_3"
493490286Sobrien  [(set (match_operand 0 "register_operand" "=r")
4935117404Skan	(plus (plus (mult (match_operand 1 "index_register_operand" "r")
493690286Sobrien			  (match_operand 2 "const248_operand" "i"))
493790286Sobrien		    (match_operand 3 "register_operand" "r"))
493890286Sobrien	      (match_operand 4 "immediate_operand" "i")))]
493990286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
494090286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
494190286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
494290286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
494390286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
494490286Sobrien  "#"
494590286Sobrien  "&& reload_completed"
494690286Sobrien  [(const_int 0)]
494790286Sobrien{
494890286Sobrien  rtx pat;
494990286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
495090286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
495190286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
495290286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
495390286Sobrien  pat = gen_rtx_PLUS (Pmode,
495490286Sobrien  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
495590286Sobrien		      					 operands[2]),
495690286Sobrien				    operands[3]),
495790286Sobrien  		      operands[4]);
495890286Sobrien  if (Pmode != SImode)
495990286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
496090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
496190286Sobrien  DONE;
496290286Sobrien}
496390286Sobrien  [(set_attr "type" "lea")
496490286Sobrien   (set_attr "mode" "SI")])
496552296Sobrien
496690286Sobrien(define_insn_and_split "*lea_general_3_zext"
496790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
496890286Sobrien	(zero_extend:DI
4969117404Skan	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
497090286Sobrien				     (match_operand:SI 2 "const248_operand" "n"))
497190286Sobrien			    (match_operand:SI 3 "register_operand" "r"))
497290286Sobrien		   (match_operand:SI 4 "immediate_operand" "i"))))]
497390286Sobrien  "TARGET_64BIT"
497490286Sobrien  "#"
497590286Sobrien  "&& reload_completed"
497690286Sobrien  [(set (match_dup 0)
497790286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
497890286Sobrien							      (match_dup 2))
497990286Sobrien						     (match_dup 3))
498090286Sobrien					    (match_dup 4)) 0)))]
498190286Sobrien{
498290286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
498390286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
498490286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
498590286Sobrien}
498690286Sobrien  [(set_attr "type" "lea")
498790286Sobrien   (set_attr "mode" "SI")])
498818334Speter
498990286Sobrien(define_insn "*adddi_1_rex64"
499090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
499190286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
499290286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
499390286Sobrien   (clobber (reg:CC 17))]
499490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
499590286Sobrien{
499690286Sobrien  switch (get_attr_type (insn))
499790286Sobrien    {
499890286Sobrien    case TYPE_LEA:
499990286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
500090286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
500190286Sobrien
500290286Sobrien    case TYPE_INCDEC:
500390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
500490286Sobrien	abort ();
500590286Sobrien      if (operands[2] == const1_rtx)
500690286Sobrien        return "inc{q}\t%0";
500790286Sobrien      else if (operands[2] == constm1_rtx)
500890286Sobrien        return "dec{q}\t%0";
500990286Sobrien      else
501090286Sobrien	abort ();
501190286Sobrien
501290286Sobrien    default:
501390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
501490286Sobrien	abort ();
501590286Sobrien
501690286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
501790286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
501890286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
501990286Sobrien	  /* Avoid overflows.  */
502090286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
502190286Sobrien          && (INTVAL (operands[2]) == 128
502290286Sobrien	      || (INTVAL (operands[2]) < 0
502390286Sobrien		  && INTVAL (operands[2]) != -128)))
502490286Sobrien        {
502590286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
502690286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
502790286Sobrien        }
502890286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
502990286Sobrien    }
503090286Sobrien}
503190286Sobrien  [(set (attr "type")
503290286Sobrien     (cond [(eq_attr "alternative" "2")
503390286Sobrien	      (const_string "lea")
503490286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
503590286Sobrien	    ; ought but a memory context.
503690286Sobrien	    (match_operand:DI 2 "pic_symbolic_operand" "")
503790286Sobrien	      (const_string "lea")
503890286Sobrien	    (match_operand:DI 2 "incdec_operand" "")
503990286Sobrien	      (const_string "incdec")
504090286Sobrien	   ]
504190286Sobrien	   (const_string "alu")))
504290286Sobrien   (set_attr "mode" "DI")])
504390286Sobrien
504490286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
504552296Sobrien(define_split
504690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
504790286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "")
504890286Sobrien		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
504990286Sobrien   (clobber (reg:CC 17))]
505090286Sobrien  "TARGET_64BIT && reload_completed
505190286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
505252296Sobrien  [(set (match_dup 0)
505390286Sobrien	(plus:DI (match_dup 1)
505490286Sobrien		 (match_dup 2)))]
505552296Sobrien  "")
505652296Sobrien
505790286Sobrien(define_insn "*adddi_2_rex64"
505890286Sobrien  [(set (reg 17)
505990286Sobrien	(compare
506090286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
506190286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
506290286Sobrien	  (const_int 0)))			
506390286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
506490286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
506590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
506690286Sobrien   && ix86_binary_operator_ok (PLUS, DImode, operands)
506790286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
506890286Sobrien      ought but a memory context.  */
506990286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
507090286Sobrien{
507190286Sobrien  switch (get_attr_type (insn))
507290286Sobrien    {
507390286Sobrien    case TYPE_INCDEC:
507490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
507590286Sobrien	abort ();
507690286Sobrien      if (operands[2] == const1_rtx)
507790286Sobrien        return "inc{q}\t%0";
507890286Sobrien      else if (operands[2] == constm1_rtx)
507990286Sobrien        return "dec{q}\t%0";
508090286Sobrien      else
508190286Sobrien	abort ();
508252296Sobrien
508390286Sobrien    default:
508490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
508590286Sobrien	abort ();
508690286Sobrien      /* ???? We ought to handle there the 32bit case too
508790286Sobrien	 - do we need new constrant?  */
508890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
508990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
509090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
509190286Sobrien	  /* Avoid overflows.  */
509290286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
509390286Sobrien          && (INTVAL (operands[2]) == 128
509490286Sobrien	      || (INTVAL (operands[2]) < 0
509590286Sobrien		  && INTVAL (operands[2]) != -128)))
509690286Sobrien        {
509790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
509890286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
509990286Sobrien        }
510090286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
510190286Sobrien    }
510290286Sobrien}
510390286Sobrien  [(set (attr "type")
510490286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
510590286Sobrien	(const_string "incdec")
510690286Sobrien	(const_string "alu")))
510790286Sobrien   (set_attr "mode" "DI")])
510818334Speter
510990286Sobrien(define_insn "*adddi_3_rex64"
511090286Sobrien  [(set (reg 17)
511190286Sobrien	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
511290286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
511390286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
511490286Sobrien  "TARGET_64BIT
511590286Sobrien   && ix86_match_ccmode (insn, CCZmode)
511690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
511790286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
511890286Sobrien      ought but a memory context.  */
511990286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
512050650Sobrien{
512190286Sobrien  switch (get_attr_type (insn))
512290286Sobrien    {
512390286Sobrien    case TYPE_INCDEC:
512490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
512590286Sobrien	abort ();
512690286Sobrien      if (operands[2] == const1_rtx)
512790286Sobrien        return "inc{q}\t%0";
512890286Sobrien      else if (operands[2] == constm1_rtx)
512990286Sobrien        return "dec{q}\t%0";
513090286Sobrien      else
513190286Sobrien	abort ();
513250650Sobrien
513390286Sobrien    default:
513490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
513590286Sobrien	abort ();
513690286Sobrien      /* ???? We ought to handle there the 32bit case too
513790286Sobrien	 - do we need new constrant?  */
513890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
513990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
514090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
514190286Sobrien	  /* Avoid overflows.  */
514290286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
514390286Sobrien          && (INTVAL (operands[2]) == 128
514490286Sobrien	      || (INTVAL (operands[2]) < 0
514590286Sobrien		  && INTVAL (operands[2]) != -128)))
514690286Sobrien        {
514790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
514890286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
514990286Sobrien        }
515090286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
515190286Sobrien    }
515290286Sobrien}
515390286Sobrien  [(set (attr "type")
515490286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
515590286Sobrien	(const_string "incdec")
515690286Sobrien	(const_string "alu")))
515790286Sobrien   (set_attr "mode" "DI")])
515850650Sobrien
515990286Sobrien; For comparisons against 1, -1 and 128, we may generate better code
516090286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
516190286Sobrien; is matched then.  We can't accept general immediate, because for
516290286Sobrien; case of overflows,  the result is messed up.
516390286Sobrien; This pattern also don't hold of 0x8000000000000000, since the value overflows
516490286Sobrien; when negated.
516590286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
516690286Sobrien; only for comparisons not depending on it.
516790286Sobrien(define_insn "*adddi_4_rex64"
516890286Sobrien  [(set (reg 17)
516990286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
517090286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
517190286Sobrien   (clobber (match_scratch:DI 0 "=rm"))]
517290286Sobrien  "TARGET_64BIT
517390286Sobrien   &&  ix86_match_ccmode (insn, CCGCmode)"
517490286Sobrien{
517590286Sobrien  switch (get_attr_type (insn))
517690286Sobrien    {
517790286Sobrien    case TYPE_INCDEC:
517890286Sobrien      if (operands[2] == constm1_rtx)
517990286Sobrien        return "inc{q}\t%0";
518090286Sobrien      else if (operands[2] == const1_rtx)
518190286Sobrien        return "dec{q}\t%0";
518290286Sobrien      else
518390286Sobrien	abort();
518450650Sobrien
518590286Sobrien    default:
518690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
518790286Sobrien	abort ();
518890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
518990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
519090286Sobrien      if ((INTVAL (operands[2]) == -128
519190286Sobrien	   || (INTVAL (operands[2]) > 0
519290286Sobrien	       && INTVAL (operands[2]) != 128))
519390286Sobrien	  /* Avoid overflows.  */
519490286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
519590286Sobrien	return "sub{q}\t{%2, %0|%0, %2}";
519690286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
519790286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
519890286Sobrien    }
519990286Sobrien}
520090286Sobrien  [(set (attr "type")
520190286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
520290286Sobrien	(const_string "incdec")
520390286Sobrien	(const_string "alu")))
520490286Sobrien   (set_attr "mode" "DI")])
520590286Sobrien
520690286Sobrien(define_insn "*adddi_5_rex64"
520790286Sobrien  [(set (reg 17)
520890286Sobrien	(compare
520990286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
521090286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
521190286Sobrien	  (const_int 0)))			
521290286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
521390286Sobrien  "TARGET_64BIT
521490286Sobrien   && ix86_match_ccmode (insn, CCGOCmode)
521590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
521690286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
521790286Sobrien      ought but a memory context.  */
521890286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
521990286Sobrien{
522090286Sobrien  switch (get_attr_type (insn))
522150650Sobrien    {
522290286Sobrien    case TYPE_INCDEC:
522390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
522490286Sobrien	abort ();
522590286Sobrien      if (operands[2] == const1_rtx)
522690286Sobrien        return "inc{q}\t%0";
522790286Sobrien      else if (operands[2] == constm1_rtx)
522890286Sobrien        return "dec{q}\t%0";
522990286Sobrien      else
523090286Sobrien	abort();
523150650Sobrien
523290286Sobrien    default:
523390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
523490286Sobrien	abort ();
523590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
523690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
523790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
523890286Sobrien	  /* Avoid overflows.  */
523990286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
524090286Sobrien          && (INTVAL (operands[2]) == 128
524190286Sobrien	      || (INTVAL (operands[2]) < 0
524290286Sobrien		  && INTVAL (operands[2]) != -128)))
524390286Sobrien        {
524490286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
524590286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
524690286Sobrien        }
524790286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
524850650Sobrien    }
524990286Sobrien}
525090286Sobrien  [(set (attr "type")
525190286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
525290286Sobrien	(const_string "incdec")
525390286Sobrien	(const_string "alu")))
525490286Sobrien   (set_attr "mode" "DI")])
525550650Sobrien
525650650Sobrien
525790286Sobrien(define_insn "*addsi_1"
525890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
525990286Sobrien	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
526090286Sobrien		 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
526190286Sobrien   (clobber (reg:CC 17))]
526290286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
526350650Sobrien{
526490286Sobrien  switch (get_attr_type (insn))
526590286Sobrien    {
526690286Sobrien    case TYPE_LEA:
526790286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
526890286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
526950650Sobrien
527090286Sobrien    case TYPE_INCDEC:
527190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
527290286Sobrien	abort ();
527390286Sobrien      if (operands[2] == const1_rtx)
527490286Sobrien        return "inc{l}\t%0";
527590286Sobrien      else if (operands[2] == constm1_rtx)
527690286Sobrien        return "dec{l}\t%0";
527790286Sobrien      else
527890286Sobrien	abort();
527950650Sobrien
528090286Sobrien    default:
528190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
528290286Sobrien	abort ();
528350650Sobrien
528490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
528590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
528690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
528790286Sobrien          && (INTVAL (operands[2]) == 128
528890286Sobrien	      || (INTVAL (operands[2]) < 0
528990286Sobrien		  && INTVAL (operands[2]) != -128)))
529090286Sobrien        {
529190286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
529290286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
529390286Sobrien        }
529490286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
529590286Sobrien    }
529690286Sobrien}
529790286Sobrien  [(set (attr "type")
529890286Sobrien     (cond [(eq_attr "alternative" "2")
529990286Sobrien	      (const_string "lea")
530090286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
530190286Sobrien	    ; ought but a memory context.
530290286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
530390286Sobrien	      (const_string "lea")
530490286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
530590286Sobrien	      (const_string "incdec")
530690286Sobrien	   ]
530790286Sobrien	   (const_string "alu")))
530890286Sobrien   (set_attr "mode" "SI")])
530990286Sobrien
531090286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
531190286Sobrien(define_split
531290286Sobrien  [(set (match_operand 0 "register_operand" "")
531390286Sobrien	(plus (match_operand 1 "register_operand" "")
531490286Sobrien              (match_operand 2 "nonmemory_operand" "")))
531590286Sobrien   (clobber (reg:CC 17))]
531690286Sobrien  "reload_completed
531790286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
531890286Sobrien  [(const_int 0)]
531990286Sobrien{
532090286Sobrien  rtx pat;
532190286Sobrien  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
532290286Sobrien     may confuse gen_lowpart.  */
532390286Sobrien  if (GET_MODE (operands[0]) != Pmode)
532450650Sobrien    {
532590286Sobrien      operands[1] = gen_lowpart (Pmode, operands[1]);
532690286Sobrien      operands[2] = gen_lowpart (Pmode, operands[2]);
532790286Sobrien    }
532890286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
532990286Sobrien  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
533090286Sobrien  if (Pmode != SImode)
533190286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
533290286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
533390286Sobrien  DONE;
533490286Sobrien})
533550650Sobrien
533690286Sobrien;; It may seem that nonimmediate operand is proper one for operand 1.
533790286Sobrien;; The addsi_1 pattern allows nonimmediate operand at that place and
533890286Sobrien;; we take care in ix86_binary_operator_ok to not allow two memory
533990286Sobrien;; operands so proper swapping will be done in reload.  This allow
534090286Sobrien;; patterns constructed from addsi_1 to match.
534190286Sobrien(define_insn "addsi_1_zext"
534290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
534390286Sobrien	(zero_extend:DI
534490286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
534590286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))))
534690286Sobrien   (clobber (reg:CC 17))]
534790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
534890286Sobrien{
534990286Sobrien  switch (get_attr_type (insn))
535090286Sobrien    {
535190286Sobrien    case TYPE_LEA:
535290286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
535390286Sobrien      return "lea{l}\t{%a2, %k0|%k0, %a2}";
535490286Sobrien
535590286Sobrien    case TYPE_INCDEC:
535690286Sobrien      if (operands[2] == const1_rtx)
535790286Sobrien        return "inc{l}\t%k0";
535890286Sobrien      else if (operands[2] == constm1_rtx)
535990286Sobrien        return "dec{l}\t%k0";
536050650Sobrien      else
536190286Sobrien	abort();
536290286Sobrien
536390286Sobrien    default:
536490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
536590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
536690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
536790286Sobrien          && (INTVAL (operands[2]) == 128
536890286Sobrien	      || (INTVAL (operands[2]) < 0
536990286Sobrien		  && INTVAL (operands[2]) != -128)))
537090286Sobrien        {
537190286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
537290286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
537390286Sobrien        }
537490286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
537550650Sobrien    }
537690286Sobrien}
537790286Sobrien  [(set (attr "type")
537890286Sobrien     (cond [(eq_attr "alternative" "1")
537990286Sobrien	      (const_string "lea")
538090286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
538190286Sobrien	    ; ought but a memory context.
538290286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
538390286Sobrien	      (const_string "lea")
538490286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
538590286Sobrien	      (const_string "incdec")
538690286Sobrien	   ]
538790286Sobrien	   (const_string "alu")))
538890286Sobrien   (set_attr "mode" "SI")])
538950650Sobrien
539090286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
539190286Sobrien(define_split
539290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
539390286Sobrien	(zero_extend:DI
539490286Sobrien	  (plus:SI (match_operand:SI 1 "register_operand" "")
539590286Sobrien		   (match_operand:SI 2 "nonmemory_operand" ""))))
539690286Sobrien   (clobber (reg:CC 17))]
539790286Sobrien  "reload_completed
539890286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
539990286Sobrien  [(set (match_dup 0)
540090286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
540190286Sobrien{
540290286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
540390286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
540490286Sobrien})
540550650Sobrien
540690286Sobrien(define_insn "*addsi_2"
540790286Sobrien  [(set (reg 17)
540890286Sobrien	(compare
540990286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
541090286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))
541190286Sobrien	  (const_int 0)))			
541290286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
541390286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
541490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
541590286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
541690286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
541790286Sobrien      ought but a memory context.  */
541890286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
541918334Speter{
542090286Sobrien  switch (get_attr_type (insn))
542190286Sobrien    {
542290286Sobrien    case TYPE_INCDEC:
542390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
542490286Sobrien	abort ();
542590286Sobrien      if (operands[2] == const1_rtx)
542690286Sobrien        return "inc{l}\t%0";
542790286Sobrien      else if (operands[2] == constm1_rtx)
542890286Sobrien        return "dec{l}\t%0";
542990286Sobrien      else
543090286Sobrien	abort();
543118334Speter
543290286Sobrien    default:
543390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
543490286Sobrien	abort ();
543590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
543690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
543790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
543890286Sobrien          && (INTVAL (operands[2]) == 128
543990286Sobrien	      || (INTVAL (operands[2]) < 0
544090286Sobrien		  && INTVAL (operands[2]) != -128)))
544190286Sobrien        {
544290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
544390286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
544490286Sobrien        }
544590286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
544690286Sobrien    }
544790286Sobrien}
544890286Sobrien  [(set (attr "type")
544990286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
545090286Sobrien	(const_string "incdec")
545190286Sobrien	(const_string "alu")))
545290286Sobrien   (set_attr "mode" "SI")])
545318334Speter
545490286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
545590286Sobrien(define_insn "*addsi_2_zext"
545690286Sobrien  [(set (reg 17)
545790286Sobrien	(compare
545890286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
545990286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
546090286Sobrien	  (const_int 0)))			
546190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
546290286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
546390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
546490286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
546590286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
546690286Sobrien      ought but a memory context.  */
546790286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
546890286Sobrien{
546990286Sobrien  switch (get_attr_type (insn))
547018334Speter    {
547190286Sobrien    case TYPE_INCDEC:
547290286Sobrien      if (operands[2] == const1_rtx)
547390286Sobrien        return "inc{l}\t%k0";
547490286Sobrien      else if (operands[2] == constm1_rtx)
547590286Sobrien        return "dec{l}\t%k0";
547690286Sobrien      else
547790286Sobrien	abort();
547890286Sobrien
547990286Sobrien    default:
548090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
548190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
548290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
548390286Sobrien          && (INTVAL (operands[2]) == 128
548490286Sobrien	      || (INTVAL (operands[2]) < 0
548590286Sobrien		  && INTVAL (operands[2]) != -128)))
548690286Sobrien        {
548790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
548890286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
548990286Sobrien        }
549090286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
549118334Speter    }
549290286Sobrien}
549390286Sobrien  [(set (attr "type")
549490286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
549590286Sobrien	(const_string "incdec")
549690286Sobrien	(const_string "alu")))
549790286Sobrien   (set_attr "mode" "SI")])
549818334Speter
549990286Sobrien(define_insn "*addsi_3"
550090286Sobrien  [(set (reg 17)
550190286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
550290286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
550390286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
550490286Sobrien  "ix86_match_ccmode (insn, CCZmode)
550590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
550690286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
550790286Sobrien      ought but a memory context.  */
550890286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
550990286Sobrien{
551090286Sobrien  switch (get_attr_type (insn))
551118334Speter    {
551290286Sobrien    case TYPE_INCDEC:
551390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
551490286Sobrien	abort ();
551590286Sobrien      if (operands[2] == const1_rtx)
551690286Sobrien        return "inc{l}\t%0";
551790286Sobrien      else if (operands[2] == constm1_rtx)
551890286Sobrien        return "dec{l}\t%0";
551990286Sobrien      else
552090286Sobrien	abort();
552118334Speter
552290286Sobrien    default:
552390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
552490286Sobrien	abort ();
552590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
552690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
552790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
552890286Sobrien          && (INTVAL (operands[2]) == 128
552990286Sobrien	      || (INTVAL (operands[2]) < 0
553090286Sobrien		  && INTVAL (operands[2]) != -128)))
553190286Sobrien        {
553290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
553390286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
553490286Sobrien        }
553590286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
553690286Sobrien    }
553790286Sobrien}
553890286Sobrien  [(set (attr "type")
553990286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
554090286Sobrien	(const_string "incdec")
554190286Sobrien	(const_string "alu")))
554290286Sobrien   (set_attr "mode" "SI")])
554390286Sobrien
554490286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
554590286Sobrien(define_insn "*addsi_3_zext"
554690286Sobrien  [(set (reg 17)
554790286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
554890286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
554990286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
555090286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
555190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
555290286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
555390286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
555490286Sobrien      ought but a memory context.  */
555590286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
555690286Sobrien{
555790286Sobrien  switch (get_attr_type (insn))
555890286Sobrien    {
555990286Sobrien    case TYPE_INCDEC:
556090286Sobrien      if (operands[2] == const1_rtx)
556190286Sobrien        return "inc{l}\t%k0";
556290286Sobrien      else if (operands[2] == constm1_rtx)
556390286Sobrien        return "dec{l}\t%k0";
556418334Speter      else
556590286Sobrien	abort();
556690286Sobrien
556790286Sobrien    default:
556890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
556990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
557090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
557190286Sobrien          && (INTVAL (operands[2]) == 128
557290286Sobrien	      || (INTVAL (operands[2]) < 0
557390286Sobrien		  && INTVAL (operands[2]) != -128)))
557490286Sobrien        {
557590286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
557690286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
557790286Sobrien        }
557890286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
557918334Speter    }
558090286Sobrien}
558190286Sobrien  [(set (attr "type")
558290286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
558390286Sobrien	(const_string "incdec")
558490286Sobrien	(const_string "alu")))
558590286Sobrien   (set_attr "mode" "SI")])
558618334Speter
558790286Sobrien; For comparisons agains 1, -1 and 128, we may generate better code
558890286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
558990286Sobrien; is matched then.  We can't accept general immediate, because for
559090286Sobrien; case of overflows,  the result is messed up.
559190286Sobrien; This pattern also don't hold of 0x80000000, since the value overflows
559290286Sobrien; when negated.
559390286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
559490286Sobrien; only for comparisons not depending on it.
559590286Sobrien(define_insn "*addsi_4"
559690286Sobrien  [(set (reg 17)
559790286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
559890286Sobrien		 (match_operand:SI 2 "const_int_operand" "n")))
559990286Sobrien   (clobber (match_scratch:SI 0 "=rm"))]
560090286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
560190286Sobrien   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
560290286Sobrien{
560390286Sobrien  switch (get_attr_type (insn))
560418334Speter    {
560590286Sobrien    case TYPE_INCDEC:
560690286Sobrien      if (operands[2] == constm1_rtx)
560790286Sobrien        return "inc{l}\t%0";
560890286Sobrien      else if (operands[2] == const1_rtx)
560990286Sobrien        return "dec{l}\t%0";
561090286Sobrien      else
561190286Sobrien	abort();
561218334Speter
561390286Sobrien    default:
561490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
561590286Sobrien	abort ();
561690286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
561790286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
561890286Sobrien      if ((INTVAL (operands[2]) == -128
561990286Sobrien	   || (INTVAL (operands[2]) > 0
562090286Sobrien	       && INTVAL (operands[2]) != 128)))
562190286Sobrien	return "sub{l}\t{%2, %0|%0, %2}";
562290286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
562390286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
562418334Speter    }
562590286Sobrien}
562690286Sobrien  [(set (attr "type")
562790286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
562890286Sobrien	(const_string "incdec")
562990286Sobrien	(const_string "alu")))
563090286Sobrien   (set_attr "mode" "SI")])
563118334Speter
563290286Sobrien(define_insn "*addsi_5"
563390286Sobrien  [(set (reg 17)
563490286Sobrien	(compare
563590286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
563690286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
563790286Sobrien	  (const_int 0)))			
563890286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
563990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
564090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
564190286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
564290286Sobrien      ought but a memory context.  */
564390286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
564490286Sobrien{
564590286Sobrien  switch (get_attr_type (insn))
564618334Speter    {
564790286Sobrien    case TYPE_INCDEC:
564890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
564990286Sobrien	abort ();
565090286Sobrien      if (operands[2] == const1_rtx)
565190286Sobrien        return "inc{l}\t%0";
565290286Sobrien      else if (operands[2] == constm1_rtx)
565390286Sobrien        return "dec{l}\t%0";
565490286Sobrien      else
565590286Sobrien	abort();
565690286Sobrien
565790286Sobrien    default:
565890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
565990286Sobrien	abort ();
566090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
566190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
566290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
566390286Sobrien          && (INTVAL (operands[2]) == 128
566490286Sobrien	      || (INTVAL (operands[2]) < 0
566590286Sobrien		  && INTVAL (operands[2]) != -128)))
566690286Sobrien        {
566790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
566890286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
566990286Sobrien        }
567090286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
567118334Speter    }
567290286Sobrien}
567390286Sobrien  [(set (attr "type")
567490286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
567590286Sobrien	(const_string "incdec")
567690286Sobrien	(const_string "alu")))
567790286Sobrien   (set_attr "mode" "SI")])
567818334Speter
567990286Sobrien(define_expand "addhi3"
568090286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
568190286Sobrien		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
568290286Sobrien			    (match_operand:HI 2 "general_operand" "")))
568390286Sobrien	      (clobber (reg:CC 17))])]
568490286Sobrien  "TARGET_HIMODE_MATH"
568590286Sobrien  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
568618334Speter
568790286Sobrien;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
568890286Sobrien;; type optimizations enabled by define-splits.  This is not important
568990286Sobrien;; for PII, and in fact harmful because of partial register stalls.
569018334Speter
569190286Sobrien(define_insn "*addhi_1_lea"
569290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
569390286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
569490286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
569590286Sobrien   (clobber (reg:CC 17))]
569690286Sobrien  "!TARGET_PARTIAL_REG_STALL
569790286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
569890286Sobrien{
569990286Sobrien  switch (get_attr_type (insn))
570090286Sobrien    {
570190286Sobrien    case TYPE_LEA:
570290286Sobrien      return "#";
570390286Sobrien    case TYPE_INCDEC:
570490286Sobrien      if (operands[2] == const1_rtx)
570590286Sobrien	return "inc{w}\t%0";
5706117404Skan      else if (operands[2] == constm1_rtx)
570790286Sobrien	return "dec{w}\t%0";
570890286Sobrien      abort();
570918334Speter
571090286Sobrien    default:
571190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
571290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
571390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
571490286Sobrien          && (INTVAL (operands[2]) == 128
571590286Sobrien	      || (INTVAL (operands[2]) < 0
571690286Sobrien		  && INTVAL (operands[2]) != -128)))
571790286Sobrien	{
571890286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
571990286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
572090286Sobrien	}
572190286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
572290286Sobrien    }
572390286Sobrien}
572490286Sobrien  [(set (attr "type")
572590286Sobrien     (if_then_else (eq_attr "alternative" "2")
572690286Sobrien	(const_string "lea")
572790286Sobrien	(if_then_else (match_operand:HI 2 "incdec_operand" "")
572890286Sobrien	   (const_string "incdec")
572990286Sobrien	   (const_string "alu"))))
573090286Sobrien   (set_attr "mode" "HI,HI,SI")])
573150650Sobrien
573290286Sobrien(define_insn "*addhi_1"
573390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
573490286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
573590286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
573690286Sobrien   (clobber (reg:CC 17))]
573790286Sobrien  "TARGET_PARTIAL_REG_STALL
573890286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
573918334Speter{
574090286Sobrien  switch (get_attr_type (insn))
574118334Speter    {
574290286Sobrien    case TYPE_INCDEC:
574390286Sobrien      if (operands[2] == const1_rtx)
574490286Sobrien	return "inc{w}\t%0";
5745117404Skan      else if (operands[2] == constm1_rtx)
574690286Sobrien	return "dec{w}\t%0";
574790286Sobrien      abort();
574818334Speter
574990286Sobrien    default:
575090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
575190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
575290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
575390286Sobrien          && (INTVAL (operands[2]) == 128
575490286Sobrien	      || (INTVAL (operands[2]) < 0
575590286Sobrien		  && INTVAL (operands[2]) != -128)))
575618334Speter	{
575790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
575890286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
575918334Speter	}
576090286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
576190286Sobrien    }
576290286Sobrien}
576390286Sobrien  [(set (attr "type")
576490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
576590286Sobrien	(const_string "incdec")
576690286Sobrien	(const_string "alu")))
576790286Sobrien   (set_attr "mode" "HI")])
576818334Speter
576990286Sobrien(define_insn "*addhi_2"
577090286Sobrien  [(set (reg 17)
577190286Sobrien	(compare
577290286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
577390286Sobrien		   (match_operand:HI 2 "general_operand" "rmni,rni"))
577490286Sobrien	  (const_int 0)))			
577590286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
577690286Sobrien	(plus:HI (match_dup 1) (match_dup 2)))]
577790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
577890286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
577990286Sobrien{
578090286Sobrien  switch (get_attr_type (insn))
578190286Sobrien    {
578290286Sobrien    case TYPE_INCDEC:
578390286Sobrien      if (operands[2] == const1_rtx)
578490286Sobrien	return "inc{w}\t%0";
5785117404Skan      else if (operands[2] == constm1_rtx)
578690286Sobrien	return "dec{w}\t%0";
578790286Sobrien      abort();
578890286Sobrien
578990286Sobrien    default:
579090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
579190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
579290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
579390286Sobrien          && (INTVAL (operands[2]) == 128
579490286Sobrien	      || (INTVAL (operands[2]) < 0
579590286Sobrien		  && INTVAL (operands[2]) != -128)))
579618334Speter	{
579790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
579890286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
579918334Speter	}
580090286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
580118334Speter    }
580290286Sobrien}
580390286Sobrien  [(set (attr "type")
580490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
580590286Sobrien	(const_string "incdec")
580690286Sobrien	(const_string "alu")))
580790286Sobrien   (set_attr "mode" "HI")])
580818334Speter
580990286Sobrien(define_insn "*addhi_3"
581090286Sobrien  [(set (reg 17)
581190286Sobrien	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
581290286Sobrien		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
581390286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
581490286Sobrien  "ix86_match_ccmode (insn, CCZmode)
581590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
581690286Sobrien{
581790286Sobrien  switch (get_attr_type (insn))
581890286Sobrien    {
581990286Sobrien    case TYPE_INCDEC:
582090286Sobrien      if (operands[2] == const1_rtx)
582190286Sobrien	return "inc{w}\t%0";
5822117404Skan      else if (operands[2] == constm1_rtx)
582390286Sobrien	return "dec{w}\t%0";
582490286Sobrien      abort();
582550650Sobrien
582690286Sobrien    default:
582790286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
582890286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
582990286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
583090286Sobrien          && (INTVAL (operands[2]) == 128
583190286Sobrien	      || (INTVAL (operands[2]) < 0
583290286Sobrien		  && INTVAL (operands[2]) != -128)))
583390286Sobrien	{
583490286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
583590286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
583690286Sobrien	}
583790286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
583890286Sobrien    }
583990286Sobrien}
584090286Sobrien  [(set (attr "type")
584190286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
584290286Sobrien	(const_string "incdec")
584390286Sobrien	(const_string "alu")))
584490286Sobrien   (set_attr "mode" "HI")])
584518334Speter
584690286Sobrien; See comments above addsi_3_imm for details.
584790286Sobrien(define_insn "*addhi_4"
584890286Sobrien  [(set (reg 17)
584990286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
585090286Sobrien		 (match_operand:HI 2 "const_int_operand" "n")))
585190286Sobrien   (clobber (match_scratch:HI 0 "=rm"))]
585290286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
585390286Sobrien   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
585490286Sobrien{
585590286Sobrien  switch (get_attr_type (insn))
585690286Sobrien    {
585790286Sobrien    case TYPE_INCDEC:
5858117404Skan      if (operands[2] == constm1_rtx)
585990286Sobrien        return "inc{w}\t%0";
586090286Sobrien      else if (operands[2] == const1_rtx)
586190286Sobrien        return "dec{w}\t%0";
586290286Sobrien      else
586390286Sobrien	abort();
586418334Speter
586590286Sobrien    default:
586690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
586790286Sobrien	abort ();
586890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
586990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
587090286Sobrien      if ((INTVAL (operands[2]) == -128
587190286Sobrien	   || (INTVAL (operands[2]) > 0
587290286Sobrien	       && INTVAL (operands[2]) != 128)))
587390286Sobrien	return "sub{w}\t{%2, %0|%0, %2}";
587490286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
587590286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
587650650Sobrien    }
587790286Sobrien}
587890286Sobrien  [(set (attr "type")
587990286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
588090286Sobrien	(const_string "incdec")
588190286Sobrien	(const_string "alu")))
588290286Sobrien   (set_attr "mode" "SI")])
588350650Sobrien
588418334Speter
588590286Sobrien(define_insn "*addhi_5"
588690286Sobrien  [(set (reg 17)
588790286Sobrien	(compare
588890286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
588990286Sobrien		   (match_operand:HI 2 "general_operand" "rmni"))
589090286Sobrien	  (const_int 0)))			
589190286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
589290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
589390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
589450650Sobrien{
589590286Sobrien  switch (get_attr_type (insn))
589650650Sobrien    {
589790286Sobrien    case TYPE_INCDEC:
589890286Sobrien      if (operands[2] == const1_rtx)
589990286Sobrien	return "inc{w}\t%0";
5900117404Skan      else if (operands[2] == constm1_rtx)
590190286Sobrien	return "dec{w}\t%0";
590290286Sobrien      abort();
590350650Sobrien
590490286Sobrien    default:
590590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
590690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
590790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
590890286Sobrien          && (INTVAL (operands[2]) == 128
590990286Sobrien	      || (INTVAL (operands[2]) < 0
591090286Sobrien		  && INTVAL (operands[2]) != -128)))
591190286Sobrien	{
591290286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
591390286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
591490286Sobrien	}
591590286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
591650650Sobrien    }
591790286Sobrien}
591890286Sobrien  [(set (attr "type")
591990286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
592090286Sobrien	(const_string "incdec")
592190286Sobrien	(const_string "alu")))
592290286Sobrien   (set_attr "mode" "HI")])
592350650Sobrien
592490286Sobrien(define_expand "addqi3"
592590286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
592690286Sobrien		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
592790286Sobrien			    (match_operand:QI 2 "general_operand" "")))
592890286Sobrien	      (clobber (reg:CC 17))])]
592990286Sobrien  "TARGET_QIMODE_MATH"
593090286Sobrien  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
593150650Sobrien
593290286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
593390286Sobrien(define_insn "*addqi_1_lea"
593490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
593590286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
593690286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
593790286Sobrien   (clobber (reg:CC 17))]
593890286Sobrien  "!TARGET_PARTIAL_REG_STALL
593990286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
594090286Sobrien{
594190286Sobrien  int widen = (which_alternative == 2);
594290286Sobrien  switch (get_attr_type (insn))
594390286Sobrien    {
594490286Sobrien    case TYPE_LEA:
594590286Sobrien      return "#";
594690286Sobrien    case TYPE_INCDEC:
594790286Sobrien      if (operands[2] == const1_rtx)
594890286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5949117404Skan      else if (operands[2] == constm1_rtx)
595090286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
595190286Sobrien      abort();
595218334Speter
595390286Sobrien    default:
595490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
595590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
595690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
595790286Sobrien          && (INTVAL (operands[2]) == 128
595890286Sobrien	      || (INTVAL (operands[2]) < 0
595990286Sobrien		  && INTVAL (operands[2]) != -128)))
596090286Sobrien	{
596190286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
596290286Sobrien	  if (widen)
596390286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
596490286Sobrien	  else
596590286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
596690286Sobrien	}
596790286Sobrien      if (widen)
596890286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
596990286Sobrien      else
597090286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
597190286Sobrien    }
597290286Sobrien}
597390286Sobrien  [(set (attr "type")
597490286Sobrien     (if_then_else (eq_attr "alternative" "3")
597590286Sobrien	(const_string "lea")
597690286Sobrien	(if_then_else (match_operand:QI 2 "incdec_operand" "")
597790286Sobrien	   (const_string "incdec")
597890286Sobrien	   (const_string "alu"))))
597990286Sobrien   (set_attr "mode" "QI,QI,SI,SI")])
598050650Sobrien
598190286Sobrien(define_insn "*addqi_1"
598290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
598390286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
598490286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
598590286Sobrien   (clobber (reg:CC 17))]
598690286Sobrien  "TARGET_PARTIAL_REG_STALL
598790286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
598818334Speter{
598990286Sobrien  int widen = (which_alternative == 2);
599090286Sobrien  switch (get_attr_type (insn))
599152296Sobrien    {
599290286Sobrien    case TYPE_INCDEC:
599390286Sobrien      if (operands[2] == const1_rtx)
599490286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5995117404Skan      else if (operands[2] == constm1_rtx)
599690286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
599790286Sobrien      abort();
599852296Sobrien
599990286Sobrien    default:
600090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
600190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
600290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
600390286Sobrien          && (INTVAL (operands[2]) == 128
600490286Sobrien	      || (INTVAL (operands[2]) < 0
600590286Sobrien		  && INTVAL (operands[2]) != -128)))
600690286Sobrien	{
600790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
600890286Sobrien	  if (widen)
600990286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
601090286Sobrien	  else
601190286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
601290286Sobrien	}
601390286Sobrien      if (widen)
601490286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
601590286Sobrien      else
601690286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
601752296Sobrien    }
601890286Sobrien}
601990286Sobrien  [(set (attr "type")
602090286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
602190286Sobrien	(const_string "incdec")
602290286Sobrien	(const_string "alu")))
602390286Sobrien   (set_attr "mode" "QI,QI,SI")])
602452296Sobrien
6025117404Skan(define_insn "*addqi_1_slp"
6026117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6027117404Skan	(plus:QI (match_dup 0)
6028117404Skan		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6029117404Skan   (clobber (reg:CC 17))]
6030117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6031117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6032117404Skan{
6033117404Skan  switch (get_attr_type (insn))
6034117404Skan    {
6035117404Skan    case TYPE_INCDEC:
6036117404Skan      if (operands[1] == const1_rtx)
6037117404Skan	return "inc{b}\t%0";
6038117404Skan      else if (operands[1] == constm1_rtx)
6039117404Skan	return "dec{b}\t%0";
6040117404Skan      abort();
6041117404Skan
6042117404Skan    default:
6043117404Skan      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6044117404Skan      if (GET_CODE (operands[1]) == CONST_INT
6045117404Skan	  && INTVAL (operands[1]) < 0)
6046117404Skan	{
6047117404Skan	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6048117404Skan	  return "sub{b}\t{%1, %0|%0, %1}";
6049117404Skan	}
6050117404Skan      return "add{b}\t{%1, %0|%0, %1}";
6051117404Skan    }
6052117404Skan}
6053117404Skan  [(set (attr "type")
6054117404Skan     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6055117404Skan	(const_string "incdec")
6056117404Skan	(const_string "alu1")))
6057117404Skan   (set_attr "mode" "QI")])
6058117404Skan
605990286Sobrien(define_insn "*addqi_2"
606090286Sobrien  [(set (reg 17)
606190286Sobrien	(compare
606290286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
606390286Sobrien		   (match_operand:QI 2 "general_operand" "qmni,qni"))
606490286Sobrien	  (const_int 0)))
606590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
606690286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
606790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
606890286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
606990286Sobrien{
607090286Sobrien  switch (get_attr_type (insn))
607118334Speter    {
607290286Sobrien    case TYPE_INCDEC:
607390286Sobrien      if (operands[2] == const1_rtx)
607490286Sobrien	return "inc{b}\t%0";
607590286Sobrien      else if (operands[2] == constm1_rtx
607690286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
607790286Sobrien		   && INTVAL (operands[2]) == 255))
607890286Sobrien	return "dec{b}\t%0";
607990286Sobrien      abort();
608018334Speter
608190286Sobrien    default:
608290286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
608390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
608490286Sobrien          && INTVAL (operands[2]) < 0)
608590286Sobrien	{
608690286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
608790286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
608890286Sobrien	}
608990286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
609018334Speter    }
609190286Sobrien}
609290286Sobrien  [(set (attr "type")
609390286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
609490286Sobrien	(const_string "incdec")
609590286Sobrien	(const_string "alu")))
609690286Sobrien   (set_attr "mode" "QI")])
609718334Speter
609890286Sobrien(define_insn "*addqi_3"
609990286Sobrien  [(set (reg 17)
610090286Sobrien	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
610190286Sobrien		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
610290286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
610390286Sobrien  "ix86_match_ccmode (insn, CCZmode)
610490286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
610590286Sobrien{
610690286Sobrien  switch (get_attr_type (insn))
610750650Sobrien    {
610890286Sobrien    case TYPE_INCDEC:
610990286Sobrien      if (operands[2] == const1_rtx)
611090286Sobrien	return "inc{b}\t%0";
611190286Sobrien      else if (operands[2] == constm1_rtx
611290286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
611390286Sobrien		   && INTVAL (operands[2]) == 255))
611490286Sobrien	return "dec{b}\t%0";
611590286Sobrien      abort();
611650650Sobrien
611790286Sobrien    default:
611890286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
611990286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
612090286Sobrien          && INTVAL (operands[2]) < 0)
612150650Sobrien	{
612290286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
612390286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
612490286Sobrien	}
612590286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
612690286Sobrien    }
612790286Sobrien}
612890286Sobrien  [(set (attr "type")
612990286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
613090286Sobrien	(const_string "incdec")
613190286Sobrien	(const_string "alu")))
613290286Sobrien   (set_attr "mode" "QI")])
613350650Sobrien
613490286Sobrien; See comments above addsi_3_imm for details.
613590286Sobrien(define_insn "*addqi_4"
613690286Sobrien  [(set (reg 17)
613790286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
613890286Sobrien		 (match_operand:QI 2 "const_int_operand" "n")))
613990286Sobrien   (clobber (match_scratch:QI 0 "=qm"))]
614090286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
614190286Sobrien   && (INTVAL (operands[2]) & 0xff) != 0x80"
614290286Sobrien{
614390286Sobrien  switch (get_attr_type (insn))
614490286Sobrien    {
614590286Sobrien    case TYPE_INCDEC:
614690286Sobrien      if (operands[2] == constm1_rtx
614790286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
614890286Sobrien	      && INTVAL (operands[2]) == 255))
614990286Sobrien        return "inc{b}\t%0";
615090286Sobrien      else if (operands[2] == const1_rtx)
615190286Sobrien        return "dec{b}\t%0";
615290286Sobrien      else
615390286Sobrien	abort();
615450650Sobrien
615590286Sobrien    default:
615690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
615790286Sobrien	abort ();
615890286Sobrien      if (INTVAL (operands[2]) < 0)
615990286Sobrien        {
616090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
616190286Sobrien          return "add{b}\t{%2, %0|%0, %2}";
616290286Sobrien        }
616390286Sobrien      return "sub{b}\t{%2, %0|%0, %2}";
616450650Sobrien    }
616590286Sobrien}
616690286Sobrien  [(set (attr "type")
616790286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
616890286Sobrien	(const_string "incdec")
616990286Sobrien	(const_string "alu")))
617090286Sobrien   (set_attr "mode" "QI")])
617150650Sobrien
617218334Speter
617390286Sobrien(define_insn "*addqi_5"
617490286Sobrien  [(set (reg 17)
617590286Sobrien	(compare
617690286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
617790286Sobrien		   (match_operand:QI 2 "general_operand" "qmni"))
617890286Sobrien	  (const_int 0)))
617990286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
618090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
618190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
618290286Sobrien{
618390286Sobrien  switch (get_attr_type (insn))
618490286Sobrien    {
618590286Sobrien    case TYPE_INCDEC:
618690286Sobrien      if (operands[2] == const1_rtx)
618790286Sobrien	return "inc{b}\t%0";
618890286Sobrien      else if (operands[2] == constm1_rtx
618990286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
619090286Sobrien		   && INTVAL (operands[2]) == 255))
619190286Sobrien	return "dec{b}\t%0";
619290286Sobrien      abort();
619318334Speter
619490286Sobrien    default:
619590286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
619690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
619790286Sobrien          && INTVAL (operands[2]) < 0)
619890286Sobrien	{
619990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
620090286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
620190286Sobrien	}
620290286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
620390286Sobrien    }
620490286Sobrien}
620590286Sobrien  [(set (attr "type")
620690286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
620790286Sobrien	(const_string "incdec")
620890286Sobrien	(const_string "alu")))
620990286Sobrien   (set_attr "mode" "QI")])
621018334Speter
621150650Sobrien
621290286Sobrien(define_insn "addqi_ext_1"
621390286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
621490286Sobrien			 (const_int 8)
621590286Sobrien			 (const_int 8))
621690286Sobrien	(plus:SI
621790286Sobrien	  (zero_extract:SI
621890286Sobrien	    (match_operand 1 "ext_register_operand" "0")
621990286Sobrien	    (const_int 8)
622090286Sobrien	    (const_int 8))
622190286Sobrien	  (match_operand:QI 2 "general_operand" "Qmn")))
622290286Sobrien   (clobber (reg:CC 17))]
622390286Sobrien  "!TARGET_64BIT"
622418334Speter{
622590286Sobrien  switch (get_attr_type (insn))
622652296Sobrien    {
622790286Sobrien    case TYPE_INCDEC:
622890286Sobrien      if (operands[2] == const1_rtx)
622990286Sobrien	return "inc{b}\t%h0";
623090286Sobrien      else if (operands[2] == constm1_rtx
623190286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
623290286Sobrien		   && INTVAL (operands[2]) == 255))
623390286Sobrien	return "dec{b}\t%h0";
623490286Sobrien      abort();
623552296Sobrien
623690286Sobrien    default:
623790286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
623852296Sobrien    }
623990286Sobrien}
624090286Sobrien  [(set (attr "type")
624190286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
624290286Sobrien	(const_string "incdec")
624390286Sobrien	(const_string "alu")))
624490286Sobrien   (set_attr "mode" "QI")])
624518334Speter
624690286Sobrien(define_insn "*addqi_ext_1_rex64"
624790286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
624890286Sobrien			 (const_int 8)
624990286Sobrien			 (const_int 8))
625090286Sobrien	(plus:SI
625190286Sobrien	  (zero_extract:SI
625290286Sobrien	    (match_operand 1 "ext_register_operand" "0")
625390286Sobrien	    (const_int 8)
625490286Sobrien	    (const_int 8))
625590286Sobrien	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
625690286Sobrien   (clobber (reg:CC 17))]
625790286Sobrien  "TARGET_64BIT"
625890286Sobrien{
625990286Sobrien  switch (get_attr_type (insn))
626090286Sobrien    {
626190286Sobrien    case TYPE_INCDEC:
626290286Sobrien      if (operands[2] == const1_rtx)
626390286Sobrien	return "inc{b}\t%h0";
626490286Sobrien      else if (operands[2] == constm1_rtx
626590286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
626690286Sobrien		   && INTVAL (operands[2]) == 255))
626790286Sobrien	return "dec{b}\t%h0";
626890286Sobrien      abort();
626918334Speter
627090286Sobrien    default:
627190286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
627290286Sobrien    }
627390286Sobrien}
627490286Sobrien  [(set (attr "type")
627590286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
627690286Sobrien	(const_string "incdec")
627790286Sobrien	(const_string "alu")))
627890286Sobrien   (set_attr "mode" "QI")])
627918334Speter
628090286Sobrien(define_insn "*addqi_ext_2"
628190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
628290286Sobrien			 (const_int 8)
628390286Sobrien			 (const_int 8))
628490286Sobrien	(plus:SI
628590286Sobrien	  (zero_extract:SI
628690286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
628790286Sobrien	    (const_int 8)
628890286Sobrien	    (const_int 8))
628990286Sobrien	  (zero_extract:SI
629090286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
629190286Sobrien	    (const_int 8)
629290286Sobrien	    (const_int 8))))
629390286Sobrien   (clobber (reg:CC 17))]
629490286Sobrien  ""
629590286Sobrien  "add{b}\t{%h2, %h0|%h0, %h2}"
629690286Sobrien  [(set_attr "type" "alu")
629790286Sobrien   (set_attr "mode" "QI")])
629818334Speter
629918334Speter;; The patterns that match these are at the end of this file.
630018334Speter
630118334Speter(define_expand "addxf3"
630218334Speter  [(set (match_operand:XF 0 "register_operand" "")
630350650Sobrien	(plus:XF (match_operand:XF 1 "register_operand" "")
630450650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
630590286Sobrien  "!TARGET_64BIT && TARGET_80387"
630690286Sobrien  "")
630790286Sobrien
630890286Sobrien(define_expand "addtf3"
630990286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
631090286Sobrien	(plus:TF (match_operand:TF 1 "register_operand" "")
631190286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
631218334Speter  "TARGET_80387"
631318334Speter  "")
631418334Speter
631518334Speter(define_expand "adddf3"
631618334Speter  [(set (match_operand:DF 0 "register_operand" "")
631790286Sobrien	(plus:DF (match_operand:DF 1 "register_operand" "")
631818334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
631990286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
632018334Speter  "")
632118334Speter
632218334Speter(define_expand "addsf3"
632318334Speter  [(set (match_operand:SF 0 "register_operand" "")
632490286Sobrien	(plus:SF (match_operand:SF 1 "register_operand" "")
632518334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
632690286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
632718334Speter  "")
632818334Speter
632990286Sobrien;; Subtract instructions
633018334Speter
633190286Sobrien;; %%% splits for subsidi3
633250650Sobrien
633390286Sobrien(define_expand "subdi3"
633490286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
633590286Sobrien		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
633690286Sobrien			     (match_operand:DI 2 "x86_64_general_operand" "")))
633790286Sobrien	      (clobber (reg:CC 17))])]
633818334Speter  ""
633990286Sobrien  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
634018334Speter
634190286Sobrien(define_insn "*subdi3_1"
634290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
634390286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
634490286Sobrien		  (match_operand:DI 2 "general_operand" "roiF,riF")))
634590286Sobrien   (clobber (reg:CC 17))]
6346107605Sobrien  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
634790286Sobrien  "#")
634818334Speter
634990286Sobrien(define_split
635090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
635190286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
635290286Sobrien		  (match_operand:DI 2 "general_operand" "")))
635390286Sobrien   (clobber (reg:CC 17))]
635490286Sobrien  "!TARGET_64BIT && reload_completed"
635590286Sobrien  [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
635690286Sobrien	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
635790286Sobrien   (parallel [(set (match_dup 3)
635890286Sobrien		   (minus:SI (match_dup 4)
635990286Sobrien			     (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
636090286Sobrien				      (match_dup 5))))
636190286Sobrien	      (clobber (reg:CC 17))])]
636290286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
636390286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
636490286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
636518334Speter
636690286Sobrien(define_insn "subdi3_carry_rex64"
636790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
636890286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
636990286Sobrien	    (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
637090286Sobrien	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
637190286Sobrien   (clobber (reg:CC 17))]
637290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
637390286Sobrien  "sbb{q}\t{%2, %0|%0, %2}"
637490286Sobrien  [(set_attr "type" "alu")
637590286Sobrien   (set_attr "pent_pair" "pu")
637690286Sobrien   (set_attr "ppro_uops" "few")
637790286Sobrien   (set_attr "mode" "DI")])
637818334Speter
637990286Sobrien(define_insn "*subdi_1_rex64"
638090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
638190286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
638290286Sobrien		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
638390286Sobrien   (clobber (reg:CC 17))]
638490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
638590286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
638690286Sobrien  [(set_attr "type" "alu")
638790286Sobrien   (set_attr "mode" "DI")])
638818334Speter
638990286Sobrien(define_insn "*subdi_2_rex64"
639090286Sobrien  [(set (reg 17)
639190286Sobrien	(compare
639290286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
639390286Sobrien		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
639490286Sobrien	  (const_int 0)))
639590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
639690286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
639790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
639890286Sobrien   && ix86_binary_operator_ok (MINUS, DImode, operands)"
639990286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
640090286Sobrien  [(set_attr "type" "alu")
640190286Sobrien   (set_attr "mode" "DI")])
640252296Sobrien
640390286Sobrien(define_insn "*subdi_3_rex63"
640490286Sobrien  [(set (reg 17)
640590286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
640690286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
640790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
640890286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
640990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
641090286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
641190286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
641290286Sobrien  [(set_attr "type" "alu")
641390286Sobrien   (set_attr "mode" "DI")])
641418334Speter
641518334Speter
641690286Sobrien(define_insn "subsi3_carry"
641790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
641890286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
641990286Sobrien	    (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
642090286Sobrien	       (match_operand:SI 2 "general_operand" "ri,rm"))))
642190286Sobrien   (clobber (reg:CC 17))]
642290286Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
642390286Sobrien  "sbb{l}\t{%2, %0|%0, %2}"
642490286Sobrien  [(set_attr "type" "alu")
642590286Sobrien   (set_attr "pent_pair" "pu")
642690286Sobrien   (set_attr "ppro_uops" "few")
642790286Sobrien   (set_attr "mode" "SI")])
642818334Speter
642990286Sobrien(define_insn "subsi3_carry_zext"
643090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm,r")
643190286Sobrien	  (zero_extend:DI
643290286Sobrien	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
643390286Sobrien	      (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
643490286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))))
643590286Sobrien   (clobber (reg:CC 17))]
643690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
643790286Sobrien  "sbb{l}\t{%2, %k0|%k0, %2}"
643890286Sobrien  [(set_attr "type" "alu")
643990286Sobrien   (set_attr "pent_pair" "pu")
644090286Sobrien   (set_attr "ppro_uops" "few")
644190286Sobrien   (set_attr "mode" "SI")])
644218334Speter
644350650Sobrien(define_expand "subsi3"
644490286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
644590286Sobrien		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
644690286Sobrien			     (match_operand:SI 2 "general_operand" "")))
644790286Sobrien	      (clobber (reg:CC 17))])]
644850650Sobrien  ""
644990286Sobrien  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
645050650Sobrien
645190286Sobrien(define_insn "*subsi_1"
645250650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
645350650Sobrien	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
645490286Sobrien		  (match_operand:SI 2 "general_operand" "ri,rm")))
645590286Sobrien   (clobber (reg:CC 17))]
645650650Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
645790286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
645890286Sobrien  [(set_attr "type" "alu")
645990286Sobrien   (set_attr "mode" "SI")])
646018334Speter
646190286Sobrien(define_insn "*subsi_1_zext"
646290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
646390286Sobrien	(zero_extend:DI
646490286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
646590286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))))
646690286Sobrien   (clobber (reg:CC 17))]
646790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
646890286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
646990286Sobrien  [(set_attr "type" "alu")
647090286Sobrien   (set_attr "mode" "SI")])
647190286Sobrien
647290286Sobrien(define_insn "*subsi_2"
647390286Sobrien  [(set (reg 17)
647490286Sobrien	(compare
647590286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
647690286Sobrien		    (match_operand:SI 2 "general_operand" "ri,rm"))
647790286Sobrien	  (const_int 0)))
647890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
647990286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
648090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
648190286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
648290286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
648390286Sobrien  [(set_attr "type" "alu")
648490286Sobrien   (set_attr "mode" "SI")])
648590286Sobrien
648690286Sobrien(define_insn "*subsi_2_zext"
648790286Sobrien  [(set (reg 17)
648890286Sobrien	(compare
648990286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
649090286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))
649190286Sobrien	  (const_int 0)))
649290286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
649390286Sobrien	(zero_extend:DI
649490286Sobrien	  (minus:SI (match_dup 1)
649590286Sobrien		    (match_dup 2))))]
649690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
649790286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
649890286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
649990286Sobrien  [(set_attr "type" "alu")
650090286Sobrien   (set_attr "mode" "SI")])
650190286Sobrien
650290286Sobrien(define_insn "*subsi_3"
650390286Sobrien  [(set (reg 17)
650490286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
650590286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))
650690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
650790286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
650890286Sobrien  "ix86_match_ccmode (insn, CCmode)
650990286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
651090286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
651190286Sobrien  [(set_attr "type" "alu")
651290286Sobrien   (set_attr "mode" "SI")])
651390286Sobrien
651490286Sobrien(define_insn "*subsi_3_zext"
651590286Sobrien  [(set (reg 17)
651690286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
651790286Sobrien		 (match_operand:SI 2 "general_operand" "rim")))
651890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
651990286Sobrien	(zero_extend:DI
652090286Sobrien	  (minus:SI (match_dup 1)
652190286Sobrien		    (match_dup 2))))]
652290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
652390286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
652490286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
652590286Sobrien  [(set_attr "type" "alu")
652690286Sobrien   (set_attr "mode" "DI")])
652790286Sobrien
652850650Sobrien(define_expand "subhi3"
652990286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
653090286Sobrien		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
653190286Sobrien			     (match_operand:HI 2 "general_operand" "")))
653290286Sobrien	      (clobber (reg:CC 17))])]
653390286Sobrien  "TARGET_HIMODE_MATH"
653490286Sobrien  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
653550650Sobrien
653690286Sobrien(define_insn "*subhi_1"
653750650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
653850650Sobrien	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
653990286Sobrien		  (match_operand:HI 2 "general_operand" "ri,rm")))
654090286Sobrien   (clobber (reg:CC 17))]
654150650Sobrien  "ix86_binary_operator_ok (MINUS, HImode, operands)"
654290286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
654390286Sobrien  [(set_attr "type" "alu")
654490286Sobrien   (set_attr "mode" "HI")])
654550650Sobrien
654690286Sobrien(define_insn "*subhi_2"
654790286Sobrien  [(set (reg 17)
654890286Sobrien	(compare
654990286Sobrien	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
655090286Sobrien		    (match_operand:HI 2 "general_operand" "ri,rm"))
655190286Sobrien	  (const_int 0)))
655290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
655390286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
655490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
655590286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
655690286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
655790286Sobrien  [(set_attr "type" "alu")
655890286Sobrien   (set_attr "mode" "HI")])
655990286Sobrien
656090286Sobrien(define_insn "*subhi_3"
656190286Sobrien  [(set (reg 17)
656290286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
656390286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
656490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
656590286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
656690286Sobrien  "ix86_match_ccmode (insn, CCmode)
656790286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
656890286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
656990286Sobrien  [(set_attr "type" "alu")
657090286Sobrien   (set_attr "mode" "HI")])
657190286Sobrien
657250650Sobrien(define_expand "subqi3"
657390286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
657490286Sobrien		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
657590286Sobrien			     (match_operand:QI 2 "general_operand" "")))
657690286Sobrien	      (clobber (reg:CC 17))])]
657790286Sobrien  "TARGET_QIMODE_MATH"
657890286Sobrien  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
657918334Speter
658090286Sobrien(define_insn "*subqi_1"
658150650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
658250650Sobrien	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
658390286Sobrien		  (match_operand:QI 2 "general_operand" "qn,qmn")))
658490286Sobrien   (clobber (reg:CC 17))]
658550650Sobrien  "ix86_binary_operator_ok (MINUS, QImode, operands)"
658690286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
658790286Sobrien  [(set_attr "type" "alu")
658890286Sobrien   (set_attr "mode" "QI")])
658918334Speter
6590117404Skan(define_insn "*subqi_1_slp"
6591117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6592117404Skan	(minus:QI (match_dup 0)
6593117404Skan		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6594117404Skan   (clobber (reg:CC 17))]
6595117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6596117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6597117404Skan  "sub{b}\t{%1, %0|%0, %1}"
6598117404Skan  [(set_attr "type" "alu1")
6599117404Skan   (set_attr "mode" "QI")])
6600117404Skan
660190286Sobrien(define_insn "*subqi_2"
660290286Sobrien  [(set (reg 17)
660390286Sobrien	(compare
660490286Sobrien	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
660590286Sobrien		    (match_operand:QI 2 "general_operand" "qi,qm"))
660690286Sobrien	  (const_int 0)))
660790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
660890286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
660990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
661090286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
661190286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
661290286Sobrien  [(set_attr "type" "alu")
661390286Sobrien   (set_attr "mode" "QI")])
661490286Sobrien
661590286Sobrien(define_insn "*subqi_3"
661690286Sobrien  [(set (reg 17)
661790286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
661890286Sobrien		 (match_operand:QI 2 "general_operand" "qi,qm")))
661990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
662090286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
662190286Sobrien  "ix86_match_ccmode (insn, CCmode)
662290286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
662390286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
662490286Sobrien  [(set_attr "type" "alu")
662590286Sobrien   (set_attr "mode" "QI")])
662690286Sobrien
662718334Speter;; The patterns that match these are at the end of this file.
662818334Speter
662918334Speter(define_expand "subxf3"
663018334Speter  [(set (match_operand:XF 0 "register_operand" "")
663150650Sobrien	(minus:XF (match_operand:XF 1 "register_operand" "")
663250650Sobrien		  (match_operand:XF 2 "register_operand" "")))]
663390286Sobrien  "!TARGET_64BIT && TARGET_80387"
663490286Sobrien  "")
663590286Sobrien
663690286Sobrien(define_expand "subtf3"
663790286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
663890286Sobrien	(minus:TF (match_operand:TF 1 "register_operand" "")
663990286Sobrien		  (match_operand:TF 2 "register_operand" "")))]
664018334Speter  "TARGET_80387"
664118334Speter  "")
664218334Speter
664318334Speter(define_expand "subdf3"
664418334Speter  [(set (match_operand:DF 0 "register_operand" "")
664590286Sobrien	(minus:DF (match_operand:DF 1 "register_operand" "")
664618334Speter		  (match_operand:DF 2 "nonimmediate_operand" "")))]
664790286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
664818334Speter  "")
664918334Speter
665018334Speter(define_expand "subsf3"
665118334Speter  [(set (match_operand:SF 0 "register_operand" "")
665290286Sobrien	(minus:SF (match_operand:SF 1 "register_operand" "")
665318334Speter		  (match_operand:SF 2 "nonimmediate_operand" "")))]
665490286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
665518334Speter  "")
665618334Speter
665790286Sobrien;; Multiply instructions
665818334Speter
665990286Sobrien(define_expand "muldi3"
666090286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
666190286Sobrien		   (mult:DI (match_operand:DI 1 "register_operand" "")
666290286Sobrien			    (match_operand:DI 2 "x86_64_general_operand" "")))
666390286Sobrien	      (clobber (reg:CC 17))])]
666490286Sobrien  "TARGET_64BIT"
666590286Sobrien  "")
666618334Speter
666790286Sobrien(define_insn "*muldi3_1_rex64"
666890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
666990286Sobrien	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
667090286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
667190286Sobrien   (clobber (reg:CC 17))]
667290286Sobrien  "TARGET_64BIT
667390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
667490286Sobrien  "@
667590286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
667690286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
667790286Sobrien   imul{q}\t{%2, %0|%0, %2}"
667890286Sobrien  [(set_attr "type" "imul")
667990286Sobrien   (set_attr "prefix_0f" "0,0,1")
668090286Sobrien   (set_attr "mode" "DI")])
668118334Speter
668290286Sobrien(define_expand "mulsi3"
668390286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
668490286Sobrien		   (mult:SI (match_operand:SI 1 "register_operand" "")
668590286Sobrien			    (match_operand:SI 2 "general_operand" "")))
668690286Sobrien	      (clobber (reg:CC 17))])]
668718334Speter  ""
668890286Sobrien  "")
668918334Speter
669090286Sobrien(define_insn "*mulsi3_1"
669190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
669290286Sobrien	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
669390286Sobrien		 (match_operand:SI 2 "general_operand" "K,i,mr")))
669490286Sobrien   (clobber (reg:CC 17))]
669590286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
669690286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
669790286Sobrien  ; there are two ways of writing the exact same machine instruction
669890286Sobrien  ; in assembly language.  One, for example, is:
669990286Sobrien  ;
670090286Sobrien  ;   imul $12, %eax
670190286Sobrien  ;
670290286Sobrien  ; while the other is:
670390286Sobrien  ;
670490286Sobrien  ;   imul $12, %eax, %eax
670590286Sobrien  ;
670690286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
670790286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
670890286Sobrien  "@
670990286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
671090286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
671190286Sobrien   imul{l}\t{%2, %0|%0, %2}"
671290286Sobrien  [(set_attr "type" "imul")
671390286Sobrien   (set_attr "prefix_0f" "0,0,1")
671490286Sobrien   (set_attr "mode" "SI")])
671590286Sobrien
671690286Sobrien(define_insn "*mulsi3_1_zext"
671790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
671890286Sobrien	(zero_extend:DI
671990286Sobrien	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
672090286Sobrien		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
672190286Sobrien   (clobber (reg:CC 17))]
672290286Sobrien  "TARGET_64BIT
672390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
672490286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
672590286Sobrien  ; there are two ways of writing the exact same machine instruction
672690286Sobrien  ; in assembly language.  One, for example, is:
672790286Sobrien  ;
672890286Sobrien  ;   imul $12, %eax
672990286Sobrien  ;
673090286Sobrien  ; while the other is:
673190286Sobrien  ;
673290286Sobrien  ;   imul $12, %eax, %eax
673390286Sobrien  ;
673490286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
673590286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
673690286Sobrien  "@
673790286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
673890286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
673990286Sobrien   imul{l}\t{%2, %k0|%k0, %2}"
674090286Sobrien  [(set_attr "type" "imul")
674190286Sobrien   (set_attr "prefix_0f" "0,0,1")
674290286Sobrien   (set_attr "mode" "SI")])
674390286Sobrien
674490286Sobrien(define_expand "mulhi3"
674590286Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
674690286Sobrien		   (mult:HI (match_operand:HI 1 "register_operand" "")
674790286Sobrien			    (match_operand:HI 2 "general_operand" "")))
674890286Sobrien	      (clobber (reg:CC 17))])]
674990286Sobrien  "TARGET_HIMODE_MATH"
675090286Sobrien  "")
675190286Sobrien
675290286Sobrien(define_insn "*mulhi3_1"
675390286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
675490286Sobrien	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
675590286Sobrien		 (match_operand:HI 2 "general_operand" "K,i,mr")))
675690286Sobrien   (clobber (reg:CC 17))]
675790286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
675890286Sobrien  ; %%% There was a note about "Assembler has weird restrictions",
675990286Sobrien  ; concerning alternative 1 when op1 == op0.  True?
676090286Sobrien  "@
676190286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
676290286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
676390286Sobrien   imul{w}\t{%2, %0|%0, %2}"
676490286Sobrien  [(set_attr "type" "imul")
676590286Sobrien   (set_attr "prefix_0f" "0,0,1")
676690286Sobrien   (set_attr "mode" "HI")])
676790286Sobrien
676896294Sobrien(define_expand "mulqi3"
676996294Sobrien  [(parallel [(set (match_operand:QI 0 "register_operand" "")
677096294Sobrien		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
677196294Sobrien			    (match_operand:QI 2 "register_operand" "")))
677296294Sobrien	      (clobber (reg:CC 17))])]
677396294Sobrien  "TARGET_QIMODE_MATH"
677496294Sobrien  "")
677596294Sobrien
677696294Sobrien(define_insn "*mulqi3_1"
677790286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
677896294Sobrien	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
677990286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
678090286Sobrien   (clobber (reg:CC 17))]
678196294Sobrien  "TARGET_QIMODE_MATH
678296294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
678390286Sobrien  "mul{b}\t%2"
678490286Sobrien  [(set_attr "type" "imul")
678590286Sobrien   (set_attr "length_immediate" "0")
678690286Sobrien   (set_attr "mode" "QI")])
678790286Sobrien
678896294Sobrien(define_expand "umulqihi3"
678996294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
679096294Sobrien		   (mult:HI (zero_extend:HI
679196294Sobrien			      (match_operand:QI 1 "nonimmediate_operand" ""))
679296294Sobrien			    (zero_extend:HI
679396294Sobrien			      (match_operand:QI 2 "register_operand" ""))))
679496294Sobrien	      (clobber (reg:CC 17))])]
679596294Sobrien  "TARGET_QIMODE_MATH"
679696294Sobrien  "")
679796294Sobrien
679896294Sobrien(define_insn "*umulqihi3_1"
679950650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
680096294Sobrien	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
680190286Sobrien		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
680290286Sobrien   (clobber (reg:CC 17))]
680396294Sobrien  "TARGET_QIMODE_MATH
680496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
680590286Sobrien  "mul{b}\t%2"
680690286Sobrien  [(set_attr "type" "imul")
680790286Sobrien   (set_attr "length_immediate" "0")
680890286Sobrien   (set_attr "mode" "QI")])
680918334Speter
681096294Sobrien(define_expand "mulqihi3"
681196294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
681296294Sobrien		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
681396294Sobrien			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
681496294Sobrien	      (clobber (reg:CC 17))])]
681596294Sobrien  "TARGET_QIMODE_MATH"
681696294Sobrien  "")
681796294Sobrien
681896294Sobrien(define_insn "*mulqihi3_insn"
681950650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
682096294Sobrien	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
682190286Sobrien		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
682290286Sobrien   (clobber (reg:CC 17))]
682396294Sobrien  "TARGET_QIMODE_MATH
682496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
682590286Sobrien  "imul{b}\t%2"
682690286Sobrien  [(set_attr "type" "imul")
682790286Sobrien   (set_attr "length_immediate" "0")
682890286Sobrien   (set_attr "mode" "QI")])
682918334Speter
683096294Sobrien(define_expand "umulditi3"
683196294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
683296294Sobrien		   (mult:TI (zero_extend:TI
683396294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
683496294Sobrien			    (zero_extend:TI
683596294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
683696294Sobrien	      (clobber (reg:CC 17))])]
683796294Sobrien  "TARGET_64BIT"
683896294Sobrien  "")
683996294Sobrien
684096294Sobrien(define_insn "*umulditi3_insn"
684190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
684296294Sobrien	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
684390286Sobrien		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
684490286Sobrien   (clobber (reg:CC 17))]
684596294Sobrien  "TARGET_64BIT
684696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
684790286Sobrien  "mul{q}\t%2"
684890286Sobrien  [(set_attr "type" "imul")
684990286Sobrien   (set_attr "ppro_uops" "few")
685090286Sobrien   (set_attr "length_immediate" "0")
685190286Sobrien   (set_attr "mode" "DI")])
685290286Sobrien
685390286Sobrien;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
685496294Sobrien(define_expand "umulsidi3"
685596294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
685696294Sobrien		   (mult:DI (zero_extend:DI
685796294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
685896294Sobrien			    (zero_extend:DI
685996294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
686096294Sobrien	      (clobber (reg:CC 17))])]
686196294Sobrien  "!TARGET_64BIT"
686296294Sobrien  "")
686396294Sobrien
686496294Sobrien(define_insn "*umulsidi3_insn"
686518334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
686696294Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
686790286Sobrien		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
686890286Sobrien   (clobber (reg:CC 17))]
686996294Sobrien  "!TARGET_64BIT
687096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
687190286Sobrien  "mul{l}\t%2"
687290286Sobrien  [(set_attr "type" "imul")
687390286Sobrien   (set_attr "ppro_uops" "few")
687490286Sobrien   (set_attr "length_immediate" "0")
687590286Sobrien   (set_attr "mode" "SI")])
687618334Speter
687796294Sobrien(define_expand "mulditi3"
687896294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
687996294Sobrien		   (mult:TI (sign_extend:TI
688096294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
688196294Sobrien			    (sign_extend:TI
688296294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
688396294Sobrien	      (clobber (reg:CC 17))])]
688496294Sobrien  "TARGET_64BIT"
688596294Sobrien  "")
688696294Sobrien
688796294Sobrien(define_insn "*mulditi3_insn"
688890286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
688996294Sobrien	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
689090286Sobrien		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
689190286Sobrien   (clobber (reg:CC 17))]
689296294Sobrien  "TARGET_64BIT
689396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
689490286Sobrien  "imul{q}\t%2"
689590286Sobrien  [(set_attr "type" "imul")
689690286Sobrien   (set_attr "length_immediate" "0")
689790286Sobrien   (set_attr "mode" "DI")])
689890286Sobrien
689996294Sobrien(define_expand "mulsidi3"
690096294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
690196294Sobrien		   (mult:DI (sign_extend:DI
690296294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
690396294Sobrien			    (sign_extend:DI
690496294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
690596294Sobrien	      (clobber (reg:CC 17))])]
690696294Sobrien  "!TARGET_64BIT"
690796294Sobrien  "")
690896294Sobrien
690996294Sobrien(define_insn "*mulsidi3_insn"
691018334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
691196294Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
691290286Sobrien		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
691390286Sobrien   (clobber (reg:CC 17))]
691496294Sobrien  "!TARGET_64BIT
691596294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
691690286Sobrien  "imul{l}\t%2"
691790286Sobrien  [(set_attr "type" "imul")
691890286Sobrien   (set_attr "length_immediate" "0")
691990286Sobrien   (set_attr "mode" "SI")])
692018334Speter
692196294Sobrien(define_expand "umuldi3_highpart"
692296294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
692396294Sobrien		   (truncate:DI
692496294Sobrien		     (lshiftrt:TI
692596294Sobrien		       (mult:TI (zero_extend:TI
692696294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
692796294Sobrien				(zero_extend:TI
692896294Sobrien				  (match_operand:DI 2 "register_operand" "")))
692996294Sobrien		       (const_int 64))))
693096294Sobrien	      (clobber (match_scratch:DI 3 ""))
693196294Sobrien	      (clobber (reg:CC 17))])]
693296294Sobrien  "TARGET_64BIT"
693396294Sobrien  "")
693496294Sobrien
693590286Sobrien(define_insn "*umuldi3_highpart_rex64"
693690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
693790286Sobrien	(truncate:DI
693890286Sobrien	  (lshiftrt:TI
693990286Sobrien	    (mult:TI (zero_extend:TI
694096294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
694190286Sobrien		     (zero_extend:TI
694290286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
694390286Sobrien	    (const_int 64))))
694496294Sobrien   (clobber (match_scratch:DI 3 "=1"))
694590286Sobrien   (clobber (reg:CC 17))]
694696294Sobrien  "TARGET_64BIT
694796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
694890286Sobrien  "mul{q}\t%2"
694990286Sobrien  [(set_attr "type" "imul")
695090286Sobrien   (set_attr "ppro_uops" "few")
695190286Sobrien   (set_attr "length_immediate" "0")
695290286Sobrien   (set_attr "mode" "DI")])
695390286Sobrien
695496294Sobrien(define_expand "umulsi3_highpart"
695596294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
695696294Sobrien		   (truncate:SI
695796294Sobrien		     (lshiftrt:DI
695896294Sobrien		       (mult:DI (zero_extend:DI
695996294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
696096294Sobrien				(zero_extend:DI
696196294Sobrien				  (match_operand:SI 2 "register_operand" "")))
696296294Sobrien		       (const_int 32))))
696396294Sobrien	      (clobber (match_scratch:SI 3 ""))
696496294Sobrien	      (clobber (reg:CC 17))])]
696596294Sobrien  ""
696696294Sobrien  "")
696796294Sobrien
696896294Sobrien(define_insn "*umulsi3_highpart_insn"
696918334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
697090286Sobrien	(truncate:SI
697190286Sobrien	  (lshiftrt:DI
697290286Sobrien	    (mult:DI (zero_extend:DI
697396294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
697490286Sobrien		     (zero_extend:DI
697590286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
697690286Sobrien	    (const_int 32))))
697796294Sobrien   (clobber (match_scratch:SI 3 "=1"))
697890286Sobrien   (clobber (reg:CC 17))]
697996294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
698090286Sobrien  "mul{l}\t%2"
698190286Sobrien  [(set_attr "type" "imul")
698290286Sobrien   (set_attr "ppro_uops" "few")
698390286Sobrien   (set_attr "length_immediate" "0")
698490286Sobrien   (set_attr "mode" "SI")])
698518334Speter
698690286Sobrien(define_insn "*umulsi3_highpart_zext"
698790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
698890286Sobrien	(zero_extend:DI (truncate:SI
698990286Sobrien	  (lshiftrt:DI
699090286Sobrien	    (mult:DI (zero_extend:DI
699196294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
699290286Sobrien		     (zero_extend:DI
699390286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
699490286Sobrien	    (const_int 32)))))
699596294Sobrien   (clobber (match_scratch:SI 3 "=1"))
699690286Sobrien   (clobber (reg:CC 17))]
699796294Sobrien  "TARGET_64BIT
699896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
699990286Sobrien  "mul{l}\t%2"
700090286Sobrien  [(set_attr "type" "imul")
700190286Sobrien   (set_attr "ppro_uops" "few")
700290286Sobrien   (set_attr "length_immediate" "0")
700390286Sobrien   (set_attr "mode" "SI")])
700490286Sobrien
700596294Sobrien(define_expand "smuldi3_highpart"
700696294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
700796294Sobrien		   (truncate:DI
700896294Sobrien		     (lshiftrt:TI
700996294Sobrien		       (mult:TI (sign_extend:TI
701096294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
701196294Sobrien				(sign_extend:TI
701296294Sobrien				  (match_operand:DI 2 "register_operand" "")))
701396294Sobrien		       (const_int 64))))
701496294Sobrien	      (clobber (match_scratch:DI 3 ""))
701596294Sobrien	      (clobber (reg:CC 17))])]
701696294Sobrien  "TARGET_64BIT"
701796294Sobrien  "")
701896294Sobrien
701990286Sobrien(define_insn "*smuldi3_highpart_rex64"
702090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
702190286Sobrien	(truncate:DI
702290286Sobrien	  (lshiftrt:TI
702390286Sobrien	    (mult:TI (sign_extend:TI
702496294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
702590286Sobrien		     (sign_extend:TI
702690286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
702790286Sobrien	    (const_int 64))))
702896294Sobrien   (clobber (match_scratch:DI 3 "=1"))
702990286Sobrien   (clobber (reg:CC 17))]
703096294Sobrien  "TARGET_64BIT
703196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
703290286Sobrien  "imul{q}\t%2"
703390286Sobrien  [(set_attr "type" "imul")
703490286Sobrien   (set_attr "ppro_uops" "few")
703590286Sobrien   (set_attr "mode" "DI")])
703690286Sobrien
703796294Sobrien(define_expand "smulsi3_highpart"
703896294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
703996294Sobrien		   (truncate:SI
704096294Sobrien		     (lshiftrt:DI
704196294Sobrien		       (mult:DI (sign_extend:DI
704296294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
704396294Sobrien				(sign_extend:DI
704496294Sobrien				  (match_operand:SI 2 "register_operand" "")))
704596294Sobrien		       (const_int 32))))
704696294Sobrien	      (clobber (match_scratch:SI 3 ""))
704796294Sobrien	      (clobber (reg:CC 17))])]
704896294Sobrien  ""
704996294Sobrien  "")
705096294Sobrien
705196294Sobrien(define_insn "*smulsi3_highpart_insn"
705218334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
705390286Sobrien	(truncate:SI
705490286Sobrien	  (lshiftrt:DI
705590286Sobrien	    (mult:DI (sign_extend:DI
705696294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
705790286Sobrien		     (sign_extend:DI
705890286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
705990286Sobrien	    (const_int 32))))
706096294Sobrien   (clobber (match_scratch:SI 3 "=1"))
706190286Sobrien   (clobber (reg:CC 17))]
706296294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
706390286Sobrien  "imul{l}\t%2"
706490286Sobrien  [(set_attr "type" "imul")
706590286Sobrien   (set_attr "ppro_uops" "few")
706690286Sobrien   (set_attr "mode" "SI")])
706718334Speter
706890286Sobrien(define_insn "*smulsi3_highpart_zext"
706990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
707090286Sobrien	(zero_extend:DI (truncate:SI
707190286Sobrien	  (lshiftrt:DI
707290286Sobrien	    (mult:DI (sign_extend:DI
707396294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
707490286Sobrien		     (sign_extend:DI
707590286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
707690286Sobrien	    (const_int 32)))))
707796294Sobrien   (clobber (match_scratch:SI 3 "=1"))
707890286Sobrien   (clobber (reg:CC 17))]
707996294Sobrien  "TARGET_64BIT
708096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
708190286Sobrien  "imul{l}\t%2"
708290286Sobrien  [(set_attr "type" "imul")
708390286Sobrien   (set_attr "ppro_uops" "few")
708490286Sobrien   (set_attr "mode" "SI")])
708590286Sobrien
708618334Speter;; The patterns that match these are at the end of this file.
708718334Speter
708818334Speter(define_expand "mulxf3"
708918334Speter  [(set (match_operand:XF 0 "register_operand" "")
709050650Sobrien	(mult:XF (match_operand:XF 1 "register_operand" "")
709150650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
709290286Sobrien  "!TARGET_64BIT && TARGET_80387"
709390286Sobrien  "")
709490286Sobrien
709590286Sobrien(define_expand "multf3"
709690286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
709790286Sobrien	(mult:TF (match_operand:TF 1 "register_operand" "")
709890286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
709918334Speter  "TARGET_80387"
710018334Speter  "")
710118334Speter
710218334Speter(define_expand "muldf3"
710318334Speter  [(set (match_operand:DF 0 "register_operand" "")
710450650Sobrien	(mult:DF (match_operand:DF 1 "register_operand" "")
710518334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
710690286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
710718334Speter  "")
710818334Speter
710918334Speter(define_expand "mulsf3"
711018334Speter  [(set (match_operand:SF 0 "register_operand" "")
711150650Sobrien	(mult:SF (match_operand:SF 1 "register_operand" "")
711218334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
711390286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
711418334Speter  "")
711518334Speter
711690286Sobrien;; Divide instructions
711718334Speter
711818334Speter(define_insn "divqi3"
711950650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
712050650Sobrien	(div:QI (match_operand:HI 1 "register_operand" "0")
712190286Sobrien		(match_operand:QI 2 "nonimmediate_operand" "qm")))
712290286Sobrien   (clobber (reg:CC 17))]
712390286Sobrien  "TARGET_QIMODE_MATH"
712490286Sobrien  "idiv{b}\t%2"
712590286Sobrien  [(set_attr "type" "idiv")
712690286Sobrien   (set_attr "mode" "QI")
712790286Sobrien   (set_attr "ppro_uops" "few")])
712818334Speter
712918334Speter(define_insn "udivqi3"
713050650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
713150650Sobrien	(udiv:QI (match_operand:HI 1 "register_operand" "0")
713290286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
713390286Sobrien   (clobber (reg:CC 17))]
713490286Sobrien  "TARGET_QIMODE_MATH"
713590286Sobrien  "div{b}\t%2"
713690286Sobrien  [(set_attr "type" "idiv")
713790286Sobrien   (set_attr "mode" "QI")
713890286Sobrien   (set_attr "ppro_uops" "few")])
713918334Speter
714018334Speter;; The patterns that match these are at the end of this file.
714118334Speter
714218334Speter(define_expand "divxf3"
714318334Speter  [(set (match_operand:XF 0 "register_operand" "")
714450650Sobrien	(div:XF (match_operand:XF 1 "register_operand" "")
714550650Sobrien		(match_operand:XF 2 "register_operand" "")))]
714690286Sobrien  "!TARGET_64BIT && TARGET_80387"
714790286Sobrien  "")
714890286Sobrien
714990286Sobrien(define_expand "divtf3"
715090286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
715190286Sobrien	(div:TF (match_operand:TF 1 "register_operand" "")
715290286Sobrien		(match_operand:TF 2 "register_operand" "")))]
715318334Speter  "TARGET_80387"
715418334Speter  "")
715518334Speter
715618334Speter(define_expand "divdf3"
715718334Speter  [(set (match_operand:DF 0 "register_operand" "")
715850650Sobrien 	(div:DF (match_operand:DF 1 "register_operand" "")
715950650Sobrien 		(match_operand:DF 2 "nonimmediate_operand" "")))]
716090286Sobrien   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
716150650Sobrien   "")
716250650Sobrien 
716318334Speter(define_expand "divsf3"
716418334Speter  [(set (match_operand:SF 0 "register_operand" "")
716550650Sobrien	(div:SF (match_operand:SF 1 "register_operand" "")
716618334Speter		(match_operand:SF 2 "nonimmediate_operand" "")))]
716790286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
716818334Speter  "")
716918334Speter
717018334Speter;; Remainder instructions.
717118334Speter
717290286Sobrien(define_expand "divmoddi4"
717390286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
717490286Sobrien		   (div:DI (match_operand:DI 1 "register_operand" "")
717590286Sobrien			   (match_operand:DI 2 "nonimmediate_operand" "")))
717690286Sobrien	      (set (match_operand:DI 3 "register_operand" "")
717790286Sobrien		   (mod:DI (match_dup 1) (match_dup 2)))
717890286Sobrien	      (clobber (reg:CC 17))])]
717990286Sobrien  "TARGET_64BIT"
718090286Sobrien  "")
718190286Sobrien
718290286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
718390286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
718490286Sobrien;; of code.
718590286Sobrien(define_insn "*divmoddi4_nocltd_rex64"
718690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
718790286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "1,0")
718890286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
718990286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d,&d")
719090286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
719190286Sobrien   (clobber (reg:CC 17))]
719290286Sobrien  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
719390286Sobrien  "#"
719490286Sobrien  [(set_attr "type" "multi")])
719590286Sobrien
719690286Sobrien(define_insn "*divmoddi4_cltd_rex64"
719790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
719890286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "a")
719990286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm")))
720090286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d")
720190286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
720290286Sobrien   (clobber (reg:CC 17))]
720390286Sobrien  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
720490286Sobrien  "#"
720590286Sobrien  [(set_attr "type" "multi")])
720690286Sobrien
720790286Sobrien(define_insn "*divmoddi_noext_rex64"
720890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
720990286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "0")
721090286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "rm")))
721190286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
721290286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
721390286Sobrien   (use (match_operand:DI 4 "register_operand" "3"))
721490286Sobrien   (clobber (reg:CC 17))]
721590286Sobrien  "TARGET_64BIT"
721690286Sobrien  "idiv{q}\t%2"
721790286Sobrien  [(set_attr "type" "idiv")
721890286Sobrien   (set_attr "mode" "DI")
721990286Sobrien   (set_attr "ppro_uops" "few")])
722090286Sobrien
722190286Sobrien(define_split
722290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
722390286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "")
722490286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "")))
722590286Sobrien   (set (match_operand:DI 3 "register_operand" "")
722690286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
722790286Sobrien   (clobber (reg:CC 17))]
722890286Sobrien  "TARGET_64BIT && reload_completed"
722990286Sobrien  [(parallel [(set (match_dup 3)
723090286Sobrien		   (ashiftrt:DI (match_dup 4) (const_int 63)))
723190286Sobrien	      (clobber (reg:CC 17))])
723290286Sobrien   (parallel [(set (match_dup 0)
723390286Sobrien	           (div:DI (reg:DI 0) (match_dup 2)))
723490286Sobrien	      (set (match_dup 3)
723590286Sobrien		   (mod:DI (reg:DI 0) (match_dup 2)))
723690286Sobrien	      (use (match_dup 3))
723790286Sobrien	      (clobber (reg:CC 17))])]
723890286Sobrien{
7239117404Skan  /* Avoid use of cltd in favor of a mov+shift.  */
724090286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
724190286Sobrien    {
724290286Sobrien      if (true_regnum (operands[1]))
724390286Sobrien        emit_move_insn (operands[0], operands[1]);
724490286Sobrien      else
724590286Sobrien	emit_move_insn (operands[3], operands[1]);
724690286Sobrien      operands[4] = operands[3];
724790286Sobrien    }
724890286Sobrien  else
724990286Sobrien    {
725090286Sobrien      if (true_regnum (operands[1]))
725190286Sobrien	abort();
725290286Sobrien      operands[4] = operands[1];
725390286Sobrien    }
725490286Sobrien})
725590286Sobrien
725690286Sobrien
725790286Sobrien(define_expand "divmodsi4"
725890286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
725990286Sobrien		   (div:SI (match_operand:SI 1 "register_operand" "")
726090286Sobrien			   (match_operand:SI 2 "nonimmediate_operand" "")))
726190286Sobrien	      (set (match_operand:SI 3 "register_operand" "")
726290286Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))
726390286Sobrien	      (clobber (reg:CC 17))])]
726490286Sobrien  ""
726590286Sobrien  "")
726690286Sobrien
726790286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
726890286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
726990286Sobrien;; of code.
727090286Sobrien(define_insn "*divmodsi4_nocltd"
727190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
727290286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "1,0")
727390286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
727490286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d,&d")
727590286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
727690286Sobrien   (clobber (reg:CC 17))]
727790286Sobrien  "!optimize_size && !TARGET_USE_CLTD"
727890286Sobrien  "#"
727990286Sobrien  [(set_attr "type" "multi")])
728090286Sobrien
728190286Sobrien(define_insn "*divmodsi4_cltd"
728218334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
728390286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "a")
728490286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm")))
728590286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d")
728690286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
728790286Sobrien   (clobber (reg:CC 17))]
728890286Sobrien  "optimize_size || TARGET_USE_CLTD"
728990286Sobrien  "#"
729090286Sobrien  [(set_attr "type" "multi")])
729190286Sobrien
729290286Sobrien(define_insn "*divmodsi_noext"
729390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
729418334Speter	(div:SI (match_operand:SI 1 "register_operand" "0")
729550650Sobrien		(match_operand:SI 2 "nonimmediate_operand" "rm")))
729690286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
729790286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
729890286Sobrien   (use (match_operand:SI 4 "register_operand" "3"))
729990286Sobrien   (clobber (reg:CC 17))]
730018334Speter  ""
730190286Sobrien  "idiv{l}\t%2"
730290286Sobrien  [(set_attr "type" "idiv")
730390286Sobrien   (set_attr "mode" "SI")
730490286Sobrien   (set_attr "ppro_uops" "few")])
730590286Sobrien
730690286Sobrien(define_split
730790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
730890286Sobrien	(div:SI (match_operand:SI 1 "register_operand" "")
730990286Sobrien		(match_operand:SI 2 "nonimmediate_operand" "")))
731090286Sobrien   (set (match_operand:SI 3 "register_operand" "")
731190286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
731290286Sobrien   (clobber (reg:CC 17))]
731390286Sobrien  "reload_completed"
731490286Sobrien  [(parallel [(set (match_dup 3)
731590286Sobrien		   (ashiftrt:SI (match_dup 4) (const_int 31)))
731690286Sobrien	      (clobber (reg:CC 17))])
731790286Sobrien   (parallel [(set (match_dup 0)
731890286Sobrien	           (div:SI (reg:SI 0) (match_dup 2)))
731990286Sobrien	      (set (match_dup 3)
732090286Sobrien		   (mod:SI (reg:SI 0) (match_dup 2)))
732190286Sobrien	      (use (match_dup 3))
732290286Sobrien	      (clobber (reg:CC 17))])]
732318334Speter{
7324117404Skan  /* Avoid use of cltd in favor of a mov+shift.  */
732590286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
732690286Sobrien    {
732790286Sobrien      if (true_regnum (operands[1]))
732890286Sobrien        emit_move_insn (operands[0], operands[1]);
732990286Sobrien      else
733090286Sobrien	emit_move_insn (operands[3], operands[1]);
733190286Sobrien      operands[4] = operands[3];
733290286Sobrien    }
733390286Sobrien  else
733490286Sobrien    {
733590286Sobrien      if (true_regnum (operands[1]))
733690286Sobrien	abort();
733790286Sobrien      operands[4] = operands[1];
733890286Sobrien    }
733990286Sobrien})
734090286Sobrien;; %%% Split me.
734118334Speter(define_insn "divmodhi4"
734218334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
734318334Speter	(div:HI (match_operand:HI 1 "register_operand" "0")
734450650Sobrien		(match_operand:HI 2 "nonimmediate_operand" "rm")))
734518334Speter   (set (match_operand:HI 3 "register_operand" "=&d")
734690286Sobrien	(mod:HI (match_dup 1) (match_dup 2)))
734790286Sobrien   (clobber (reg:CC 17))]
734890286Sobrien  "TARGET_HIMODE_MATH"
734990286Sobrien  "cwtd\;idiv{w}\t%2"
735090286Sobrien  [(set_attr "type" "multi")
735190286Sobrien   (set_attr "length_immediate" "0")
735290286Sobrien   (set_attr "mode" "SI")])
735318334Speter
735490286Sobrien(define_insn "udivmoddi4"
735590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
735690286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
735790286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
735890286Sobrien   (set (match_operand:DI 3 "register_operand" "=&d")
735990286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
736090286Sobrien   (clobber (reg:CC 17))]
736190286Sobrien  "TARGET_64BIT"
736290286Sobrien  "xor{q}\t%3, %3\;div{q}\t%2"
736390286Sobrien  [(set_attr "type" "multi")
736490286Sobrien   (set_attr "length_immediate" "0")
736590286Sobrien   (set_attr "mode" "DI")])
736690286Sobrien
736790286Sobrien(define_insn "*udivmoddi4_noext"
736890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
736990286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
737090286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
737190286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
737290286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
737390286Sobrien   (use (match_dup 3))
737490286Sobrien   (clobber (reg:CC 17))]
737590286Sobrien  "TARGET_64BIT"
737690286Sobrien  "div{q}\t%2"
737790286Sobrien  [(set_attr "type" "idiv")
737890286Sobrien   (set_attr "ppro_uops" "few")
737990286Sobrien   (set_attr "mode" "DI")])
738090286Sobrien
738190286Sobrien(define_split
738290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
738390286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "")
738490286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "")))
738590286Sobrien   (set (match_operand:DI 3 "register_operand" "")
738690286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
738790286Sobrien   (clobber (reg:CC 17))]
738890286Sobrien  "TARGET_64BIT && reload_completed"
738990286Sobrien  [(set (match_dup 3) (const_int 0))
739090286Sobrien   (parallel [(set (match_dup 0)
739190286Sobrien		   (udiv:DI (match_dup 1) (match_dup 2)))
739290286Sobrien	      (set (match_dup 3)
739390286Sobrien		   (umod:DI (match_dup 1) (match_dup 2)))
739490286Sobrien	      (use (match_dup 3))
739590286Sobrien	      (clobber (reg:CC 17))])]
739690286Sobrien  "")
739790286Sobrien
739818334Speter(define_insn "udivmodsi4"
739918334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
740018334Speter	(udiv:SI (match_operand:SI 1 "register_operand" "0")
740150650Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
740218334Speter   (set (match_operand:SI 3 "register_operand" "=&d")
740390286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
740490286Sobrien   (clobber (reg:CC 17))]
740518334Speter  ""
740690286Sobrien  "xor{l}\t%3, %3\;div{l}\t%2"
740790286Sobrien  [(set_attr "type" "multi")
740890286Sobrien   (set_attr "length_immediate" "0")
740990286Sobrien   (set_attr "mode" "SI")])
741018334Speter
741190286Sobrien(define_insn "*udivmodsi4_noext"
741290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
741390286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "0")
741490286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
741590286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
741690286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
741790286Sobrien   (use (match_dup 3))
741890286Sobrien   (clobber (reg:CC 17))]
741990286Sobrien  ""
742090286Sobrien  "div{l}\t%2"
742190286Sobrien  [(set_attr "type" "idiv")
742290286Sobrien   (set_attr "ppro_uops" "few")
742390286Sobrien   (set_attr "mode" "SI")])
742490286Sobrien
742590286Sobrien(define_split
742690286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
742790286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "")
742890286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "")))
742990286Sobrien   (set (match_operand:SI 3 "register_operand" "")
743090286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
743190286Sobrien   (clobber (reg:CC 17))]
743290286Sobrien  "reload_completed"
743390286Sobrien  [(set (match_dup 3) (const_int 0))
743490286Sobrien   (parallel [(set (match_dup 0)
743590286Sobrien		   (udiv:SI (match_dup 1) (match_dup 2)))
743690286Sobrien	      (set (match_dup 3)
743790286Sobrien		   (umod:SI (match_dup 1) (match_dup 2)))
743890286Sobrien	      (use (match_dup 3))
743990286Sobrien	      (clobber (reg:CC 17))])]
744090286Sobrien  "")
744190286Sobrien
744290286Sobrien(define_expand "udivmodhi4"
744390286Sobrien  [(set (match_dup 4) (const_int 0))
744490286Sobrien   (parallel [(set (match_operand:HI 0 "register_operand" "")
744590286Sobrien		   (udiv:HI (match_operand:HI 1 "register_operand" "")
744690286Sobrien		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
744790286Sobrien	      (set (match_operand:HI 3 "register_operand" "")
744890286Sobrien	   	   (umod:HI (match_dup 1) (match_dup 2)))
744990286Sobrien	      (use (match_dup 4))
745090286Sobrien	      (clobber (reg:CC 17))])]
745190286Sobrien  "TARGET_HIMODE_MATH"
745290286Sobrien  "operands[4] = gen_reg_rtx (HImode);")
745390286Sobrien
745490286Sobrien(define_insn "*udivmodhi_noext"
745518334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
745618334Speter	(udiv:HI (match_operand:HI 1 "register_operand" "0")
745750650Sobrien		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
745890286Sobrien   (set (match_operand:HI 3 "register_operand" "=d")
745990286Sobrien	(umod:HI (match_dup 1) (match_dup 2)))
746090286Sobrien   (use (match_operand:HI 4 "register_operand" "3"))
746190286Sobrien   (clobber (reg:CC 17))]
746218334Speter  ""
746390286Sobrien  "div{w}\t%2"
746490286Sobrien  [(set_attr "type" "idiv")
746590286Sobrien   (set_attr "mode" "HI")
746690286Sobrien   (set_attr "ppro_uops" "few")])
746718334Speter
746890286Sobrien;; We can not use div/idiv for double division, because it causes
746990286Sobrien;; "division by zero" on the overflow and that's not what we expect
747090286Sobrien;; from truncate.  Because true (non truncating) double division is
747190286Sobrien;; never generated, we can't create this insn anyway.
747290286Sobrien;
747390286Sobrien;(define_insn ""
747490286Sobrien;  [(set (match_operand:SI 0 "register_operand" "=a")
747590286Sobrien;	(truncate:SI
747690286Sobrien;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
747790286Sobrien;		   (zero_extend:DI
747890286Sobrien;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
747990286Sobrien;   (set (match_operand:SI 3 "register_operand" "=d")
748090286Sobrien;	(truncate:SI
748190286Sobrien;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
748290286Sobrien;   (clobber (reg:CC 17))]
748390286Sobrien;  ""
748490286Sobrien;  "div{l}\t{%2, %0|%0, %2}"
748590286Sobrien;  [(set_attr "type" "idiv")
748690286Sobrien;   (set_attr "ppro_uops" "few")])
748790286Sobrien
748890286Sobrien;;- Logical AND instructions
748918334Speter
749090286Sobrien;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
749190286Sobrien;; Note that this excludes ah.
749290286Sobrien
749390286Sobrien(define_insn "*testdi_1_rex64"
749490286Sobrien  [(set (reg 17)
749590286Sobrien	(compare
749690286Sobrien	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
749790286Sobrien		  (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
749890286Sobrien	  (const_int 0)))]
749990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
750090286Sobrien  "@
750190286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
750290286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
750390286Sobrien   test{q}\t{%1, %0|%0, %1} 
750490286Sobrien   test{q}\t{%1, %0|%0, %1} 
750590286Sobrien   test{q}\t{%1, %0|%0, %1}"
750690286Sobrien  [(set_attr "type" "test")
750790286Sobrien   (set_attr "modrm" "0,1,0,1,1")
750890286Sobrien   (set_attr "mode" "SI,SI,DI,DI,DI")
750990286Sobrien   (set_attr "pent_pair" "uv,np,uv,np,uv")])
751090286Sobrien
751190286Sobrien(define_insn "testsi_1"
751290286Sobrien  [(set (reg 17)
751390286Sobrien	(compare
751490286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
751590286Sobrien		  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
751690286Sobrien	  (const_int 0)))]
751790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
751890286Sobrien  "test{l}\t{%1, %0|%0, %1}"
751990286Sobrien  [(set_attr "type" "test")
752090286Sobrien   (set_attr "modrm" "0,1,1")
752190286Sobrien   (set_attr "mode" "SI")
752290286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
752390286Sobrien
752490286Sobrien(define_expand "testsi_ccno_1"
752590286Sobrien  [(set (reg:CCNO 17)
752690286Sobrien	(compare:CCNO
752790286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
752890286Sobrien		  (match_operand:SI 1 "nonmemory_operand" ""))
752990286Sobrien	  (const_int 0)))]
753018334Speter  ""
753190286Sobrien  "")
753218334Speter
753390286Sobrien(define_insn "*testhi_1"
753490286Sobrien  [(set (reg 17)
753590286Sobrien        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
753690286Sobrien			 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
753790286Sobrien		 (const_int 0)))]
753890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
753990286Sobrien  "test{w}\t{%1, %0|%0, %1}"
754090286Sobrien  [(set_attr "type" "test")
754190286Sobrien   (set_attr "modrm" "0,1,1")
754290286Sobrien   (set_attr "mode" "HI")
754390286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
754418334Speter
754590286Sobrien(define_expand "testqi_ccz_1"
754690286Sobrien  [(set (reg:CCZ 17)
754790286Sobrien        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
754890286Sobrien			     (match_operand:QI 1 "nonmemory_operand" ""))
754990286Sobrien		 (const_int 0)))]
755090286Sobrien  ""
755190286Sobrien  "")
755218334Speter
755390286Sobrien(define_insn "*testqi_1"
755490286Sobrien  [(set (reg 17)
755590286Sobrien        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
755690286Sobrien			 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
755790286Sobrien		 (const_int 0)))]
755890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
755918334Speter{
756090286Sobrien  if (which_alternative == 3)
756118334Speter    {
756290286Sobrien      if (GET_CODE (operands[1]) == CONST_INT
756390286Sobrien	  && (INTVAL (operands[1]) & 0xffffff00))
756490286Sobrien	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
756590286Sobrien      return "test{l}\t{%1, %k0|%k0, %1}";
756650650Sobrien    }
756790286Sobrien  return "test{b}\t{%1, %0|%0, %1}";
756890286Sobrien}
756990286Sobrien  [(set_attr "type" "test")
757090286Sobrien   (set_attr "modrm" "0,1,1,1")
757190286Sobrien   (set_attr "mode" "QI,QI,QI,SI")
757290286Sobrien   (set_attr "pent_pair" "uv,np,uv,np")])
757318334Speter
757490286Sobrien(define_expand "testqi_ext_ccno_0"
757590286Sobrien  [(set (reg:CCNO 17)
757690286Sobrien	(compare:CCNO
757790286Sobrien	  (and:SI
757890286Sobrien	    (zero_extract:SI
757990286Sobrien	      (match_operand 0 "ext_register_operand" "")
758090286Sobrien	      (const_int 8)
758190286Sobrien	      (const_int 8))
758290286Sobrien	    (match_operand 1 "const_int_operand" ""))
758390286Sobrien	  (const_int 0)))]
758490286Sobrien  ""
758590286Sobrien  "")
758618334Speter
758790286Sobrien(define_insn "*testqi_ext_0"
758890286Sobrien  [(set (reg 17)
758990286Sobrien	(compare
759090286Sobrien	  (and:SI
759190286Sobrien	    (zero_extract:SI
759290286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
759390286Sobrien	      (const_int 8)
759490286Sobrien	      (const_int 8))
759590286Sobrien	    (match_operand 1 "const_int_operand" "n"))
759690286Sobrien	  (const_int 0)))]
7597117404Skan  "ix86_match_ccmode (insn, CCNOmode)"
759890286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
759990286Sobrien  [(set_attr "type" "test")
760090286Sobrien   (set_attr "mode" "QI")
760190286Sobrien   (set_attr "length_immediate" "1")
760290286Sobrien   (set_attr "pent_pair" "np")])
760350650Sobrien
760490286Sobrien(define_insn "*testqi_ext_1"
760590286Sobrien  [(set (reg 17)
760690286Sobrien	(compare
760790286Sobrien	  (and:SI
760890286Sobrien	    (zero_extract:SI
760990286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
761090286Sobrien	      (const_int 8)
761190286Sobrien	      (const_int 8))
761290286Sobrien	    (zero_extend:SI
761390286Sobrien	      (match_operand:QI 1 "nonimmediate_operand" "Qm")))
761490286Sobrien	  (const_int 0)))]
761590286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
761690286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
761790286Sobrien  [(set_attr "type" "test")
761890286Sobrien   (set_attr "mode" "QI")])
761918334Speter
762090286Sobrien(define_insn "*testqi_ext_1_rex64"
762190286Sobrien  [(set (reg 17)
762290286Sobrien	(compare
762390286Sobrien	  (and:SI
762490286Sobrien	    (zero_extract:SI
762590286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
762690286Sobrien	      (const_int 8)
762790286Sobrien	      (const_int 8))
762890286Sobrien	    (zero_extend:SI
762990286Sobrien	      (match_operand:QI 1 "register_operand" "Q")))
763090286Sobrien	  (const_int 0)))]
763190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
763290286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
763390286Sobrien  [(set_attr "type" "test")
763490286Sobrien   (set_attr "mode" "QI")])
763518334Speter
763690286Sobrien(define_insn "*testqi_ext_2"
763790286Sobrien  [(set (reg 17)
763890286Sobrien	(compare
763990286Sobrien	  (and:SI
764090286Sobrien	    (zero_extract:SI
764190286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
764290286Sobrien	      (const_int 8)
764390286Sobrien	      (const_int 8))
764490286Sobrien	    (zero_extract:SI
764590286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
764690286Sobrien	      (const_int 8)
764790286Sobrien	      (const_int 8)))
764890286Sobrien	  (const_int 0)))]
764990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
765090286Sobrien  "test{b}\t{%h1, %h0|%h0, %h1}"
765190286Sobrien  [(set_attr "type" "test")
765290286Sobrien   (set_attr "mode" "QI")])
765350650Sobrien
765490286Sobrien;; Combine likes to form bit extractions for some tests.  Humor it.
765590286Sobrien(define_insn "*testqi_ext_3"
765690286Sobrien  [(set (reg 17)
765790286Sobrien        (compare (zero_extract:SI
765890286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
765990286Sobrien		   (match_operand:SI 1 "const_int_operand" "")
766090286Sobrien		   (match_operand:SI 2 "const_int_operand" ""))
766190286Sobrien		 (const_int 0)))]
766290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
766390286Sobrien   && (GET_MODE (operands[0]) == SImode
766490286Sobrien       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
766590286Sobrien       || GET_MODE (operands[0]) == HImode
766690286Sobrien       || GET_MODE (operands[0]) == QImode)"
766790286Sobrien  "#")
766850650Sobrien
766990286Sobrien(define_insn "*testqi_ext_3_rex64"
767090286Sobrien  [(set (reg 17)
767190286Sobrien        (compare (zero_extract:DI
767290286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
767390286Sobrien		   (match_operand:DI 1 "const_int_operand" "")
767490286Sobrien		   (match_operand:DI 2 "const_int_operand" ""))
767590286Sobrien		 (const_int 0)))]
767690286Sobrien  "TARGET_64BIT
767790286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
767890286Sobrien   /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
767990286Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
768090286Sobrien   /* Ensure that resulting mask is zero or sign extended operand.  */
768190286Sobrien   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
768290286Sobrien       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
768390286Sobrien	   && INTVAL (operands[1]) > 32))
768490286Sobrien   && (GET_MODE (operands[0]) == SImode
768590286Sobrien       || GET_MODE (operands[0]) == DImode
768690286Sobrien       || GET_MODE (operands[0]) == HImode
768790286Sobrien       || GET_MODE (operands[0]) == QImode)"
768890286Sobrien  "#")
768950650Sobrien
769090286Sobrien(define_split
769190286Sobrien  [(set (reg 17)
769290286Sobrien        (compare (zero_extract
769390286Sobrien		   (match_operand 0 "nonimmediate_operand" "")
769490286Sobrien		   (match_operand 1 "const_int_operand" "")
769590286Sobrien		   (match_operand 2 "const_int_operand" ""))
769690286Sobrien		 (const_int 0)))]
769790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
769890286Sobrien  [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
769990286Sobrien{
770090286Sobrien  HOST_WIDE_INT len = INTVAL (operands[1]);
770190286Sobrien  HOST_WIDE_INT pos = INTVAL (operands[2]);
770290286Sobrien  HOST_WIDE_INT mask;
770390286Sobrien  enum machine_mode mode, submode;
770418334Speter
770590286Sobrien  mode = GET_MODE (operands[0]);
770690286Sobrien  if (GET_CODE (operands[0]) == MEM)
770790286Sobrien    {
770890286Sobrien      /* ??? Combine likes to put non-volatile mem extractions in QImode
770990286Sobrien	 no matter the size of the test.  So find a mode that works.  */
771090286Sobrien      if (! MEM_VOLATILE_P (operands[0]))
771118334Speter	{
771290286Sobrien	  mode = smallest_mode_for_size (pos + len, MODE_INT);
771390286Sobrien	  operands[0] = adjust_address (operands[0], mode, 0);
771490286Sobrien	}
771590286Sobrien    }
771690286Sobrien  else if (GET_CODE (operands[0]) == SUBREG
771790286Sobrien	   && (submode = GET_MODE (SUBREG_REG (operands[0])),
771890286Sobrien	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
771990286Sobrien	   && pos + len <= GET_MODE_BITSIZE (submode))
772090286Sobrien    {
772190286Sobrien      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
772290286Sobrien      mode = submode;
772390286Sobrien      operands[0] = SUBREG_REG (operands[0]);
772490286Sobrien    }
772590286Sobrien  else if (mode == HImode && pos + len <= 8)
772690286Sobrien    {
772790286Sobrien      /* Small HImode tests can be converted to QImode.  */
772890286Sobrien      mode = QImode;
772990286Sobrien      operands[0] = gen_lowpart (QImode, operands[0]);
773090286Sobrien    }
773118334Speter
773290286Sobrien  mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
773390286Sobrien  mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
773418334Speter
7735117404Skan  operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
773690286Sobrien})
773750650Sobrien
7738117404Skan;; Convert HImode/SImode test instructions with immediate to QImode ones.
7739117404Skan;; i386 does not allow to encode test with 8bit sign extended immediate, so
7740117404Skan;; this is relatively important trick.
7741117404Skan;; Do the converison only post-reload to avoid limiting of the register class
7742117404Skan;; to QI regs.
7743117404Skan(define_split
7744117404Skan  [(set (reg 17)
7745117404Skan	(compare
7746117404Skan	  (and (match_operand 0 "register_operand" "")
7747117404Skan	       (match_operand 1 "const_int_operand" ""))
7748117404Skan	  (const_int 0)))]
7749117404Skan   "reload_completed
7750117404Skan    && QI_REG_P (operands[0])
7751117404Skan    && ((ix86_match_ccmode (insn, CCZmode)
7752117404Skan    	 && !(INTVAL (operands[1]) & ~(255 << 8)))
7753117404Skan	|| (ix86_match_ccmode (insn, CCNOmode)
7754117404Skan	    && !(INTVAL (operands[1]) & ~(127 << 8))))
7755117404Skan    && GET_MODE (operands[0]) != QImode"
7756117404Skan  [(set (reg:CCNO 17)
7757117404Skan	(compare:CCNO
7758117404Skan	  (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7759117404Skan		  (match_dup 1))
7760117404Skan	  (const_int 0)))]
7761117404Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
7762117404Skan   operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
7763117404Skan
7764117404Skan(define_split
7765117404Skan  [(set (reg 17)
7766117404Skan	(compare
7767117404Skan	  (and (match_operand 0 "nonimmediate_operand" "")
7768117404Skan	       (match_operand 1 "const_int_operand" ""))
7769117404Skan	  (const_int 0)))]
7770117404Skan   "reload_completed
7771117404Skan    && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
7772117404Skan    && ((ix86_match_ccmode (insn, CCZmode)
7773117404Skan	 && !(INTVAL (operands[1]) & ~255))
7774117404Skan	|| (ix86_match_ccmode (insn, CCNOmode)
7775117404Skan	    && !(INTVAL (operands[1]) & ~127)))
7776117404Skan    && GET_MODE (operands[0]) != QImode"
7777117404Skan  [(set (reg:CCNO 17)
7778117404Skan	(compare:CCNO
7779117404Skan	  (and:QI (match_dup 0)
7780117404Skan		  (match_dup 1))
7781117404Skan	  (const_int 0)))]
7782117404Skan  "operands[0] = gen_lowpart (QImode, operands[0]);
7783117404Skan   operands[1] = gen_lowpart (QImode, operands[1]);")
7784117404Skan
7785117404Skan
778690286Sobrien;; %%% This used to optimize known byte-wide and operations to memory,
778790286Sobrien;; and sometimes to QImode registers.  If this is considered useful,
778890286Sobrien;; it should be done with splitters.
778918334Speter
779090286Sobrien(define_expand "anddi3"
779190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
779290286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
779390286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
779490286Sobrien   (clobber (reg:CC 17))]
779590286Sobrien  "TARGET_64BIT"
779690286Sobrien  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
779750650Sobrien
779890286Sobrien(define_insn "*anddi_1_rex64"
779990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
780090286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
780190286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
780290286Sobrien   (clobber (reg:CC 17))]
780390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
780490286Sobrien{
780590286Sobrien  switch (get_attr_type (insn))
780690286Sobrien    {
780790286Sobrien    case TYPE_IMOVX:
780890286Sobrien      {
780990286Sobrien	enum machine_mode mode;
781050650Sobrien
781190286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
781290286Sobrien	  abort ();
781390286Sobrien        if (INTVAL (operands[2]) == 0xff)
781490286Sobrien	  mode = QImode;
781590286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
781690286Sobrien	  mode = HImode;
781790286Sobrien	else
781890286Sobrien	  abort ();
781990286Sobrien	
782090286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
782190286Sobrien	if (mode == QImode)
782290286Sobrien	  return "movz{bq|x}\t{%1,%0|%0, %1}";
782390286Sobrien	else
782490286Sobrien	  return "movz{wq|x}\t{%1,%0|%0, %1}";
782590286Sobrien      }
782650650Sobrien
782750650Sobrien    default:
782890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
782990286Sobrien	abort ();
783090286Sobrien      if (get_attr_mode (insn) == MODE_SI)
783190286Sobrien	return "and{l}\t{%k2, %k0|%k0, %k2}";
783290286Sobrien      else
783390286Sobrien	return "and{q}\t{%2, %0|%0, %2}";
783418334Speter    }
783590286Sobrien}
783690286Sobrien  [(set_attr "type" "alu,alu,alu,imovx")
783790286Sobrien   (set_attr "length_immediate" "*,*,*,0")
783890286Sobrien   (set_attr "mode" "SI,DI,DI,DI")])
783918334Speter
784090286Sobrien(define_insn "*anddi_2"
784190286Sobrien  [(set (reg 17)
784290286Sobrien	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
784390286Sobrien			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
784490286Sobrien		 (const_int 0)))
784590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
784690286Sobrien	(and:DI (match_dup 1) (match_dup 2)))]
784790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
784890286Sobrien   && ix86_binary_operator_ok (AND, DImode, operands)"
784990286Sobrien  "@
785090286Sobrien   and{l}\t{%k2, %k0|%k0, %k2} 
785190286Sobrien   and{q}\t{%2, %0|%0, %2} 
785290286Sobrien   and{q}\t{%2, %0|%0, %2}"
785390286Sobrien  [(set_attr "type" "alu")
785490286Sobrien   (set_attr "mode" "SI,DI,DI")])
785518334Speter
785690286Sobrien(define_expand "andsi3"
785790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
785890286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
785990286Sobrien		(match_operand:SI 2 "general_operand" "")))
786090286Sobrien   (clobber (reg:CC 17))]
786118334Speter  ""
786290286Sobrien  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
786390286Sobrien
786490286Sobrien(define_insn "*andsi_1"
786590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
786690286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
786790286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm,L")))
786890286Sobrien   (clobber (reg:CC 17))]
786990286Sobrien  "ix86_binary_operator_ok (AND, SImode, operands)"
787018334Speter{
787190286Sobrien  switch (get_attr_type (insn))
787218334Speter    {
787390286Sobrien    case TYPE_IMOVX:
787490286Sobrien      {
787590286Sobrien	enum machine_mode mode;
787618334Speter
787790286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
787890286Sobrien	  abort ();
787990286Sobrien        if (INTVAL (operands[2]) == 0xff)
788090286Sobrien	  mode = QImode;
788190286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
788290286Sobrien	  mode = HImode;
788390286Sobrien	else
788490286Sobrien	  abort ();
788590286Sobrien	
788690286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
788790286Sobrien	if (mode == QImode)
788890286Sobrien	  return "movz{bl|x}\t{%1,%0|%0, %1}";
788990286Sobrien	else
789090286Sobrien	  return "movz{wl|x}\t{%1,%0|%0, %1}";
789190286Sobrien      }
789218334Speter
789390286Sobrien    default:
789490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
789590286Sobrien	abort ();
789690286Sobrien      return "and{l}\t{%2, %0|%0, %2}";
789790286Sobrien    }
789890286Sobrien}
789990286Sobrien  [(set_attr "type" "alu,alu,imovx")
790090286Sobrien   (set_attr "length_immediate" "*,*,0")
790190286Sobrien   (set_attr "mode" "SI")])
790218334Speter
790390286Sobrien(define_split
790490286Sobrien  [(set (match_operand 0 "register_operand" "")
790590286Sobrien	(and (match_dup 0)
790690286Sobrien	     (const_int -65536)))
790790286Sobrien   (clobber (reg:CC 17))]
7908117404Skan  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
790990286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
791090286Sobrien  "operands[1] = gen_lowpart (HImode, operands[0]);")
791118334Speter
791290286Sobrien(define_split
791390286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
791490286Sobrien	(and (match_dup 0)
791590286Sobrien	     (const_int -256)))
791690286Sobrien   (clobber (reg:CC 17))]
791790286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
791890286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
791990286Sobrien  "operands[1] = gen_lowpart (QImode, operands[0]);")
792018334Speter
792190286Sobrien(define_split
792290286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
792390286Sobrien	(and (match_dup 0)
792490286Sobrien	     (const_int -65281)))
792590286Sobrien   (clobber (reg:CC 17))]
792690286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
792790286Sobrien  [(parallel [(set (zero_extract:SI (match_dup 0)
792890286Sobrien				    (const_int 8)
792990286Sobrien				    (const_int 8))
793090286Sobrien		   (xor:SI 
793190286Sobrien		     (zero_extract:SI (match_dup 0)
793290286Sobrien				      (const_int 8)
793390286Sobrien				      (const_int 8))
793490286Sobrien		     (zero_extract:SI (match_dup 0)
793590286Sobrien				      (const_int 8)
793690286Sobrien				      (const_int 8))))
793790286Sobrien	      (clobber (reg:CC 17))])]
793890286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);")
793950650Sobrien
794090286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
794190286Sobrien(define_insn "*andsi_1_zext"
794290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
794390286Sobrien	(zero_extend:DI
794490286Sobrien	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
794590286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
794690286Sobrien   (clobber (reg:CC 17))]
794790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
794890286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
794990286Sobrien  [(set_attr "type" "alu")
795090286Sobrien   (set_attr "mode" "SI")])
795118334Speter
795290286Sobrien(define_insn "*andsi_2"
795390286Sobrien  [(set (reg 17)
795490286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
795590286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
795690286Sobrien		 (const_int 0)))
795790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
795890286Sobrien	(and:SI (match_dup 1) (match_dup 2)))]
795990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
796090286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
796190286Sobrien  "and{l}\t{%2, %0|%0, %2}"
796290286Sobrien  [(set_attr "type" "alu")
796390286Sobrien   (set_attr "mode" "SI")])
796490286Sobrien
796590286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
796690286Sobrien(define_insn "*andsi_2_zext"
796790286Sobrien  [(set (reg 17)
796890286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
796990286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
797090286Sobrien		 (const_int 0)))
797190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
797290286Sobrien	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
797390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
797490286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
797590286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
797690286Sobrien  [(set_attr "type" "alu")
797790286Sobrien   (set_attr "mode" "SI")])
797890286Sobrien
797990286Sobrien(define_expand "andhi3"
798090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
798190286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
798290286Sobrien		(match_operand:HI 2 "general_operand" "")))
798390286Sobrien   (clobber (reg:CC 17))]
798490286Sobrien  "TARGET_HIMODE_MATH"
798590286Sobrien  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
798690286Sobrien
798790286Sobrien(define_insn "*andhi_1"
798890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
798990286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
799090286Sobrien		(match_operand:HI 2 "general_operand" "ri,rm,L")))
799190286Sobrien   (clobber (reg:CC 17))]
799290286Sobrien  "ix86_binary_operator_ok (AND, HImode, operands)"
799390286Sobrien{
799490286Sobrien  switch (get_attr_type (insn))
799550650Sobrien    {
799690286Sobrien    case TYPE_IMOVX:
799790286Sobrien      if (GET_CODE (operands[2]) != CONST_INT)
799890286Sobrien	abort ();
799990286Sobrien      if (INTVAL (operands[2]) == 0xff)
800090286Sobrien	return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
800190286Sobrien      abort ();
800290286Sobrien
800390286Sobrien    default:
800490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
800590286Sobrien	abort ();
800690286Sobrien
800790286Sobrien      return "and{w}\t{%2, %0|%0, %2}";
800850650Sobrien    }
800990286Sobrien}
801090286Sobrien  [(set_attr "type" "alu,alu,imovx")
801190286Sobrien   (set_attr "length_immediate" "*,*,0")
801290286Sobrien   (set_attr "mode" "HI,HI,SI")])
801350650Sobrien
801490286Sobrien(define_insn "*andhi_2"
801590286Sobrien  [(set (reg 17)
801690286Sobrien	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
801790286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
801890286Sobrien		 (const_int 0)))
801990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
802090286Sobrien	(and:HI (match_dup 1) (match_dup 2)))]
802190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
802290286Sobrien   && ix86_binary_operator_ok (AND, HImode, operands)"
802390286Sobrien  "and{w}\t{%2, %0|%0, %2}"
802490286Sobrien  [(set_attr "type" "alu")
802590286Sobrien   (set_attr "mode" "HI")])
802690286Sobrien
802790286Sobrien(define_expand "andqi3"
802890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
802990286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
803090286Sobrien		(match_operand:QI 2 "general_operand" "")))
803190286Sobrien   (clobber (reg:CC 17))]
803290286Sobrien  "TARGET_QIMODE_MATH"
803390286Sobrien  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
803490286Sobrien
803590286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
803690286Sobrien(define_insn "*andqi_1"
803790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
803890286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
803990286Sobrien		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
804090286Sobrien   (clobber (reg:CC 17))]
804190286Sobrien  "ix86_binary_operator_ok (AND, QImode, operands)"
804290286Sobrien  "@
804390286Sobrien   and{b}\t{%2, %0|%0, %2}
804490286Sobrien   and{b}\t{%2, %0|%0, %2}
804590286Sobrien   and{l}\t{%k2, %k0|%k0, %k2}"
804690286Sobrien  [(set_attr "type" "alu")
804790286Sobrien   (set_attr "mode" "QI,QI,SI")])
804890286Sobrien
804990286Sobrien(define_insn "*andqi_1_slp"
805090286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
805190286Sobrien	(and:QI (match_dup 0)
805290286Sobrien		(match_operand:QI 1 "general_operand" "qi,qmi")))
805390286Sobrien   (clobber (reg:CC 17))]
8054117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8055117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
805690286Sobrien  "and{b}\t{%1, %0|%0, %1}"
805790286Sobrien  [(set_attr "type" "alu1")
805890286Sobrien   (set_attr "mode" "QI")])
805990286Sobrien
806090286Sobrien(define_insn "*andqi_2"
806190286Sobrien  [(set (reg 17)
806290286Sobrien	(compare (and:QI
806390286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
806490286Sobrien		   (match_operand:QI 2 "general_operand" "qim,qi,i"))
806590286Sobrien		 (const_int 0)))
806690286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
806790286Sobrien	(and:QI (match_dup 1) (match_dup 2)))]
806890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
806990286Sobrien   && ix86_binary_operator_ok (AND, QImode, operands)"
807090286Sobrien{
807190286Sobrien  if (which_alternative == 2)
807250650Sobrien    {
807390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
807490286Sobrien          && (INTVAL (operands[2]) & 0xffffff00))
807590286Sobrien        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
807690286Sobrien      return "and{l}\t{%2, %k0|%k0, %2}";
807750650Sobrien    }
807890286Sobrien  return "and{b}\t{%2, %0|%0, %2}";
807990286Sobrien}
808090286Sobrien  [(set_attr "type" "alu")
808190286Sobrien   (set_attr "mode" "QI,QI,SI")])
808250650Sobrien
808390286Sobrien(define_insn "*andqi_2_slp"
808490286Sobrien  [(set (reg 17)
808590286Sobrien	(compare (and:QI
808690286Sobrien		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
808790286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
808890286Sobrien		 (const_int 0)))
808990286Sobrien   (set (strict_low_part (match_dup 0))
809090286Sobrien	(and:QI (match_dup 0) (match_dup 1)))]
8091117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8092117404Skan   && ix86_match_ccmode (insn, CCNOmode)
8093117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
809490286Sobrien  "and{b}\t{%1, %0|%0, %1}"
809590286Sobrien  [(set_attr "type" "alu1")
809690286Sobrien   (set_attr "mode" "QI")])
809718334Speter
809890286Sobrien;; ??? A bug in recog prevents it from recognizing a const_int as an
809990286Sobrien;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
810090286Sobrien;; for a QImode operand, which of course failed.
810118334Speter
810290286Sobrien(define_insn "andqi_ext_0"
810390286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
810490286Sobrien			 (const_int 8)
810590286Sobrien			 (const_int 8))
810690286Sobrien	(and:SI 
810790286Sobrien	  (zero_extract:SI
810890286Sobrien	    (match_operand 1 "ext_register_operand" "0")
810990286Sobrien	    (const_int 8)
811090286Sobrien	    (const_int 8))
811190286Sobrien	  (match_operand 2 "const_int_operand" "n")))
811290286Sobrien   (clobber (reg:CC 17))]
8113117404Skan  ""
811490286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
811590286Sobrien  [(set_attr "type" "alu")
811690286Sobrien   (set_attr "length_immediate" "1")
811790286Sobrien   (set_attr "mode" "QI")])
811818334Speter
811990286Sobrien;; Generated by peephole translating test to and.  This shows up
812090286Sobrien;; often in fp comparisons.
812190286Sobrien
812290286Sobrien(define_insn "*andqi_ext_0_cc"
812390286Sobrien  [(set (reg 17)
812490286Sobrien	(compare
812590286Sobrien	  (and:SI
812690286Sobrien	    (zero_extract:SI
812790286Sobrien	      (match_operand 1 "ext_register_operand" "0")
812890286Sobrien	      (const_int 8)
812990286Sobrien	      (const_int 8))
813090286Sobrien	    (match_operand 2 "const_int_operand" "n"))
813190286Sobrien	  (const_int 0)))
813290286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
813390286Sobrien			 (const_int 8)
813490286Sobrien			 (const_int 8))
813590286Sobrien	(and:SI 
813690286Sobrien	  (zero_extract:SI
813790286Sobrien	    (match_dup 1)
813890286Sobrien	    (const_int 8)
813990286Sobrien	    (const_int 8))
814090286Sobrien	  (match_dup 2)))]
8141117404Skan  "ix86_match_ccmode (insn, CCNOmode)"
814290286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
814390286Sobrien  [(set_attr "type" "alu")
814490286Sobrien   (set_attr "length_immediate" "1")
814590286Sobrien   (set_attr "mode" "QI")])
814690286Sobrien
814790286Sobrien(define_insn "*andqi_ext_1"
814890286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
814990286Sobrien			 (const_int 8)
815090286Sobrien			 (const_int 8))
815190286Sobrien	(and:SI 
815290286Sobrien	  (zero_extract:SI
815390286Sobrien	    (match_operand 1 "ext_register_operand" "0")
815490286Sobrien	    (const_int 8)
815590286Sobrien	    (const_int 8))
815690286Sobrien	  (zero_extend:SI
815790286Sobrien	    (match_operand:QI 2 "general_operand" "Qm"))))
815890286Sobrien   (clobber (reg:CC 17))]
815990286Sobrien  "!TARGET_64BIT"
816090286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
816190286Sobrien  [(set_attr "type" "alu")
816290286Sobrien   (set_attr "length_immediate" "0")
816390286Sobrien   (set_attr "mode" "QI")])
816490286Sobrien
816590286Sobrien(define_insn "*andqi_ext_1_rex64"
816690286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
816790286Sobrien			 (const_int 8)
816890286Sobrien			 (const_int 8))
816990286Sobrien	(and:SI 
817090286Sobrien	  (zero_extract:SI
817190286Sobrien	    (match_operand 1 "ext_register_operand" "0")
817290286Sobrien	    (const_int 8)
817390286Sobrien	    (const_int 8))
817490286Sobrien	  (zero_extend:SI
817590286Sobrien	    (match_operand 2 "ext_register_operand" "Q"))))
817690286Sobrien   (clobber (reg:CC 17))]
817790286Sobrien  "TARGET_64BIT"
817890286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
817990286Sobrien  [(set_attr "type" "alu")
818090286Sobrien   (set_attr "length_immediate" "0")
818190286Sobrien   (set_attr "mode" "QI")])
818290286Sobrien
818390286Sobrien(define_insn "*andqi_ext_2"
818490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
818590286Sobrien			 (const_int 8)
818690286Sobrien			 (const_int 8))
818718334Speter	(and:SI
818890286Sobrien	  (zero_extract:SI
818990286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
819090286Sobrien	    (const_int 8)
819190286Sobrien	    (const_int 8))
819290286Sobrien	  (zero_extract:SI
819390286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
819490286Sobrien	    (const_int 8)
819590286Sobrien	    (const_int 8))))
819690286Sobrien   (clobber (reg:CC 17))]
819790286Sobrien  ""
819890286Sobrien  "and{b}\t{%h2, %h0|%h0, %h2}"
819990286Sobrien  [(set_attr "type" "alu")
820090286Sobrien   (set_attr "length_immediate" "0")
820190286Sobrien   (set_attr "mode" "QI")])
8202117404Skan
8203117404Skan;; Convert wide AND instructions with immediate operand to shorter QImode
8204117404Skan;; equivalents when possible.
8205117404Skan;; Don't do the splitting with memory operands, since it intoduces risc
8206117404Skan;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8207117404Skan;; for size, but that can (should?) be handled by generic code instead.
8208117404Skan(define_split
8209117404Skan  [(set (match_operand 0 "register_operand" "")
8210117404Skan	(and (match_operand 1 "register_operand" "")
8211117404Skan	     (match_operand 2 "const_int_operand" "")))
8212117404Skan   (clobber (reg:CC 17))]
8213117404Skan   "reload_completed
8214117404Skan    && QI_REG_P (operands[0])
8215117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8216117404Skan    && !(~INTVAL (operands[2]) & ~(255 << 8))
8217117404Skan    && GET_MODE (operands[0]) != QImode"
8218117404Skan  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8219117404Skan		   (and:SI (zero_extract:SI (match_dup 1)
8220117404Skan					    (const_int 8) (const_int 8))
8221117404Skan			   (match_dup 2)))
8222117404Skan	      (clobber (reg:CC 17))])]
8223117404Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
8224117404Skan   operands[1] = gen_lowpart (SImode, operands[1]);
8225117404Skan   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8226117404Skan
8227117404Skan;; Since AND can be encoded with sign extended immediate, this is only
8228117404Skan;; profitable when 7th bit is not set.
8229117404Skan(define_split
8230117404Skan  [(set (match_operand 0 "register_operand" "")
8231117404Skan	(and (match_operand 1 "general_operand" "")
8232117404Skan	     (match_operand 2 "const_int_operand" "")))
8233117404Skan   (clobber (reg:CC 17))]
8234117404Skan   "reload_completed
8235117404Skan    && ANY_QI_REG_P (operands[0])
8236117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8237117404Skan    && !(~INTVAL (operands[2]) & ~255)
8238117404Skan    && !(INTVAL (operands[2]) & 128)
8239117404Skan    && GET_MODE (operands[0]) != QImode"
8240117404Skan  [(parallel [(set (strict_low_part (match_dup 0))
8241117404Skan		   (and:QI (match_dup 1)
8242117404Skan			   (match_dup 2)))
8243117404Skan	      (clobber (reg:CC 17))])]
8244117404Skan  "operands[0] = gen_lowpart (QImode, operands[0]);
8245117404Skan   operands[1] = gen_lowpart (QImode, operands[1]);
8246117404Skan   operands[2] = gen_lowpart (QImode, operands[2]);")
824718334Speter
824890286Sobrien;; Logical inclusive OR instructions
824918334Speter
825090286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
825190286Sobrien;; If this is considered useful, it should be done with splitters.
825290286Sobrien
825390286Sobrien(define_expand "iordi3"
825490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
825590286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
825690286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
825790286Sobrien   (clobber (reg:CC 17))]
825890286Sobrien  "TARGET_64BIT"
825990286Sobrien  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
826090286Sobrien
826190286Sobrien(define_insn "*iordi_1_rex64"
826290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
826390286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
826490286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
826590286Sobrien   (clobber (reg:CC 17))]
826690286Sobrien  "TARGET_64BIT
826790286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
826890286Sobrien  "or{q}\t{%2, %0|%0, %2}"
826990286Sobrien  [(set_attr "type" "alu")
827090286Sobrien   (set_attr "mode" "DI")])
827190286Sobrien
827290286Sobrien(define_insn "*iordi_2_rex64"
827390286Sobrien  [(set (reg 17)
827490286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
827590286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
827690286Sobrien		 (const_int 0)))
827790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
827890286Sobrien	(ior:DI (match_dup 1) (match_dup 2)))]
827990286Sobrien  "TARGET_64BIT
828090286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
828190286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
828290286Sobrien  "or{q}\t{%2, %0|%0, %2}"
828390286Sobrien  [(set_attr "type" "alu")
828490286Sobrien   (set_attr "mode" "DI")])
828590286Sobrien
828690286Sobrien(define_insn "*iordi_3_rex64"
828790286Sobrien  [(set (reg 17)
828890286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
828990286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
829090286Sobrien		 (const_int 0)))
829190286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
829290286Sobrien  "TARGET_64BIT
829390286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
829490286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
829590286Sobrien  "or{q}\t{%2, %0|%0, %2}"
829690286Sobrien  [(set_attr "type" "alu")
829790286Sobrien   (set_attr "mode" "DI")])
829890286Sobrien
829990286Sobrien
830090286Sobrien(define_expand "iorsi3"
830190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
830290286Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
830390286Sobrien		(match_operand:SI 2 "general_operand" "")))
830490286Sobrien   (clobber (reg:CC 17))]
830590286Sobrien  ""
830690286Sobrien  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
830790286Sobrien
830890286Sobrien(define_insn "*iorsi_1"
830950650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
831050650Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
831190286Sobrien		(match_operand:SI 2 "general_operand" "ri,rmi")))
831290286Sobrien   (clobber (reg:CC 17))]
831390286Sobrien  "ix86_binary_operator_ok (IOR, SImode, operands)"
831490286Sobrien  "or{l}\t{%2, %0|%0, %2}"
831590286Sobrien  [(set_attr "type" "alu")
831690286Sobrien   (set_attr "mode" "SI")])
831750650Sobrien
831890286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
831990286Sobrien(define_insn "*iorsi_1_zext"
832090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
832190286Sobrien	(zero_extend:DI
832290286Sobrien	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
832390286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
832490286Sobrien   (clobber (reg:CC 17))]
832590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
832690286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
832790286Sobrien  [(set_attr "type" "alu")
832890286Sobrien   (set_attr "mode" "SI")])
832950650Sobrien
833090286Sobrien(define_insn "*iorsi_1_zext_imm"
833190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
833290286Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
833390286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
833490286Sobrien   (clobber (reg:CC 17))]
833590286Sobrien  "TARGET_64BIT"
833690286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
833790286Sobrien  [(set_attr "type" "alu")
833890286Sobrien   (set_attr "mode" "SI")])
833950650Sobrien
834090286Sobrien(define_insn "*iorsi_2"
834190286Sobrien  [(set (reg 17)
834290286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
834390286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
834490286Sobrien		 (const_int 0)))
834590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
834690286Sobrien	(ior:SI (match_dup 1) (match_dup 2)))]
834790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
834890286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
834990286Sobrien  "or{l}\t{%2, %0|%0, %2}"
835090286Sobrien  [(set_attr "type" "alu")
835190286Sobrien   (set_attr "mode" "SI")])
835250650Sobrien
835390286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
835490286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
835590286Sobrien(define_insn "*iorsi_2_zext"
835690286Sobrien  [(set (reg 17)
835790286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
835890286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
835990286Sobrien		 (const_int 0)))
836090286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
836190286Sobrien	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
836290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
836390286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
836490286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
836590286Sobrien  [(set_attr "type" "alu")
836690286Sobrien   (set_attr "mode" "SI")])
836750650Sobrien
836890286Sobrien(define_insn "*iorsi_2_zext_imm"
836990286Sobrien  [(set (reg 17)
837090286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
837190286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
837290286Sobrien		 (const_int 0)))
837390286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
837490286Sobrien	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
837590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
837690286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
837790286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
837890286Sobrien  [(set_attr "type" "alu")
837990286Sobrien   (set_attr "mode" "SI")])
838050650Sobrien
838190286Sobrien(define_insn "*iorsi_3"
838290286Sobrien  [(set (reg 17)
838390286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
838490286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
838590286Sobrien		 (const_int 0)))
838690286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
838790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
838890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
838990286Sobrien  "or{l}\t{%2, %0|%0, %2}"
839090286Sobrien  [(set_attr "type" "alu")
839190286Sobrien   (set_attr "mode" "SI")])
839250650Sobrien
839390286Sobrien(define_expand "iorhi3"
839490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
839590286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
839690286Sobrien		(match_operand:HI 2 "general_operand" "")))
839790286Sobrien   (clobber (reg:CC 17))]
839890286Sobrien  "TARGET_HIMODE_MATH"
839990286Sobrien  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
840050650Sobrien
840190286Sobrien(define_insn "*iorhi_1"
840290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
840390286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
840490286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
840590286Sobrien   (clobber (reg:CC 17))]
840690286Sobrien  "ix86_binary_operator_ok (IOR, HImode, operands)"
840790286Sobrien  "or{w}\t{%2, %0|%0, %2}"
840890286Sobrien  [(set_attr "type" "alu")
840990286Sobrien   (set_attr "mode" "HI")])
841018334Speter
841190286Sobrien(define_insn "*iorhi_2"
841290286Sobrien  [(set (reg 17)
841390286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
841490286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
841590286Sobrien		 (const_int 0)))
841690286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
841790286Sobrien	(ior:HI (match_dup 1) (match_dup 2)))]
841890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
841990286Sobrien   && ix86_binary_operator_ok (IOR, HImode, operands)"
842090286Sobrien  "or{w}\t{%2, %0|%0, %2}"
842190286Sobrien  [(set_attr "type" "alu")
842290286Sobrien   (set_attr "mode" "HI")])
842318334Speter
842490286Sobrien(define_insn "*iorhi_3"
842590286Sobrien  [(set (reg 17)
842690286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
842790286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
842890286Sobrien		 (const_int 0)))
842990286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
843090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
843190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
843290286Sobrien  "or{w}\t{%2, %0|%0, %2}"
843390286Sobrien  [(set_attr "type" "alu")
843490286Sobrien   (set_attr "mode" "HI")])
843550650Sobrien
843690286Sobrien(define_expand "iorqi3"
843790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
843890286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
843990286Sobrien		(match_operand:QI 2 "general_operand" "")))
844090286Sobrien   (clobber (reg:CC 17))]
844190286Sobrien  "TARGET_QIMODE_MATH"
844290286Sobrien  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
844318334Speter
844490286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
844590286Sobrien(define_insn "*iorqi_1"
844690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
844790286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
844890286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
844990286Sobrien   (clobber (reg:CC 17))]
845090286Sobrien  "ix86_binary_operator_ok (IOR, QImode, operands)"
845190286Sobrien  "@
845290286Sobrien   or{b}\t{%2, %0|%0, %2}
845390286Sobrien   or{b}\t{%2, %0|%0, %2}
845490286Sobrien   or{l}\t{%k2, %k0|%k0, %k2}"
845590286Sobrien  [(set_attr "type" "alu")
845690286Sobrien   (set_attr "mode" "QI,QI,SI")])
845750650Sobrien
845890286Sobrien(define_insn "*iorqi_1_slp"
845990286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
846090286Sobrien	(ior:QI (match_dup 0)
846190286Sobrien		(match_operand:QI 1 "general_operand" "qmi,qi")))
846290286Sobrien   (clobber (reg:CC 17))]
8463117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8464117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
846590286Sobrien  "or{b}\t{%1, %0|%0, %1}"
846690286Sobrien  [(set_attr "type" "alu1")
846790286Sobrien   (set_attr "mode" "QI")])
846818334Speter
846990286Sobrien(define_insn "*iorqi_2"
847090286Sobrien  [(set (reg 17)
847190286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
847290286Sobrien			 (match_operand:QI 2 "general_operand" "qim,qi"))
847390286Sobrien		 (const_int 0)))
847490286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
847590286Sobrien	(ior:QI (match_dup 1) (match_dup 2)))]
847690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
847790286Sobrien   && ix86_binary_operator_ok (IOR, QImode, operands)"
847890286Sobrien  "or{b}\t{%2, %0|%0, %2}"
847990286Sobrien  [(set_attr "type" "alu")
848090286Sobrien   (set_attr "mode" "QI")])
848118334Speter
848290286Sobrien(define_insn "*iorqi_2_slp"
848390286Sobrien  [(set (reg 17)
848490286Sobrien	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
848590286Sobrien			 (match_operand:QI 1 "general_operand" "qim,qi"))
848690286Sobrien		 (const_int 0)))
848790286Sobrien   (set (strict_low_part (match_dup 0))
848890286Sobrien	(ior:QI (match_dup 0) (match_dup 1)))]
8489117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8490117404Skan   && ix86_match_ccmode (insn, CCNOmode)
8491117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
849290286Sobrien  "or{b}\t{%1, %0|%0, %1}"
849390286Sobrien  [(set_attr "type" "alu1")
849490286Sobrien   (set_attr "mode" "QI")])
849518334Speter
849690286Sobrien(define_insn "*iorqi_3"
849790286Sobrien  [(set (reg 17)
849890286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
849990286Sobrien			 (match_operand:QI 2 "general_operand" "qim"))
850090286Sobrien		 (const_int 0)))
850190286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
850290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
850390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
850490286Sobrien  "or{b}\t{%2, %0|%0, %2}"
850590286Sobrien  [(set_attr "type" "alu")
850690286Sobrien   (set_attr "mode" "QI")])
850718334Speter
8508117404Skan(define_insn "iorqi_ext_0"
8509117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8510117404Skan			 (const_int 8)
8511117404Skan			 (const_int 8))
8512117404Skan	(ior:SI 
8513117404Skan	  (zero_extract:SI
8514117404Skan	    (match_operand 1 "ext_register_operand" "0")
8515117404Skan	    (const_int 8)
8516117404Skan	    (const_int 8))
8517117404Skan	  (match_operand 2 "const_int_operand" "n")))
8518117404Skan   (clobber (reg:CC 17))]
8519117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8520117404Skan  "or{b}\t{%2, %h0|%h0, %2}"
8521117404Skan  [(set_attr "type" "alu")
8522117404Skan   (set_attr "length_immediate" "1")
8523117404Skan   (set_attr "mode" "QI")])
8524117404Skan
8525117404Skan(define_insn "*iorqi_ext_1"
8526117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8527117404Skan			 (const_int 8)
8528117404Skan			 (const_int 8))
8529117404Skan	(ior:SI 
8530117404Skan	  (zero_extract:SI
8531117404Skan	    (match_operand 1 "ext_register_operand" "0")
8532117404Skan	    (const_int 8)
8533117404Skan	    (const_int 8))
8534117404Skan	  (zero_extend:SI
8535117404Skan	    (match_operand:QI 2 "general_operand" "Qm"))))
8536117404Skan   (clobber (reg:CC 17))]
8537117404Skan  "!TARGET_64BIT
8538117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8539117404Skan  "or{b}\t{%2, %h0|%h0, %2}"
8540117404Skan  [(set_attr "type" "alu")
8541117404Skan   (set_attr "length_immediate" "0")
8542117404Skan   (set_attr "mode" "QI")])
8543117404Skan
8544117404Skan(define_insn "*iorqi_ext_1_rex64"
8545117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8546117404Skan			 (const_int 8)
8547117404Skan			 (const_int 8))
8548117404Skan	(ior:SI 
8549117404Skan	  (zero_extract:SI
8550117404Skan	    (match_operand 1 "ext_register_operand" "0")
8551117404Skan	    (const_int 8)
8552117404Skan	    (const_int 8))
8553117404Skan	  (zero_extend:SI
8554117404Skan	    (match_operand 2 "ext_register_operand" "Q"))))
8555117404Skan   (clobber (reg:CC 17))]
8556117404Skan  "TARGET_64BIT
8557117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8558117404Skan  "or{b}\t{%2, %h0|%h0, %2}"
8559117404Skan  [(set_attr "type" "alu")
8560117404Skan   (set_attr "length_immediate" "0")
8561117404Skan   (set_attr "mode" "QI")])
8562117404Skan
8563117404Skan(define_insn "*iorqi_ext_2"
8564117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8565117404Skan			 (const_int 8)
8566117404Skan			 (const_int 8))
8567117404Skan	(ior:SI 
8568117404Skan	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8569117404Skan	  		   (const_int 8)
8570117404Skan			   (const_int 8))
8571117404Skan	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8572117404Skan	  		   (const_int 8)
8573117404Skan			   (const_int 8))))
8574117404Skan   (clobber (reg:CC 17))]
8575117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8576117404Skan  "ior{b}\t{%h2, %h0|%h0, %h2}"
8577117404Skan  [(set_attr "type" "alu")
8578117404Skan   (set_attr "length_immediate" "0")
8579117404Skan   (set_attr "mode" "QI")])
8580117404Skan
8581117404Skan(define_split
8582117404Skan  [(set (match_operand 0 "register_operand" "")
8583117404Skan	(ior (match_operand 1 "register_operand" "")
8584117404Skan	     (match_operand 2 "const_int_operand" "")))
8585117404Skan   (clobber (reg:CC 17))]
8586117404Skan   "reload_completed
8587117404Skan    && QI_REG_P (operands[0])
8588117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8589117404Skan    && !(INTVAL (operands[2]) & ~(255 << 8))
8590117404Skan    && GET_MODE (operands[0]) != QImode"
8591117404Skan  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8592117404Skan		   (ior:SI (zero_extract:SI (match_dup 1)
8593117404Skan					    (const_int 8) (const_int 8))
8594117404Skan			   (match_dup 2)))
8595117404Skan	      (clobber (reg:CC 17))])]
8596117404Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
8597117404Skan   operands[1] = gen_lowpart (SImode, operands[1]);
8598117404Skan   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8599117404Skan
8600117404Skan;; Since OR can be encoded with sign extended immediate, this is only
8601117404Skan;; profitable when 7th bit is set.
8602117404Skan(define_split
8603117404Skan  [(set (match_operand 0 "register_operand" "")
8604117404Skan	(ior (match_operand 1 "general_operand" "")
8605117404Skan	     (match_operand 2 "const_int_operand" "")))
8606117404Skan   (clobber (reg:CC 17))]
8607117404Skan   "reload_completed
8608117404Skan    && ANY_QI_REG_P (operands[0])
8609117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8610117404Skan    && !(INTVAL (operands[2]) & ~255)
8611117404Skan    && (INTVAL (operands[2]) & 128)
8612117404Skan    && GET_MODE (operands[0]) != QImode"
8613117404Skan  [(parallel [(set (strict_low_part (match_dup 0))
8614117404Skan		   (ior:QI (match_dup 1)
8615117404Skan			   (match_dup 2)))
8616117404Skan	      (clobber (reg:CC 17))])]
8617117404Skan  "operands[0] = gen_lowpart (QImode, operands[0]);
8618117404Skan   operands[1] = gen_lowpart (QImode, operands[1]);
8619117404Skan   operands[2] = gen_lowpart (QImode, operands[2]);")
862090286Sobrien
862190286Sobrien;; Logical XOR instructions
862290286Sobrien
862390286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
862490286Sobrien;; If this is considered useful, it should be done with splitters.
862590286Sobrien
862690286Sobrien(define_expand "xordi3"
862790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
862890286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
862990286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
863090286Sobrien   (clobber (reg:CC 17))]
863190286Sobrien  "TARGET_64BIT"
863290286Sobrien  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
863390286Sobrien
863490286Sobrien(define_insn "*xordi_1_rex64"
863590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
863690286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
863790286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
863890286Sobrien   (clobber (reg:CC 17))]
863990286Sobrien  "TARGET_64BIT
864090286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
864190286Sobrien  "@
864290286Sobrien   xor{q}\t{%2, %0|%0, %2} 
864390286Sobrien   xor{q}\t{%2, %0|%0, %2}"
864490286Sobrien  [(set_attr "type" "alu")
864590286Sobrien   (set_attr "mode" "DI,DI")])
864690286Sobrien
864790286Sobrien(define_insn "*xordi_2_rex64"
864890286Sobrien  [(set (reg 17)
864990286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
865090286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
865190286Sobrien		 (const_int 0)))
865290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
865390286Sobrien	(xor:DI (match_dup 1) (match_dup 2)))]
865490286Sobrien  "TARGET_64BIT
865590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
865690286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
865790286Sobrien  "@
865890286Sobrien   xor{q}\t{%2, %0|%0, %2} 
865990286Sobrien   xor{q}\t{%2, %0|%0, %2}"
866090286Sobrien  [(set_attr "type" "alu")
866190286Sobrien   (set_attr "mode" "DI,DI")])
866290286Sobrien
866390286Sobrien(define_insn "*xordi_3_rex64"
866490286Sobrien  [(set (reg 17)
866590286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
866690286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
866790286Sobrien		 (const_int 0)))
866890286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
866990286Sobrien  "TARGET_64BIT
867090286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
867190286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
867290286Sobrien  "xor{q}\t{%2, %0|%0, %2}"
867390286Sobrien  [(set_attr "type" "alu")
867490286Sobrien   (set_attr "mode" "DI")])
867590286Sobrien
867690286Sobrien(define_expand "xorsi3"
867790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
867890286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
867990286Sobrien		(match_operand:SI 2 "general_operand" "")))
868090286Sobrien   (clobber (reg:CC 17))]
868118334Speter  ""
868290286Sobrien  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
868318334Speter
868490286Sobrien(define_insn "*xorsi_1"
868590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
868690286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
868790286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm")))
868890286Sobrien   (clobber (reg:CC 17))]
868990286Sobrien  "ix86_binary_operator_ok (XOR, SImode, operands)"
869090286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
869190286Sobrien  [(set_attr "type" "alu")
869290286Sobrien   (set_attr "mode" "SI")])
869318334Speter
869490286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
869590286Sobrien;; Add speccase for immediates
869690286Sobrien(define_insn "*xorsi_1_zext"
869790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
869890286Sobrien	(zero_extend:DI
869990286Sobrien	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
870090286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
870190286Sobrien   (clobber (reg:CC 17))]
870290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
870390286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
870490286Sobrien  [(set_attr "type" "alu")
870590286Sobrien   (set_attr "mode" "SI")])
870650650Sobrien
870790286Sobrien(define_insn "*xorsi_1_zext_imm"
870890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
870990286Sobrien	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
871090286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
871190286Sobrien   (clobber (reg:CC 17))]
871290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
871390286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
871490286Sobrien  [(set_attr "type" "alu")
871590286Sobrien   (set_attr "mode" "SI")])
871650650Sobrien
871790286Sobrien(define_insn "*xorsi_2"
871890286Sobrien  [(set (reg 17)
871990286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
872090286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
872190286Sobrien		 (const_int 0)))
872290286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
872390286Sobrien	(xor:SI (match_dup 1) (match_dup 2)))]
872490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
872590286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
872690286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
872790286Sobrien  [(set_attr "type" "alu")
872890286Sobrien   (set_attr "mode" "SI")])
872950650Sobrien
873090286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
873190286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
873290286Sobrien(define_insn "*xorsi_2_zext"
873390286Sobrien  [(set (reg 17)
873490286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
873590286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
873690286Sobrien		 (const_int 0)))
873790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
873890286Sobrien	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
873990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
874090286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
874190286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
874290286Sobrien  [(set_attr "type" "alu")
874390286Sobrien   (set_attr "mode" "SI")])
874450650Sobrien
874590286Sobrien(define_insn "*xorsi_2_zext_imm"
874690286Sobrien  [(set (reg 17)
874790286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
874890286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
874990286Sobrien		 (const_int 0)))
875090286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
875190286Sobrien	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
875290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
875390286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
875490286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
875590286Sobrien  [(set_attr "type" "alu")
875690286Sobrien   (set_attr "mode" "SI")])
875750650Sobrien
875890286Sobrien(define_insn "*xorsi_3"
875990286Sobrien  [(set (reg 17)
876090286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
876190286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
876290286Sobrien		 (const_int 0)))
876390286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
876490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
876590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
876690286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
876790286Sobrien  [(set_attr "type" "alu")
876890286Sobrien   (set_attr "mode" "SI")])
876918334Speter
877090286Sobrien(define_expand "xorhi3"
877190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
877290286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
877390286Sobrien		(match_operand:HI 2 "general_operand" "")))
877490286Sobrien   (clobber (reg:CC 17))]
877590286Sobrien  "TARGET_HIMODE_MATH"
877690286Sobrien  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
877718334Speter
877890286Sobrien(define_insn "*xorhi_1"
877990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
878090286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
878190286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
878290286Sobrien   (clobber (reg:CC 17))]
878390286Sobrien  "ix86_binary_operator_ok (XOR, HImode, operands)"
878490286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
878590286Sobrien  [(set_attr "type" "alu")
878690286Sobrien   (set_attr "mode" "HI")])
878718334Speter
878890286Sobrien(define_insn "*xorhi_2"
878990286Sobrien  [(set (reg 17)
879090286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
879190286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
879290286Sobrien		 (const_int 0)))
879390286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
879490286Sobrien	(xor:HI (match_dup 1) (match_dup 2)))]
879590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
879690286Sobrien   && ix86_binary_operator_ok (XOR, HImode, operands)"
879790286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
879890286Sobrien  [(set_attr "type" "alu")
879990286Sobrien   (set_attr "mode" "HI")])
880050650Sobrien
880190286Sobrien(define_insn "*xorhi_3"
880290286Sobrien  [(set (reg 17)
880390286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
880490286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
880590286Sobrien		 (const_int 0)))
880690286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
880790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
880890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
880990286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
881090286Sobrien  [(set_attr "type" "alu")
881190286Sobrien   (set_attr "mode" "HI")])
881250650Sobrien
881390286Sobrien(define_expand "xorqi3"
881490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
881590286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
881690286Sobrien		(match_operand:QI 2 "general_operand" "")))
881790286Sobrien   (clobber (reg:CC 17))]
881890286Sobrien  "TARGET_QIMODE_MATH"
881990286Sobrien  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
882050650Sobrien
882190286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
882290286Sobrien(define_insn "*xorqi_1"
882390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
882490286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
882590286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
882690286Sobrien   (clobber (reg:CC 17))]
882790286Sobrien  "ix86_binary_operator_ok (XOR, QImode, operands)"
882890286Sobrien  "@
882990286Sobrien   xor{b}\t{%2, %0|%0, %2}
883090286Sobrien   xor{b}\t{%2, %0|%0, %2}
883190286Sobrien   xor{l}\t{%k2, %k0|%k0, %k2}"
883290286Sobrien  [(set_attr "type" "alu")
883390286Sobrien   (set_attr "mode" "QI,QI,SI")])
883418334Speter
8835117404Skan(define_insn "*xorqi_1_slp"
8836117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8837117404Skan	(xor:QI (match_dup 0)
8838117404Skan		(match_operand:QI 1 "general_operand" "qi,qmi")))
8839117404Skan   (clobber (reg:CC 17))]
8840117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8841117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8842117404Skan  "xor{b}\t{%1, %0|%0, %1}"
8843117404Skan  [(set_attr "type" "alu1")
8844117404Skan   (set_attr "mode" "QI")])
8845117404Skan
8846117404Skan(define_insn "xorqi_ext_0"
8847117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8848117404Skan			 (const_int 8)
8849117404Skan			 (const_int 8))
8850117404Skan	(xor:SI 
8851117404Skan	  (zero_extract:SI
8852117404Skan	    (match_operand 1 "ext_register_operand" "0")
8853117404Skan	    (const_int 8)
8854117404Skan	    (const_int 8))
8855117404Skan	  (match_operand 2 "const_int_operand" "n")))
8856117404Skan   (clobber (reg:CC 17))]
8857117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8858117404Skan  "xor{b}\t{%2, %h0|%h0, %2}"
8859117404Skan  [(set_attr "type" "alu")
8860117404Skan   (set_attr "length_immediate" "1")
8861117404Skan   (set_attr "mode" "QI")])
8862117404Skan
886390286Sobrien(define_insn "*xorqi_ext_1"
886490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
886590286Sobrien			 (const_int 8)
886690286Sobrien			 (const_int 8))
886790286Sobrien	(xor:SI 
8868117404Skan	  (zero_extract:SI
8869117404Skan	    (match_operand 1 "ext_register_operand" "0")
8870117404Skan	    (const_int 8)
8871117404Skan	    (const_int 8))
8872117404Skan	  (zero_extend:SI
8873117404Skan	    (match_operand:QI 2 "general_operand" "Qm"))))
8874117404Skan   (clobber (reg:CC 17))]
8875117404Skan  "!TARGET_64BIT
8876117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8877117404Skan  "xor{b}\t{%2, %h0|%h0, %2}"
8878117404Skan  [(set_attr "type" "alu")
8879117404Skan   (set_attr "length_immediate" "0")
8880117404Skan   (set_attr "mode" "QI")])
8881117404Skan
8882117404Skan(define_insn "*xorqi_ext_1_rex64"
8883117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8884117404Skan			 (const_int 8)
8885117404Skan			 (const_int 8))
8886117404Skan	(xor:SI 
8887117404Skan	  (zero_extract:SI
8888117404Skan	    (match_operand 1 "ext_register_operand" "0")
8889117404Skan	    (const_int 8)
8890117404Skan	    (const_int 8))
8891117404Skan	  (zero_extend:SI
8892117404Skan	    (match_operand 2 "ext_register_operand" "Q"))))
8893117404Skan   (clobber (reg:CC 17))]
8894117404Skan  "TARGET_64BIT
8895117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8896117404Skan  "xor{b}\t{%2, %h0|%h0, %2}"
8897117404Skan  [(set_attr "type" "alu")
8898117404Skan   (set_attr "length_immediate" "0")
8899117404Skan   (set_attr "mode" "QI")])
8900117404Skan
8901117404Skan(define_insn "*xorqi_ext_2"
8902117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8903117404Skan			 (const_int 8)
8904117404Skan			 (const_int 8))
8905117404Skan	(xor:SI 
890690286Sobrien	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
890790286Sobrien	  		   (const_int 8)
890890286Sobrien			   (const_int 8))
890990286Sobrien	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
891090286Sobrien	  		   (const_int 8)
891190286Sobrien			   (const_int 8))))
891290286Sobrien   (clobber (reg:CC 17))]
8913117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
891490286Sobrien  "xor{b}\t{%h2, %h0|%h0, %h2}"
891590286Sobrien  [(set_attr "type" "alu")
891690286Sobrien   (set_attr "length_immediate" "0")
891790286Sobrien   (set_attr "mode" "QI")])
891850650Sobrien
891990286Sobrien(define_insn "*xorqi_cc_1"
892090286Sobrien  [(set (reg 17)
892190286Sobrien	(compare
892290286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
892390286Sobrien		  (match_operand:QI 2 "general_operand" "qim,qi"))
892490286Sobrien	  (const_int 0)))
892590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
892690286Sobrien	(xor:QI (match_dup 1) (match_dup 2)))]
892790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
892890286Sobrien   && ix86_binary_operator_ok (XOR, QImode, operands)"
892990286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
893090286Sobrien  [(set_attr "type" "alu")
893190286Sobrien   (set_attr "mode" "QI")])
893250650Sobrien
8933117404Skan(define_insn "*xorqi_2_slp"
8934117404Skan  [(set (reg 17)
8935117404Skan	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8936117404Skan			 (match_operand:QI 1 "general_operand" "qim,qi"))
8937117404Skan		 (const_int 0)))
8938117404Skan   (set (strict_low_part (match_dup 0))
8939117404Skan	(xor:QI (match_dup 0) (match_dup 1)))]
8940117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8941117404Skan   && ix86_match_ccmode (insn, CCNOmode)
8942117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8943117404Skan  "xor{b}\t{%1, %0|%0, %1}"
8944117404Skan  [(set_attr "type" "alu1")
8945117404Skan   (set_attr "mode" "QI")])
8946117404Skan
894790286Sobrien(define_insn "*xorqi_cc_2"
894890286Sobrien  [(set (reg 17)
894990286Sobrien	(compare
895090286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
895190286Sobrien		  (match_operand:QI 2 "general_operand" "qim"))
895290286Sobrien	  (const_int 0)))
895390286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
895490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
895590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
895690286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
895790286Sobrien  [(set_attr "type" "alu")
895890286Sobrien   (set_attr "mode" "QI")])
895918334Speter
896090286Sobrien(define_insn "*xorqi_cc_ext_1"
896190286Sobrien  [(set (reg 17)
896290286Sobrien	(compare
896390286Sobrien	  (xor:SI
896490286Sobrien	    (zero_extract:SI
896590286Sobrien	      (match_operand 1 "ext_register_operand" "0")
896690286Sobrien	      (const_int 8)
896790286Sobrien	      (const_int 8))
896890286Sobrien	    (match_operand:QI 2 "general_operand" "qmn"))
896990286Sobrien	  (const_int 0)))
897090286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
897190286Sobrien			 (const_int 8)
897290286Sobrien			 (const_int 8))
897390286Sobrien	(xor:SI 
897490286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
897590286Sobrien	  (match_dup 2)))]
897690286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
897790286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
897890286Sobrien  [(set_attr "type" "alu")
897990286Sobrien   (set_attr "mode" "QI")])
898090286Sobrien
898190286Sobrien(define_insn "*xorqi_cc_ext_1_rex64"
898290286Sobrien  [(set (reg 17)
898390286Sobrien	(compare
898490286Sobrien	  (xor:SI
898590286Sobrien	    (zero_extract:SI
898690286Sobrien	      (match_operand 1 "ext_register_operand" "0")
898790286Sobrien	      (const_int 8)
898890286Sobrien	      (const_int 8))
898990286Sobrien	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
899090286Sobrien	  (const_int 0)))
899190286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
899290286Sobrien			 (const_int 8)
899390286Sobrien			 (const_int 8))
899490286Sobrien	(xor:SI 
899590286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
899690286Sobrien	  (match_dup 2)))]
899790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
899890286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
899990286Sobrien  [(set_attr "type" "alu")
900090286Sobrien   (set_attr "mode" "QI")])
900190286Sobrien
900290286Sobrien(define_expand "xorqi_cc_ext_1"
900390286Sobrien  [(parallel [
900490286Sobrien     (set (reg:CCNO 17)
900590286Sobrien	  (compare:CCNO
900690286Sobrien	    (xor:SI
900790286Sobrien	      (zero_extract:SI
900890286Sobrien		(match_operand 1 "ext_register_operand" "")
900990286Sobrien		(const_int 8)
901090286Sobrien		(const_int 8))
901190286Sobrien	      (match_operand:QI 2 "general_operand" ""))
901290286Sobrien	    (const_int 0)))
901390286Sobrien     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
901490286Sobrien			   (const_int 8)
901590286Sobrien			   (const_int 8))
901690286Sobrien	  (xor:SI 
901790286Sobrien	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
901890286Sobrien	    (match_dup 2)))])]
901918334Speter  ""
902090286Sobrien  "")
9021117404Skan
9022117404Skan(define_split
9023117404Skan  [(set (match_operand 0 "register_operand" "")
9024117404Skan	(xor (match_operand 1 "register_operand" "")
9025117404Skan	     (match_operand 2 "const_int_operand" "")))
9026117404Skan   (clobber (reg:CC 17))]
9027117404Skan   "reload_completed
9028117404Skan    && QI_REG_P (operands[0])
9029117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9030117404Skan    && !(INTVAL (operands[2]) & ~(255 << 8))
9031117404Skan    && GET_MODE (operands[0]) != QImode"
9032117404Skan  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9033117404Skan		   (xor:SI (zero_extract:SI (match_dup 1)
9034117404Skan					    (const_int 8) (const_int 8))
9035117404Skan			   (match_dup 2)))
9036117404Skan	      (clobber (reg:CC 17))])]
9037117404Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
9038117404Skan   operands[1] = gen_lowpart (SImode, operands[1]);
9039117404Skan   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9040117404Skan
9041117404Skan;; Since XOR can be encoded with sign extended immediate, this is only
9042117404Skan;; profitable when 7th bit is set.
9043117404Skan(define_split
9044117404Skan  [(set (match_operand 0 "register_operand" "")
9045117404Skan	(xor (match_operand 1 "general_operand" "")
9046117404Skan	     (match_operand 2 "const_int_operand" "")))
9047117404Skan   (clobber (reg:CC 17))]
9048117404Skan   "reload_completed
9049117404Skan    && ANY_QI_REG_P (operands[0])
9050117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9051117404Skan    && !(INTVAL (operands[2]) & ~255)
9052117404Skan    && (INTVAL (operands[2]) & 128)
9053117404Skan    && GET_MODE (operands[0]) != QImode"
9054117404Skan  [(parallel [(set (strict_low_part (match_dup 0))
9055117404Skan		   (xor:QI (match_dup 1)
9056117404Skan			   (match_dup 2)))
9057117404Skan	      (clobber (reg:CC 17))])]
9058117404Skan  "operands[0] = gen_lowpart (QImode, operands[0]);
9059117404Skan   operands[1] = gen_lowpart (QImode, operands[1]);
9060117404Skan   operands[2] = gen_lowpart (QImode, operands[2]);")
906118334Speter
906290286Sobrien;; Negation instructions
906318334Speter
906490286Sobrien(define_expand "negdi2"
906590286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
906690286Sobrien		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
906790286Sobrien	      (clobber (reg:CC 17))])]
906818334Speter  ""
906990286Sobrien  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
907050650Sobrien
907190286Sobrien(define_insn "*negdi2_1"
907290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
907390286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "0")))
907490286Sobrien   (clobber (reg:CC 17))]
907590286Sobrien  "!TARGET_64BIT
907690286Sobrien   && ix86_unary_operator_ok (NEG, DImode, operands)"
907790286Sobrien  "#")
907850650Sobrien
907990286Sobrien(define_split
908090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
908190286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "")))
908290286Sobrien   (clobber (reg:CC 17))]
908390286Sobrien  "!TARGET_64BIT && reload_completed"
908490286Sobrien  [(parallel
908590286Sobrien    [(set (reg:CCZ 17)
908690286Sobrien	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
908790286Sobrien     (set (match_dup 0) (neg:SI (match_dup 2)))])
908890286Sobrien   (parallel
908990286Sobrien    [(set (match_dup 1)
909090286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
909190286Sobrien			    (match_dup 3))
909290286Sobrien		   (const_int 0)))
909390286Sobrien     (clobber (reg:CC 17))])
909490286Sobrien   (parallel
909590286Sobrien    [(set (match_dup 1)
909690286Sobrien	  (neg:SI (match_dup 1)))
909790286Sobrien     (clobber (reg:CC 17))])]
909890286Sobrien  "split_di (operands+1, 1, operands+2, operands+3);
909990286Sobrien   split_di (operands+0, 1, operands+0, operands+1);")
910050650Sobrien
910190286Sobrien(define_insn "*negdi2_1_rex64"
910290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
910390286Sobrien	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
910490286Sobrien   (clobber (reg:CC 17))]
910590286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
910690286Sobrien  "neg{q}\t%0"
910790286Sobrien  [(set_attr "type" "negnot")
910890286Sobrien   (set_attr "mode" "DI")])
910950650Sobrien
911090286Sobrien;; The problem with neg is that it does not perform (compare x 0),
911190286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
911290286Sobrien;; flag being the only useful item.
911350650Sobrien
911490286Sobrien(define_insn "*negdi2_cmpz_rex64"
911590286Sobrien  [(set (reg:CCZ 17)
911690286Sobrien	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
911790286Sobrien		     (const_int 0)))
911890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
911990286Sobrien	(neg:DI (match_dup 1)))]
912090286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
912190286Sobrien  "neg{q}\t%0"
912290286Sobrien  [(set_attr "type" "negnot")
912390286Sobrien   (set_attr "mode" "DI")])
912450650Sobrien
912518334Speter
912690286Sobrien(define_expand "negsi2"
912790286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
912890286Sobrien		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
912990286Sobrien	      (clobber (reg:CC 17))])]
913090286Sobrien  ""
913190286Sobrien  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
913218334Speter
913390286Sobrien(define_insn "*negsi2_1"
913490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
913590286Sobrien	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
913690286Sobrien   (clobber (reg:CC 17))]
913790286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
913890286Sobrien  "neg{l}\t%0"
913990286Sobrien  [(set_attr "type" "negnot")
914090286Sobrien   (set_attr "mode" "SI")])
914150650Sobrien
914290286Sobrien;; Combine is quite creative about this pattern.
914390286Sobrien(define_insn "*negsi2_1_zext"
914490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
914590286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
914690286Sobrien					(const_int 32)))
914790286Sobrien		     (const_int 32)))
914890286Sobrien   (clobber (reg:CC 17))]
914990286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
915090286Sobrien  "neg{l}\t%k0"
915190286Sobrien  [(set_attr "type" "negnot")
915290286Sobrien   (set_attr "mode" "SI")])
915350650Sobrien
915490286Sobrien;; The problem with neg is that it does not perform (compare x 0),
915590286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
915690286Sobrien;; flag being the only useful item.
915718334Speter
915890286Sobrien(define_insn "*negsi2_cmpz"
915990286Sobrien  [(set (reg:CCZ 17)
916090286Sobrien	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
916190286Sobrien		     (const_int 0)))
916290286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
916390286Sobrien	(neg:SI (match_dup 1)))]
916490286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
916590286Sobrien  "neg{l}\t%0"
916690286Sobrien  [(set_attr "type" "negnot")
916790286Sobrien   (set_attr "mode" "SI")])
916850650Sobrien
916990286Sobrien(define_insn "*negsi2_cmpz_zext"
917090286Sobrien  [(set (reg:CCZ 17)
917190286Sobrien	(compare:CCZ (lshiftrt:DI
917290286Sobrien		       (neg:DI (ashift:DI
917390286Sobrien				 (match_operand:DI 1 "register_operand" "0")
917490286Sobrien				 (const_int 32)))
917590286Sobrien		       (const_int 32))
917690286Sobrien		     (const_int 0)))
917790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
917890286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
917990286Sobrien					(const_int 32)))
918090286Sobrien		     (const_int 32)))]
918190286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
918290286Sobrien  "neg{l}\t%k0"
918390286Sobrien  [(set_attr "type" "negnot")
918490286Sobrien   (set_attr "mode" "SI")])
918590286Sobrien
918690286Sobrien(define_expand "neghi2"
918790286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
918890286Sobrien		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
918990286Sobrien	      (clobber (reg:CC 17))])]
919090286Sobrien  "TARGET_HIMODE_MATH"
919190286Sobrien  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
919290286Sobrien
919390286Sobrien(define_insn "*neghi2_1"
919490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
919590286Sobrien	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
919690286Sobrien   (clobber (reg:CC 17))]
919790286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
919890286Sobrien  "neg{w}\t%0"
919990286Sobrien  [(set_attr "type" "negnot")
920090286Sobrien   (set_attr "mode" "HI")])
920190286Sobrien
920290286Sobrien(define_insn "*neghi2_cmpz"
920390286Sobrien  [(set (reg:CCZ 17)
920490286Sobrien	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
920590286Sobrien		     (const_int 0)))
920690286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
920790286Sobrien	(neg:HI (match_dup 1)))]
920890286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
920990286Sobrien  "neg{w}\t%0"
921090286Sobrien  [(set_attr "type" "negnot")
921190286Sobrien   (set_attr "mode" "HI")])
921290286Sobrien
921390286Sobrien(define_expand "negqi2"
921490286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
921590286Sobrien		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
921690286Sobrien	      (clobber (reg:CC 17))])]
921790286Sobrien  "TARGET_QIMODE_MATH"
921890286Sobrien  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
921990286Sobrien
922090286Sobrien(define_insn "*negqi2_1"
922190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
922290286Sobrien	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
922390286Sobrien   (clobber (reg:CC 17))]
922490286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
922590286Sobrien  "neg{b}\t%0"
922690286Sobrien  [(set_attr "type" "negnot")
922790286Sobrien   (set_attr "mode" "QI")])
922890286Sobrien
922990286Sobrien(define_insn "*negqi2_cmpz"
923090286Sobrien  [(set (reg:CCZ 17)
923190286Sobrien	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
923290286Sobrien		     (const_int 0)))
923390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
923490286Sobrien	(neg:QI (match_dup 1)))]
923590286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
923690286Sobrien  "neg{b}\t%0"
923790286Sobrien  [(set_attr "type" "negnot")
923890286Sobrien   (set_attr "mode" "QI")])
923990286Sobrien
924090286Sobrien;; Changing of sign for FP values is doable using integer unit too.
924190286Sobrien
924290286Sobrien(define_expand "negsf2"
924390286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
924490286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
924590286Sobrien	      (clobber (reg:CC 17))])]
924690286Sobrien  "TARGET_80387"
924790286Sobrien  "if (TARGET_SSE)
924890286Sobrien     {
924990286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
925090286Sobrien       if (memory_operand (operands[0], VOIDmode)
925190286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
925290286Sobrien	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
925390286Sobrien       else
925418334Speter	{
925590286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
925690286Sobrien	     in register.  */
925790286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
925890286Sobrien	  rtx dest = operands[0];
925918334Speter
926090286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
926190286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
926290286Sobrien	  emit_move_insn (reg,
926390286Sobrien			  gen_lowpart (SFmode,
9264117404Skan				       gen_int_mode (0x80000000, SImode)));
926590286Sobrien	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
926690286Sobrien	  if (dest != operands[0])
926790286Sobrien	    emit_move_insn (dest, operands[0]);
926850650Sobrien	}
926990286Sobrien       DONE;
927090286Sobrien     }
927190286Sobrien   ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
927218334Speter
927390286Sobrien(define_insn "negsf2_memory"
927490286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
927590286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
927690286Sobrien   (clobber (reg:CC 17))]
927790286Sobrien  "ix86_unary_operator_ok (NEG, SFmode, operands)"
927890286Sobrien  "#")
927918334Speter
928090286Sobrien(define_insn "negsf2_ifs"
928190286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
928290286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
928390286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
928490286Sobrien   (clobber (reg:CC 17))]
928590286Sobrien  "TARGET_SSE
928690286Sobrien   && (reload_in_progress || reload_completed
928790286Sobrien       || (register_operand (operands[0], VOIDmode)
928890286Sobrien	   && register_operand (operands[1], VOIDmode)))"
928990286Sobrien  "#")
929018334Speter
929190286Sobrien(define_split
929290286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
929390286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "")))
929490286Sobrien   (use (match_operand:SF 2 "" ""))
929590286Sobrien   (clobber (reg:CC 17))]
929618334Speter  ""
929790286Sobrien  [(parallel [(set (match_dup 0)
929890286Sobrien		   (neg:SF (match_dup 1)))
929990286Sobrien	      (clobber (reg:CC 17))])])
930090286Sobrien
930190286Sobrien(define_split
930290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
930390286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
930490286Sobrien   (use (match_operand:SF 2 "" ""))
930590286Sobrien   (clobber (reg:CC 17))]
930690286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
930790286Sobrien  [(parallel [(set (match_dup 0)
930890286Sobrien		   (neg:SF (match_dup 1)))
930990286Sobrien	      (clobber (reg:CC 17))])])
931090286Sobrien
931190286Sobrien(define_split
931290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
931390286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
931490286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
931590286Sobrien   (clobber (reg:CC 17))]
931690286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
931790286Sobrien  [(set (subreg:TI (match_dup 0) 0)
931890286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
931990286Sobrien		(subreg:TI (match_dup 2) 0)))]
932018334Speter{
932190286Sobrien  if (operands_match_p (operands[0], operands[2]))
932218334Speter    {
932390286Sobrien      rtx tmp;
932490286Sobrien      tmp = operands[1];
932590286Sobrien      operands[1] = operands[2];
932690286Sobrien      operands[2] = tmp;
932790286Sobrien    }
932890286Sobrien})
932918334Speter
933018334Speter
933190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
933290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
933390286Sobrien;; to itself.
933490286Sobrien(define_insn "*negsf2_if"
933590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
933690286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
933790286Sobrien   (clobber (reg:CC 17))]
933890286Sobrien  "TARGET_80387 && !TARGET_SSE
933990286Sobrien   && ix86_unary_operator_ok (NEG, SFmode, operands)"
934090286Sobrien  "#")
934118334Speter
934290286Sobrien(define_split
9343117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
934490286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
934590286Sobrien   (clobber (reg:CC 17))]
9346117404Skan  "TARGET_80387 && reload_completed"
934790286Sobrien  [(set (match_dup 0)
934890286Sobrien	(neg:SF (match_dup 1)))]
934990286Sobrien  "")
935090286Sobrien
935190286Sobrien(define_split
9352117404Skan  [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
935390286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
935490286Sobrien   (clobber (reg:CC 17))]
9355117404Skan  "TARGET_80387 && reload_completed"
935690286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
935790286Sobrien	      (clobber (reg:CC 17))])]
9358117404Skan  "operands[1] = gen_int_mode (0x80000000, SImode);
935990286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
936090286Sobrien
936190286Sobrien(define_split
936290286Sobrien  [(set (match_operand 0 "memory_operand" "")
936390286Sobrien	(neg (match_operand 1 "memory_operand" "")))
936490286Sobrien   (clobber (reg:CC 17))]
936590286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
936690286Sobrien  [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
936790286Sobrien	      (clobber (reg:CC 17))])]
936890286Sobrien{
936990286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
937090286Sobrien
937190286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
937290286Sobrien  if (size >= 12)
937390286Sobrien    size = 10;
937490286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
9375117404Skan  operands[1] = gen_int_mode (0x80, QImode);
937690286Sobrien})
937790286Sobrien
937890286Sobrien(define_expand "negdf2"
937990286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
938090286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
938190286Sobrien	      (clobber (reg:CC 17))])]
938290286Sobrien  "TARGET_80387"
938390286Sobrien  "if (TARGET_SSE2)
938490286Sobrien     {
938590286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
938690286Sobrien       if (memory_operand (operands[0], VOIDmode)
938790286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
938890286Sobrien	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
938990286Sobrien       else
939018334Speter	{
939190286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
939290286Sobrien	     in register.  */
939390286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
939490286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
9395117404Skan	  rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
939690286Sobrien#else
939790286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
939890286Sobrien#endif
939990286Sobrien	  rtx dest = operands[0];
940018334Speter
940190286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
940290286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
940390286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
940490286Sobrien	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
940590286Sobrien	  if (dest != operands[0])
940690286Sobrien	    emit_move_insn (dest, operands[0]);
940718334Speter	}
940890286Sobrien       DONE;
940990286Sobrien     }
941090286Sobrien   ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
941118334Speter
941290286Sobrien(define_insn "negdf2_memory"
941390286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
941490286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
941590286Sobrien   (clobber (reg:CC 17))]
941690286Sobrien  "ix86_unary_operator_ok (NEG, DFmode, operands)"
941790286Sobrien  "#")
941850650Sobrien
941990286Sobrien(define_insn "negdf2_ifs"
942090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
942190286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
942290286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
942390286Sobrien   (clobber (reg:CC 17))]
942490286Sobrien  "!TARGET_64BIT && TARGET_SSE2
942590286Sobrien   && (reload_in_progress || reload_completed
942690286Sobrien       || (register_operand (operands[0], VOIDmode)
942790286Sobrien	   && register_operand (operands[1], VOIDmode)))"
942890286Sobrien  "#")
942950650Sobrien
943090286Sobrien(define_insn "*negdf2_ifs_rex64"
9431117404Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9432117404Skan	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#f,0")))
9433117404Skan   (use (match_operand:DF 2 "general_operand" "Y,0,*g#Y*r"))
943490286Sobrien   (clobber (reg:CC 17))]
943590286Sobrien  "TARGET_64BIT && TARGET_SSE2
943690286Sobrien   && (reload_in_progress || reload_completed
943790286Sobrien       || (register_operand (operands[0], VOIDmode)
943890286Sobrien	   && register_operand (operands[1], VOIDmode)))"
943990286Sobrien  "#")
944018334Speter
944190286Sobrien(define_split
944290286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
944390286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "")))
944490286Sobrien   (use (match_operand:DF 2 "" ""))
944590286Sobrien   (clobber (reg:CC 17))]
944618334Speter  ""
944790286Sobrien  [(parallel [(set (match_dup 0)
944890286Sobrien		   (neg:DF (match_dup 1)))
944990286Sobrien	      (clobber (reg:CC 17))])])
945050650Sobrien
945190286Sobrien(define_split
945290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
945390286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
945490286Sobrien   (use (match_operand:DF 2 "" ""))
945590286Sobrien   (clobber (reg:CC 17))]
945690286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
945790286Sobrien   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
945890286Sobrien  [(parallel [(set (match_dup 0)
945990286Sobrien		   (neg:DF (match_dup 1)))
946090286Sobrien	      (clobber (reg:CC 17))])])
946150650Sobrien
946290286Sobrien(define_split
946390286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
946490286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
946590286Sobrien   (use (match_operand:DF 2 "" ""))
946690286Sobrien   (clobber (reg:CC 17))]
946790286Sobrien  "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
946890286Sobrien  [(parallel [(set (match_dup 0)
946990286Sobrien		   (xor:DI (match_dup 1) (match_dup 2)))
947090286Sobrien	      (clobber (reg:CC 17))])]
947190286Sobrien   "operands[0] = gen_lowpart (DImode, operands[0]);
947290286Sobrien    operands[1] = gen_lowpart (DImode, operands[1]);
947390286Sobrien    operands[2] = gen_lowpart (DImode, operands[2]);")
947452296Sobrien
947590286Sobrien(define_split
947690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
947790286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
947890286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
947990286Sobrien   (clobber (reg:CC 17))]
948090286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
948190286Sobrien  [(set (subreg:TI (match_dup 0) 0)
948290286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
948390286Sobrien		(subreg:TI (match_dup 2) 0)))]
948490286Sobrien{
948590286Sobrien  if (operands_match_p (operands[0], operands[2]))
948690286Sobrien    {
948790286Sobrien      rtx tmp;
948890286Sobrien      tmp = operands[1];
948990286Sobrien      operands[1] = operands[2];
949090286Sobrien      operands[2] = tmp;
949190286Sobrien    }
949290286Sobrien})
949352296Sobrien
949490286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
949590286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
949690286Sobrien;; to itself.
949790286Sobrien(define_insn "*negdf2_if"
949890286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
949990286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
950090286Sobrien   (clobber (reg:CC 17))]
950190286Sobrien  "!TARGET_64BIT && TARGET_80387
950290286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
950390286Sobrien  "#")
950450650Sobrien
950590286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
950690286Sobrien;; we need another scratch register to get constant from.
950790286Sobrien;; Forcing constant to mem if no register available in peep2 should be
950890286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
950990286Sobrien(define_insn "*negdf2_if_rex64"
951090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
951190286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
951290286Sobrien   (clobber (reg:CC 17))]
951390286Sobrien  "TARGET_64BIT && TARGET_80387
951490286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
951590286Sobrien  "#")
951690286Sobrien
951750650Sobrien(define_split
9518117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
951990286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
952090286Sobrien   (clobber (reg:CC 17))]
9521117404Skan  "TARGET_80387 && reload_completed"
952290286Sobrien  [(set (match_dup 0)
952390286Sobrien	(neg:DF (match_dup 1)))]
952490286Sobrien  "")
952550650Sobrien
952690286Sobrien(define_split
9527117404Skan  [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
952890286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
952990286Sobrien   (clobber (reg:CC 17))]
9530117404Skan  "!TARGET_64BIT && TARGET_80387 && reload_completed"
953190286Sobrien  [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
953290286Sobrien	      (clobber (reg:CC 17))])]
9533117404Skan  "operands[4] = gen_int_mode (0x80000000, SImode);
953490286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
953518334Speter
953690286Sobrien(define_expand "negxf2"
953790286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
953890286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
953990286Sobrien	      (clobber (reg:CC 17))])]
954090286Sobrien  "!TARGET_64BIT && TARGET_80387"
954190286Sobrien  "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
954218334Speter
954390286Sobrien(define_expand "negtf2"
954490286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
954590286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
954690286Sobrien	      (clobber (reg:CC 17))])]
954790286Sobrien  "TARGET_80387"
954890286Sobrien  "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
954918334Speter
955090286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
955190286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
955290286Sobrien;; to itself.
955390286Sobrien(define_insn "*negxf2_if"
955490286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
955590286Sobrien	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
955690286Sobrien   (clobber (reg:CC 17))]
955790286Sobrien  "!TARGET_64BIT && TARGET_80387
955890286Sobrien   && ix86_unary_operator_ok (NEG, XFmode, operands)"
955990286Sobrien  "#")
956018334Speter
956190286Sobrien(define_split
9562117404Skan  [(set (match_operand:XF 0 "fp_register_operand" "")
956390286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
956490286Sobrien   (clobber (reg:CC 17))]
9565117404Skan  "TARGET_80387 && reload_completed"
956690286Sobrien  [(set (match_dup 0)
956790286Sobrien	(neg:XF (match_dup 1)))]
956890286Sobrien  "")
956918334Speter
957090286Sobrien(define_split
9571117404Skan  [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
957290286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
957390286Sobrien   (clobber (reg:CC 17))]
9574117404Skan  "TARGET_80387 && reload_completed"
957590286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
957690286Sobrien	      (clobber (reg:CC 17))])]
957790286Sobrien  "operands[1] = GEN_INT (0x8000);
957890286Sobrien   operands[0] = gen_rtx_REG (SImode,
957990286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
958018334Speter
958190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
958290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
958390286Sobrien;; to itself.
958490286Sobrien(define_insn "*negtf2_if"
958590286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
958690286Sobrien	(neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
958790286Sobrien   (clobber (reg:CC 17))]
958890286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
958990286Sobrien  "#")
959018334Speter
959190286Sobrien(define_split
9592117404Skan  [(set (match_operand:TF 0 "fp_register_operand" "")
959390286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
959490286Sobrien   (clobber (reg:CC 17))]
9595117404Skan  "TARGET_80387 && reload_completed"
959690286Sobrien  [(set (match_dup 0)
959790286Sobrien	(neg:TF (match_dup 1)))]
959890286Sobrien  "")
959918334Speter
960090286Sobrien(define_split
9601117404Skan  [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
960290286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
960390286Sobrien   (clobber (reg:CC 17))]
9604117404Skan  "TARGET_80387 && reload_completed"
960590286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
960690286Sobrien	      (clobber (reg:CC 17))])]
960790286Sobrien  "operands[1] = GEN_INT (0x8000);
960890286Sobrien   operands[0] = gen_rtx_REG (SImode,
960990286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
961090286Sobrien
961190286Sobrien;; Conditionize these after reload. If they matches before reload, we 
961290286Sobrien;; lose the clobber and ability to use integer instructions.
961390286Sobrien
961490286Sobrien(define_insn "*negsf2_1"
961518334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
961650650Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
961790286Sobrien  "TARGET_80387 && reload_completed"
961852296Sobrien  "fchs"
961990286Sobrien  [(set_attr "type" "fsgn")
962090286Sobrien   (set_attr "mode" "SF")
962190286Sobrien   (set_attr "ppro_uops" "few")])
962218334Speter
962390286Sobrien(define_insn "*negdf2_1"
962418334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
962550650Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
962690286Sobrien  "TARGET_80387 && reload_completed"
962752296Sobrien  "fchs"
962890286Sobrien  [(set_attr "type" "fsgn")
962990286Sobrien   (set_attr "mode" "DF")
963090286Sobrien   (set_attr "ppro_uops" "few")])
963118334Speter
963290286Sobrien(define_insn "*negextendsfdf2"
963318334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
963490286Sobrien	(neg:DF (float_extend:DF
963590286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
963618334Speter  "TARGET_80387"
963752296Sobrien  "fchs"
963890286Sobrien  [(set_attr "type" "fsgn")
963990286Sobrien   (set_attr "mode" "DF")
964090286Sobrien   (set_attr "ppro_uops" "few")])
964118334Speter
964290286Sobrien(define_insn "*negxf2_1"
964318334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
964450650Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
964590286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
964652296Sobrien  "fchs"
964790286Sobrien  [(set_attr "type" "fsgn")
964890286Sobrien   (set_attr "mode" "XF")
964990286Sobrien   (set_attr "ppro_uops" "few")])
965018334Speter
965190286Sobrien(define_insn "*negextenddfxf2"
965218334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
965390286Sobrien	(neg:XF (float_extend:XF
965490286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
965590286Sobrien  "!TARGET_64BIT && TARGET_80387"
965690286Sobrien  "fchs"
965790286Sobrien  [(set_attr "type" "fsgn")
965890286Sobrien   (set_attr "mode" "XF")
965990286Sobrien   (set_attr "ppro_uops" "few")])
966090286Sobrien
966190286Sobrien(define_insn "*negextendsfxf2"
966290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
966390286Sobrien	(neg:XF (float_extend:XF
966490286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
966590286Sobrien  "!TARGET_64BIT && TARGET_80387"
966690286Sobrien  "fchs"
966790286Sobrien  [(set_attr "type" "fsgn")
966890286Sobrien   (set_attr "mode" "XF")
966990286Sobrien   (set_attr "ppro_uops" "few")])
967090286Sobrien
967190286Sobrien(define_insn "*negtf2_1"
967290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
967390286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "0")))]
967490286Sobrien  "TARGET_80387 && reload_completed"
967590286Sobrien  "fchs"
967690286Sobrien  [(set_attr "type" "fsgn")
967790286Sobrien   (set_attr "mode" "XF")
967890286Sobrien   (set_attr "ppro_uops" "few")])
967990286Sobrien
968090286Sobrien(define_insn "*negextenddftf2"
968190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
968290286Sobrien	(neg:TF (float_extend:TF
968390286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
968418334Speter  "TARGET_80387"
968552296Sobrien  "fchs"
968690286Sobrien  [(set_attr "type" "fsgn")
968790286Sobrien   (set_attr "mode" "XF")
968890286Sobrien   (set_attr "ppro_uops" "few")])
968990286Sobrien
969090286Sobrien(define_insn "*negextendsftf2"
969190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
969290286Sobrien	(neg:TF (float_extend:TF
969390286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
969490286Sobrien  "TARGET_80387"
969590286Sobrien  "fchs"
969690286Sobrien  [(set_attr "type" "fsgn")
969790286Sobrien   (set_attr "mode" "XF")
969890286Sobrien   (set_attr "ppro_uops" "few")])
969918334Speter
970018334Speter;; Absolute value instructions
970118334Speter
970290286Sobrien(define_expand "abssf2"
970390286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
970490286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
970590286Sobrien	      (clobber (reg:CC 17))])]
970690286Sobrien  "TARGET_80387"
970790286Sobrien  "if (TARGET_SSE)
970890286Sobrien     {
970990286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
971090286Sobrien       if (memory_operand (operands[0], VOIDmode)
971190286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
971290286Sobrien	 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
971390286Sobrien       else
971490286Sobrien	{
971590286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
971690286Sobrien	     in register.  */
971790286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
971890286Sobrien	  rtx dest = operands[0];
971990286Sobrien
972090286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
972190286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
972290286Sobrien	  emit_move_insn (reg,
972390286Sobrien			  gen_lowpart (SFmode,
9724117404Skan				       gen_int_mode (0x80000000, SImode)));
972590286Sobrien	  emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
972690286Sobrien	  if (dest != operands[0])
972790286Sobrien	    emit_move_insn (dest, operands[0]);
972890286Sobrien	}
972990286Sobrien       DONE;
973090286Sobrien     }
973190286Sobrien   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
973290286Sobrien
973390286Sobrien(define_insn "abssf2_memory"
973490286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
973590286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "0")))
973690286Sobrien   (clobber (reg:CC 17))]
973790286Sobrien  "ix86_unary_operator_ok (ABS, SFmode, operands)"
973890286Sobrien  "#")
973990286Sobrien
974090286Sobrien(define_insn "abssf2_ifs"
974190286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
974290286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
974390286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
974490286Sobrien   (clobber (reg:CC 17))]
974590286Sobrien  "TARGET_SSE
974690286Sobrien   && (reload_in_progress || reload_completed
974790286Sobrien       || (register_operand (operands[0], VOIDmode)
974890286Sobrien	   && register_operand (operands[1], VOIDmode)))"
974990286Sobrien  "#")
975090286Sobrien
975190286Sobrien(define_split
975290286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
975390286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "")))
975490286Sobrien   (use (match_operand:SF 2 "" ""))
975590286Sobrien   (clobber (reg:CC 17))]
975690286Sobrien  ""
975790286Sobrien  [(parallel [(set (match_dup 0)
975890286Sobrien		   (abs:SF (match_dup 1)))
975990286Sobrien	      (clobber (reg:CC 17))])])
976090286Sobrien
976190286Sobrien(define_split
976290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
976390286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
976490286Sobrien   (use (match_operand:SF 2 "" ""))
976590286Sobrien   (clobber (reg:CC 17))]
976690286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
976790286Sobrien  [(parallel [(set (match_dup 0)
976890286Sobrien		   (abs:SF (match_dup 1)))
976990286Sobrien	      (clobber (reg:CC 17))])])
977090286Sobrien
977190286Sobrien(define_split
977290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
977390286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
977490286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
977590286Sobrien   (clobber (reg:CC 17))]
977690286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
977790286Sobrien  [(set (subreg:TI (match_dup 0) 0)
977890286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
977990286Sobrien		(subreg:TI (match_dup 1) 0)))])
978090286Sobrien
978190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
978290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
978390286Sobrien;; to itself.
978490286Sobrien(define_insn "*abssf2_if"
978590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
978690286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
978790286Sobrien   (clobber (reg:CC 17))]
978890286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
978990286Sobrien  "#")
979090286Sobrien
979190286Sobrien(define_split
9792117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
979390286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
979490286Sobrien   (clobber (reg:CC 17))]
9795117404Skan  "TARGET_80387"
979690286Sobrien  [(set (match_dup 0)
979790286Sobrien	(abs:SF (match_dup 1)))]
979890286Sobrien  "")
979990286Sobrien
980090286Sobrien(define_split
9801117404Skan  [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
980290286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
980390286Sobrien   (clobber (reg:CC 17))]
9804117404Skan  "TARGET_80387 && reload_completed"
980590286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
980690286Sobrien	      (clobber (reg:CC 17))])]
9807117404Skan  "operands[1] = gen_int_mode (~0x80000000, SImode);
980890286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
980990286Sobrien
981090286Sobrien(define_split
981190286Sobrien  [(set (match_operand 0 "memory_operand" "")
981290286Sobrien	(abs (match_operand 1 "memory_operand" "")))
981390286Sobrien   (clobber (reg:CC 17))]
981490286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
981590286Sobrien  [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
981690286Sobrien	      (clobber (reg:CC 17))])]
981790286Sobrien{
981890286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
981990286Sobrien
982090286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
982190286Sobrien  if (size >= 12)
982290286Sobrien    size = 10;
982390286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
9824117404Skan  operands[1] = gen_int_mode (~0x80, QImode);
982590286Sobrien})
982690286Sobrien
982790286Sobrien(define_expand "absdf2"
982890286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
982990286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
983090286Sobrien	      (clobber (reg:CC 17))])]
983190286Sobrien  "TARGET_80387"
983290286Sobrien  "if (TARGET_SSE2)
983390286Sobrien     {
983490286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
983590286Sobrien       if (memory_operand (operands[0], VOIDmode)
983690286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
983790286Sobrien	 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
983890286Sobrien       else
983990286Sobrien	{
984090286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
984190286Sobrien	     in register.  */
984290286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
984390286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
9844117404Skan	  rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
984590286Sobrien#else
984690286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
984790286Sobrien#endif
984890286Sobrien	  rtx dest = operands[0];
984990286Sobrien
985090286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
985190286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
985290286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
985390286Sobrien	  emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
985490286Sobrien	  if (dest != operands[0])
985590286Sobrien	    emit_move_insn (dest, operands[0]);
985690286Sobrien	}
985790286Sobrien       DONE;
985890286Sobrien     }
985990286Sobrien   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
986090286Sobrien
986190286Sobrien(define_insn "absdf2_memory"
986290286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
986390286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "0")))
986490286Sobrien   (clobber (reg:CC 17))]
986590286Sobrien  "ix86_unary_operator_ok (ABS, DFmode, operands)"
986690286Sobrien  "#")
986790286Sobrien
986890286Sobrien(define_insn "absdf2_ifs"
986990286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
987090286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
987190286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
987290286Sobrien   (clobber (reg:CC 17))]
987390286Sobrien  "!TARGET_64BIT && TARGET_SSE2
987490286Sobrien   && (reload_in_progress || reload_completed
987590286Sobrien       || (register_operand (operands[0], VOIDmode)
987690286Sobrien	   && register_operand (operands[1], VOIDmode)))"
987790286Sobrien  "#")
987890286Sobrien
987990286Sobrien(define_insn "*absdf2_ifs_rex64"
988090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
988190286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
988290286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
988390286Sobrien   (clobber (reg:CC 17))]
988490286Sobrien  "TARGET_64BIT && TARGET_SSE2
988590286Sobrien   && (reload_in_progress || reload_completed
988690286Sobrien       || (register_operand (operands[0], VOIDmode)
988790286Sobrien	   && register_operand (operands[1], VOIDmode)))"
988890286Sobrien  "#")
988990286Sobrien
989090286Sobrien(define_split
989190286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
989290286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "")))
989390286Sobrien   (use (match_operand:DF 2 "" ""))
989490286Sobrien   (clobber (reg:CC 17))]
989590286Sobrien  ""
989690286Sobrien  [(parallel [(set (match_dup 0)
989790286Sobrien		   (abs:DF (match_dup 1)))
989890286Sobrien	      (clobber (reg:CC 17))])])
989990286Sobrien
990090286Sobrien(define_split
990190286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
990290286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
990390286Sobrien   (use (match_operand:DF 2 "" ""))
990490286Sobrien   (clobber (reg:CC 17))]
990590286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
990690286Sobrien  [(parallel [(set (match_dup 0)
990790286Sobrien		   (abs:DF (match_dup 1)))
990890286Sobrien	      (clobber (reg:CC 17))])])
990990286Sobrien
991090286Sobrien(define_split
991190286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
991290286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
991390286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
991490286Sobrien   (clobber (reg:CC 17))]
991590286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
991690286Sobrien  [(set (subreg:TI (match_dup 0) 0)
991790286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
991890286Sobrien		(subreg:TI (match_dup 1) 0)))])
991990286Sobrien
992090286Sobrien
992190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
992290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
992390286Sobrien;; to itself.
992490286Sobrien(define_insn "*absdf2_if"
992590286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
992690286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
992790286Sobrien   (clobber (reg:CC 17))]
992890286Sobrien  "!TARGET_64BIT && TARGET_80387
992990286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
993090286Sobrien  "#")
993190286Sobrien
993290286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
993390286Sobrien;; we need another scratch register to get constant from.
993490286Sobrien;; Forcing constant to mem if no register available in peep2 should be
993590286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
993690286Sobrien(define_insn "*absdf2_if_rex64"
993790286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
993890286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
993990286Sobrien   (clobber (reg:CC 17))]
994090286Sobrien  "TARGET_64BIT && TARGET_80387
994190286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
994290286Sobrien  "#")
994390286Sobrien
994490286Sobrien(define_split
9945117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
994690286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
994790286Sobrien   (clobber (reg:CC 17))]
9948117404Skan  "TARGET_80387 && reload_completed"
994990286Sobrien  [(set (match_dup 0)
995090286Sobrien	(abs:DF (match_dup 1)))]
995190286Sobrien  "")
995290286Sobrien
995390286Sobrien(define_split
9954117404Skan  [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
995590286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
995690286Sobrien   (clobber (reg:CC 17))]
9957117404Skan  "!TARGET_64BIT && TARGET_80387 && reload_completed"
995890286Sobrien  [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
995990286Sobrien	      (clobber (reg:CC 17))])]
9960117404Skan  "operands[4] = gen_int_mode (~0x80000000, SImode);
996190286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
996290286Sobrien
996390286Sobrien(define_expand "absxf2"
996490286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
996590286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
996690286Sobrien	      (clobber (reg:CC 17))])]
996790286Sobrien  "!TARGET_64BIT && TARGET_80387"
996890286Sobrien  "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
996990286Sobrien
997090286Sobrien(define_expand "abstf2"
997190286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
997290286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
997390286Sobrien	      (clobber (reg:CC 17))])]
997490286Sobrien  "TARGET_80387"
997590286Sobrien  "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
997690286Sobrien
997790286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
997890286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
997990286Sobrien;; to itself.
998090286Sobrien(define_insn "*absxf2_if"
998190286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
998290286Sobrien	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
998390286Sobrien   (clobber (reg:CC 17))]
998490286Sobrien  "!TARGET_64BIT && TARGET_80387
998590286Sobrien   && ix86_unary_operator_ok (ABS, XFmode, operands)"
998690286Sobrien  "#")
998790286Sobrien
998890286Sobrien(define_split
9989117404Skan  [(set (match_operand:XF 0 "fp_register_operand" "")
999090286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
999190286Sobrien   (clobber (reg:CC 17))]
9992117404Skan  "TARGET_80387 && reload_completed"
999390286Sobrien  [(set (match_dup 0)
999490286Sobrien	(abs:XF (match_dup 1)))]
999590286Sobrien  "")
999690286Sobrien
999790286Sobrien(define_split
9998117404Skan  [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
999990286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1000090286Sobrien   (clobber (reg:CC 17))]
10001117404Skan  "TARGET_80387 && reload_completed"
1000290286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1000390286Sobrien	      (clobber (reg:CC 17))])]
1000490286Sobrien  "operands[1] = GEN_INT (~0x8000);
1000590286Sobrien   operands[0] = gen_rtx_REG (SImode,
1000690286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1000790286Sobrien
1000890286Sobrien(define_insn "*abstf2_if"
1000990286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
1001090286Sobrien	(abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
1001190286Sobrien   (clobber (reg:CC 17))]
1001290286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
1001390286Sobrien  "#")
1001490286Sobrien
1001590286Sobrien(define_split
10016117404Skan  [(set (match_operand:TF 0 "fp_register_operand" "")
1001790286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1001890286Sobrien   (clobber (reg:CC 17))]
10019117404Skan  "TARGET_80387 && reload_completed"
1002090286Sobrien  [(set (match_dup 0)
1002190286Sobrien	(abs:TF (match_dup 1)))]
1002290286Sobrien  "")
1002390286Sobrien
1002490286Sobrien(define_split
10025117404Skan  [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
1002690286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1002790286Sobrien   (clobber (reg:CC 17))]
10028117404Skan  "TARGET_80387 && reload_completed"
1002990286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1003090286Sobrien	      (clobber (reg:CC 17))])]
1003190286Sobrien  "operands[1] = GEN_INT (~0x8000);
1003290286Sobrien   operands[0] = gen_rtx_REG (SImode,
1003390286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1003490286Sobrien
1003590286Sobrien(define_insn "*abssf2_1"
1003618334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
1003750650Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
1003890286Sobrien  "TARGET_80387 && reload_completed"
1003950650Sobrien  "fabs"
1004090286Sobrien  [(set_attr "type" "fsgn")
1004190286Sobrien   (set_attr "mode" "SF")])
1004218334Speter
1004390286Sobrien(define_insn "*absdf2_1"
1004418334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1004550650Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
1004690286Sobrien  "TARGET_80387 && reload_completed"
1004750650Sobrien  "fabs"
1004890286Sobrien  [(set_attr "type" "fsgn")
1004990286Sobrien   (set_attr "mode" "DF")])
1005018334Speter
1005190286Sobrien(define_insn "*absextendsfdf2"
1005218334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1005390286Sobrien	(abs:DF (float_extend:DF
1005490286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1005518334Speter  "TARGET_80387"
1005650650Sobrien  "fabs"
1005790286Sobrien  [(set_attr "type" "fsgn")
1005890286Sobrien   (set_attr "mode" "DF")])
1005918334Speter
1006090286Sobrien(define_insn "*absxf2_1"
1006118334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1006250650Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
1006390286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
1006450650Sobrien  "fabs"
1006590286Sobrien  [(set_attr "type" "fsgn")
1006690286Sobrien   (set_attr "mode" "DF")])
1006718334Speter
1006890286Sobrien(define_insn "*absextenddfxf2"
1006918334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1007090286Sobrien	(abs:XF (float_extend:XF
1007190286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1007290286Sobrien  "!TARGET_64BIT && TARGET_80387"
1007350650Sobrien  "fabs"
1007490286Sobrien  [(set_attr "type" "fsgn")
1007590286Sobrien   (set_attr "mode" "XF")])
1007618334Speter
1007790286Sobrien(define_insn "*absextendsfxf2"
1007890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1007990286Sobrien	(abs:XF (float_extend:XF
1008090286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1008190286Sobrien  "!TARGET_64BIT && TARGET_80387"
1008290286Sobrien  "fabs"
1008390286Sobrien  [(set_attr "type" "fsgn")
1008490286Sobrien   (set_attr "mode" "XF")])
1008518334Speter
1008690286Sobrien(define_insn "*abstf2_1"
1008790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1008890286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "0")))]
1008990286Sobrien  "TARGET_80387 && reload_completed"
1009090286Sobrien  "fabs"
1009190286Sobrien  [(set_attr "type" "fsgn")
1009290286Sobrien   (set_attr "mode" "DF")])
1009318334Speter
1009490286Sobrien(define_insn "*absextenddftf2"
1009590286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1009690286Sobrien	(abs:TF (float_extend:TF
1009790286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1009890286Sobrien  "TARGET_80387"
1009990286Sobrien  "fabs"
1010090286Sobrien  [(set_attr "type" "fsgn")
1010190286Sobrien   (set_attr "mode" "XF")])
1010218334Speter
1010390286Sobrien(define_insn "*absextendsftf2"
1010490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1010590286Sobrien	(abs:TF (float_extend:TF
1010690286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1010790286Sobrien  "TARGET_80387"
1010890286Sobrien  "fabs"
1010990286Sobrien  [(set_attr "type" "fsgn")
1011090286Sobrien   (set_attr "mode" "XF")])
1011190286Sobrien
1011290286Sobrien;; One complement instructions
1011318334Speter
1011490286Sobrien(define_expand "one_cmpldi2"
1011590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1011690286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
1011790286Sobrien  "TARGET_64BIT"
1011890286Sobrien  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
1011918334Speter
1012090286Sobrien(define_insn "*one_cmpldi2_1_rex64"
1012190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1012290286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
1012390286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
1012490286Sobrien  "not{q}\t%0"
1012590286Sobrien  [(set_attr "type" "negnot")
1012690286Sobrien   (set_attr "mode" "DI")])
1012718334Speter
1012890286Sobrien(define_insn "*one_cmpldi2_2_rex64"
1012990286Sobrien  [(set (reg 17)
1013090286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
1013190286Sobrien		 (const_int 0)))
1013290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1013390286Sobrien	(not:DI (match_dup 1)))]
1013490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1013590286Sobrien   && ix86_unary_operator_ok (NOT, DImode, operands)"
1013690286Sobrien  "#"
1013790286Sobrien  [(set_attr "type" "alu1")
1013890286Sobrien   (set_attr "mode" "DI")])
1013918334Speter
1014090286Sobrien(define_split
1014190286Sobrien  [(set (reg 17)
1014290286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
1014390286Sobrien		 (const_int 0)))
1014490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "")
1014590286Sobrien	(not:DI (match_dup 1)))]
1014690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1014790286Sobrien  [(parallel [(set (reg:CCNO 17)
1014890286Sobrien		   (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
1014990286Sobrien				 (const_int 0)))
1015090286Sobrien	      (set (match_dup 0)
1015190286Sobrien		   (xor:DI (match_dup 1) (const_int -1)))])]
1015290286Sobrien  "")
1015318334Speter
1015490286Sobrien(define_expand "one_cmplsi2"
1015590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1015690286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1015790286Sobrien  ""
1015890286Sobrien  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
1015918334Speter
1016090286Sobrien(define_insn "*one_cmplsi2_1"
1016190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1016290286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
1016390286Sobrien  "ix86_unary_operator_ok (NOT, SImode, operands)"
1016490286Sobrien  "not{l}\t%0"
1016590286Sobrien  [(set_attr "type" "negnot")
1016690286Sobrien   (set_attr "mode" "SI")])
1016718334Speter
1016890286Sobrien;; ??? Currently never generated - xor is used instead.
1016990286Sobrien(define_insn "*one_cmplsi2_1_zext"
1017090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1017190286Sobrien	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
1017290286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
1017390286Sobrien  "not{l}\t%k0"
1017490286Sobrien  [(set_attr "type" "negnot")
1017590286Sobrien   (set_attr "mode" "SI")])
1017618334Speter
1017790286Sobrien(define_insn "*one_cmplsi2_2"
1017890286Sobrien  [(set (reg 17)
1017990286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
1018090286Sobrien		 (const_int 0)))
1018190286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1018290286Sobrien	(not:SI (match_dup 1)))]
1018390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1018490286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1018590286Sobrien  "#"
1018690286Sobrien  [(set_attr "type" "alu1")
1018790286Sobrien   (set_attr "mode" "SI")])
1018818334Speter
1018990286Sobrien(define_split
1019090286Sobrien  [(set (reg 17)
1019190286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
1019290286Sobrien		 (const_int 0)))
1019390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "")
1019490286Sobrien	(not:SI (match_dup 1)))]
1019590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1019690286Sobrien  [(parallel [(set (reg:CCNO 17)
1019790286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1019890286Sobrien				 (const_int 0)))
1019990286Sobrien	      (set (match_dup 0)
1020090286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))])]
1020190286Sobrien  "")
1020218334Speter
1020390286Sobrien;; ??? Currently never generated - xor is used instead.
1020490286Sobrien(define_insn "*one_cmplsi2_2_zext"
1020590286Sobrien  [(set (reg 17)
1020690286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
1020790286Sobrien		 (const_int 0)))
1020890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1020990286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1021090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1021190286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1021290286Sobrien  "#"
1021390286Sobrien  [(set_attr "type" "alu1")
1021490286Sobrien   (set_attr "mode" "SI")])
1021518334Speter
1021690286Sobrien(define_split
1021790286Sobrien  [(set (reg 17)
1021890286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" ""))
1021990286Sobrien		 (const_int 0)))
1022090286Sobrien   (set (match_operand:DI 0 "register_operand" "")
1022190286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1022290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1022390286Sobrien  [(parallel [(set (reg:CCNO 17)
1022490286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1022590286Sobrien				 (const_int 0)))
1022690286Sobrien	      (set (match_dup 0)
1022790286Sobrien		   (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
1022890286Sobrien  "")
1022918334Speter
1023090286Sobrien(define_expand "one_cmplhi2"
1023190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1023290286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1023390286Sobrien  "TARGET_HIMODE_MATH"
1023490286Sobrien  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
1023552296Sobrien
1023690286Sobrien(define_insn "*one_cmplhi2_1"
1023750650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1023850650Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
1023990286Sobrien  "ix86_unary_operator_ok (NOT, HImode, operands)"
1024090286Sobrien  "not{w}\t%0"
1024190286Sobrien  [(set_attr "type" "negnot")
1024290286Sobrien   (set_attr "mode" "HI")])
1024318334Speter
1024490286Sobrien(define_insn "*one_cmplhi2_2"
1024590286Sobrien  [(set (reg 17)
1024690286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
1024790286Sobrien		 (const_int 0)))
1024890286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1024990286Sobrien	(not:HI (match_dup 1)))]
1025090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1025190286Sobrien   && ix86_unary_operator_ok (NEG, HImode, operands)"
1025290286Sobrien  "#"
1025390286Sobrien  [(set_attr "type" "alu1")
1025490286Sobrien   (set_attr "mode" "HI")])
1025552296Sobrien
1025690286Sobrien(define_split
1025790286Sobrien  [(set (reg 17)
1025890286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
1025990286Sobrien		 (const_int 0)))
1026090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "")
1026190286Sobrien	(not:HI (match_dup 1)))]
1026290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1026390286Sobrien  [(parallel [(set (reg:CCNO 17)
1026490286Sobrien		   (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
1026590286Sobrien		      		 (const_int 0)))
1026690286Sobrien	      (set (match_dup 0)
1026790286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))])]
1026890286Sobrien  "")
1026952296Sobrien
1027090286Sobrien;; %%% Potential partial reg stall on alternative 1.  What to do?
1027190286Sobrien(define_expand "one_cmplqi2"
1027290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1027390286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1027490286Sobrien  "TARGET_QIMODE_MATH"
1027590286Sobrien  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
1027690286Sobrien
1027790286Sobrien(define_insn "*one_cmplqi2_1"
1027890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1027990286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
1028090286Sobrien  "ix86_unary_operator_ok (NOT, QImode, operands)"
1028190286Sobrien  "@
1028290286Sobrien   not{b}\t%0
1028390286Sobrien   not{l}\t%k0"
1028490286Sobrien  [(set_attr "type" "negnot")
1028590286Sobrien   (set_attr "mode" "QI,SI")])
1028690286Sobrien
1028790286Sobrien(define_insn "*one_cmplqi2_2"
1028890286Sobrien  [(set (reg 17)
1028990286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
1029090286Sobrien		 (const_int 0)))
1029190286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1029290286Sobrien	(not:QI (match_dup 1)))]
1029390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1029490286Sobrien   && ix86_unary_operator_ok (NOT, QImode, operands)"
1029590286Sobrien  "#"
1029690286Sobrien  [(set_attr "type" "alu1")
1029790286Sobrien   (set_attr "mode" "QI")])
1029890286Sobrien
1029990286Sobrien(define_split
1030090286Sobrien  [(set (reg 17)
1030190286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
1030290286Sobrien		 (const_int 0)))
1030390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "")
1030490286Sobrien	(not:QI (match_dup 1)))]
1030590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1030690286Sobrien  [(parallel [(set (reg:CCNO 17)
1030790286Sobrien		   (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
1030890286Sobrien		      		 (const_int 0)))
1030990286Sobrien	      (set (match_dup 0)
1031090286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))])]
1031190286Sobrien  "")
1031218334Speter
1031390286Sobrien;; Arithmetic shift instructions
1031418334Speter
1031518334Speter;; DImode shifts are implemented using the i386 "shift double" opcode,
1031618334Speter;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
1031718334Speter;; is variable, then the count is in %cl and the "imm" operand is dropped
1031818334Speter;; from the assembler input.
1031990286Sobrien;;
1032018334Speter;; This instruction shifts the target reg/mem as usual, but instead of
1032118334Speter;; shifting in zeros, bits are shifted in from reg operand.  If the insn
1032218334Speter;; is a left shift double, bits are taken from the high order bits of
1032318334Speter;; reg, else if the insn is a shift right double, bits are taken from the
1032418334Speter;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
1032518334Speter;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
1032690286Sobrien;;
1032718334Speter;; Since sh[lr]d does not change the `reg' operand, that is done
1032818334Speter;; separately, making all shifts emit pairs of shift double and normal
1032918334Speter;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
1033018334Speter;; support a 63 bit shift, each shift where the count is in a reg expands
1033150650Sobrien;; to a pair of shifts, a branch, a shift by 32 and a label.
1033290286Sobrien;;
1033318334Speter;; If the shift count is a constant, we need never emit more than one
1033418334Speter;; shift pair, instead using moves and sign extension for counts greater
1033518334Speter;; than 31.
1033618334Speter
1033718334Speter(define_expand "ashldi3"
1033890286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1033990286Sobrien		   (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
1034090286Sobrien			      (match_operand:QI 2 "nonmemory_operand" "")))
1034190286Sobrien	      (clobber (reg:CC 17))])]
1034218334Speter  ""
1034318334Speter{
1034490286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1034518334Speter    {
1034690286Sobrien      emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
1034790286Sobrien      DONE;
1034818334Speter    }
1034990286Sobrien  ix86_expand_binary_operator (ASHIFT, DImode, operands);
1035018334Speter  DONE;
1035190286Sobrien})
1035218334Speter
1035390286Sobrien(define_insn "*ashldi3_1_rex64"
1035490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
1035590286Sobrien	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
1035690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
1035790286Sobrien   (clobber (reg:CC 17))]
1035890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1035918334Speter{
1036090286Sobrien  switch (get_attr_type (insn))
1036190286Sobrien    {
1036290286Sobrien    case TYPE_ALU:
1036390286Sobrien      if (operands[2] != const1_rtx)
1036490286Sobrien	abort ();
1036590286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1036690286Sobrien	abort ();
1036790286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1036818334Speter
1036990286Sobrien    case TYPE_LEA:
1037090286Sobrien      if (GET_CODE (operands[2]) != CONST_INT
1037190286Sobrien	  || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
1037290286Sobrien	abort ();
1037390286Sobrien      operands[1] = gen_rtx_MULT (DImode, operands[1],
1037490286Sobrien				  GEN_INT (1 << INTVAL (operands[2])));
1037590286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
1037618334Speter
1037790286Sobrien    default:
1037890286Sobrien      if (REG_P (operands[2]))
1037990286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1038090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1038190286Sobrien	       && INTVAL (operands[2]) == 1
10382117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1038390286Sobrien	return "sal{q}\t%0";
1038490286Sobrien      else
1038590286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1038690286Sobrien    }
1038790286Sobrien}
1038890286Sobrien  [(set (attr "type")
1038990286Sobrien     (cond [(eq_attr "alternative" "1")
1039090286Sobrien	      (const_string "lea")
1039190286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1039290286Sobrien		          (const_int 0))
1039390286Sobrien		      (match_operand 0 "register_operand" ""))
1039490286Sobrien		 (match_operand 2 "const1_operand" ""))
1039590286Sobrien	      (const_string "alu")
1039690286Sobrien	   ]
1039790286Sobrien	   (const_string "ishift")))
1039890286Sobrien   (set_attr "mode" "DI")])
1039918334Speter
1040090286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1040190286Sobrien(define_split
1040290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1040390286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1040490286Sobrien		   (match_operand:QI 2 "immediate_operand" "")))
1040590286Sobrien   (clobber (reg:CC 17))]
1040690286Sobrien  "TARGET_64BIT && reload_completed
1040790286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1040890286Sobrien  [(set (match_dup 0)
1040990286Sobrien	(mult:DI (match_dup 1)
1041090286Sobrien		 (match_dup 2)))]
10411117404Skan  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
1041290286Sobrien
1041390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1041490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1041590286Sobrien;; zero are optimized away.
1041690286Sobrien(define_insn "*ashldi3_cmp_rex64"
1041790286Sobrien  [(set (reg 17)
1041890286Sobrien	(compare
1041990286Sobrien	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1042090286Sobrien		     (match_operand:QI 2 "immediate_operand" "e"))
1042190286Sobrien	  (const_int 0)))
1042290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1042390286Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))]
1042490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1042590286Sobrien   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1042690286Sobrien{
1042790286Sobrien  switch (get_attr_type (insn))
1042818334Speter    {
1042990286Sobrien    case TYPE_ALU:
1043090286Sobrien      if (operands[2] != const1_rtx)
1043190286Sobrien	abort ();
1043290286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1043318334Speter
1043490286Sobrien    default:
1043590286Sobrien      if (REG_P (operands[2]))
1043690286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1043790286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1043890286Sobrien	       && INTVAL (operands[2]) == 1
10439117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1044090286Sobrien	return "sal{q}\t%0";
1044190286Sobrien      else
1044290286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1044318334Speter    }
1044490286Sobrien}
1044590286Sobrien  [(set (attr "type")
1044690286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1044790286Sobrien		          (const_int 0))
1044890286Sobrien		      (match_operand 0 "register_operand" ""))
1044990286Sobrien		 (match_operand 2 "const1_operand" ""))
1045090286Sobrien	      (const_string "alu")
1045190286Sobrien	   ]
1045290286Sobrien	   (const_string "ishift")))
1045390286Sobrien   (set_attr "mode" "DI")])
1045418334Speter
1045590286Sobrien(define_insn "ashldi3_1"
1045690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1045718334Speter	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1045890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1045990286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1046090286Sobrien   (clobber (reg:CC 17))]
1046190286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1046290286Sobrien  "#"
1046390286Sobrien  [(set_attr "type" "multi")])
1046490286Sobrien
1046590286Sobrien(define_insn "*ashldi3_2"
1046690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1046790286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1046890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1046990286Sobrien   (clobber (reg:CC 17))]
1047090286Sobrien  "!TARGET_64BIT"
1047190286Sobrien  "#"
1047290286Sobrien  [(set_attr "type" "multi")])
1047390286Sobrien
1047490286Sobrien(define_split
1047590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1047690286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1047790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1047890286Sobrien   (clobber (match_scratch:SI 3 ""))
1047990286Sobrien   (clobber (reg:CC 17))]
1048090286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1048190286Sobrien  [(const_int 0)]
1048290286Sobrien  "ix86_split_ashldi (operands, operands[3]); DONE;")
1048390286Sobrien
1048490286Sobrien(define_split
1048590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1048690286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1048790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1048890286Sobrien   (clobber (reg:CC 17))]
1048990286Sobrien  "!TARGET_64BIT && reload_completed"
1049090286Sobrien  [(const_int 0)]
1049190286Sobrien  "ix86_split_ashldi (operands, NULL_RTX); DONE;")
1049290286Sobrien
1049390286Sobrien(define_insn "x86_shld_1"
1049490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1049590286Sobrien        (ior:SI (ashift:SI (match_dup 0)
1049690286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1049790286Sobrien		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1049890286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1049990286Sobrien   (clobber (reg:CC 17))]
1050018334Speter  ""
1050190286Sobrien  "@
1050290286Sobrien   shld{l}\t{%2, %1, %0|%0, %1, %2}
1050390286Sobrien   shld{l}\t{%s2%1, %0|%0, %1, %2}"
1050490286Sobrien  [(set_attr "type" "ishift")
1050590286Sobrien   (set_attr "prefix_0f" "1")
1050690286Sobrien   (set_attr "mode" "SI")
1050790286Sobrien   (set_attr "pent_pair" "np")
1050890286Sobrien   (set_attr "athlon_decode" "vector")
1050990286Sobrien   (set_attr "ppro_uops" "few")])
1051090286Sobrien
1051190286Sobrien(define_expand "x86_shift_adj_1"
1051290286Sobrien  [(set (reg:CCZ 17)
1051390286Sobrien	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
1051490286Sobrien			     (const_int 32))
1051590286Sobrien		     (const_int 0)))
1051690286Sobrien   (set (match_operand:SI 0 "register_operand" "")
1051790286Sobrien        (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1051890286Sobrien			 (match_operand:SI 1 "register_operand" "")
1051990286Sobrien			 (match_dup 0)))
1052090286Sobrien   (set (match_dup 1)
1052190286Sobrien	(if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1052290286Sobrien			 (match_operand:SI 3 "register_operand" "r")
1052390286Sobrien			 (match_dup 1)))]
1052490286Sobrien  "TARGET_CMOVE"
1052590286Sobrien  "")
1052690286Sobrien
1052790286Sobrien(define_expand "x86_shift_adj_2"
1052890286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1052990286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1053090286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1053190286Sobrien  ""
1053218334Speter{
1053390286Sobrien  rtx label = gen_label_rtx ();
1053490286Sobrien  rtx tmp;
1053518334Speter
1053690286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1053718334Speter
1053890286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1053990286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1054090286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1054190286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1054290286Sobrien			      pc_rtx);
1054390286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1054490286Sobrien  JUMP_LABEL (tmp) = label;
1054518334Speter
1054690286Sobrien  emit_move_insn (operands[0], operands[1]);
1054790286Sobrien  emit_move_insn (operands[1], const0_rtx);
1054818334Speter
1054990286Sobrien  emit_label (label);
1055090286Sobrien  LABEL_NUSES (label) = 1;
1055190286Sobrien
1055290286Sobrien  DONE;
1055390286Sobrien})
1055490286Sobrien
1055552296Sobrien(define_expand "ashlsi3"
1055652296Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1055752296Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
1055890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1055990286Sobrien   (clobber (reg:CC 17))]
1056052296Sobrien  ""
1056190286Sobrien  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
1056218334Speter
1056390286Sobrien(define_insn "*ashlsi3_1"
1056490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
1056590286Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
1056690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1056790286Sobrien   (clobber (reg:CC 17))]
1056890286Sobrien  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1056990286Sobrien{
1057090286Sobrien  switch (get_attr_type (insn))
1057190286Sobrien    {
1057290286Sobrien    case TYPE_ALU:
1057390286Sobrien      if (operands[2] != const1_rtx)
1057490286Sobrien	abort ();
1057590286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1057690286Sobrien	abort ();
1057790286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1057890286Sobrien
1057990286Sobrien    case TYPE_LEA:
1058090286Sobrien      return "#";
1058190286Sobrien
1058290286Sobrien    default:
1058390286Sobrien      if (REG_P (operands[2]))
1058490286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1058590286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1058690286Sobrien	       && INTVAL (operands[2]) == 1
10587117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1058890286Sobrien	return "sal{l}\t%0";
1058990286Sobrien      else
1059090286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1059190286Sobrien    }
1059290286Sobrien}
1059390286Sobrien  [(set (attr "type")
1059490286Sobrien     (cond [(eq_attr "alternative" "1")
1059590286Sobrien	      (const_string "lea")
1059690286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1059790286Sobrien		          (const_int 0))
1059890286Sobrien		      (match_operand 0 "register_operand" ""))
1059990286Sobrien		 (match_operand 2 "const1_operand" ""))
1060090286Sobrien	      (const_string "alu")
1060190286Sobrien	   ]
1060290286Sobrien	   (const_string "ishift")))
1060390286Sobrien   (set_attr "mode" "SI")])
1060490286Sobrien
1060590286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1060690286Sobrien(define_split
1060790286Sobrien  [(set (match_operand 0 "register_operand" "")
10608117404Skan	(ashift (match_operand 1 "index_register_operand" "")
1060990286Sobrien                (match_operand:QI 2 "const_int_operand" "")))
1061090286Sobrien   (clobber (reg:CC 17))]
1061190286Sobrien  "reload_completed
1061290286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1061390286Sobrien  [(const_int 0)]
1061490286Sobrien{
1061590286Sobrien  rtx pat;
1061690286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
1061790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
10618117404Skan  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
1061990286Sobrien  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
1062090286Sobrien  if (Pmode != SImode)
1062190286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
1062290286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
1062390286Sobrien  DONE;
1062490286Sobrien})
1062590286Sobrien
10626117404Skan;; Rare case of shifting RSP is handled by generating move and shift
10627117404Skan(define_split
10628117404Skan  [(set (match_operand 0 "register_operand" "")
10629117404Skan	(ashift (match_operand 1 "register_operand" "")
10630117404Skan                (match_operand:QI 2 "const_int_operand" "")))
10631117404Skan   (clobber (reg:CC 17))]
10632117404Skan  "reload_completed
10633117404Skan   && true_regnum (operands[0]) != true_regnum (operands[1])"
10634117404Skan  [(const_int 0)]
10635117404Skan{
10636117404Skan  rtx pat, clob;
10637117404Skan  emit_move_insn (operands[1], operands[0]);
10638117404Skan  pat = gen_rtx_SET (VOIDmode, operands[0],
10639117404Skan		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10640117404Skan				     operands[0], operands[2]));
10641117404Skan  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10642117404Skan  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10643117404Skan  DONE;
10644117404Skan})
10645117404Skan
1064690286Sobrien(define_insn "*ashlsi3_1_zext"
1064790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1064890286Sobrien	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
1064990286Sobrien			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
1065090286Sobrien   (clobber (reg:CC 17))]
1065190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1065290286Sobrien{
1065390286Sobrien  switch (get_attr_type (insn))
1065490286Sobrien    {
1065590286Sobrien    case TYPE_ALU:
1065690286Sobrien      if (operands[2] != const1_rtx)
1065790286Sobrien	abort ();
1065890286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1065990286Sobrien
1066090286Sobrien    case TYPE_LEA:
1066190286Sobrien      return "#";
1066290286Sobrien
1066390286Sobrien    default:
1066490286Sobrien      if (REG_P (operands[2]))
1066590286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1066690286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1066790286Sobrien	       && INTVAL (operands[2]) == 1
10668117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1066990286Sobrien	return "sal{l}\t%k0";
1067090286Sobrien      else
1067190286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1067290286Sobrien    }
1067390286Sobrien}
1067490286Sobrien  [(set (attr "type")
1067590286Sobrien     (cond [(eq_attr "alternative" "1")
1067690286Sobrien	      (const_string "lea")
1067790286Sobrien            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1067890286Sobrien		     (const_int 0))
1067990286Sobrien		 (match_operand 2 "const1_operand" ""))
1068090286Sobrien	      (const_string "alu")
1068190286Sobrien	   ]
1068290286Sobrien	   (const_string "ishift")))
1068390286Sobrien   (set_attr "mode" "SI")])
1068490286Sobrien
1068590286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1068690286Sobrien(define_split
1068790286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1068890286Sobrien	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
1068990286Sobrien				(match_operand:QI 2 "const_int_operand" ""))))
1069090286Sobrien   (clobber (reg:CC 17))]
1069190286Sobrien  "reload_completed
1069290286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1069390286Sobrien  [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
1069490286Sobrien{
1069590286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
10696117404Skan  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
1069790286Sobrien})
1069890286Sobrien
1069990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1070090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1070190286Sobrien;; zero are optimized away.
1070290286Sobrien(define_insn "*ashlsi3_cmp"
1070390286Sobrien  [(set (reg 17)
1070490286Sobrien	(compare
1070590286Sobrien	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10706102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1070790286Sobrien	  (const_int 0)))
1070890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1070990286Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))]
1071090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1071190286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1071290286Sobrien{
1071390286Sobrien  switch (get_attr_type (insn))
1071490286Sobrien    {
1071590286Sobrien    case TYPE_ALU:
1071690286Sobrien      if (operands[2] != const1_rtx)
1071790286Sobrien	abort ();
1071890286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1071990286Sobrien
1072090286Sobrien    default:
1072190286Sobrien      if (REG_P (operands[2]))
1072290286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1072390286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1072490286Sobrien	       && INTVAL (operands[2]) == 1
10725117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1072690286Sobrien	return "sal{l}\t%0";
1072790286Sobrien      else
1072890286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1072990286Sobrien    }
1073090286Sobrien}
1073190286Sobrien  [(set (attr "type")
1073290286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1073390286Sobrien		          (const_int 0))
1073490286Sobrien		      (match_operand 0 "register_operand" ""))
1073590286Sobrien		 (match_operand 2 "const1_operand" ""))
1073690286Sobrien	      (const_string "alu")
1073790286Sobrien	   ]
1073890286Sobrien	   (const_string "ishift")))
1073990286Sobrien   (set_attr "mode" "SI")])
1074090286Sobrien
1074190286Sobrien(define_insn "*ashlsi3_cmp_zext"
1074290286Sobrien  [(set (reg 17)
1074390286Sobrien	(compare
1074490286Sobrien	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10745102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1074690286Sobrien	  (const_int 0)))
1074790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1074890286Sobrien	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
1074990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1075090286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1075190286Sobrien{
1075290286Sobrien  switch (get_attr_type (insn))
1075390286Sobrien    {
1075490286Sobrien    case TYPE_ALU:
1075590286Sobrien      if (operands[2] != const1_rtx)
1075690286Sobrien	abort ();
1075790286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1075890286Sobrien
1075990286Sobrien    default:
1076090286Sobrien      if (REG_P (operands[2]))
1076190286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1076290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1076390286Sobrien	       && INTVAL (operands[2]) == 1
10764117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1076590286Sobrien	return "sal{l}\t%k0";
1076690286Sobrien      else
1076790286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1076890286Sobrien    }
1076990286Sobrien}
1077090286Sobrien  [(set (attr "type")
1077190286Sobrien     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1077290286Sobrien		     (const_int 0))
1077390286Sobrien		 (match_operand 2 "const1_operand" ""))
1077490286Sobrien	      (const_string "alu")
1077590286Sobrien	   ]
1077690286Sobrien	   (const_string "ishift")))
1077790286Sobrien   (set_attr "mode" "SI")])
1077890286Sobrien
1077952296Sobrien(define_expand "ashlhi3"
1078052296Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1078152296Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
1078290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1078390286Sobrien   (clobber (reg:CC 17))]
1078490286Sobrien  "TARGET_HIMODE_MATH"
1078590286Sobrien  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
1078618334Speter
1078790286Sobrien(define_insn "*ashlhi3_1_lea"
1078890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
1078990286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
1079090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1079190286Sobrien   (clobber (reg:CC 17))]
1079290286Sobrien  "!TARGET_PARTIAL_REG_STALL
1079390286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1079490286Sobrien{
1079590286Sobrien  switch (get_attr_type (insn))
1079690286Sobrien    {
1079790286Sobrien    case TYPE_LEA:
1079890286Sobrien      return "#";
1079990286Sobrien    case TYPE_ALU:
1080090286Sobrien      if (operands[2] != const1_rtx)
1080190286Sobrien	abort ();
1080290286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1080390286Sobrien
1080490286Sobrien    default:
1080590286Sobrien      if (REG_P (operands[2]))
1080690286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1080790286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1080890286Sobrien	       && INTVAL (operands[2]) == 1
10809117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1081090286Sobrien	return "sal{w}\t%0";
1081190286Sobrien      else
1081290286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1081390286Sobrien    }
1081490286Sobrien}
1081590286Sobrien  [(set (attr "type")
1081690286Sobrien     (cond [(eq_attr "alternative" "1")
1081790286Sobrien	      (const_string "lea")
1081890286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1081990286Sobrien		          (const_int 0))
1082090286Sobrien		      (match_operand 0 "register_operand" ""))
1082190286Sobrien		 (match_operand 2 "const1_operand" ""))
1082290286Sobrien	      (const_string "alu")
1082390286Sobrien	   ]
1082490286Sobrien	   (const_string "ishift")))
1082590286Sobrien   (set_attr "mode" "HI,SI")])
1082690286Sobrien
1082790286Sobrien(define_insn "*ashlhi3_1"
1082890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1082990286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1083090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI")))
1083190286Sobrien   (clobber (reg:CC 17))]
1083290286Sobrien  "TARGET_PARTIAL_REG_STALL
1083390286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1083490286Sobrien{
1083590286Sobrien  switch (get_attr_type (insn))
1083690286Sobrien    {
1083790286Sobrien    case TYPE_ALU:
1083890286Sobrien      if (operands[2] != const1_rtx)
1083990286Sobrien	abort ();
1084090286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1084190286Sobrien
1084290286Sobrien    default:
1084390286Sobrien      if (REG_P (operands[2]))
1084490286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1084590286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1084690286Sobrien	       && INTVAL (operands[2]) == 1
10847117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1084890286Sobrien	return "sal{w}\t%0";
1084990286Sobrien      else
1085090286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1085190286Sobrien    }
1085290286Sobrien}
1085390286Sobrien  [(set (attr "type")
1085490286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1085590286Sobrien		          (const_int 0))
1085690286Sobrien		      (match_operand 0 "register_operand" ""))
1085790286Sobrien		 (match_operand 2 "const1_operand" ""))
1085890286Sobrien	      (const_string "alu")
1085990286Sobrien	   ]
1086090286Sobrien	   (const_string "ishift")))
1086190286Sobrien   (set_attr "mode" "HI")])
1086290286Sobrien
1086390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1086490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1086590286Sobrien;; zero are optimized away.
1086690286Sobrien(define_insn "*ashlhi3_cmp"
1086790286Sobrien  [(set (reg 17)
1086890286Sobrien	(compare
1086990286Sobrien	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10870102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1087190286Sobrien	  (const_int 0)))
1087290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1087390286Sobrien	(ashift:HI (match_dup 1) (match_dup 2)))]
1087490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1087590286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1087690286Sobrien{
1087790286Sobrien  switch (get_attr_type (insn))
1087890286Sobrien    {
1087990286Sobrien    case TYPE_ALU:
1088090286Sobrien      if (operands[2] != const1_rtx)
1088190286Sobrien	abort ();
1088290286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1088390286Sobrien
1088490286Sobrien    default:
1088590286Sobrien      if (REG_P (operands[2]))
1088690286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1088790286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1088890286Sobrien	       && INTVAL (operands[2]) == 1
10889117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1089090286Sobrien	return "sal{w}\t%0";
1089190286Sobrien      else
1089290286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1089390286Sobrien    }
1089490286Sobrien}
1089590286Sobrien  [(set (attr "type")
1089690286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1089790286Sobrien		          (const_int 0))
1089890286Sobrien		      (match_operand 0 "register_operand" ""))
1089990286Sobrien		 (match_operand 2 "const1_operand" ""))
1090090286Sobrien	      (const_string "alu")
1090190286Sobrien	   ]
1090290286Sobrien	   (const_string "ishift")))
1090390286Sobrien   (set_attr "mode" "HI")])
1090490286Sobrien
1090552296Sobrien(define_expand "ashlqi3"
1090652296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1090752296Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
1090890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1090990286Sobrien   (clobber (reg:CC 17))]
1091090286Sobrien  "TARGET_QIMODE_MATH"
1091190286Sobrien  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
1091218334Speter
1091390286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
1091418334Speter
1091590286Sobrien(define_insn "*ashlqi3_1_lea"
1091690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
1091790286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
1091890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
1091990286Sobrien   (clobber (reg:CC 17))]
1092090286Sobrien  "!TARGET_PARTIAL_REG_STALL
1092190286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1092290286Sobrien{
1092390286Sobrien  switch (get_attr_type (insn))
1092490286Sobrien    {
1092590286Sobrien    case TYPE_LEA:
1092690286Sobrien      return "#";
1092790286Sobrien    case TYPE_ALU:
1092890286Sobrien      if (operands[2] != const1_rtx)
1092990286Sobrien	abort ();
1093090286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1093190286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1093290286Sobrien      else
1093390286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1093418334Speter
1093590286Sobrien    default:
1093690286Sobrien      if (REG_P (operands[2]))
1093790286Sobrien	{
1093890286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1093990286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1094090286Sobrien	  else
1094190286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1094290286Sobrien	}
1094390286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1094490286Sobrien	       && INTVAL (operands[2]) == 1
10945117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1094690286Sobrien	{
1094790286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1094890286Sobrien	    return "sal{l}\t%0";
1094990286Sobrien	  else
1095090286Sobrien	    return "sal{b}\t%0";
1095190286Sobrien	}
1095290286Sobrien      else
1095390286Sobrien	{
1095490286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1095590286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1095690286Sobrien	  else
1095790286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1095890286Sobrien	}
1095990286Sobrien    }
1096090286Sobrien}
1096190286Sobrien  [(set (attr "type")
1096290286Sobrien     (cond [(eq_attr "alternative" "2")
1096390286Sobrien	      (const_string "lea")
1096490286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1096590286Sobrien		          (const_int 0))
1096690286Sobrien		      (match_operand 0 "register_operand" ""))
1096790286Sobrien		 (match_operand 2 "const1_operand" ""))
1096890286Sobrien	      (const_string "alu")
1096990286Sobrien	   ]
1097090286Sobrien	   (const_string "ishift")))
1097190286Sobrien   (set_attr "mode" "QI,SI,SI")])
1097218334Speter
1097390286Sobrien(define_insn "*ashlqi3_1"
1097490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1097590286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1097690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
1097790286Sobrien   (clobber (reg:CC 17))]
1097890286Sobrien  "TARGET_PARTIAL_REG_STALL
1097990286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1098090286Sobrien{
1098190286Sobrien  switch (get_attr_type (insn))
1098290286Sobrien    {
1098390286Sobrien    case TYPE_ALU:
1098490286Sobrien      if (operands[2] != const1_rtx)
1098590286Sobrien	abort ();
1098690286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1098790286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1098890286Sobrien      else
1098990286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1099052296Sobrien
1099190286Sobrien    default:
1099290286Sobrien      if (REG_P (operands[2]))
1099390286Sobrien	{
1099490286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1099590286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1099690286Sobrien	  else
1099790286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1099890286Sobrien	}
1099990286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1100090286Sobrien	       && INTVAL (operands[2]) == 1
11001117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1100290286Sobrien	{
1100390286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1100490286Sobrien	    return "sal{l}\t%0";
1100590286Sobrien	  else
1100690286Sobrien	    return "sal{b}\t%0";
1100790286Sobrien	}
1100890286Sobrien      else
1100990286Sobrien	{
1101090286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1101190286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1101290286Sobrien	  else
1101390286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1101490286Sobrien	}
1101590286Sobrien    }
1101690286Sobrien}
1101790286Sobrien  [(set (attr "type")
1101890286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1101990286Sobrien		          (const_int 0))
1102090286Sobrien		      (match_operand 0 "register_operand" ""))
1102190286Sobrien		 (match_operand 2 "const1_operand" ""))
1102290286Sobrien	      (const_string "alu")
1102390286Sobrien	   ]
1102490286Sobrien	   (const_string "ishift")))
1102590286Sobrien   (set_attr "mode" "QI,SI")])
1102618334Speter
1102790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1102890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1102990286Sobrien;; zero are optimized away.
1103090286Sobrien(define_insn "*ashlqi3_cmp"
1103190286Sobrien  [(set (reg 17)
1103290286Sobrien	(compare
1103390286Sobrien	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11034102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1103590286Sobrien	  (const_int 0)))
1103690286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1103790286Sobrien	(ashift:QI (match_dup 1) (match_dup 2)))]
1103890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1103990286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1104090286Sobrien{
1104190286Sobrien  switch (get_attr_type (insn))
1104290286Sobrien    {
1104390286Sobrien    case TYPE_ALU:
1104490286Sobrien      if (operands[2] != const1_rtx)
1104590286Sobrien	abort ();
1104690286Sobrien      return "add{b}\t{%0, %0|%0, %0}";
1104718334Speter
1104890286Sobrien    default:
1104990286Sobrien      if (REG_P (operands[2]))
1105090286Sobrien	return "sal{b}\t{%b2, %0|%0, %b2}";
1105190286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1105290286Sobrien	       && INTVAL (operands[2]) == 1
11053117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1105490286Sobrien	return "sal{b}\t%0";
1105590286Sobrien      else
1105690286Sobrien	return "sal{b}\t{%2, %0|%0, %2}";
1105790286Sobrien    }
1105890286Sobrien}
1105990286Sobrien  [(set (attr "type")
1106090286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1106190286Sobrien		          (const_int 0))
1106290286Sobrien		      (match_operand 0 "register_operand" ""))
1106390286Sobrien		 (match_operand 2 "const1_operand" ""))
1106490286Sobrien	      (const_string "alu")
1106590286Sobrien	   ]
1106690286Sobrien	   (const_string "ishift")))
1106790286Sobrien   (set_attr "mode" "QI")])
1106818334Speter
1106918334Speter;; See comment above `ashldi3' about how this works.
1107018334Speter
1107118334Speter(define_expand "ashrdi3"
1107290286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1107390286Sobrien		   (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1107490286Sobrien				(match_operand:QI 2 "nonmemory_operand" "")))
1107590286Sobrien	      (clobber (reg:CC 17))])]
1107618334Speter  ""
1107718334Speter{
1107890286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1107918334Speter    {
1108090286Sobrien      emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
1108190286Sobrien      DONE;
1108218334Speter    }
1108390286Sobrien  ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
1108418334Speter  DONE;
1108590286Sobrien})
1108618334Speter
1108790286Sobrien(define_insn "ashrdi3_63_rex64"
1108890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
1108990286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
1109090286Sobrien		     (match_operand:DI 2 "const_int_operand" "i,i")))
1109190286Sobrien   (clobber (reg:CC 17))]
1109290286Sobrien  "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
1109390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1109490286Sobrien  "@
1109590286Sobrien   {cqto|cqo}
1109690286Sobrien   sar{q}\t{%2, %0|%0, %2}"
1109790286Sobrien  [(set_attr "type" "imovx,ishift")
1109890286Sobrien   (set_attr "prefix_0f" "0,*")
1109990286Sobrien   (set_attr "length_immediate" "0,*")
1110090286Sobrien   (set_attr "modrm" "0,1")
1110190286Sobrien   (set_attr "mode" "DI")])
1110250650Sobrien
1110390286Sobrien(define_insn "*ashrdi3_1_one_bit_rex64"
1110490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1110590286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1110690286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1110790286Sobrien   (clobber (reg:CC 17))]
1110890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11109117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1111090286Sobrien  "sar{q}\t%0"
1111190286Sobrien  [(set_attr "type" "ishift")
1111290286Sobrien   (set (attr "length") 
1111390286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1111490286Sobrien	(const_string "2")
1111590286Sobrien	(const_string "*")))])
1111650650Sobrien
1111790286Sobrien(define_insn "*ashrdi3_1_rex64"
1111890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1111990286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1112090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1112190286Sobrien   (clobber (reg:CC 17))]
1112290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1112390286Sobrien  "@
1112490286Sobrien   sar{q}\t{%2, %0|%0, %2}
1112590286Sobrien   sar{q}\t{%b2, %0|%0, %b2}"
1112690286Sobrien  [(set_attr "type" "ishift")
1112790286Sobrien   (set_attr "mode" "DI")])
1112850650Sobrien
1112990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1113090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1113190286Sobrien;; zero are optimized away.
1113290286Sobrien(define_insn "*ashrdi3_one_bit_cmp_rex64"
1113390286Sobrien  [(set (reg 17)
1113490286Sobrien	(compare
1113590286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1113690286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1113790286Sobrien	  (const_int 0)))
1113890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1113990286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1114090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11141117404Skan   && (TARGET_SHIFT1 || optimize_size)
1114290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1114390286Sobrien  "sar{q}\t%0"
1114490286Sobrien  [(set_attr "type" "ishift")
1114590286Sobrien   (set (attr "length") 
1114690286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1114790286Sobrien	(const_string "2")
1114890286Sobrien	(const_string "*")))])
1114950650Sobrien
1115090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1115190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1115290286Sobrien;; zero are optimized away.
1115390286Sobrien(define_insn "*ashrdi3_cmp_rex64"
1115490286Sobrien  [(set (reg 17)
1115590286Sobrien	(compare
1115690286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1115790286Sobrien		       (match_operand:QI 2 "const_int_operand" "n"))
1115890286Sobrien	  (const_int 0)))
1115990286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1116090286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1116190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1116290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1116390286Sobrien  "sar{q}\t{%2, %0|%0, %2}"
1116490286Sobrien  [(set_attr "type" "ishift")
1116590286Sobrien   (set_attr "mode" "DI")])
1116618334Speter
1116718334Speter
1116890286Sobrien(define_insn "ashrdi3_1"
1116990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1117090286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1117190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1117290286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1117390286Sobrien   (clobber (reg:CC 17))]
1117490286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1117590286Sobrien  "#"
1117690286Sobrien  [(set_attr "type" "multi")])
1117718334Speter
1117890286Sobrien(define_insn "*ashrdi3_2"
1117990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1118090286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1118190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1118290286Sobrien   (clobber (reg:CC 17))]
1118390286Sobrien  "!TARGET_64BIT"
1118490286Sobrien  "#"
1118590286Sobrien  [(set_attr "type" "multi")])
1118618334Speter
1118790286Sobrien(define_split
1118890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1118990286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1119090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1119190286Sobrien   (clobber (match_scratch:SI 3 ""))
1119290286Sobrien   (clobber (reg:CC 17))]
1119390286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1119490286Sobrien  [(const_int 0)]
1119590286Sobrien  "ix86_split_ashrdi (operands, operands[3]); DONE;")
1119618334Speter
1119790286Sobrien(define_split
1119890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1119990286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1120090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1120190286Sobrien   (clobber (reg:CC 17))]
1120290286Sobrien  "!TARGET_64BIT && reload_completed"
1120390286Sobrien  [(const_int 0)]
1120490286Sobrien  "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
1120518334Speter
1120690286Sobrien(define_insn "x86_shrd_1"
1120790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1120890286Sobrien        (ior:SI (ashiftrt:SI (match_dup 0)
1120990286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1121090286Sobrien		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1121190286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1121290286Sobrien   (clobber (reg:CC 17))]
1121318334Speter  ""
1121490286Sobrien  "@
1121590286Sobrien   shrd{l}\t{%2, %1, %0|%0, %1, %2}
1121690286Sobrien   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
1121790286Sobrien  [(set_attr "type" "ishift")
1121890286Sobrien   (set_attr "prefix_0f" "1")
1121990286Sobrien   (set_attr "pent_pair" "np")
1122090286Sobrien   (set_attr "ppro_uops" "few")
1122190286Sobrien   (set_attr "mode" "SI")])
1122290286Sobrien
1122390286Sobrien(define_expand "x86_shift_adj_3"
1122490286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1122590286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1122690286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1122790286Sobrien  ""
1122818334Speter{
1122990286Sobrien  rtx label = gen_label_rtx ();
1123090286Sobrien  rtx tmp;
1123118334Speter
1123290286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1123318334Speter
1123490286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1123590286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1123690286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1123790286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1123890286Sobrien			      pc_rtx);
1123990286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1124090286Sobrien  JUMP_LABEL (tmp) = label;
1124118334Speter
1124290286Sobrien  emit_move_insn (operands[0], operands[1]);
1124390286Sobrien  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
1124418334Speter
1124590286Sobrien  emit_label (label);
1124690286Sobrien  LABEL_NUSES (label) = 1;
1124790286Sobrien
1124890286Sobrien  DONE;
1124990286Sobrien})
1125090286Sobrien
1125152296Sobrien(define_insn "ashrsi3_31"
1125290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
1125390286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
1125490286Sobrien		     (match_operand:SI 2 "const_int_operand" "i,i")))
1125590286Sobrien   (clobber (reg:CC 17))]
1125690286Sobrien  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
1125790286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1125852296Sobrien  "@
1125990286Sobrien   {cltd|cdq}
1126090286Sobrien   sar{l}\t{%2, %0|%0, %2}"
1126190286Sobrien  [(set_attr "type" "imovx,ishift")
1126290286Sobrien   (set_attr "prefix_0f" "0,*")
1126390286Sobrien   (set_attr "length_immediate" "0,*")
1126490286Sobrien   (set_attr "modrm" "0,1")
1126590286Sobrien   (set_attr "mode" "SI")])
1126652296Sobrien
1126790286Sobrien(define_insn "*ashrsi3_31_zext"
1126890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*d,r")
1126990286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
1127090286Sobrien				     (match_operand:SI 2 "const_int_operand" "i,i"))))
1127190286Sobrien   (clobber (reg:CC 17))]
1127290286Sobrien  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
1127390286Sobrien   && INTVAL (operands[2]) == 31
1127490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1127590286Sobrien  "@
1127690286Sobrien   {cltd|cdq}
1127790286Sobrien   sar{l}\t{%2, %k0|%k0, %2}"
1127890286Sobrien  [(set_attr "type" "imovx,ishift")
1127990286Sobrien   (set_attr "prefix_0f" "0,*")
1128090286Sobrien   (set_attr "length_immediate" "0,*")
1128190286Sobrien   (set_attr "modrm" "0,1")
1128290286Sobrien   (set_attr "mode" "SI")])
1128390286Sobrien
1128490286Sobrien(define_expand "ashrsi3"
1128590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1128690286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1128790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1128890286Sobrien   (clobber (reg:CC 17))]
1128990286Sobrien  ""
1129090286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
1129190286Sobrien
1129290286Sobrien(define_insn "*ashrsi3_1_one_bit"
1129350650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1129450650Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1129590286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1129690286Sobrien   (clobber (reg:CC 17))]
1129790286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11298117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1129990286Sobrien  "sar{l}\t%0"
1130090286Sobrien  [(set_attr "type" "ishift")
1130190286Sobrien   (set (attr "length") 
1130290286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1130390286Sobrien	(const_string "2")
1130490286Sobrien	(const_string "*")))])
1130518334Speter
1130690286Sobrien(define_insn "*ashrsi3_1_one_bit_zext"
1130790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1130890286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1130990286Sobrien				     (match_operand:QI 2 "const_int_1_operand" ""))))
1131090286Sobrien   (clobber (reg:CC 17))]
1131190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11312117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1131390286Sobrien  "sar{l}\t%k0"
1131490286Sobrien  [(set_attr "type" "ishift")
1131590286Sobrien   (set_attr "length" "2")])
1131690286Sobrien
1131790286Sobrien(define_insn "*ashrsi3_1"
1131890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1131990286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1132090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1132190286Sobrien   (clobber (reg:CC 17))]
1132290286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1132390286Sobrien  "@
1132490286Sobrien   sar{l}\t{%2, %0|%0, %2}
1132590286Sobrien   sar{l}\t{%b2, %0|%0, %b2}"
1132690286Sobrien  [(set_attr "type" "ishift")
1132790286Sobrien   (set_attr "mode" "SI")])
1132890286Sobrien
1132990286Sobrien(define_insn "*ashrsi3_1_zext"
1133090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1133190286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1133290286Sobrien				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1133390286Sobrien   (clobber (reg:CC 17))]
1133490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1133590286Sobrien  "@
1133690286Sobrien   sar{l}\t{%2, %k0|%k0, %2}
1133790286Sobrien   sar{l}\t{%b2, %k0|%k0, %b2}"
1133890286Sobrien  [(set_attr "type" "ishift")
1133990286Sobrien   (set_attr "mode" "SI")])
1134090286Sobrien
1134190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1134290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1134390286Sobrien;; zero are optimized away.
1134490286Sobrien(define_insn "*ashrsi3_one_bit_cmp"
1134590286Sobrien  [(set (reg 17)
1134690286Sobrien	(compare
1134790286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1134890286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1134990286Sobrien	  (const_int 0)))
1135090286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1135190286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1135290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11353117404Skan   && (TARGET_SHIFT1 || optimize_size)
1135490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1135590286Sobrien  "sar{l}\t%0"
1135690286Sobrien  [(set_attr "type" "ishift")
1135790286Sobrien   (set (attr "length") 
1135890286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1135990286Sobrien	(const_string "2")
1136090286Sobrien	(const_string "*")))])
1136190286Sobrien
1136290286Sobrien(define_insn "*ashrsi3_one_bit_cmp_zext"
1136390286Sobrien  [(set (reg 17)
1136490286Sobrien	(compare
1136590286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1136690286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1136790286Sobrien	  (const_int 0)))
1136890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1136990286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1137090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11371117404Skan   && (TARGET_SHIFT1 || optimize_size)
1137290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1137390286Sobrien  "sar{l}\t%k0"
1137490286Sobrien  [(set_attr "type" "ishift")
1137590286Sobrien   (set_attr "length" "2")])
1137690286Sobrien
1137790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1137890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1137990286Sobrien;; zero are optimized away.
1138090286Sobrien(define_insn "*ashrsi3_cmp"
1138190286Sobrien  [(set (reg 17)
1138290286Sobrien	(compare
1138390286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11384102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1138590286Sobrien	  (const_int 0)))
1138690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1138790286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1138890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1138990286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1139090286Sobrien  "sar{l}\t{%2, %0|%0, %2}"
1139190286Sobrien  [(set_attr "type" "ishift")
1139290286Sobrien   (set_attr "mode" "SI")])
1139390286Sobrien
1139490286Sobrien(define_insn "*ashrsi3_cmp_zext"
1139590286Sobrien  [(set (reg 17)
1139690286Sobrien	(compare
1139790286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11398102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1139990286Sobrien	  (const_int 0)))
1140090286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1140190286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1140290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1140390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1140490286Sobrien  "sar{l}\t{%2, %k0|%k0, %2}"
1140590286Sobrien  [(set_attr "type" "ishift")
1140690286Sobrien   (set_attr "mode" "SI")])
1140790286Sobrien
1140890286Sobrien(define_expand "ashrhi3"
1140990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1141090286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1141190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1141290286Sobrien   (clobber (reg:CC 17))]
1141390286Sobrien  "TARGET_HIMODE_MATH"
1141490286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
1141590286Sobrien
1141690286Sobrien(define_insn "*ashrhi3_1_one_bit"
1141750650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1141850650Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1141990286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1142090286Sobrien   (clobber (reg:CC 17))]
1142190286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11422117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1142390286Sobrien  "sar{w}\t%0"
1142490286Sobrien  [(set_attr "type" "ishift")
1142590286Sobrien   (set (attr "length") 
1142690286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1142790286Sobrien	(const_string "2")
1142890286Sobrien	(const_string "*")))])
1142918334Speter
1143090286Sobrien(define_insn "*ashrhi3_1"
1143190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1143290286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1143390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1143490286Sobrien   (clobber (reg:CC 17))]
1143590286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1143690286Sobrien  "@
1143790286Sobrien   sar{w}\t{%2, %0|%0, %2}
1143890286Sobrien   sar{w}\t{%b2, %0|%0, %b2}"
1143990286Sobrien  [(set_attr "type" "ishift")
1144090286Sobrien   (set_attr "mode" "HI")])
1144190286Sobrien
1144290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1144390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1144490286Sobrien;; zero are optimized away.
1144590286Sobrien(define_insn "*ashrhi3_one_bit_cmp"
1144690286Sobrien  [(set (reg 17)
1144790286Sobrien	(compare
1144890286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1144990286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1145090286Sobrien	  (const_int 0)))
1145190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1145290286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1145390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11454117404Skan   && (TARGET_SHIFT1 || optimize_size)
1145590286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1145690286Sobrien  "sar{w}\t%0"
1145790286Sobrien  [(set_attr "type" "ishift")
1145890286Sobrien   (set (attr "length") 
1145990286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1146090286Sobrien	(const_string "2")
1146190286Sobrien	(const_string "*")))])
1146290286Sobrien
1146390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1146490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1146590286Sobrien;; zero are optimized away.
1146690286Sobrien(define_insn "*ashrhi3_cmp"
1146790286Sobrien  [(set (reg 17)
1146890286Sobrien	(compare
1146990286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11470102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1147190286Sobrien	  (const_int 0)))
1147290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1147390286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1147490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1147590286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1147690286Sobrien  "sar{w}\t{%2, %0|%0, %2}"
1147790286Sobrien  [(set_attr "type" "ishift")
1147890286Sobrien   (set_attr "mode" "HI")])
1147990286Sobrien
1148090286Sobrien(define_expand "ashrqi3"
1148190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1148290286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1148390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1148490286Sobrien   (clobber (reg:CC 17))]
1148590286Sobrien  "TARGET_QIMODE_MATH"
1148690286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
1148790286Sobrien
1148890286Sobrien(define_insn "*ashrqi3_1_one_bit"
1148950650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1149050650Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1149190286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1149290286Sobrien   (clobber (reg:CC 17))]
1149390286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11494117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1149590286Sobrien  "sar{b}\t%0"
1149690286Sobrien  [(set_attr "type" "ishift")
1149790286Sobrien   (set (attr "length") 
1149890286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1149990286Sobrien	(const_string "2")
1150090286Sobrien	(const_string "*")))])
1150190286Sobrien
11502117404Skan(define_insn "*ashrqi3_1_one_bit_slp"
11503117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11504117404Skan	(ashiftrt:QI (match_dup 0)
11505117404Skan		     (match_operand:QI 1 "const_int_1_operand" "")))
11506117404Skan   (clobber (reg:CC 17))]
11507117404Skan  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11508117404Skan   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11509117404Skan   && (TARGET_SHIFT1 || optimize_size)"
11510117404Skan  "sar{b}\t%0"
11511117404Skan  [(set_attr "type" "ishift1")
11512117404Skan   (set (attr "length") 
11513117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
11514117404Skan	(const_string "2")
11515117404Skan	(const_string "*")))])
11516117404Skan
1151790286Sobrien(define_insn "*ashrqi3_1"
1151890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1151990286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1152090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1152190286Sobrien   (clobber (reg:CC 17))]
1152290286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1152390286Sobrien  "@
1152490286Sobrien   sar{b}\t{%2, %0|%0, %2}
1152590286Sobrien   sar{b}\t{%b2, %0|%0, %b2}"
1152690286Sobrien  [(set_attr "type" "ishift")
1152790286Sobrien   (set_attr "mode" "QI")])
1152890286Sobrien
11529117404Skan(define_insn "*ashrqi3_1_slp"
11530117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11531117404Skan	(ashiftrt:QI (match_dup 0)
11532117404Skan		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11533117404Skan   (clobber (reg:CC 17))]
11534117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11535117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11536117404Skan  "@
11537117404Skan   sar{b}\t{%1, %0|%0, %1}
11538117404Skan   sar{b}\t{%b1, %0|%0, %b1}"
11539117404Skan  [(set_attr "type" "ishift1")
11540117404Skan   (set_attr "mode" "QI")])
11541117404Skan
1154290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1154390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1154490286Sobrien;; zero are optimized away.
1154590286Sobrien(define_insn "*ashrqi3_one_bit_cmp"
1154690286Sobrien  [(set (reg 17)
1154790286Sobrien	(compare
1154890286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1154990286Sobrien		       (match_operand:QI 2 "const_int_1_operand" "I"))
1155090286Sobrien	  (const_int 0)))
11551102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1155290286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1155390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11554117404Skan   && (TARGET_SHIFT1 || optimize_size)
1155590286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1155690286Sobrien  "sar{b}\t%0"
1155790286Sobrien  [(set_attr "type" "ishift")
1155890286Sobrien   (set (attr "length") 
1155990286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1156090286Sobrien	(const_string "2")
1156190286Sobrien	(const_string "*")))])
1156290286Sobrien
1156390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1156490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1156590286Sobrien;; zero are optimized away.
1156690286Sobrien(define_insn "*ashrqi3_cmp"
1156790286Sobrien  [(set (reg 17)
1156890286Sobrien	(compare
1156990286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11570102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1157190286Sobrien	  (const_int 0)))
11572102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1157390286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1157490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1157590286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1157690286Sobrien  "sar{b}\t{%2, %0|%0, %2}"
1157790286Sobrien  [(set_attr "type" "ishift")
1157890286Sobrien   (set_attr "mode" "QI")])
1157918334Speter
1158090286Sobrien;; Logical shift instructions
1158118334Speter
1158218334Speter;; See comment above `ashldi3' about how this works.
1158318334Speter
1158418334Speter(define_expand "lshrdi3"
1158590286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1158690286Sobrien		   (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1158790286Sobrien			        (match_operand:QI 2 "nonmemory_operand" "")))
1158890286Sobrien	      (clobber (reg:CC 17))])]
1158918334Speter  ""
1159018334Speter{
1159190286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1159218334Speter    {
1159390286Sobrien      emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
1159490286Sobrien      DONE;
1159518334Speter    }
1159690286Sobrien  ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
1159718334Speter  DONE;
1159890286Sobrien})
1159918334Speter
1160090286Sobrien(define_insn "*lshrdi3_1_one_bit_rex64"
1160190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1160290286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1160390286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1160490286Sobrien   (clobber (reg:CC 17))]
1160590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11606117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1160790286Sobrien  "shr{q}\t%0"
1160890286Sobrien  [(set_attr "type" "ishift")
1160990286Sobrien   (set (attr "length") 
1161090286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1161190286Sobrien	(const_string "2")
1161290286Sobrien	(const_string "*")))])
1161350650Sobrien
1161490286Sobrien(define_insn "*lshrdi3_1_rex64"
1161590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1161690286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1161790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1161890286Sobrien   (clobber (reg:CC 17))]
1161990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1162090286Sobrien  "@
1162190286Sobrien   shr{q}\t{%2, %0|%0, %2}
1162290286Sobrien   shr{q}\t{%b2, %0|%0, %b2}"
1162390286Sobrien  [(set_attr "type" "ishift")
1162490286Sobrien   (set_attr "mode" "DI")])
1162550650Sobrien
1162690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1162790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1162890286Sobrien;; zero are optimized away.
1162990286Sobrien(define_insn "*lshrdi3_cmp_one_bit_rex64"
1163090286Sobrien  [(set (reg 17)
1163190286Sobrien	(compare
1163290286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1163390286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1163490286Sobrien	  (const_int 0)))
1163590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1163690286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1163790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11638117404Skan   && (TARGET_SHIFT1 || optimize_size)
1163990286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1164090286Sobrien  "shr{q}\t%0"
1164190286Sobrien  [(set_attr "type" "ishift")
1164290286Sobrien   (set (attr "length") 
1164390286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1164490286Sobrien	(const_string "2")
1164590286Sobrien	(const_string "*")))])
1164650650Sobrien
1164790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1164890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1164990286Sobrien;; zero are optimized away.
1165090286Sobrien(define_insn "*lshrdi3_cmp_rex64"
1165190286Sobrien  [(set (reg 17)
1165290286Sobrien	(compare
1165390286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1165490286Sobrien		       (match_operand:QI 2 "const_int_operand" "e"))
1165590286Sobrien	  (const_int 0)))
1165690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1165790286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1165890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1165990286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1166090286Sobrien  "shr{q}\t{%2, %0|%0, %2}"
1166190286Sobrien  [(set_attr "type" "ishift")
1166290286Sobrien   (set_attr "mode" "DI")])
1166350650Sobrien
1166490286Sobrien(define_insn "lshrdi3_1"
1166590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1166618334Speter	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1166790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1166890286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1166990286Sobrien   (clobber (reg:CC 17))]
1167090286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1167190286Sobrien  "#"
1167290286Sobrien  [(set_attr "type" "multi")])
1167318334Speter
1167490286Sobrien(define_insn "*lshrdi3_2"
1167590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1167690286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1167790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1167890286Sobrien   (clobber (reg:CC 17))]
1167990286Sobrien  "!TARGET_64BIT"
1168090286Sobrien  "#"
1168190286Sobrien  [(set_attr "type" "multi")])
1168218334Speter
1168390286Sobrien(define_split 
1168490286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1168590286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1168690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1168790286Sobrien   (clobber (match_scratch:SI 3 ""))
1168890286Sobrien   (clobber (reg:CC 17))]
1168990286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1169090286Sobrien  [(const_int 0)]
1169190286Sobrien  "ix86_split_lshrdi (operands, operands[3]); DONE;")
1169218334Speter
1169390286Sobrien(define_split 
1169490286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1169590286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1169690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1169790286Sobrien   (clobber (reg:CC 17))]
1169890286Sobrien  "!TARGET_64BIT && reload_completed"
1169990286Sobrien  [(const_int 0)]
1170090286Sobrien  "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
1170118334Speter
1170290286Sobrien(define_expand "lshrsi3"
1170390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1170490286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1170590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1170690286Sobrien   (clobber (reg:CC 17))]
1170790286Sobrien  ""
1170890286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
1170918334Speter
1171090286Sobrien(define_insn "*lshrsi3_1_one_bit"
1171190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1171290286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1171390286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1171490286Sobrien   (clobber (reg:CC 17))]
1171590286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11716117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1171790286Sobrien  "shr{l}\t%0"
1171890286Sobrien  [(set_attr "type" "ishift")
1171990286Sobrien   (set (attr "length") 
1172090286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1172190286Sobrien	(const_string "2")
1172290286Sobrien	(const_string "*")))])
1172318334Speter
1172490286Sobrien(define_insn "*lshrsi3_1_one_bit_zext"
1172590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1172690286Sobrien	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
1172790286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1172890286Sobrien   (clobber (reg:CC 17))]
1172990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11730117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1173190286Sobrien  "shr{l}\t%k0"
1173290286Sobrien  [(set_attr "type" "ishift")
1173390286Sobrien   (set_attr "length" "2")])
1173418334Speter
1173590286Sobrien(define_insn "*lshrsi3_1"
1173690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1173790286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1173890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1173990286Sobrien   (clobber (reg:CC 17))]
1174090286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1174190286Sobrien  "@
1174290286Sobrien   shr{l}\t{%2, %0|%0, %2}
1174390286Sobrien   shr{l}\t{%b2, %0|%0, %b2}"
1174490286Sobrien  [(set_attr "type" "ishift")
1174590286Sobrien   (set_attr "mode" "SI")])
1174618334Speter
1174790286Sobrien(define_insn "*lshrsi3_1_zext"
1174890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1174990286Sobrien	(zero_extend:DI
1175090286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1175190286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1175290286Sobrien   (clobber (reg:CC 17))]
1175390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1175490286Sobrien  "@
1175590286Sobrien   shr{l}\t{%2, %k0|%k0, %2}
1175690286Sobrien   shr{l}\t{%b2, %k0|%k0, %b2}"
1175790286Sobrien  [(set_attr "type" "ishift")
1175890286Sobrien   (set_attr "mode" "SI")])
1175918334Speter
1176090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1176190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1176290286Sobrien;; zero are optimized away.
1176390286Sobrien(define_insn "*lshrsi3_one_bit_cmp"
1176490286Sobrien  [(set (reg 17)
1176590286Sobrien	(compare
1176690286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1176790286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1176890286Sobrien	  (const_int 0)))
1176990286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1177090286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1177190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11772117404Skan   && (TARGET_SHIFT1 || optimize_size)
1177390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1177490286Sobrien  "shr{l}\t%0"
1177590286Sobrien  [(set_attr "type" "ishift")
1177690286Sobrien   (set (attr "length") 
1177790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1177890286Sobrien	(const_string "2")
1177990286Sobrien	(const_string "*")))])
1178018334Speter
1178190286Sobrien(define_insn "*lshrsi3_cmp_one_bit_zext"
1178290286Sobrien  [(set (reg 17)
1178390286Sobrien	(compare
1178490286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1178590286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1178690286Sobrien	  (const_int 0)))
1178790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1178890286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1178990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11790117404Skan   && (TARGET_SHIFT1 || optimize_size)
1179190286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1179290286Sobrien  "shr{l}\t%k0"
1179390286Sobrien  [(set_attr "type" "ishift")
1179490286Sobrien   (set_attr "length" "2")])
1179518334Speter
1179690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1179790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1179890286Sobrien;; zero are optimized away.
1179990286Sobrien(define_insn "*lshrsi3_cmp"
1180090286Sobrien  [(set (reg 17)
1180190286Sobrien	(compare
1180290286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11803102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1180490286Sobrien	  (const_int 0)))
1180590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1180690286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1180790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1180890286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1180990286Sobrien  "shr{l}\t{%2, %0|%0, %2}"
1181090286Sobrien  [(set_attr "type" "ishift")
1181190286Sobrien   (set_attr "mode" "SI")])
1181290286Sobrien
1181390286Sobrien(define_insn "*lshrsi3_cmp_zext"
1181490286Sobrien  [(set (reg 17)
1181590286Sobrien	(compare
1181690286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11817102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1181890286Sobrien	  (const_int 0)))
1181990286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1182090286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1182190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1182290286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1182390286Sobrien  "shr{l}\t{%2, %k0|%k0, %2}"
1182490286Sobrien  [(set_attr "type" "ishift")
1182590286Sobrien   (set_attr "mode" "SI")])
1182690286Sobrien
1182790286Sobrien(define_expand "lshrhi3"
1182890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1182990286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1183090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1183190286Sobrien   (clobber (reg:CC 17))]
1183290286Sobrien  "TARGET_HIMODE_MATH"
1183390286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
1183490286Sobrien
1183590286Sobrien(define_insn "*lshrhi3_1_one_bit"
1183650650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1183750650Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1183890286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1183990286Sobrien   (clobber (reg:CC 17))]
1184090286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11841117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1184290286Sobrien  "shr{w}\t%0"
1184390286Sobrien  [(set_attr "type" "ishift")
1184490286Sobrien   (set (attr "length") 
1184590286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1184690286Sobrien	(const_string "2")
1184790286Sobrien	(const_string "*")))])
1184818334Speter
1184990286Sobrien(define_insn "*lshrhi3_1"
1185090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1185190286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1185290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1185390286Sobrien   (clobber (reg:CC 17))]
1185490286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1185590286Sobrien  "@
1185690286Sobrien   shr{w}\t{%2, %0|%0, %2}
1185790286Sobrien   shr{w}\t{%b2, %0|%0, %b2}"
1185890286Sobrien  [(set_attr "type" "ishift")
1185990286Sobrien   (set_attr "mode" "HI")])
1186090286Sobrien
1186190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1186290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1186390286Sobrien;; zero are optimized away.
1186490286Sobrien(define_insn "*lshrhi3_one_bit_cmp"
1186590286Sobrien  [(set (reg 17)
1186690286Sobrien	(compare
1186790286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1186890286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1186990286Sobrien	  (const_int 0)))
1187090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1187190286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1187290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11873117404Skan   && (TARGET_SHIFT1 || optimize_size)
1187490286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1187590286Sobrien  "shr{w}\t%0"
1187690286Sobrien  [(set_attr "type" "ishift")
1187790286Sobrien   (set (attr "length") 
1187890286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1187990286Sobrien	(const_string "2")
1188090286Sobrien	(const_string "*")))])
1188190286Sobrien
1188290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1188390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1188490286Sobrien;; zero are optimized away.
1188590286Sobrien(define_insn "*lshrhi3_cmp"
1188690286Sobrien  [(set (reg 17)
1188790286Sobrien	(compare
1188890286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11889102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1189090286Sobrien	  (const_int 0)))
1189190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1189290286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1189390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1189490286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1189590286Sobrien  "shr{w}\t{%2, %0|%0, %2}"
1189690286Sobrien  [(set_attr "type" "ishift")
1189790286Sobrien   (set_attr "mode" "HI")])
1189890286Sobrien
1189990286Sobrien(define_expand "lshrqi3"
1190090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1190190286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1190290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1190390286Sobrien   (clobber (reg:CC 17))]
1190490286Sobrien  "TARGET_QIMODE_MATH"
1190590286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
1190690286Sobrien
1190790286Sobrien(define_insn "*lshrqi3_1_one_bit"
1190850650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1190950650Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1191090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1191190286Sobrien   (clobber (reg:CC 17))]
1191290286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11913117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1191490286Sobrien  "shr{b}\t%0"
1191590286Sobrien  [(set_attr "type" "ishift")
1191690286Sobrien   (set (attr "length") 
1191790286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1191890286Sobrien	(const_string "2")
1191990286Sobrien	(const_string "*")))])
1192090286Sobrien
11921117404Skan(define_insn "*lshrqi3_1_one_bit_slp"
11922117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11923117404Skan	(lshiftrt:QI (match_dup 0)
11924117404Skan		     (match_operand:QI 1 "const_int_1_operand" "")))
11925117404Skan   (clobber (reg:CC 17))]
11926117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11927117404Skan   && (TARGET_SHIFT1 || optimize_size)"
11928117404Skan  "shr{b}\t%0"
11929117404Skan  [(set_attr "type" "ishift1")
11930117404Skan   (set (attr "length") 
11931117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
11932117404Skan	(const_string "2")
11933117404Skan	(const_string "*")))])
11934117404Skan
1193590286Sobrien(define_insn "*lshrqi3_1"
1193690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1193790286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1193890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1193990286Sobrien   (clobber (reg:CC 17))]
1194090286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1194190286Sobrien  "@
1194290286Sobrien   shr{b}\t{%2, %0|%0, %2}
1194390286Sobrien   shr{b}\t{%b2, %0|%0, %b2}"
1194490286Sobrien  [(set_attr "type" "ishift")
1194590286Sobrien   (set_attr "mode" "QI")])
1194690286Sobrien
11947117404Skan(define_insn "*lshrqi3_1_slp"
11948117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11949117404Skan	(lshiftrt:QI (match_dup 0)
11950117404Skan		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11951117404Skan   (clobber (reg:CC 17))]
11952117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11953117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11954117404Skan  "@
11955117404Skan   shr{b}\t{%1, %0|%0, %1}
11956117404Skan   shr{b}\t{%b1, %0|%0, %b1}"
11957117404Skan  [(set_attr "type" "ishift1")
11958117404Skan   (set_attr "mode" "QI")])
11959117404Skan
1196090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1196190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1196290286Sobrien;; zero are optimized away.
1196390286Sobrien(define_insn "*lshrqi2_one_bit_cmp"
1196490286Sobrien  [(set (reg 17)
1196590286Sobrien	(compare
1196690286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1196790286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1196890286Sobrien	  (const_int 0)))
1196990286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1197090286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1197190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11972117404Skan   && (TARGET_SHIFT1 || optimize_size)
1197390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1197490286Sobrien  "shr{b}\t%0"
1197590286Sobrien  [(set_attr "type" "ishift")
1197690286Sobrien   (set (attr "length") 
1197790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1197890286Sobrien	(const_string "2")
1197990286Sobrien	(const_string "*")))])
1198090286Sobrien
1198190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1198290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1198390286Sobrien;; zero are optimized away.
1198490286Sobrien(define_insn "*lshrqi2_cmp"
1198590286Sobrien  [(set (reg 17)
1198690286Sobrien	(compare
1198790286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11988102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1198990286Sobrien	  (const_int 0)))
1199090286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1199190286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1199290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1199390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1199490286Sobrien  "shr{b}\t{%2, %0|%0, %2}"
1199590286Sobrien  [(set_attr "type" "ishift")
1199690286Sobrien   (set_attr "mode" "QI")])
1199718334Speter
1199890286Sobrien;; Rotate instructions
1199918334Speter
1200090286Sobrien(define_expand "rotldi3"
1200190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1200290286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
1200390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1200490286Sobrien   (clobber (reg:CC 17))]
1200590286Sobrien  "TARGET_64BIT"
1200690286Sobrien  "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
1200718334Speter
1200890286Sobrien(define_insn "*rotlsi3_1_one_bit_rex64"
1200990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1201090286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1201190286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1201290286Sobrien   (clobber (reg:CC 17))]
1201390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12014117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1201590286Sobrien  "rol{q}\t%0"
12016117404Skan  [(set_attr "type" "rotate")
1201790286Sobrien   (set (attr "length") 
1201890286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1201990286Sobrien	(const_string "2")
1202090286Sobrien	(const_string "*")))])
1202118334Speter
1202290286Sobrien(define_insn "*rotldi3_1_rex64"
1202390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1202490286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1202590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
1202690286Sobrien   (clobber (reg:CC 17))]
1202790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
1202890286Sobrien  "@
1202990286Sobrien   rol{q}\t{%2, %0|%0, %2}
1203090286Sobrien   rol{q}\t{%b2, %0|%0, %b2}"
12031117404Skan  [(set_attr "type" "rotate")
1203290286Sobrien   (set_attr "mode" "DI")])
1203390286Sobrien
1203490286Sobrien(define_expand "rotlsi3"
1203590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1203690286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
1203790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1203890286Sobrien   (clobber (reg:CC 17))]
1203918334Speter  ""
1204090286Sobrien  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
1204118334Speter
1204290286Sobrien(define_insn "*rotlsi3_1_one_bit"
1204350650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1204490286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1204590286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1204690286Sobrien   (clobber (reg:CC 17))]
1204790286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12048117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1204990286Sobrien  "rol{l}\t%0"
12050117404Skan  [(set_attr "type" "rotate")
1205190286Sobrien   (set (attr "length") 
1205290286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1205390286Sobrien	(const_string "2")
1205490286Sobrien	(const_string "*")))])
1205518334Speter
1205690286Sobrien(define_insn "*rotlsi3_1_one_bit_zext"
1205790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1205890286Sobrien	(zero_extend:DI
1205990286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
1206090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" ""))))
1206190286Sobrien   (clobber (reg:CC 17))]
1206290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12063117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1206490286Sobrien  "rol{l}\t%k0"
12065117404Skan  [(set_attr "type" "rotate")
1206690286Sobrien   (set_attr "length" "2")])
1206718334Speter
1206890286Sobrien(define_insn "*rotlsi3_1"
1206990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1207090286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1207190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1207290286Sobrien   (clobber (reg:CC 17))]
1207390286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
1207490286Sobrien  "@
1207590286Sobrien   rol{l}\t{%2, %0|%0, %2}
1207690286Sobrien   rol{l}\t{%b2, %0|%0, %b2}"
12077117404Skan  [(set_attr "type" "rotate")
1207890286Sobrien   (set_attr "mode" "SI")])
1207918334Speter
1208090286Sobrien(define_insn "*rotlsi3_1_zext"
1208190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1208290286Sobrien	(zero_extend:DI
1208390286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
1208490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1208590286Sobrien   (clobber (reg:CC 17))]
1208690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
1208790286Sobrien  "@
1208890286Sobrien   rol{l}\t{%2, %k0|%k0, %2}
1208990286Sobrien   rol{l}\t{%b2, %k0|%k0, %b2}"
12090117404Skan  [(set_attr "type" "rotate")
1209190286Sobrien   (set_attr "mode" "SI")])
1209218334Speter
1209390286Sobrien(define_expand "rotlhi3"
1209490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1209590286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
1209690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1209790286Sobrien   (clobber (reg:CC 17))]
1209890286Sobrien  "TARGET_HIMODE_MATH"
1209990286Sobrien  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
1210018334Speter
1210190286Sobrien(define_insn "*rotlhi3_1_one_bit"
1210290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1210390286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1210490286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1210590286Sobrien   (clobber (reg:CC 17))]
1210690286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12107117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1210890286Sobrien  "rol{w}\t%0"
12109117404Skan  [(set_attr "type" "rotate")
1211090286Sobrien   (set (attr "length") 
1211190286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1211290286Sobrien	(const_string "2")
1211390286Sobrien	(const_string "*")))])
1211418334Speter
1211590286Sobrien(define_insn "*rotlhi3_1"
1211690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1211790286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1211890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1211990286Sobrien   (clobber (reg:CC 17))]
1212090286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
1212190286Sobrien  "@
1212290286Sobrien   rol{w}\t{%2, %0|%0, %2}
1212390286Sobrien   rol{w}\t{%b2, %0|%0, %b2}"
12124117404Skan  [(set_attr "type" "rotate")
1212590286Sobrien   (set_attr "mode" "HI")])
1212618334Speter
1212790286Sobrien(define_expand "rotlqi3"
1212890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1212990286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
1213090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1213190286Sobrien   (clobber (reg:CC 17))]
1213290286Sobrien  "TARGET_QIMODE_MATH"
1213390286Sobrien  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
1213418334Speter
12135117404Skan(define_insn "*rotlqi3_1_one_bit_slp"
12136117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12137117404Skan	(rotate:QI (match_dup 0)
12138117404Skan		   (match_operand:QI 1 "const_int_1_operand" "")))
12139117404Skan   (clobber (reg:CC 17))]
12140117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141117404Skan   && (TARGET_SHIFT1 || optimize_size)"
12142117404Skan  "rol{b}\t%0"
12143117404Skan  [(set_attr "type" "rotate1")
12144117404Skan   (set (attr "length") 
12145117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
12146117404Skan	(const_string "2")
12147117404Skan	(const_string "*")))])
12148117404Skan
1214990286Sobrien(define_insn "*rotlqi3_1_one_bit"
1215090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1215190286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1215290286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1215390286Sobrien   (clobber (reg:CC 17))]
1215490286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12155117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1215690286Sobrien  "rol{b}\t%0"
12157117404Skan  [(set_attr "type" "rotate")
1215890286Sobrien   (set (attr "length") 
1215990286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1216090286Sobrien	(const_string "2")
1216190286Sobrien	(const_string "*")))])
1216218334Speter
12163117404Skan(define_insn "*rotlqi3_1_slp"
12164117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12165117404Skan	(rotate:QI (match_dup 0)
12166117404Skan		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12167117404Skan   (clobber (reg:CC 17))]
12168117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12169117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12170117404Skan  "@
12171117404Skan   rol{b}\t{%1, %0|%0, %1}
12172117404Skan   rol{b}\t{%b1, %0|%0, %b1}"
12173117404Skan  [(set_attr "type" "rotate1")
12174117404Skan   (set_attr "mode" "QI")])
12175117404Skan
1217690286Sobrien(define_insn "*rotlqi3_1"
1217790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1217890286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1217990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1218090286Sobrien   (clobber (reg:CC 17))]
1218190286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
1218290286Sobrien  "@
1218390286Sobrien   rol{b}\t{%2, %0|%0, %2}
1218490286Sobrien   rol{b}\t{%b2, %0|%0, %b2}"
12185117404Skan  [(set_attr "type" "rotate")
1218690286Sobrien   (set_attr "mode" "QI")])
1218718334Speter
1218890286Sobrien(define_expand "rotrdi3"
1218990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1219090286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
1219190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1219290286Sobrien   (clobber (reg:CC 17))]
1219390286Sobrien  "TARGET_64BIT"
1219490286Sobrien  "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
1219518334Speter
1219690286Sobrien(define_insn "*rotrdi3_1_one_bit_rex64"
1219790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1219890286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1219990286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1220090286Sobrien   (clobber (reg:CC 17))]
1220190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12202117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1220390286Sobrien  "ror{q}\t%0"
12204117404Skan  [(set_attr "type" "rotate")
1220590286Sobrien   (set (attr "length") 
1220690286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1220790286Sobrien	(const_string "2")
1220890286Sobrien	(const_string "*")))])
1220918334Speter
1221090286Sobrien(define_insn "*rotrdi3_1_rex64"
1221190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1221290286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1221390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1221490286Sobrien   (clobber (reg:CC 17))]
1221590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
1221690286Sobrien  "@
1221790286Sobrien   ror{q}\t{%2, %0|%0, %2}
1221890286Sobrien   ror{q}\t{%b2, %0|%0, %b2}"
12219117404Skan  [(set_attr "type" "rotate")
1222090286Sobrien   (set_attr "mode" "DI")])
1222190286Sobrien
1222290286Sobrien(define_expand "rotrsi3"
1222390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1222490286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
1222590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1222690286Sobrien   (clobber (reg:CC 17))]
1222790286Sobrien  ""
1222890286Sobrien  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
1222990286Sobrien
1223090286Sobrien(define_insn "*rotrsi3_1_one_bit"
1223150650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1223290286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1223390286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1223490286Sobrien   (clobber (reg:CC 17))]
1223590286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12236117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1223790286Sobrien  "ror{l}\t%0"
12238117404Skan  [(set_attr "type" "rotate")
1223990286Sobrien   (set (attr "length") 
1224090286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1224190286Sobrien	(const_string "2")
1224290286Sobrien	(const_string "*")))])
1224318334Speter
1224490286Sobrien(define_insn "*rotrsi3_1_one_bit_zext"
1224590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1224690286Sobrien	(zero_extend:DI
1224790286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1224890286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))))
1224990286Sobrien   (clobber (reg:CC 17))]
1225090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12251117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1225290286Sobrien  "ror{l}\t%k0"
12253117404Skan  [(set_attr "type" "rotate")
1225490286Sobrien   (set (attr "length") 
1225590286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1225690286Sobrien	(const_string "2")
1225790286Sobrien	(const_string "*")))])
1225818334Speter
1225990286Sobrien(define_insn "*rotrsi3_1"
1226090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1226190286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1226290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1226390286Sobrien   (clobber (reg:CC 17))]
1226490286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1226590286Sobrien  "@
1226690286Sobrien   ror{l}\t{%2, %0|%0, %2}
1226790286Sobrien   ror{l}\t{%b2, %0|%0, %b2}"
12268117404Skan  [(set_attr "type" "rotate")
1226990286Sobrien   (set_attr "mode" "SI")])
1227018334Speter
1227190286Sobrien(define_insn "*rotrsi3_1_zext"
1227290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1227390286Sobrien	(zero_extend:DI
1227490286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
1227590286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1227690286Sobrien   (clobber (reg:CC 17))]
1227790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1227890286Sobrien  "@
1227990286Sobrien   ror{l}\t{%2, %k0|%k0, %2}
1228090286Sobrien   ror{l}\t{%b2, %k0|%k0, %b2}"
12281117404Skan  [(set_attr "type" "rotate")
1228290286Sobrien   (set_attr "mode" "SI")])
1228318334Speter
1228490286Sobrien(define_expand "rotrhi3"
1228590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1228690286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
1228790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1228890286Sobrien   (clobber (reg:CC 17))]
1228990286Sobrien  "TARGET_HIMODE_MATH"
1229090286Sobrien  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
1229118334Speter
1229290286Sobrien(define_insn "*rotrhi3_one_bit"
1229390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1229490286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1229590286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1229690286Sobrien   (clobber (reg:CC 17))]
1229790286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12298117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1229990286Sobrien  "ror{w}\t%0"
12300117404Skan  [(set_attr "type" "rotate")
1230190286Sobrien   (set (attr "length") 
1230290286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1230390286Sobrien	(const_string "2")
1230490286Sobrien	(const_string "*")))])
1230518334Speter
1230690286Sobrien(define_insn "*rotrhi3"
1230790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1230890286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1230990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1231090286Sobrien   (clobber (reg:CC 17))]
1231190286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
1231290286Sobrien  "@
1231390286Sobrien   ror{w}\t{%2, %0|%0, %2}
1231490286Sobrien   ror{w}\t{%b2, %0|%0, %b2}"
12315117404Skan  [(set_attr "type" "rotate")
1231690286Sobrien   (set_attr "mode" "HI")])
1231718334Speter
1231890286Sobrien(define_expand "rotrqi3"
1231990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1232090286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
1232190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1232290286Sobrien   (clobber (reg:CC 17))]
1232390286Sobrien  "TARGET_QIMODE_MATH"
1232490286Sobrien  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
1232518334Speter
1232690286Sobrien(define_insn "*rotrqi3_1_one_bit"
1232790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1232890286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1232990286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1233090286Sobrien   (clobber (reg:CC 17))]
1233190286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12332117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1233390286Sobrien  "ror{b}\t%0"
12334117404Skan  [(set_attr "type" "rotate")
1233590286Sobrien   (set (attr "length") 
1233690286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1233790286Sobrien	(const_string "2")
1233890286Sobrien	(const_string "*")))])
1233918334Speter
12340117404Skan(define_insn "*rotrqi3_1_one_bit_slp"
12341117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12342117404Skan	(rotatert:QI (match_dup 0)
12343117404Skan		     (match_operand:QI 1 "const_int_1_operand" "")))
12344117404Skan   (clobber (reg:CC 17))]
12345117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12346117404Skan   && (TARGET_SHIFT1 || optimize_size)"
12347117404Skan  "ror{b}\t%0"
12348117404Skan  [(set_attr "type" "rotate1")
12349117404Skan   (set (attr "length") 
12350117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
12351117404Skan	(const_string "2")
12352117404Skan	(const_string "*")))])
12353117404Skan
1235490286Sobrien(define_insn "*rotrqi3_1"
1235590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1235690286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1235790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1235890286Sobrien   (clobber (reg:CC 17))]
1235990286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
1236090286Sobrien  "@
1236190286Sobrien   ror{b}\t{%2, %0|%0, %2}
1236290286Sobrien   ror{b}\t{%b2, %0|%0, %b2}"
12363117404Skan  [(set_attr "type" "rotate")
1236490286Sobrien   (set_attr "mode" "QI")])
12365117404Skan
12366117404Skan(define_insn "*rotrqi3_1_slp"
12367117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12368117404Skan	(rotatert:QI (match_dup 0)
12369117404Skan		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12370117404Skan   (clobber (reg:CC 17))]
12371117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12372117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12373117404Skan  "@
12374117404Skan   ror{b}\t{%1, %0|%0, %1}
12375117404Skan   ror{b}\t{%b1, %0|%0, %b1}"
12376117404Skan  [(set_attr "type" "rotate1")
12377117404Skan   (set_attr "mode" "QI")])
1237890286Sobrien
1237990286Sobrien;; Bit set / bit test instructions
1238018334Speter
1238190286Sobrien(define_expand "extv"
1238290286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1238390286Sobrien	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
1238490286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1238590286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1238690286Sobrien  ""
1238718334Speter{
1238890286Sobrien  /* Handle extractions from %ah et al.  */
1238990286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1239090286Sobrien    FAIL;
1239118334Speter
1239290286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1239390286Sobrien     matches the predicate, so check it again here.  */
1239490286Sobrien  if (! register_operand (operands[1], VOIDmode))
1239590286Sobrien    FAIL;
1239690286Sobrien})
1239718334Speter
1239890286Sobrien(define_expand "extzv"
1239990286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1240090286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
1240190286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1240290286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1240390286Sobrien  ""
1240490286Sobrien{
1240590286Sobrien  /* Handle extractions from %ah et al.  */
1240690286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1240790286Sobrien    FAIL;
1240818334Speter
1240990286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1241090286Sobrien     matches the predicate, so check it again here.  */
1241190286Sobrien  if (! register_operand (operands[1], VOIDmode))
1241290286Sobrien    FAIL;
1241390286Sobrien})
1241418334Speter
1241590286Sobrien(define_expand "insv"
1241690286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
1241790286Sobrien			 (match_operand:SI 1 "immediate_operand" "")
1241890286Sobrien			 (match_operand:SI 2 "immediate_operand" ""))
1241990286Sobrien        (match_operand:SI 3 "register_operand" ""))]
1242090286Sobrien  ""
1242190286Sobrien{
1242290286Sobrien  /* Handle extractions from %ah et al.  */
1242390286Sobrien  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
1242490286Sobrien    FAIL;
1242518334Speter
1242690286Sobrien  /* From mips.md: insert_bit_field doesn't verify that our source
1242790286Sobrien     matches the predicate, so check it again here.  */
1242890286Sobrien  if (! register_operand (operands[0], VOIDmode))
1242990286Sobrien    FAIL;
1243090286Sobrien})
1243118334Speter
1243290286Sobrien;; %%% bts, btr, btc, bt.
1243318334Speter
1243418334Speter;; Store-flag instructions.
1243518334Speter
1243618334Speter;; For all sCOND expanders, also expand the compare or test insn that
1243718334Speter;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
1243818334Speter
1243990286Sobrien;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
1244090286Sobrien;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
1244190286Sobrien;; way, which can later delete the movzx if only QImode is needed.
1244290286Sobrien
1244318334Speter(define_expand "seq"
1244490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1244590286Sobrien        (eq:QI (reg:CC 17) (const_int 0)))]
1244618334Speter  ""
1244790286Sobrien  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
1244818334Speter
1244918334Speter(define_expand "sne"
1245090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1245190286Sobrien        (ne:QI (reg:CC 17) (const_int 0)))]
1245218334Speter  ""
1245390286Sobrien  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
1245418334Speter
1245518334Speter(define_expand "sgt"
1245690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1245790286Sobrien        (gt:QI (reg:CC 17) (const_int 0)))]
1245818334Speter  ""
1245990286Sobrien  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
1246018334Speter
1246118334Speter(define_expand "sgtu"
1246290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1246390286Sobrien        (gtu:QI (reg:CC 17) (const_int 0)))]
1246418334Speter  ""
1246590286Sobrien  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
1246618334Speter
1246718334Speter(define_expand "slt"
1246890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1246990286Sobrien        (lt:QI (reg:CC 17) (const_int 0)))]
1247018334Speter  ""
1247190286Sobrien  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
1247218334Speter
1247318334Speter(define_expand "sltu"
1247490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1247590286Sobrien        (ltu:QI (reg:CC 17) (const_int 0)))]
1247618334Speter  ""
1247790286Sobrien  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
1247818334Speter
1247918334Speter(define_expand "sge"
1248090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1248190286Sobrien        (ge:QI (reg:CC 17) (const_int 0)))]
1248218334Speter  ""
1248390286Sobrien  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
1248418334Speter
1248518334Speter(define_expand "sgeu"
1248690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1248790286Sobrien        (geu:QI (reg:CC 17) (const_int 0)))]
1248818334Speter  ""
1248990286Sobrien  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
1249018334Speter
1249118334Speter(define_expand "sle"
1249290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1249390286Sobrien        (le:QI (reg:CC 17) (const_int 0)))]
1249418334Speter  ""
1249590286Sobrien  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
1249618334Speter
1249718334Speter(define_expand "sleu"
1249890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1249990286Sobrien        (leu:QI (reg:CC 17) (const_int 0)))]
1250018334Speter  ""
1250190286Sobrien  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
1250218334Speter
1250390286Sobrien(define_expand "sunordered"
1250490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1250590286Sobrien        (unordered:QI (reg:CC 17) (const_int 0)))]
1250690286Sobrien  "TARGET_80387 || TARGET_SSE"
1250790286Sobrien  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
1250852296Sobrien
1250990286Sobrien(define_expand "sordered"
1251090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1251190286Sobrien        (ordered:QI (reg:CC 17) (const_int 0)))]
1251290286Sobrien  "TARGET_80387"
1251390286Sobrien  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
1251490286Sobrien
1251590286Sobrien(define_expand "suneq"
1251690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1251790286Sobrien        (uneq:QI (reg:CC 17) (const_int 0)))]
1251890286Sobrien  "TARGET_80387 || TARGET_SSE"
1251990286Sobrien  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
1252090286Sobrien
1252190286Sobrien(define_expand "sunge"
1252290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1252390286Sobrien        (unge:QI (reg:CC 17) (const_int 0)))]
1252490286Sobrien  "TARGET_80387 || TARGET_SSE"
1252590286Sobrien  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
1252690286Sobrien
1252790286Sobrien(define_expand "sungt"
1252890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1252990286Sobrien        (ungt:QI (reg:CC 17) (const_int 0)))]
1253090286Sobrien  "TARGET_80387 || TARGET_SSE"
1253190286Sobrien  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
1253290286Sobrien
1253390286Sobrien(define_expand "sunle"
1253490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1253590286Sobrien        (unle:QI (reg:CC 17) (const_int 0)))]
1253690286Sobrien  "TARGET_80387 || TARGET_SSE"
1253790286Sobrien  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
1253890286Sobrien
1253990286Sobrien(define_expand "sunlt"
1254090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1254190286Sobrien        (unlt:QI (reg:CC 17) (const_int 0)))]
1254290286Sobrien  "TARGET_80387 || TARGET_SSE"
1254390286Sobrien  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
1254490286Sobrien
1254590286Sobrien(define_expand "sltgt"
1254690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1254790286Sobrien        (ltgt:QI (reg:CC 17) (const_int 0)))]
1254890286Sobrien  "TARGET_80387 || TARGET_SSE"
1254990286Sobrien  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
1255090286Sobrien
1255190286Sobrien(define_insn "*setcc_1"
1255252296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1255390286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1255490286Sobrien	  [(reg 17) (const_int 0)]))]
1255590286Sobrien  ""
1255690286Sobrien  "set%C1\t%0"
1255790286Sobrien  [(set_attr "type" "setcc")
1255890286Sobrien   (set_attr "mode" "QI")])
1255990286Sobrien
1256090286Sobrien(define_insn "setcc_2"
1256190286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1256290286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1256390286Sobrien	  [(reg 17) (const_int 0)]))]
1256490286Sobrien  ""
1256590286Sobrien  "set%C1\t%0"
1256690286Sobrien  [(set_attr "type" "setcc")
1256790286Sobrien   (set_attr "mode" "QI")])
1256890286Sobrien
1256990286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1257090286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1257190286Sobrien;; conditions this is safe on x86, so help combine not create
1257290286Sobrien;;
1257390286Sobrien;;	seta	%al
1257490286Sobrien;;	testb	%al, %al
1257590286Sobrien;;	sete	%al
1257690286Sobrien
1257790286Sobrien(define_split 
1257890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1257990286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1258090286Sobrien	         [(reg 17) (const_int 0)])
1258190286Sobrien	    (const_int 0)))]
1258290286Sobrien  ""
1258390286Sobrien  [(set (match_dup 0) (match_dup 1))]
1258452296Sobrien{
1258590286Sobrien  PUT_MODE (operands[1], QImode);
1258690286Sobrien})
1258752296Sobrien
1258890286Sobrien(define_split 
1258990286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1259090286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1259190286Sobrien	         [(reg 17) (const_int 0)])
1259290286Sobrien	    (const_int 0)))]
1259390286Sobrien  ""
1259490286Sobrien  [(set (match_dup 0) (match_dup 1))]
1259590286Sobrien{
1259690286Sobrien  PUT_MODE (operands[1], QImode);
1259790286Sobrien})
1259852296Sobrien
1259990286Sobrien(define_split 
1260090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1260190286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1260290286Sobrien	         [(reg 17) (const_int 0)])
1260390286Sobrien	    (const_int 0)))]
1260490286Sobrien  ""
1260590286Sobrien  [(set (match_dup 0) (match_dup 1))]
1260690286Sobrien{
1260790286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1260890286Sobrien  operands[1] = new_op1;
1260990286Sobrien  PUT_MODE (new_op1, QImode);
1261090286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1261190286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1261290286Sobrien
1261390286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1261490286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1261590286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1261690286Sobrien    FAIL;
1261790286Sobrien})
1261890286Sobrien
1261990286Sobrien(define_split 
1262090286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1262190286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1262290286Sobrien	         [(reg 17) (const_int 0)])
1262390286Sobrien	    (const_int 0)))]
1262490286Sobrien  ""
1262590286Sobrien  [(set (match_dup 0) (match_dup 1))]
1262690286Sobrien{
1262790286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1262890286Sobrien  operands[1] = new_op1;
1262990286Sobrien  PUT_MODE (new_op1, QImode);
1263090286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1263190286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1263290286Sobrien
1263390286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1263490286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1263590286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1263690286Sobrien    FAIL;
1263790286Sobrien})
1263890286Sobrien
1263990286Sobrien;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
1264090286Sobrien;; subsequent logical operations are used to imitate conditional moves.
1264190286Sobrien;; 0xffffffff is NaN, but not in normalized form, so we can't represent
1264290286Sobrien;; it directly.  Futher holding this value in pseudo register might bring
1264390286Sobrien;; problem in implicit normalization in spill code.
1264490286Sobrien;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
1264590286Sobrien;; instructions after reload by splitting the conditional move patterns.
1264690286Sobrien
1264790286Sobrien(define_insn "*sse_setccsf"
1264890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1264990286Sobrien	(match_operator:SF 1 "sse_comparison_operator"
1265090286Sobrien	  [(match_operand:SF 2 "register_operand" "0")
1265190286Sobrien	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
1265290286Sobrien  "TARGET_SSE && reload_completed"
1265390286Sobrien  "cmp%D1ss\t{%3, %0|%0, %3}"
12654117404Skan  [(set_attr "type" "ssecmp")
1265590286Sobrien   (set_attr "mode" "SF")])
1265690286Sobrien
1265790286Sobrien(define_insn "*sse_setccdf"
1265890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1265990286Sobrien	(match_operator:DF 1 "sse_comparison_operator"
1266090286Sobrien	  [(match_operand:DF 2 "register_operand" "0")
1266190286Sobrien	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
1266290286Sobrien  "TARGET_SSE2 && reload_completed"
1266390286Sobrien  "cmp%D1sd\t{%3, %0|%0, %3}"
12664117404Skan  [(set_attr "type" "ssecmp")
1266590286Sobrien   (set_attr "mode" "DF")])
1266618334Speter
1266718334Speter;; Basic conditional jump instructions.
1266818334Speter;; We ignore the overflow flag for signed branch instructions.
1266918334Speter
1267018334Speter;; For all bCOND expanders, also expand the compare or test insn that
1267190286Sobrien;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
1267218334Speter
1267318334Speter(define_expand "beq"
1267490286Sobrien  [(set (pc)
1267590286Sobrien	(if_then_else (match_dup 1)
1267618334Speter		      (label_ref (match_operand 0 "" ""))
1267718334Speter		      (pc)))]
1267818334Speter  ""
1267990286Sobrien  "ix86_expand_branch (EQ, operands[0]); DONE;")
1268018334Speter
1268118334Speter(define_expand "bne"
1268290286Sobrien  [(set (pc)
1268390286Sobrien	(if_then_else (match_dup 1)
1268418334Speter		      (label_ref (match_operand 0 "" ""))
1268518334Speter		      (pc)))]
1268618334Speter  ""
1268790286Sobrien  "ix86_expand_branch (NE, operands[0]); DONE;")
1268818334Speter
1268918334Speter(define_expand "bgt"
1269090286Sobrien  [(set (pc)
1269190286Sobrien	(if_then_else (match_dup 1)
1269218334Speter		      (label_ref (match_operand 0 "" ""))
1269318334Speter		      (pc)))]
1269418334Speter  ""
1269590286Sobrien  "ix86_expand_branch (GT, operands[0]); DONE;")
1269618334Speter
1269718334Speter(define_expand "bgtu"
1269890286Sobrien  [(set (pc)
1269990286Sobrien	(if_then_else (match_dup 1)
1270018334Speter		      (label_ref (match_operand 0 "" ""))
1270118334Speter		      (pc)))]
1270218334Speter  ""
1270390286Sobrien  "ix86_expand_branch (GTU, operands[0]); DONE;")
1270418334Speter
1270518334Speter(define_expand "blt"
1270690286Sobrien  [(set (pc)
1270790286Sobrien	(if_then_else (match_dup 1)
1270818334Speter		      (label_ref (match_operand 0 "" ""))
1270918334Speter		      (pc)))]
1271018334Speter  ""
1271190286Sobrien  "ix86_expand_branch (LT, operands[0]); DONE;")
1271218334Speter
1271318334Speter(define_expand "bltu"
1271490286Sobrien  [(set (pc)
1271590286Sobrien	(if_then_else (match_dup 1)
1271618334Speter		      (label_ref (match_operand 0 "" ""))
1271718334Speter		      (pc)))]
1271818334Speter  ""
1271990286Sobrien  "ix86_expand_branch (LTU, operands[0]); DONE;")
1272018334Speter
1272118334Speter(define_expand "bge"
1272290286Sobrien  [(set (pc)
1272390286Sobrien	(if_then_else (match_dup 1)
1272418334Speter		      (label_ref (match_operand 0 "" ""))
1272518334Speter		      (pc)))]
1272618334Speter  ""
1272790286Sobrien  "ix86_expand_branch (GE, operands[0]); DONE;")
1272818334Speter
1272918334Speter(define_expand "bgeu"
1273090286Sobrien  [(set (pc)
1273190286Sobrien	(if_then_else (match_dup 1)
1273218334Speter		      (label_ref (match_operand 0 "" ""))
1273318334Speter		      (pc)))]
1273418334Speter  ""
1273590286Sobrien  "ix86_expand_branch (GEU, operands[0]); DONE;")
1273618334Speter
1273718334Speter(define_expand "ble"
1273890286Sobrien  [(set (pc)
1273990286Sobrien	(if_then_else (match_dup 1)
1274018334Speter		      (label_ref (match_operand 0 "" ""))
1274118334Speter		      (pc)))]
1274218334Speter  ""
1274390286Sobrien  "ix86_expand_branch (LE, operands[0]); DONE;")
1274418334Speter
1274518334Speter(define_expand "bleu"
1274690286Sobrien  [(set (pc)
1274790286Sobrien	(if_then_else (match_dup 1)
1274818334Speter		      (label_ref (match_operand 0 "" ""))
1274918334Speter		      (pc)))]
1275018334Speter  ""
1275190286Sobrien  "ix86_expand_branch (LEU, operands[0]); DONE;")
1275218334Speter
1275390286Sobrien(define_expand "bunordered"
1275418334Speter  [(set (pc)
1275590286Sobrien	(if_then_else (match_dup 1)
1275690286Sobrien		      (label_ref (match_operand 0 "" ""))
1275718334Speter		      (pc)))]
1275890286Sobrien  "TARGET_80387 || TARGET_SSE"
1275990286Sobrien  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
1276018334Speter
1276190286Sobrien(define_expand "bordered"
1276290286Sobrien  [(set (pc)
1276390286Sobrien	(if_then_else (match_dup 1)
1276490286Sobrien		      (label_ref (match_operand 0 "" ""))
1276590286Sobrien		      (pc)))]
1276690286Sobrien  "TARGET_80387 || TARGET_SSE"
1276790286Sobrien  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
1276818334Speter
1276990286Sobrien(define_expand "buneq"
1277018334Speter  [(set (pc)
1277190286Sobrien	(if_then_else (match_dup 1)
1277290286Sobrien		      (label_ref (match_operand 0 "" ""))
1277390286Sobrien		      (pc)))]
1277490286Sobrien  "TARGET_80387 || TARGET_SSE"
1277590286Sobrien  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
1277618334Speter
1277790286Sobrien(define_expand "bunge"
1277890286Sobrien  [(set (pc)
1277990286Sobrien	(if_then_else (match_dup 1)
1278090286Sobrien		      (label_ref (match_operand 0 "" ""))
1278190286Sobrien		      (pc)))]
1278290286Sobrien  "TARGET_80387 || TARGET_SSE"
1278390286Sobrien  "ix86_expand_branch (UNGE, operands[0]); DONE;")
1278418334Speter
1278590286Sobrien(define_expand "bungt"
1278618334Speter  [(set (pc)
1278790286Sobrien	(if_then_else (match_dup 1)
1278890286Sobrien		      (label_ref (match_operand 0 "" ""))
1278990286Sobrien		      (pc)))]
1279090286Sobrien  "TARGET_80387 || TARGET_SSE"
1279190286Sobrien  "ix86_expand_branch (UNGT, operands[0]); DONE;")
1279218334Speter
1279390286Sobrien(define_expand "bunle"
1279490286Sobrien  [(set (pc)
1279590286Sobrien	(if_then_else (match_dup 1)
1279690286Sobrien		      (label_ref (match_operand 0 "" ""))
1279790286Sobrien		      (pc)))]
1279890286Sobrien  "TARGET_80387 || TARGET_SSE"
1279990286Sobrien  "ix86_expand_branch (UNLE, operands[0]); DONE;")
1280018334Speter
1280190286Sobrien(define_expand "bunlt"
1280290286Sobrien  [(set (pc)
1280390286Sobrien	(if_then_else (match_dup 1)
1280490286Sobrien		      (label_ref (match_operand 0 "" ""))
1280590286Sobrien		      (pc)))]
1280690286Sobrien  "TARGET_80387 || TARGET_SSE"
1280790286Sobrien  "ix86_expand_branch (UNLT, operands[0]); DONE;")
1280818334Speter
1280990286Sobrien(define_expand "bltgt"
1281090286Sobrien  [(set (pc)
1281190286Sobrien	(if_then_else (match_dup 1)
1281290286Sobrien		      (label_ref (match_operand 0 "" ""))
1281390286Sobrien		      (pc)))]
1281490286Sobrien  "TARGET_80387 || TARGET_SSE"
1281590286Sobrien  "ix86_expand_branch (LTGT, operands[0]); DONE;")
1281618334Speter
1281790286Sobrien(define_insn "*jcc_1"
1281890286Sobrien  [(set (pc)
1281990286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1282090286Sobrien				      [(reg 17) (const_int 0)])
1282190286Sobrien		      (label_ref (match_operand 0 "" ""))
1282290286Sobrien		      (pc)))]
1282318334Speter  ""
1282490286Sobrien  "%+j%C1\t%l0"
1282590286Sobrien  [(set_attr "type" "ibr")
12826117404Skan   (set_attr "modrm" "0")
12827117404Skan   (set (attr "length")
1282890286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
12829117404Skan				  (const_int -126))
1283090286Sobrien			      (lt (minus (match_dup 0) (pc))
12831117404Skan				  (const_int 128)))
12832117404Skan	     (const_int 2)
12833117404Skan	     (const_int 6)))])
1283418334Speter
1283590286Sobrien(define_insn "*jcc_2"
1283618334Speter  [(set (pc)
1283790286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1283890286Sobrien				      [(reg 17) (const_int 0)])
1283990286Sobrien		      (pc)
1284090286Sobrien		      (label_ref (match_operand 0 "" ""))))]
1284118334Speter  ""
1284290286Sobrien  "%+j%c1\t%l0"
1284390286Sobrien  [(set_attr "type" "ibr")
12844117404Skan   (set_attr "modrm" "0")
12845117404Skan   (set (attr "length")
1284690286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
12847117404Skan				  (const_int -126))
1284890286Sobrien			      (lt (minus (match_dup 0) (pc))
12849117404Skan				  (const_int 128)))
12850117404Skan	     (const_int 2)
12851117404Skan	     (const_int 6)))])
1285290286Sobrien
1285390286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1285490286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1285590286Sobrien;; conditions this is safe on x86, so help combine not create
1285690286Sobrien;;
1285790286Sobrien;;	seta	%al
1285890286Sobrien;;	testb	%al, %al
1285990286Sobrien;;	je	Lfoo
1286090286Sobrien
1286190286Sobrien(define_split 
1286290286Sobrien  [(set (pc)
1286390286Sobrien	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
1286490286Sobrien				      [(reg 17) (const_int 0)])
1286590286Sobrien			  (const_int 0))
1286690286Sobrien		      (label_ref (match_operand 1 "" ""))
1286790286Sobrien		      (pc)))]
1286890286Sobrien  ""
1286990286Sobrien  [(set (pc)
1287090286Sobrien	(if_then_else (match_dup 0)
1287190286Sobrien		      (label_ref (match_dup 1))
1287290286Sobrien		      (pc)))]
1287318334Speter{
1287490286Sobrien  PUT_MODE (operands[0], VOIDmode);
1287590286Sobrien})
1287690286Sobrien  
1287790286Sobrien(define_split 
1287890286Sobrien  [(set (pc)
1287990286Sobrien	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
1288090286Sobrien				      [(reg 17) (const_int 0)])
1288190286Sobrien			  (const_int 0))
1288290286Sobrien		      (label_ref (match_operand 1 "" ""))
1288390286Sobrien		      (pc)))]
1288490286Sobrien  ""
1288590286Sobrien  [(set (pc)
1288690286Sobrien	(if_then_else (match_dup 0)
1288790286Sobrien		      (label_ref (match_dup 1))
1288890286Sobrien		      (pc)))]
1288990286Sobrien{
1289090286Sobrien  rtx new_op0 = copy_rtx (operands[0]);
1289190286Sobrien  operands[0] = new_op0;
1289290286Sobrien  PUT_MODE (new_op0, VOIDmode);
1289390286Sobrien  PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
1289490286Sobrien					GET_MODE (XEXP (new_op0, 0))));
1289552296Sobrien
1289690286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1289790286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1289890286Sobrien  if (! ix86_comparison_operator (new_op0, VOIDmode))
1289990286Sobrien    FAIL;
1290090286Sobrien})
1290152296Sobrien
1290290286Sobrien;; Define combination compare-and-branch fp compare instructions to use
1290390286Sobrien;; during early optimization.  Splitting the operation apart early makes
1290490286Sobrien;; for bad code when we want to reverse the operation.
1290518334Speter
1290690286Sobrien(define_insn "*fp_jcc_1"
1290790286Sobrien  [(set (pc)
1290890286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1290990286Sobrien			[(match_operand 1 "register_operand" "f")
1291090286Sobrien			 (match_operand 2 "register_operand" "f")])
1291190286Sobrien	  (label_ref (match_operand 3 "" ""))
1291290286Sobrien	  (pc)))
1291390286Sobrien   (clobber (reg:CCFP 18))
1291490286Sobrien   (clobber (reg:CCFP 17))]
1291590286Sobrien  "TARGET_CMOVE && TARGET_80387
1291690286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1291790286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1291890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1291990286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1292090286Sobrien  "#")
1292118334Speter
1292290286Sobrien(define_insn "*fp_jcc_1_sse"
1292390286Sobrien  [(set (pc)
1292490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1292590286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1292690286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1292790286Sobrien	  (label_ref (match_operand 3 "" ""))
1292890286Sobrien	  (pc)))
1292990286Sobrien   (clobber (reg:CCFP 18))
1293090286Sobrien   (clobber (reg:CCFP 17))]
1293190286Sobrien  "TARGET_80387
1293290286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1293390286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1293490286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1293590286Sobrien  "#")
1293618334Speter
1293790286Sobrien(define_insn "*fp_jcc_1_sse_only"
1293890286Sobrien  [(set (pc)
1293990286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1294090286Sobrien			[(match_operand 1 "register_operand" "x")
1294190286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1294290286Sobrien	  (label_ref (match_operand 3 "" ""))
1294390286Sobrien	  (pc)))
1294490286Sobrien   (clobber (reg:CCFP 18))
1294590286Sobrien   (clobber (reg:CCFP 17))]
1294690286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1294790286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1294890286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1294990286Sobrien  "#")
1295018334Speter
1295190286Sobrien(define_insn "*fp_jcc_2"
1295218334Speter  [(set (pc)
1295390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1295490286Sobrien			[(match_operand 1 "register_operand" "f")
1295590286Sobrien			 (match_operand 2 "register_operand" "f")])
1295690286Sobrien	  (pc)
1295790286Sobrien	  (label_ref (match_operand 3 "" ""))))
1295890286Sobrien   (clobber (reg:CCFP 18))
1295990286Sobrien   (clobber (reg:CCFP 17))]
1296090286Sobrien  "TARGET_CMOVE && TARGET_80387
1296190286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1296290286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1296390286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1296490286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1296590286Sobrien  "#")
1296618334Speter
1296790286Sobrien(define_insn "*fp_jcc_2_sse"
1296890286Sobrien  [(set (pc)
1296990286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1297090286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1297190286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1297290286Sobrien	  (pc)
1297390286Sobrien	  (label_ref (match_operand 3 "" ""))))
1297490286Sobrien   (clobber (reg:CCFP 18))
1297590286Sobrien   (clobber (reg:CCFP 17))]
1297690286Sobrien  "TARGET_80387
1297790286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1297890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1297990286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1298090286Sobrien  "#")
1298118334Speter
1298290286Sobrien(define_insn "*fp_jcc_2_sse_only"
1298390286Sobrien  [(set (pc)
1298490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1298590286Sobrien			[(match_operand 1 "register_operand" "x")
1298690286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1298790286Sobrien	  (pc)
1298890286Sobrien	  (label_ref (match_operand 3 "" ""))))
1298990286Sobrien   (clobber (reg:CCFP 18))
1299090286Sobrien   (clobber (reg:CCFP 17))]
1299190286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1299290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1299390286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1299490286Sobrien  "#")
1299518334Speter
1299690286Sobrien(define_insn "*fp_jcc_3"
1299790286Sobrien  [(set (pc)
1299890286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1299990286Sobrien			[(match_operand 1 "register_operand" "f")
1300090286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1300190286Sobrien	  (label_ref (match_operand 3 "" ""))
1300290286Sobrien	  (pc)))
1300390286Sobrien   (clobber (reg:CCFP 18))
1300490286Sobrien   (clobber (reg:CCFP 17))
1300590286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1300690286Sobrien  "TARGET_80387
1300790286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1300890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1300990286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1301090286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1301190286Sobrien		      operands[1], operands[2]) == CCFPmode
1301290286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1301390286Sobrien  "#")
1301418334Speter
1301590286Sobrien(define_insn "*fp_jcc_4"
1301650650Sobrien  [(set (pc)
1301790286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1301890286Sobrien			[(match_operand 1 "register_operand" "f")
1301990286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1302090286Sobrien	  (pc)
1302190286Sobrien	  (label_ref (match_operand 3 "" ""))))
1302290286Sobrien   (clobber (reg:CCFP 18))
1302390286Sobrien   (clobber (reg:CCFP 17))
1302490286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1302590286Sobrien  "TARGET_80387
1302690286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1302790286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1302890286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1302990286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1303090286Sobrien		      operands[1], operands[2]) == CCFPmode
1303190286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1303290286Sobrien  "#")
1303350650Sobrien
1303490286Sobrien(define_insn "*fp_jcc_5"
1303550650Sobrien  [(set (pc)
1303690286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1303790286Sobrien			[(match_operand 1 "register_operand" "f")
1303890286Sobrien			 (match_operand 2 "register_operand" "f")])
1303990286Sobrien	  (label_ref (match_operand 3 "" ""))
1304090286Sobrien	  (pc)))
1304190286Sobrien   (clobber (reg:CCFP 18))
1304290286Sobrien   (clobber (reg:CCFP 17))
1304390286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1304490286Sobrien  "TARGET_80387
1304590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1304690286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1304790286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1304890286Sobrien  "#")
1304950650Sobrien
1305090286Sobrien(define_insn "*fp_jcc_6"
1305150650Sobrien  [(set (pc)
1305290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1305390286Sobrien			[(match_operand 1 "register_operand" "f")
1305490286Sobrien			 (match_operand 2 "register_operand" "f")])
1305590286Sobrien	  (pc)
1305690286Sobrien	  (label_ref (match_operand 3 "" ""))))
1305790286Sobrien   (clobber (reg:CCFP 18))
1305890286Sobrien   (clobber (reg:CCFP 17))
1305990286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1306090286Sobrien  "TARGET_80387
1306190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1306290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1306390286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1306490286Sobrien  "#")
1306550650Sobrien
1306690286Sobrien(define_split
1306750650Sobrien  [(set (pc)
1306890286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1306990286Sobrien			[(match_operand 1 "register_operand" "")
1307090286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1307190286Sobrien	  (match_operand 3 "" "")
1307290286Sobrien	  (match_operand 4 "" "")))
1307390286Sobrien   (clobber (reg:CCFP 18))
1307490286Sobrien   (clobber (reg:CCFP 17))]
1307590286Sobrien  "reload_completed"
1307690286Sobrien  [(const_int 0)]
1307750650Sobrien{
1307890286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1307990286Sobrien			operands[3], operands[4], NULL_RTX);
1308090286Sobrien  DONE;
1308190286Sobrien})
1308250650Sobrien
1308390286Sobrien(define_split
1308450650Sobrien  [(set (pc)
1308590286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1308690286Sobrien			[(match_operand 1 "register_operand" "")
1308790286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1308890286Sobrien	  (match_operand 3 "" "")
1308990286Sobrien	  (match_operand 4 "" "")))
1309090286Sobrien   (clobber (reg:CCFP 18))
1309190286Sobrien   (clobber (reg:CCFP 17))
1309290286Sobrien   (clobber (match_scratch:HI 5 "=a"))]
1309390286Sobrien  "reload_completed"
1309490286Sobrien  [(set (pc)
1309590286Sobrien	(if_then_else (match_dup 6)
1309690286Sobrien	  (match_dup 3)
1309790286Sobrien	  (match_dup 4)))]
1309850650Sobrien{
1309990286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1310090286Sobrien			operands[3], operands[4], operands[5]);
1310190286Sobrien  DONE;
1310290286Sobrien})
1310390286Sobrien
1310490286Sobrien;; Unconditional and other jump instructions
1310550650Sobrien
1310690286Sobrien(define_insn "jump"
1310750650Sobrien  [(set (pc)
1310890286Sobrien	(label_ref (match_operand 0 "" "")))]
1310950650Sobrien  ""
1311090286Sobrien  "jmp\t%l0"
13111117404Skan  [(set_attr "type" "ibr")
13112117404Skan   (set (attr "length")
13113117404Skan	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13114117404Skan				  (const_int -126))
13115117404Skan			      (lt (minus (match_dup 0) (pc))
13116117404Skan				  (const_int 128)))
13117117404Skan	     (const_int 2)
13118117404Skan	     (const_int 5)))
13119117404Skan   (set_attr "modrm" "0")])
1312090286Sobrien
1312190286Sobrien(define_expand "indirect_jump"
1312290286Sobrien  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
1312390286Sobrien  ""
1312490286Sobrien  "")
1312590286Sobrien
1312690286Sobrien(define_insn "*indirect_jump"
1312790286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
1312890286Sobrien  "!TARGET_64BIT"
1312990286Sobrien  "jmp\t%A0"
1313090286Sobrien  [(set_attr "type" "ibr")
1313190286Sobrien   (set_attr "length_immediate" "0")])
1313290286Sobrien
1313390286Sobrien(define_insn "*indirect_jump_rtx64"
1313490286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
1313590286Sobrien  "TARGET_64BIT"
1313690286Sobrien  "jmp\t%A0"
1313790286Sobrien  [(set_attr "type" "ibr")
1313890286Sobrien   (set_attr "length_immediate" "0")])
1313990286Sobrien
1314090286Sobrien(define_expand "tablejump"
1314190286Sobrien  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
1314290286Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
1314390286Sobrien  ""
1314450650Sobrien{
13145117404Skan  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13146117404Skan     relative.  Convert the relative address to an absolute address.  */
1314790286Sobrien  if (flag_pic)
1314890286Sobrien    {
13149117404Skan      rtx op0, op1;
13150117404Skan      enum rtx_code code;
13151117404Skan
1315290286Sobrien      if (TARGET_64BIT)
1315390286Sobrien	{
13154117404Skan	  code = PLUS;
13155117404Skan	  op0 = operands[0];
13156117404Skan	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1315790286Sobrien	}
13158117404Skan      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13159117404Skan	{
13160117404Skan	  code = PLUS;
13161117404Skan	  op0 = operands[0];
13162117404Skan	  op1 = pic_offset_table_rtx;
13163117404Skan	}
1316490286Sobrien      else
1316590286Sobrien	{
13166117404Skan	  code = MINUS;
13167117404Skan	  op0 = pic_offset_table_rtx;
13168117404Skan	  op1 = operands[0];
1316990286Sobrien	}
13170117404Skan
13171117404Skan      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13172117404Skan					 OPTAB_DIRECT);
1317390286Sobrien    }
1317490286Sobrien})
1317550650Sobrien
1317690286Sobrien(define_insn "*tablejump_1"
1317790286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
1317890286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1317990286Sobrien  "!TARGET_64BIT"
1318090286Sobrien  "jmp\t%A0"
1318190286Sobrien  [(set_attr "type" "ibr")
1318290286Sobrien   (set_attr "length_immediate" "0")])
1318318334Speter
1318490286Sobrien(define_insn "*tablejump_1_rtx64"
1318590286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
1318690286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1318790286Sobrien  "TARGET_64BIT"
1318890286Sobrien  "jmp\t%A0"
1318990286Sobrien  [(set_attr "type" "ibr")
1319090286Sobrien   (set_attr "length_immediate" "0")])
1319190286Sobrien
1319290286Sobrien;; Loop instruction
1319390286Sobrien;;
1319490286Sobrien;; This is all complicated by the fact that since this is a jump insn
1319590286Sobrien;; we must handle our own reloads.
1319618334Speter
1319790286Sobrien(define_expand "doloop_end"
1319890286Sobrien  [(use (match_operand 0 "" ""))        ; loop pseudo
1319990286Sobrien   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
1320090286Sobrien   (use (match_operand 2 "" ""))        ; max iterations
1320190286Sobrien   (use (match_operand 3 "" ""))        ; loop level 
1320290286Sobrien   (use (match_operand 4 "" ""))]       ; label
1320390286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1320490286Sobrien  "                                 
1320518334Speter{
1320690286Sobrien  /* Only use cloop on innermost loops.  */
1320790286Sobrien  if (INTVAL (operands[3]) > 1)
1320890286Sobrien    FAIL;
1320990286Sobrien  if (GET_MODE (operands[0]) != SImode)
1321090286Sobrien    FAIL;
1321190286Sobrien  emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
1321290286Sobrien					   operands[0]));
1321390286Sobrien  DONE;
1321418334Speter}")
1321518334Speter
1321690286Sobrien(define_insn "doloop_end_internal"
1321718334Speter  [(set (pc)
1321890286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
1321990286Sobrien			  (const_int 1))
1322090286Sobrien		      (label_ref (match_operand 0 "" ""))
1322190286Sobrien		      (pc)))
1322290286Sobrien   (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
1322390286Sobrien	(plus:SI (match_dup 1)
1322490286Sobrien		 (const_int -1)))
1322590286Sobrien   (clobber (match_scratch:SI 3 "=X,X,r"))
1322690286Sobrien   (clobber (reg:CC 17))]
1322790286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1322818334Speter{
1322990286Sobrien  if (which_alternative != 0)
1323090286Sobrien    return "#";
1323190286Sobrien  if (get_attr_length (insn) == 2)
1323290286Sobrien    return "%+loop\t%l0";
1323390286Sobrien  else
1323490286Sobrien    return "dec{l}\t%1\;%+jne\t%l0";
1323590286Sobrien}
1323690286Sobrien  [(set_attr "ppro_uops" "many")
13237117404Skan   (set (attr "length")
1323890286Sobrien	(if_then_else (and (eq_attr "alternative" "0")
1323990286Sobrien			   (and (ge (minus (match_dup 0) (pc))
13240117404Skan			            (const_int -126))
1324190286Sobrien			        (lt (minus (match_dup 0) (pc))
13242117404Skan			            (const_int 128))))
13243117404Skan		      (const_int 2)
13244117404Skan		      (const_int 16)))
13245117404Skan   ;; We don't know the type before shorten branches.  Optimistically expect
13246117404Skan   ;; the loop instruction to match.
13247117404Skan   (set (attr "type") (const_string "ibr"))])
1324818334Speter
1324990286Sobrien(define_split
1325090286Sobrien  [(set (pc)
1325190286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1325290286Sobrien			  (const_int 1))
1325390286Sobrien		      (match_operand 0 "" "")
1325490286Sobrien		      (pc)))
1325590286Sobrien   (set (match_dup 1)
1325690286Sobrien	(plus:SI (match_dup 1)
1325790286Sobrien		 (const_int -1)))
1325890286Sobrien   (clobber (match_scratch:SI 2 ""))
1325990286Sobrien   (clobber (reg:CC 17))]
1326090286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1326190286Sobrien   && reload_completed
1326290286Sobrien   && REGNO (operands[1]) != 2"
1326390286Sobrien  [(parallel [(set (reg:CCZ 17)
1326490286Sobrien		   (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
1326590286Sobrien				 (const_int 0)))
1326690286Sobrien	      (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
1326790286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1326890286Sobrien			   (match_dup 0)
1326990286Sobrien			   (pc)))]
1327090286Sobrien  "")
1327190286Sobrien  
1327290286Sobrien(define_split
1327390286Sobrien  [(set (pc)
1327490286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1327590286Sobrien			  (const_int 1))
1327690286Sobrien		      (match_operand 0 "" "")
1327790286Sobrien		      (pc)))
1327890286Sobrien   (set (match_operand:SI 2 "nonimmediate_operand" "")
1327990286Sobrien	(plus:SI (match_dup 1)
1328090286Sobrien		 (const_int -1)))
1328190286Sobrien   (clobber (match_scratch:SI 3 ""))
1328290286Sobrien   (clobber (reg:CC 17))]
1328390286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1328490286Sobrien   && reload_completed
1328590286Sobrien   && (! REG_P (operands[2])
1328690286Sobrien       || ! rtx_equal_p (operands[1], operands[2]))"
1328790286Sobrien  [(set (match_dup 3) (match_dup 1))
1328890286Sobrien   (parallel [(set (reg:CCZ 17)
1328990286Sobrien		   (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
1329090286Sobrien				(const_int 0)))
1329190286Sobrien	      (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
1329290286Sobrien   (set (match_dup 2) (match_dup 3))
1329390286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1329490286Sobrien			   (match_dup 0)
1329590286Sobrien			   (pc)))]
1329690286Sobrien  "")
1329718334Speter
1329890286Sobrien;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
1329918334Speter
1330090286Sobrien(define_peephole2
1330190286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1330290286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1330390286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1330490286Sobrien	  [(reg 17) (const_int 0)]))
1330590286Sobrien   (set (match_operand 3 "q_regs_operand" "")
1330690286Sobrien	(zero_extend (match_dup 1)))]
1330790286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1330890286Sobrien    || operands_match_p (operands[1], operands[3]))
1330990286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1331090286Sobrien  [(set (match_dup 4) (match_dup 0))
1331190286Sobrien   (set (strict_low_part (match_dup 5))
1331290286Sobrien	(match_dup 2))]
1331318334Speter{
1331490286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1331590286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1331690286Sobrien  ix86_expand_clear (operands[3]);
1331790286Sobrien})
1331818334Speter
1331990286Sobrien;; Similar, but match zero_extendhisi2_and, which adds a clobber.
1332018334Speter
1332190286Sobrien(define_peephole2
1332290286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1332390286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1332490286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1332590286Sobrien	  [(reg 17) (const_int 0)]))
1332690286Sobrien   (parallel [(set (match_operand 3 "q_regs_operand" "")
1332790286Sobrien		   (zero_extend (match_dup 1)))
1332890286Sobrien	      (clobber (reg:CC 17))])]
1332990286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1333090286Sobrien    || operands_match_p (operands[1], operands[3]))
1333190286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1333290286Sobrien  [(set (match_dup 4) (match_dup 0))
1333390286Sobrien   (set (strict_low_part (match_dup 5))
1333490286Sobrien	(match_dup 2))]
1333590286Sobrien{
1333690286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1333790286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1333890286Sobrien  ix86_expand_clear (operands[3]);
1333990286Sobrien})
1334090286Sobrien
1334190286Sobrien;; Call instructions.
1334218334Speter
1334390286Sobrien;; The predicates normally associated with named expanders are not properly
1334490286Sobrien;; checked for calls.  This is a bug in the generic code, but it isn't that
1334590286Sobrien;; easy to fix.  Ignore it for now and be prepared to fix things up.
1334618334Speter
1334718334Speter;; Call subroutine returning no value.
1334818334Speter
1334918334Speter(define_expand "call_pop"
1335090286Sobrien  [(parallel [(call (match_operand:QI 0 "" "")
1335190286Sobrien		    (match_operand:SI 1 "" ""))
1335218334Speter	      (set (reg:SI 7)
1335318334Speter		   (plus:SI (reg:SI 7)
1335490286Sobrien			    (match_operand:SI 3 "" "")))])]
1335590286Sobrien  "!TARGET_64BIT"
1335618334Speter{
13357117404Skan  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3]);
13358117404Skan  DONE;
1335990286Sobrien})
1336018334Speter
1336190286Sobrien(define_insn "*call_pop_0"
1336290286Sobrien  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
1336390286Sobrien	 (match_operand:SI 1 "" ""))
1336418334Speter   (set (reg:SI 7) (plus:SI (reg:SI 7)
1336590286Sobrien			    (match_operand:SI 2 "immediate_operand" "")))]
1336690286Sobrien  "!TARGET_64BIT"
1336718334Speter{
1336890286Sobrien  if (SIBLING_CALL_P (insn))
1336990286Sobrien    return "jmp\t%P0";
1337090286Sobrien  else
1337190286Sobrien    return "call\t%P0";
1337290286Sobrien}
1337390286Sobrien  [(set_attr "type" "call")])
1337490286Sobrien  
1337590286Sobrien(define_insn "*call_pop_1"
1337690286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1337790286Sobrien	 (match_operand:SI 1 "" ""))
1337890286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1337990286Sobrien			    (match_operand:SI 2 "immediate_operand" "i")))]
1338090286Sobrien  "!TARGET_64BIT"
1338190286Sobrien{
1338290286Sobrien  if (constant_call_address_operand (operands[0], Pmode))
1338318334Speter    {
1338490286Sobrien      if (SIBLING_CALL_P (insn))
1338590286Sobrien	return "jmp\t%P0";
1338690286Sobrien      else
1338790286Sobrien	return "call\t%P0";
1338818334Speter    }
1338990286Sobrien  if (SIBLING_CALL_P (insn))
1339090286Sobrien    return "jmp\t%A0";
1339118334Speter  else
1339290286Sobrien    return "call\t%A0";
1339390286Sobrien}
1339490286Sobrien  [(set_attr "type" "call")])
1339518334Speter
1339618334Speter(define_expand "call"
1339790286Sobrien  [(call (match_operand:QI 0 "" "")
1339890286Sobrien	 (match_operand 1 "" ""))
1339990286Sobrien   (use (match_operand 2 "" ""))]
1340018334Speter  ""
1340118334Speter{
13402117404Skan  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL);
13403117404Skan  DONE;
1340490286Sobrien})
1340518334Speter
1340690286Sobrien(define_insn "*call_0"
1340790286Sobrien  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
1340890286Sobrien	 (match_operand 1 "" ""))]
1340918334Speter  ""
1341018334Speter{
1341190286Sobrien  if (SIBLING_CALL_P (insn))
1341290286Sobrien    return "jmp\t%P0";
1341390286Sobrien  else
1341490286Sobrien    return "call\t%P0";
1341590286Sobrien}
1341690286Sobrien  [(set_attr "type" "call")])
1341790286Sobrien
1341890286Sobrien(define_insn "*call_1"
1341990286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1342090286Sobrien	 (match_operand 1 "" ""))]
1342190286Sobrien  "!TARGET_64BIT"
1342290286Sobrien{
1342390286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1342418334Speter    {
1342590286Sobrien      if (SIBLING_CALL_P (insn))
1342690286Sobrien	return "jmp\t%P0";
1342790286Sobrien      else
1342890286Sobrien	return "call\t%P0";
1342918334Speter    }
1343090286Sobrien  if (SIBLING_CALL_P (insn))
1343190286Sobrien    return "jmp\t%A0";
1343218334Speter  else
1343390286Sobrien    return "call\t%A0";
1343490286Sobrien}
1343590286Sobrien  [(set_attr "type" "call")])
1343618334Speter
1343790286Sobrien(define_insn "*call_1_rex64"
1343890286Sobrien  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
1343990286Sobrien	 (match_operand 1 "" ""))]
1344090286Sobrien  "TARGET_64BIT"
1344190286Sobrien{
1344290286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1344390286Sobrien    {
1344490286Sobrien      if (SIBLING_CALL_P (insn))
1344590286Sobrien	return "jmp\t%P0";
1344690286Sobrien      else
1344790286Sobrien	return "call\t%P0";
1344890286Sobrien    }
1344990286Sobrien  if (SIBLING_CALL_P (insn))
1345090286Sobrien    return "jmp\t%A0";
1345190286Sobrien  else
1345290286Sobrien    return "call\t%A0";
1345390286Sobrien}
1345490286Sobrien  [(set_attr "type" "call")])
1345518334Speter
1345618334Speter;; Call subroutine, returning value in operand 0
1345718334Speter
1345818334Speter(define_expand "call_value_pop"
1345918334Speter  [(parallel [(set (match_operand 0 "" "")
1346090286Sobrien		   (call (match_operand:QI 1 "" "")
1346190286Sobrien			 (match_operand:SI 2 "" "")))
1346218334Speter	      (set (reg:SI 7)
1346318334Speter		   (plus:SI (reg:SI 7)
1346490286Sobrien			    (match_operand:SI 4 "" "")))])]
1346590286Sobrien  "!TARGET_64BIT"
1346618334Speter{
13467117404Skan  ix86_expand_call (operands[0], operands[1], operands[2],
13468117404Skan		    operands[3], operands[4]);
13469117404Skan  DONE;
1347090286Sobrien})
1347118334Speter
1347218334Speter(define_expand "call_value"
1347318334Speter  [(set (match_operand 0 "" "")
1347490286Sobrien	(call (match_operand:QI 1 "" "")
1347590286Sobrien	      (match_operand:SI 2 "" "")))
1347690286Sobrien   (use (match_operand:SI 3 "" ""))]
1347718334Speter  ;; Operand 2 not used on the i386.
1347818334Speter  ""
1347918334Speter{
13480117404Skan  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL);
1348190286Sobrien  DONE;
1348290286Sobrien})
1348318334Speter
1348418334Speter;; Call subroutine returning any type.
1348518334Speter
1348618334Speter(define_expand "untyped_call"
1348718334Speter  [(parallel [(call (match_operand 0 "" "")
1348818334Speter		    (const_int 0))
1348918334Speter	      (match_operand 1 "" "")
1349018334Speter	      (match_operand 2 "" "")])]
1349118334Speter  ""
1349218334Speter{
1349318334Speter  int i;
1349418334Speter
1349518334Speter  /* In order to give reg-stack an easier job in validating two
1349618334Speter     coprocessor registers as containing a possible return value,
1349718334Speter     simply pretend the untyped call returns a complex long double
1349818334Speter     value.  */
1349950650Sobrien
13500117404Skan  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13501117404Skan		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13502117404Skan		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13503117404Skan		    NULL);
1350418334Speter
1350518334Speter  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1350618334Speter    {
1350718334Speter      rtx set = XVECEXP (operands[2], 0, i);
1350818334Speter      emit_move_insn (SET_DEST (set), SET_SRC (set));
1350918334Speter    }
1351018334Speter
1351118334Speter  /* The optimizer does not know that the call sets the function value
1351218334Speter     registers we stored in the result block.  We avoid problems by
1351318334Speter     claiming that all hard registers are used and clobbered at this
1351418334Speter     point.  */
13515117404Skan  emit_insn (gen_blockage (const0_rtx));
1351618334Speter
1351718334Speter  DONE;
1351890286Sobrien})
1351990286Sobrien
1352090286Sobrien;; Prologue and epilogue instructions
1352118334Speter
1352218334Speter;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1352318334Speter;; all of memory.  This blocks insns from being moved across this point.
1352418334Speter
1352518334Speter(define_insn "blockage"
13526117404Skan  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
1352718334Speter  ""
1352852296Sobrien  ""
1352990286Sobrien  [(set_attr "length" "0")])
1353018334Speter
1353118334Speter;; Insn emitted into the body of a function to return from a function.
1353218334Speter;; This is only done if the function's epilogue is known to be simple.
1353390286Sobrien;; See comments for ix86_can_use_return_insn_p in i386.c.
1353418334Speter
1353550650Sobrien(define_expand "return"
1353618334Speter  [(return)]
1353750650Sobrien  "ix86_can_use_return_insn_p ()"
1353890286Sobrien{
1353990286Sobrien  if (current_function_pops_args)
1354090286Sobrien    {
1354190286Sobrien      rtx popc = GEN_INT (current_function_pops_args);
1354290286Sobrien      emit_jump_insn (gen_return_pop_internal (popc));
1354390286Sobrien      DONE;
1354490286Sobrien    }
1354590286Sobrien})
1354650650Sobrien
1354750650Sobrien(define_insn "return_internal"
1354850650Sobrien  [(return)]
1354950650Sobrien  "reload_completed"
1355052296Sobrien  "ret"
1355190286Sobrien  [(set_attr "length" "1")
1355290286Sobrien   (set_attr "length_immediate" "0")
1355390286Sobrien   (set_attr "modrm" "0")])
1355450650Sobrien
1355550650Sobrien(define_insn "return_pop_internal"
1355650650Sobrien  [(return)
1355750650Sobrien   (use (match_operand:SI 0 "const_int_operand" ""))]
1355850650Sobrien  "reload_completed"
1355990286Sobrien  "ret\t%0"
1356090286Sobrien  [(set_attr "length" "3")
1356190286Sobrien   (set_attr "length_immediate" "2")
1356290286Sobrien   (set_attr "modrm" "0")])
1356350650Sobrien
1356490286Sobrien(define_insn "return_indirect_internal"
1356590286Sobrien  [(return)
1356690286Sobrien   (use (match_operand:SI 0 "register_operand" "r"))]
1356790286Sobrien  "reload_completed"
1356890286Sobrien  "jmp\t%A0"
1356990286Sobrien  [(set_attr "type" "ibr")
1357090286Sobrien   (set_attr "length_immediate" "0")])
1357190286Sobrien
1357250650Sobrien(define_insn "nop"
1357350650Sobrien  [(const_int 0)]
1357450650Sobrien  ""
1357552296Sobrien  "nop"
1357690286Sobrien  [(set_attr "length" "1")
1357790286Sobrien   (set_attr "length_immediate" "0")
1357890286Sobrien   (set_attr "modrm" "0")
1357990286Sobrien   (set_attr "ppro_uops" "one")])
1358050650Sobrien
1358150650Sobrien(define_expand "prologue"
1358250650Sobrien  [(const_int 1)]
1358350650Sobrien  ""
1358490286Sobrien  "ix86_expand_prologue (); DONE;")
1358550650Sobrien
13586117404Skan(define_insn "set_got"
1358790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
13588117404Skan	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
1358990286Sobrien   (clobber (reg:CC 17))]
1359090286Sobrien  "!TARGET_64BIT"
13591117404Skan  { return output_set_got (operands[0]); }
13592117404Skan  [(set_attr "type" "multi")
13593117404Skan   (set_attr "length" "12")])
1359450650Sobrien
1359550650Sobrien(define_expand "epilogue"
1359650650Sobrien  [(const_int 1)]
1359750650Sobrien  ""
1359890286Sobrien  "ix86_expand_epilogue (1); DONE;")
1359950650Sobrien
1360090286Sobrien(define_expand "sibcall_epilogue"
1360190286Sobrien  [(const_int 1)]
1360250650Sobrien  ""
1360390286Sobrien  "ix86_expand_epilogue (0); DONE;")
1360450650Sobrien
1360590286Sobrien(define_expand "eh_return"
13606117404Skan  [(use (match_operand 0 "register_operand" ""))]
1360750650Sobrien  ""
1360850650Sobrien{
13609117404Skan  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
1361050650Sobrien
1361190286Sobrien  /* Tricky bit: we write the address of the handler to which we will
1361290286Sobrien     be returning into someone else's stack frame, one word below the
1361390286Sobrien     stack address we wish to restore.  */
1361490286Sobrien  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
1361590286Sobrien  tmp = plus_constant (tmp, -UNITS_PER_WORD);
1361690286Sobrien  tmp = gen_rtx_MEM (Pmode, tmp);
1361790286Sobrien  emit_move_insn (tmp, ra);
1361818334Speter
1361990286Sobrien  if (Pmode == SImode)
1362090286Sobrien    emit_insn (gen_eh_return_si (sa));
1362190286Sobrien  else
1362290286Sobrien    emit_insn (gen_eh_return_di (sa));
1362390286Sobrien  emit_barrier ();
1362490286Sobrien  DONE;
1362590286Sobrien})
1362618334Speter
1362790286Sobrien(define_insn_and_split "eh_return_si"
13628117404Skan  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13629117404Skan		    UNSPECV_EH_RETURN)]
1363090286Sobrien  "!TARGET_64BIT"
1363190286Sobrien  "#"
1363290286Sobrien  "reload_completed"
1363390286Sobrien  [(const_int 1)]
1363490286Sobrien  "ix86_expand_epilogue (2); DONE;")
1363518334Speter
1363690286Sobrien(define_insn_and_split "eh_return_di"
13637117404Skan  [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13638117404Skan		    UNSPECV_EH_RETURN)]
1363990286Sobrien  "TARGET_64BIT"
1364090286Sobrien  "#"
1364190286Sobrien  "reload_completed"
1364290286Sobrien  [(const_int 1)]
1364390286Sobrien  "ix86_expand_epilogue (2); DONE;")
1364418334Speter
1364590286Sobrien(define_insn "leave"
1364690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
1364790286Sobrien   (set (reg:SI 6) (mem:SI (reg:SI 6)))
1364890286Sobrien   (clobber (mem:BLK (scratch)))]
1364990286Sobrien  "!TARGET_64BIT"
1365090286Sobrien  "leave"
1365190286Sobrien  [(set_attr "length_immediate" "0")
1365290286Sobrien   (set_attr "length" "1")
1365390286Sobrien   (set_attr "modrm" "0")
1365490286Sobrien   (set_attr "athlon_decode" "vector")
1365590286Sobrien   (set_attr "ppro_uops" "few")])
1365618334Speter
1365790286Sobrien(define_insn "leave_rex64"
1365890286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
1365990286Sobrien   (set (reg:DI 6) (mem:DI (reg:DI 6)))
1366090286Sobrien   (clobber (mem:BLK (scratch)))]
1366190286Sobrien  "TARGET_64BIT"
1366290286Sobrien  "leave"
1366390286Sobrien  [(set_attr "length_immediate" "0")
1366490286Sobrien   (set_attr "length" "1")
1366590286Sobrien   (set_attr "modrm" "0")
1366690286Sobrien   (set_attr "athlon_decode" "vector")
1366790286Sobrien   (set_attr "ppro_uops" "few")])
1366890286Sobrien
1366990286Sobrien(define_expand "ffssi2"
1367090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "") 
13671117404Skan	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1367218334Speter  ""
1367318334Speter{
1367490286Sobrien  rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
1367590286Sobrien  rtx in = operands[1];
1367618334Speter
1367790286Sobrien  if (TARGET_CMOVE)
1367818334Speter    {
1367990286Sobrien      emit_move_insn (tmp, constm1_rtx);
1368090286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1368190286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, out,
1368290286Sobrien		  gen_rtx_IF_THEN_ELSE (SImode, 
1368390286Sobrien		    gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
1368490286Sobrien				const0_rtx),
1368590286Sobrien		    tmp,
1368690286Sobrien		    out)));
1368790286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1368890286Sobrien      emit_move_insn (operands[0], out);
1368918334Speter    }
1369018334Speter
1369190286Sobrien  /* Pentium bsf instruction is extremly slow.  The following code is
1369290286Sobrien     recommended by the Intel Optimizing Manual as a reasonable replacement:
1369390286Sobrien           TEST    EAX,EAX
1369490286Sobrien	   JZ      SHORT BS2
1369590286Sobrien	   XOR     ECX,ECX
1369690286Sobrien	   MOV     DWORD PTR [TEMP+4],ECX
1369790286Sobrien	   SUB     ECX,EAX
1369890286Sobrien	   AND     EAX,ECX
1369990286Sobrien	   MOV     DWORD PTR [TEMP],EAX
1370090286Sobrien	   FILD    QWORD PTR [TEMP]
1370190286Sobrien	   FSTP    QWORD PTR [TEMP]
1370290286Sobrien	   WAIT    ; WAIT only needed for compatibility with
1370390286Sobrien	           ; earlier processors
1370490286Sobrien	   MOV     ECX, DWORD PTR [TEMP+4]
1370590286Sobrien	   SHR     ECX,20
1370690286Sobrien	   SUB     ECX,3FFH
1370790286Sobrien	   TEST    EAX,EAX       ; clear zero flag
1370890286Sobrien       BS2:
1370990286Sobrien     Following piece of code expand ffs to similar beast.
1371090286Sobrien       */
1371150650Sobrien
1371290286Sobrien  else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
1371390286Sobrien    {
1371490286Sobrien      rtx label = gen_label_rtx ();
1371590286Sobrien      rtx lo, hi;
1371690286Sobrien      rtx mem = assign_386_stack_local (DImode, 0);
1371790286Sobrien      rtx fptmp = gen_reg_rtx (DFmode);
1371890286Sobrien      split_di (&mem, 1, &lo, &hi);
1371950650Sobrien
1372090286Sobrien      emit_move_insn (out, const0_rtx);
1372150650Sobrien
1372290286Sobrien      emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
1372350650Sobrien
1372490286Sobrien      emit_move_insn (hi, out);
1372590286Sobrien      emit_insn (gen_subsi3 (out, out, in));
1372690286Sobrien      emit_insn (gen_andsi3 (out, out, in));
1372790286Sobrien      emit_move_insn (lo, out);
1372890286Sobrien      emit_insn (gen_floatdidf2 (fptmp,mem));
1372990286Sobrien      emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
1373090286Sobrien      emit_move_insn (out, hi);
1373190286Sobrien      emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
1373290286Sobrien      emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
1373350650Sobrien
1373490286Sobrien      emit_label (label);
1373590286Sobrien      LABEL_NUSES (label) = 1;
1373650650Sobrien
1373790286Sobrien      emit_move_insn (operands[0], out);
1373890286Sobrien    }
1373990286Sobrien  else
1374050650Sobrien    {
1374190286Sobrien      emit_move_insn (tmp, const0_rtx);
1374290286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1374390286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, 
1374490286Sobrien		  gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
1374590286Sobrien		  gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
1374690286Sobrien			      const0_rtx)));
1374790286Sobrien      emit_insn (gen_negsi2 (tmp, tmp));
1374890286Sobrien      emit_insn (gen_iorsi3 (out, out, tmp));
1374990286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1375090286Sobrien      emit_move_insn (operands[0], out);
1375150650Sobrien    }
1375290286Sobrien  DONE;  
1375390286Sobrien})
1375450650Sobrien
1375590286Sobrien(define_insn "ffssi_1"
1375690286Sobrien  [(set (reg:CCZ 17)
1375790286Sobrien        (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
1375890286Sobrien		     (const_int 0)))
1375990286Sobrien   (set (match_operand:SI 0 "register_operand" "=r")
13760117404Skan	(unspec:SI [(match_dup 1)] UNSPEC_BSF))]
1376118334Speter  ""
1376290286Sobrien  "bsf{l}\t{%1, %0|%0, %1}"
1376390286Sobrien  [(set_attr "prefix_0f" "1")
1376490286Sobrien   (set_attr "ppro_uops" "few")])
1376518334Speter
1376690286Sobrien;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
1376790286Sobrien;; and slower than the two-byte movzx insn needed to do the work in SImode.
1376890286Sobrien
13769117404Skan;; Thread-local storage patterns for ELF.
13770117404Skan;;
13771117404Skan;; Note that these code sequences must appear exactly as shown
13772117404Skan;; in order to allow linker relaxation.
13773117404Skan
13774117404Skan(define_insn "*tls_global_dynamic_32_gnu"
13775117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
13776117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
13777117404Skan		    (match_operand:SI 2 "tls_symbolic_operand" "")
13778117404Skan		    (match_operand:SI 3 "call_insn_operand" "")]
13779117404Skan		    UNSPEC_TLS_GD))
13780117404Skan   (clobber (match_scratch:SI 4 "=d"))
13781117404Skan   (clobber (match_scratch:SI 5 "=c"))
13782117404Skan   (clobber (reg:CC 17))]
13783117404Skan  "!TARGET_64BIT && TARGET_GNU_TLS"
13784117404Skan  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13785117404Skan  [(set_attr "type" "multi")
13786117404Skan   (set_attr "length" "12")])
13787117404Skan
13788117404Skan(define_insn "*tls_global_dynamic_32_sun"
13789117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
13790117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
13791117404Skan		    (match_operand:SI 2 "tls_symbolic_operand" "")
13792117404Skan		    (match_operand:SI 3 "call_insn_operand" "")]
13793117404Skan		    UNSPEC_TLS_GD))
13794117404Skan   (clobber (match_scratch:SI 4 "=d"))
13795117404Skan   (clobber (match_scratch:SI 5 "=c"))
13796117404Skan   (clobber (reg:CC 17))]
13797117404Skan  "!TARGET_64BIT && TARGET_SUN_TLS"
13798117404Skan  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13799117404Skan	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13800117404Skan  [(set_attr "type" "multi")
13801117404Skan   (set_attr "length" "14")])
13802117404Skan
13803117404Skan(define_expand "tls_global_dynamic_32"
13804117404Skan  [(parallel [(set (match_operand:SI 0 "register_operand" "")
13805117404Skan		   (unspec:SI
13806117404Skan		    [(match_dup 2)
13807117404Skan		     (match_operand:SI 1 "tls_symbolic_operand" "")
13808117404Skan		     (match_dup 3)]
13809117404Skan		    UNSPEC_TLS_GD))
13810117404Skan	      (clobber (match_scratch:SI 4 ""))
13811117404Skan	      (clobber (match_scratch:SI 5 ""))
13812117404Skan	      (clobber (reg:CC 17))])]
13813117404Skan  ""
13814117404Skan{
13815117404Skan  if (flag_pic)
13816117404Skan    operands[2] = pic_offset_table_rtx;
13817117404Skan  else
13818117404Skan    {
13819117404Skan      operands[2] = gen_reg_rtx (Pmode);
13820117404Skan      emit_insn (gen_set_got (operands[2]));
13821117404Skan    }
13822117404Skan  operands[3] = ix86_tls_get_addr ();
13823117404Skan})
13824117404Skan
13825117404Skan(define_insn "*tls_global_dynamic_64"
13826117404Skan  [(set (match_operand:DI 0 "register_operand" "=a")
13827117404Skan	(call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13828117404Skan		      (match_operand:DI 3 "" "")))
13829117404Skan   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13830117404Skan	      UNSPEC_TLS_GD)]
13831117404Skan  "TARGET_64BIT"
13832117404Skan  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13833117404Skan  [(set_attr "type" "multi")
13834117404Skan   (set_attr "length" "16")])
13835117404Skan
13836117404Skan(define_expand "tls_global_dynamic_64"
13837117404Skan  [(parallel [(set (match_operand:DI 0 "register_operand" "")
13838117404Skan		   (call (mem:QI (match_dup 2)) (const_int 0)))
13839117404Skan	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13840117404Skan			 UNSPEC_TLS_GD)])]
13841117404Skan  ""
13842117404Skan{
13843117404Skan  operands[2] = ix86_tls_get_addr ();
13844117404Skan})
13845117404Skan
13846117404Skan(define_insn "*tls_local_dynamic_base_32_gnu"
13847117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
13848117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
13849117404Skan                    (match_operand:SI 2 "call_insn_operand" "")]
13850117404Skan		   UNSPEC_TLS_LD_BASE))
13851117404Skan   (clobber (match_scratch:SI 3 "=d"))
13852117404Skan   (clobber (match_scratch:SI 4 "=c"))
13853117404Skan   (clobber (reg:CC 17))]
13854117404Skan  "!TARGET_64BIT && TARGET_GNU_TLS"
13855117404Skan  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13856117404Skan  [(set_attr "type" "multi")
13857117404Skan   (set_attr "length" "11")])
13858117404Skan
13859117404Skan(define_insn "*tls_local_dynamic_base_32_sun"
13860117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
13861117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
13862117404Skan                    (match_operand:SI 2 "call_insn_operand" "")]
13863117404Skan		   UNSPEC_TLS_LD_BASE))
13864117404Skan   (clobber (match_scratch:SI 3 "=d"))
13865117404Skan   (clobber (match_scratch:SI 4 "=c"))
13866117404Skan   (clobber (reg:CC 17))]
13867117404Skan  "!TARGET_64BIT && TARGET_SUN_TLS"
13868117404Skan  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13869117404Skan	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13870117404Skan  [(set_attr "type" "multi")
13871117404Skan   (set_attr "length" "13")])
13872117404Skan
13873117404Skan(define_expand "tls_local_dynamic_base_32"
13874117404Skan  [(parallel [(set (match_operand:SI 0 "register_operand" "")
13875117404Skan		   (unspec:SI [(match_dup 1) (match_dup 2)]
13876117404Skan			      UNSPEC_TLS_LD_BASE))
13877117404Skan	      (clobber (match_scratch:SI 3 ""))
13878117404Skan	      (clobber (match_scratch:SI 4 ""))
13879117404Skan	      (clobber (reg:CC 17))])]
13880117404Skan  ""
13881117404Skan{
13882117404Skan  if (flag_pic)
13883117404Skan    operands[1] = pic_offset_table_rtx;
13884117404Skan  else
13885117404Skan    {
13886117404Skan      operands[1] = gen_reg_rtx (Pmode);
13887117404Skan      emit_insn (gen_set_got (operands[1]));
13888117404Skan    }
13889117404Skan  operands[2] = ix86_tls_get_addr ();
13890117404Skan})
13891117404Skan
13892117404Skan(define_insn "*tls_local_dynamic_base_64"
13893117404Skan  [(set (match_operand:DI 0 "register_operand" "=a")
13894117404Skan	(call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13895117404Skan		      (match_operand:DI 2 "" "")))
13896117404Skan   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13897117404Skan  "TARGET_64BIT"
13898117404Skan  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13899117404Skan  [(set_attr "type" "multi")
13900117404Skan   (set_attr "length" "12")])
13901117404Skan
13902117404Skan(define_expand "tls_local_dynamic_base_64"
13903117404Skan  [(parallel [(set (match_operand:DI 0 "register_operand" "")
13904117404Skan		   (call (mem:QI (match_dup 1)) (const_int 0)))
13905117404Skan	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13906117404Skan  ""
13907117404Skan{
13908117404Skan  operands[1] = ix86_tls_get_addr ();
13909117404Skan})
13910117404Skan
13911117404Skan;; Local dynamic of a single variable is a lose.  Show combine how
13912117404Skan;; to convert that back to global dynamic.
13913117404Skan
13914117404Skan(define_insn_and_split "*tls_local_dynamic_32_once"
13915117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
13916117404Skan	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13917117404Skan			     (match_operand:SI 2 "call_insn_operand" "")]
13918117404Skan			    UNSPEC_TLS_LD_BASE)
13919117404Skan		 (const:SI (unspec:SI
13920117404Skan			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
13921117404Skan			    UNSPEC_DTPOFF))))
13922117404Skan   (clobber (match_scratch:SI 4 "=d"))
13923117404Skan   (clobber (match_scratch:SI 5 "=c"))
13924117404Skan   (clobber (reg:CC 17))]
13925117404Skan  ""
13926117404Skan  "#"
13927117404Skan  ""
13928117404Skan  [(parallel [(set (match_dup 0)
13929117404Skan		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13930117404Skan			      UNSPEC_TLS_GD))
13931117404Skan	      (clobber (match_dup 4))
13932117404Skan	      (clobber (match_dup 5))
13933117404Skan	      (clobber (reg:CC 17))])]
13934117404Skan  "")
13935117404Skan
1393690286Sobrien;; These patterns match the binary 387 instructions for addM3, subM3,
1393790286Sobrien;; mulM3 and divM3.  There are three patterns for each of DFmode and
1393890286Sobrien;; SFmode.  The first is the normal insn, the second the same insn but
1393990286Sobrien;; with one operand a conversion, and the third the same insn but with
1394090286Sobrien;; the other operand a conversion.  The conversion may be SFmode or
1394190286Sobrien;; SImode if the target mode DFmode, but only SImode if the target mode
1394290286Sobrien;; is SFmode.
1394318334Speter
1394490286Sobrien;; Gcc is slightly more smart about handling normal two address instructions
1394590286Sobrien;; so use special patterns for add and mull.
1394690286Sobrien(define_insn "*fop_sf_comm_nosse"
1394790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1394890286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1394996294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1395090286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
1395190286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1395296294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1395396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1395490286Sobrien  "* return output_387_binary_op (insn, operands);"
1395590286Sobrien  [(set (attr "type") 
1395690286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1395790286Sobrien	   (const_string "fmul")
1395890286Sobrien	   (const_string "fop")))
1395990286Sobrien   (set_attr "mode" "SF")])
1396018334Speter
1396190286Sobrien(define_insn "*fop_sf_comm"
1396290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1396390286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1396496294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
1396590286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
1396690286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1396796294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1396896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1396990286Sobrien  "* return output_387_binary_op (insn, operands);"
1397090286Sobrien  [(set (attr "type") 
1397190286Sobrien	(if_then_else (eq_attr "alternative" "1")
1397290286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
13973117404Skan	      (const_string "ssemul")
13974117404Skan	      (const_string "sseadd"))
13975117404Skan	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1397690286Sobrien	      (const_string "fmul")
1397790286Sobrien	      (const_string "fop"))))
1397890286Sobrien   (set_attr "mode" "SF")])
1397918334Speter
1398090286Sobrien(define_insn "*fop_sf_comm_sse"
1398190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1398290286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1398396294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1398490286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1398596294Sobrien  "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1398696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1398790286Sobrien  "* return output_387_binary_op (insn, operands);"
13988117404Skan  [(set (attr "type") 
13989117404Skan        (if_then_else (match_operand:SF 3 "mult_operator" "") 
13990117404Skan	   (const_string "ssemul")
13991117404Skan	   (const_string "sseadd")))
1399290286Sobrien   (set_attr "mode" "SF")])
1399318334Speter
1399490286Sobrien(define_insn "*fop_df_comm_nosse"
1399590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1399690286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1399796294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1399890286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
1399990286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1400096294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1400196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1400290286Sobrien  "* return output_387_binary_op (insn, operands);"
1400390286Sobrien  [(set (attr "type") 
1400490286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1400590286Sobrien	   (const_string "fmul")
1400690286Sobrien	   (const_string "fop")))
1400790286Sobrien   (set_attr "mode" "DF")])
1400818334Speter
1400990286Sobrien(define_insn "*fop_df_comm"
1401090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1401190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1401296294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
1401390286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
1401490286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
1401596294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1401696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1401790286Sobrien  "* return output_387_binary_op (insn, operands);"
1401890286Sobrien  [(set (attr "type") 
1401990286Sobrien	(if_then_else (eq_attr "alternative" "1")
1402090286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14021117404Skan	      (const_string "ssemul")
14022117404Skan	      (const_string "sseadd"))
14023117404Skan	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1402490286Sobrien	      (const_string "fmul")
1402590286Sobrien	      (const_string "fop"))))
1402690286Sobrien   (set_attr "mode" "DF")])
1402718334Speter
1402890286Sobrien(define_insn "*fop_df_comm_sse"
1402990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1403090286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1403196294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1403290286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1403390286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1403496294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1403596294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1403690286Sobrien  "* return output_387_binary_op (insn, operands);"
14037117404Skan  [(set (attr "type") 
14038117404Skan        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14039117404Skan	   (const_string "ssemul")
14040117404Skan	   (const_string "sseadd")))
1404190286Sobrien   (set_attr "mode" "DF")])
1404218334Speter
1404390286Sobrien(define_insn "*fop_xf_comm"
1404490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1404590286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1404690286Sobrien			[(match_operand:XF 1 "register_operand" "%0")
1404790286Sobrien			 (match_operand:XF 2 "register_operand" "f")]))]
1404890286Sobrien  "!TARGET_64BIT && TARGET_80387
1404990286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1405090286Sobrien  "* return output_387_binary_op (insn, operands);"
1405190286Sobrien  [(set (attr "type") 
1405290286Sobrien        (if_then_else (match_operand:XF 3 "mult_operator" "") 
1405390286Sobrien           (const_string "fmul")
1405490286Sobrien           (const_string "fop")))
1405590286Sobrien   (set_attr "mode" "XF")])
1405618334Speter
1405790286Sobrien(define_insn "*fop_tf_comm"
1405890286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1405990286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1406090286Sobrien			[(match_operand:TF 1 "register_operand" "%0")
1406190286Sobrien			 (match_operand:TF 2 "register_operand" "f")]))]
1406290286Sobrien  "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1406390286Sobrien  "* return output_387_binary_op (insn, operands);"
1406490286Sobrien  [(set (attr "type") 
1406590286Sobrien        (if_then_else (match_operand:TF 3 "mult_operator" "") 
1406690286Sobrien           (const_string "fmul")
1406790286Sobrien           (const_string "fop")))
1406890286Sobrien   (set_attr "mode" "XF")])
1406918334Speter
1407090286Sobrien(define_insn "*fop_sf_1_nosse"
1407190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1407290286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1407390286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
1407490286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
1407590286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1407690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1407790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1407890286Sobrien  "* return output_387_binary_op (insn, operands);"
1407990286Sobrien  [(set (attr "type") 
1408090286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1408190286Sobrien                 (const_string "fmul")
1408290286Sobrien               (match_operand:SF 3 "div_operator" "") 
1408390286Sobrien                 (const_string "fdiv")
1408490286Sobrien              ]
1408590286Sobrien              (const_string "fop")))
1408690286Sobrien   (set_attr "mode" "SF")])
1408718334Speter
1408890286Sobrien(define_insn "*fop_sf_1"
1408990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
1409090286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1409190286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
1409290286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
1409390286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1409490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1409590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1409690286Sobrien  "* return output_387_binary_op (insn, operands);"
1409790286Sobrien  [(set (attr "type") 
14098117404Skan        (cond [(and (eq_attr "alternative" "2")
14099117404Skan	            (match_operand:SF 3 "mult_operator" ""))
14100117404Skan                 (const_string "ssemul")
14101117404Skan	       (and (eq_attr "alternative" "2")
14102117404Skan	            (match_operand:SF 3 "div_operator" ""))
14103117404Skan                 (const_string "ssediv")
14104117404Skan	       (eq_attr "alternative" "2")
14105117404Skan                 (const_string "sseadd")
1410690286Sobrien	       (match_operand:SF 3 "mult_operator" "") 
1410790286Sobrien                 (const_string "fmul")
1410890286Sobrien               (match_operand:SF 3 "div_operator" "") 
1410990286Sobrien                 (const_string "fdiv")
1411090286Sobrien              ]
1411190286Sobrien              (const_string "fop")))
1411290286Sobrien   (set_attr "mode" "SF")])
1411318334Speter
1411490286Sobrien(define_insn "*fop_sf_1_sse"
1411590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1411690286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1411790286Sobrien			[(match_operand:SF 1 "register_operand" "0")
1411890286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1411990286Sobrien  "TARGET_SSE_MATH
1412090286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1412190286Sobrien  "* return output_387_binary_op (insn, operands);"
14122117404Skan  [(set (attr "type") 
14123117404Skan        (cond [(match_operand:SF 3 "mult_operator" "")
14124117404Skan                 (const_string "ssemul")
14125117404Skan	       (match_operand:SF 3 "div_operator" "")
14126117404Skan                 (const_string "ssediv")
14127117404Skan              ]
14128117404Skan              (const_string "sseadd")))
1412990286Sobrien   (set_attr "mode" "SF")])
1413018334Speter
1413190286Sobrien;; ??? Add SSE splitters for these!
1413290286Sobrien(define_insn "*fop_sf_2"
1413390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1413490286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1413590286Sobrien	  [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1413690286Sobrien	   (match_operand:SF 2 "register_operand" "0,0")]))]
1413790286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1413890286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1413990286Sobrien  [(set (attr "type") 
1414090286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1414190286Sobrien                 (const_string "fmul")
1414290286Sobrien               (match_operand:SF 3 "div_operator" "") 
1414390286Sobrien                 (const_string "fdiv")
1414490286Sobrien              ]
1414590286Sobrien              (const_string "fop")))
1414690286Sobrien   (set_attr "fp_int_src" "true")
1414790286Sobrien   (set_attr "ppro_uops" "many")
1414890286Sobrien   (set_attr "mode" "SI")])
1414918334Speter
1415090286Sobrien(define_insn "*fop_sf_3"
1415190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1415290286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1415390286Sobrien	  [(match_operand:SF 1 "register_operand" "0,0")
1415490286Sobrien	   (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1415590286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1415690286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1415790286Sobrien  [(set (attr "type") 
1415890286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1415990286Sobrien                 (const_string "fmul")
1416090286Sobrien               (match_operand:SF 3 "div_operator" "") 
1416190286Sobrien                 (const_string "fdiv")
1416290286Sobrien              ]
1416390286Sobrien              (const_string "fop")))
1416490286Sobrien   (set_attr "fp_int_src" "true")
1416590286Sobrien   (set_attr "ppro_uops" "many")
1416690286Sobrien   (set_attr "mode" "SI")])
1416718334Speter
1416890286Sobrien(define_insn "*fop_df_1_nosse"
1416990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1417090286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1417190286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
1417290286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
1417390286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1417490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1417590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1417690286Sobrien  "* return output_387_binary_op (insn, operands);"
1417790286Sobrien  [(set (attr "type") 
1417890286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1417990286Sobrien                 (const_string "fmul")
14180117404Skan               (match_operand:DF 3 "div_operator" "")
1418190286Sobrien                 (const_string "fdiv")
1418290286Sobrien              ]
1418390286Sobrien              (const_string "fop")))
1418490286Sobrien   (set_attr "mode" "DF")])
1418518334Speter
1418618334Speter
1418790286Sobrien(define_insn "*fop_df_1"
1418890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
1418990286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1419090286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
1419190286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
1419290286Sobrien  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1419390286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1419490286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1419590286Sobrien  "* return output_387_binary_op (insn, operands);"
1419690286Sobrien  [(set (attr "type") 
14197117404Skan        (cond [(and (eq_attr "alternative" "2")
14198117404Skan	            (match_operand:SF 3 "mult_operator" ""))
14199117404Skan                 (const_string "ssemul")
14200117404Skan	       (and (eq_attr "alternative" "2")
14201117404Skan	            (match_operand:SF 3 "div_operator" ""))
14202117404Skan                 (const_string "ssediv")
14203117404Skan	       (eq_attr "alternative" "2")
14204117404Skan                 (const_string "sseadd")
1420590286Sobrien	       (match_operand:DF 3 "mult_operator" "") 
1420690286Sobrien                 (const_string "fmul")
1420790286Sobrien               (match_operand:DF 3 "div_operator" "") 
1420890286Sobrien                 (const_string "fdiv")
1420990286Sobrien              ]
1421090286Sobrien              (const_string "fop")))
1421190286Sobrien   (set_attr "mode" "DF")])
1421218334Speter
1421390286Sobrien(define_insn "*fop_df_1_sse"
1421490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1421590286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1421690286Sobrien			[(match_operand:DF 1 "register_operand" "0")
1421790286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1421890286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1421990286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1422090286Sobrien  "* return output_387_binary_op (insn, operands);"
14221117404Skan  [(set_attr "mode" "DF")
14222117404Skan   (set (attr "type") 
14223117404Skan        (cond [(match_operand:SF 3 "mult_operator" "")
14224117404Skan                 (const_string "ssemul")
14225117404Skan	       (match_operand:SF 3 "div_operator" "")
14226117404Skan                 (const_string "ssediv")
14227117404Skan              ]
14228117404Skan              (const_string "sseadd")))])
1422918334Speter
1423090286Sobrien;; ??? Add SSE splitters for these!
1423190286Sobrien(define_insn "*fop_df_2"
1423290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1423390286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1423490286Sobrien	   [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1423590286Sobrien	    (match_operand:DF 2 "register_operand" "0,0")]))]
1423690286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1423790286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1423890286Sobrien  [(set (attr "type") 
1423990286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1424090286Sobrien                 (const_string "fmul")
1424190286Sobrien               (match_operand:DF 3 "div_operator" "") 
1424290286Sobrien                 (const_string "fdiv")
1424390286Sobrien              ]
1424490286Sobrien              (const_string "fop")))
1424590286Sobrien   (set_attr "fp_int_src" "true")
1424690286Sobrien   (set_attr "ppro_uops" "many")
1424790286Sobrien   (set_attr "mode" "SI")])
1424818334Speter
1424990286Sobrien(define_insn "*fop_df_3"
1425090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1425190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1425290286Sobrien	   [(match_operand:DF 1 "register_operand" "0,0")
1425390286Sobrien	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1425490286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1425590286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1425690286Sobrien  [(set (attr "type") 
1425790286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1425890286Sobrien                 (const_string "fmul")
1425990286Sobrien               (match_operand:DF 3 "div_operator" "") 
1426090286Sobrien                 (const_string "fdiv")
1426190286Sobrien              ]
1426290286Sobrien              (const_string "fop")))
1426390286Sobrien   (set_attr "fp_int_src" "true")
1426490286Sobrien   (set_attr "ppro_uops" "many")
1426590286Sobrien   (set_attr "mode" "SI")])
1426618334Speter
1426790286Sobrien(define_insn "*fop_df_4"
1426890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1426990286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1427090286Sobrien	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1427190286Sobrien	    (match_operand:DF 2 "register_operand" "0,f")]))]
1427290286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1427390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1427490286Sobrien  "* return output_387_binary_op (insn, operands);"
1427590286Sobrien  [(set (attr "type") 
1427690286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1427790286Sobrien                 (const_string "fmul")
1427890286Sobrien               (match_operand:DF 3 "div_operator" "") 
1427990286Sobrien                 (const_string "fdiv")
1428090286Sobrien              ]
1428190286Sobrien              (const_string "fop")))
1428290286Sobrien   (set_attr "mode" "SF")])
1428318334Speter
1428490286Sobrien(define_insn "*fop_df_5"
1428518334Speter  [(set (match_operand:DF 0 "register_operand" "=f,f")
1428690286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1428790286Sobrien	  [(match_operand:DF 1 "register_operand" "0,f")
1428890286Sobrien	   (float_extend:DF
1428990286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1429090286Sobrien  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1429150650Sobrien  "* return output_387_binary_op (insn, operands);"
1429250650Sobrien  [(set (attr "type") 
1429390286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1429490286Sobrien                 (const_string "fmul")
1429590286Sobrien               (match_operand:DF 3 "div_operator" "") 
1429690286Sobrien                 (const_string "fdiv")
1429750650Sobrien              ]
1429890286Sobrien              (const_string "fop")))
1429990286Sobrien   (set_attr "mode" "SF")])
1430018334Speter
1430190286Sobrien(define_insn "*fop_xf_1"
1430218334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1430390286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1430450650Sobrien			[(match_operand:XF 1 "register_operand" "0,f")
1430550650Sobrien			 (match_operand:XF 2 "register_operand" "f,0")]))]
1430690286Sobrien  "!TARGET_64BIT && TARGET_80387
1430790286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1430850650Sobrien  "* return output_387_binary_op (insn, operands);"
1430950650Sobrien  [(set (attr "type") 
1431090286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1431190286Sobrien                 (const_string "fmul")
1431290286Sobrien               (match_operand:XF 3 "div_operator" "") 
1431390286Sobrien                 (const_string "fdiv")
1431450650Sobrien              ]
1431590286Sobrien              (const_string "fop")))
1431690286Sobrien   (set_attr "mode" "XF")])
1431718334Speter
1431890286Sobrien(define_insn "*fop_tf_1"
1431990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1432090286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1432190286Sobrien			[(match_operand:TF 1 "register_operand" "0,f")
1432290286Sobrien			 (match_operand:TF 2 "register_operand" "f,0")]))]
1432390286Sobrien  "TARGET_80387
1432490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1432590286Sobrien  "* return output_387_binary_op (insn, operands);"
1432690286Sobrien  [(set (attr "type") 
1432790286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1432890286Sobrien                 (const_string "fmul")
1432990286Sobrien               (match_operand:TF 3 "div_operator" "") 
1433090286Sobrien                 (const_string "fdiv")
1433190286Sobrien              ]
1433290286Sobrien              (const_string "fop")))
1433390286Sobrien   (set_attr "mode" "XF")])
1433490286Sobrien
1433590286Sobrien(define_insn "*fop_xf_2"
1433618334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1433790286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1433890286Sobrien	   [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1433990286Sobrien	    (match_operand:XF 2 "register_operand" "0,0")]))]
1434090286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1434190286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1434290286Sobrien  [(set (attr "type") 
1434390286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1434490286Sobrien                 (const_string "fmul")
1434590286Sobrien               (match_operand:XF 3 "div_operator" "") 
1434690286Sobrien                 (const_string "fdiv")
1434790286Sobrien              ]
1434890286Sobrien              (const_string "fop")))
1434990286Sobrien   (set_attr "fp_int_src" "true")
1435090286Sobrien   (set_attr "mode" "SI")
1435190286Sobrien   (set_attr "ppro_uops" "many")])
1435290286Sobrien
1435390286Sobrien(define_insn "*fop_tf_2"
1435490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1435590286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1435690286Sobrien	   [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1435790286Sobrien	    (match_operand:TF 2 "register_operand" "0,0")]))]
1435890286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1435990286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1436090286Sobrien  [(set (attr "type") 
1436190286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1436290286Sobrien                 (const_string "fmul")
1436390286Sobrien               (match_operand:TF 3 "div_operator" "") 
1436490286Sobrien                 (const_string "fdiv")
1436590286Sobrien              ]
1436690286Sobrien              (const_string "fop")))
1436790286Sobrien   (set_attr "fp_int_src" "true")
1436890286Sobrien   (set_attr "mode" "SI")
1436990286Sobrien   (set_attr "ppro_uops" "many")])
1437090286Sobrien
1437190286Sobrien(define_insn "*fop_xf_3"
1437290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1437390286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1437490286Sobrien	  [(match_operand:XF 1 "register_operand" "0,0")
1437590286Sobrien	   (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1437690286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1437790286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1437890286Sobrien  [(set (attr "type") 
1437990286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1438090286Sobrien                 (const_string "fmul")
1438190286Sobrien               (match_operand:XF 3 "div_operator" "") 
1438290286Sobrien                 (const_string "fdiv")
1438390286Sobrien              ]
1438490286Sobrien              (const_string "fop")))
1438590286Sobrien   (set_attr "fp_int_src" "true")
1438690286Sobrien   (set_attr "mode" "SI")
1438790286Sobrien   (set_attr "ppro_uops" "many")])
1438890286Sobrien
1438990286Sobrien(define_insn "*fop_tf_3"
1439090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1439190286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1439290286Sobrien	  [(match_operand:TF 1 "register_operand" "0,0")
1439390286Sobrien	   (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1439490286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1439590286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1439690286Sobrien  [(set (attr "type") 
1439790286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1439890286Sobrien                 (const_string "fmul")
1439990286Sobrien               (match_operand:TF 3 "div_operator" "") 
1440090286Sobrien                 (const_string "fdiv")
1440190286Sobrien              ]
1440290286Sobrien              (const_string "fop")))
1440390286Sobrien   (set_attr "fp_int_src" "true")
1440490286Sobrien   (set_attr "mode" "SI")
1440590286Sobrien   (set_attr "ppro_uops" "many")])
1440690286Sobrien
1440790286Sobrien(define_insn "*fop_xf_4"
1440890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1440990286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1441050650Sobrien	   [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1441150650Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1441290286Sobrien  "!TARGET_64BIT && TARGET_80387"
1441390286Sobrien  "* return output_387_binary_op (insn, operands);"
1441490286Sobrien  [(set (attr "type") 
1441590286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1441690286Sobrien                 (const_string "fmul")
1441790286Sobrien               (match_operand:XF 3 "div_operator" "") 
1441890286Sobrien                 (const_string "fdiv")
1441990286Sobrien              ]
1442090286Sobrien              (const_string "fop")))
1442190286Sobrien   (set_attr "mode" "SF")])
1442290286Sobrien
1442390286Sobrien(define_insn "*fop_tf_4"
1442490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1442590286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1442690286Sobrien	   [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1442790286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1442818334Speter  "TARGET_80387"
1442950650Sobrien  "* return output_387_binary_op (insn, operands);"
1443050650Sobrien  [(set (attr "type") 
1443190286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1443290286Sobrien                 (const_string "fmul")
1443390286Sobrien               (match_operand:TF 3 "div_operator" "") 
1443490286Sobrien                 (const_string "fdiv")
1443550650Sobrien              ]
1443690286Sobrien              (const_string "fop")))
1443790286Sobrien   (set_attr "mode" "SF")])
1443818334Speter
1443990286Sobrien(define_insn "*fop_xf_5"
1444018334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1444190286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1444250650Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1444318334Speter	   (float_extend:XF
1444450650Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1444590286Sobrien  "!TARGET_64BIT && TARGET_80387"
1444650650Sobrien  "* return output_387_binary_op (insn, operands);"
1444750650Sobrien  [(set (attr "type") 
1444890286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1444990286Sobrien                 (const_string "fmul")
1445090286Sobrien               (match_operand:XF 3 "div_operator" "") 
1445190286Sobrien                 (const_string "fdiv")
1445250650Sobrien              ]
1445390286Sobrien              (const_string "fop")))
1445490286Sobrien   (set_attr "mode" "SF")])
1445518334Speter
1445690286Sobrien(define_insn "*fop_tf_5"
1445790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1445890286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1445990286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1446090286Sobrien	   (float_extend:TF
1446190286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1446218334Speter  "TARGET_80387"
1446350650Sobrien  "* return output_387_binary_op (insn, operands);"
1446450650Sobrien  [(set (attr "type") 
1446590286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1446690286Sobrien                 (const_string "fmul")
1446790286Sobrien               (match_operand:TF 3 "div_operator" "") 
1446890286Sobrien                 (const_string "fdiv")
1446950650Sobrien              ]
1447090286Sobrien              (const_string "fop")))
1447190286Sobrien   (set_attr "mode" "SF")])
1447218334Speter
1447390286Sobrien(define_insn "*fop_xf_6"
1447490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1447590286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1447690286Sobrien	   [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1447790286Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1447890286Sobrien  "!TARGET_64BIT && TARGET_80387"
1447990286Sobrien  "* return output_387_binary_op (insn, operands);"
1448090286Sobrien  [(set (attr "type") 
1448190286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1448290286Sobrien                 (const_string "fmul")
1448390286Sobrien               (match_operand:XF 3 "div_operator" "") 
1448490286Sobrien                 (const_string "fdiv")
1448590286Sobrien              ]
1448690286Sobrien              (const_string "fop")))
1448790286Sobrien   (set_attr "mode" "DF")])
1448890286Sobrien
1448990286Sobrien(define_insn "*fop_tf_6"
1449090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1449190286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1449290286Sobrien	   [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1449390286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1449418334Speter  "TARGET_80387"
1449550650Sobrien  "* return output_387_binary_op (insn, operands);"
1449650650Sobrien  [(set (attr "type") 
1449790286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1449890286Sobrien                 (const_string "fmul")
1449990286Sobrien               (match_operand:TF 3 "div_operator" "") 
1450090286Sobrien                 (const_string "fdiv")
1450150650Sobrien              ]
1450290286Sobrien              (const_string "fop")))
1450390286Sobrien   (set_attr "mode" "DF")])
1450418334Speter
1450590286Sobrien(define_insn "*fop_xf_7"
1450690286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1450790286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1450890286Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1450990286Sobrien	   (float_extend:XF
1451090286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1451190286Sobrien  "!TARGET_64BIT && TARGET_80387"
1451290286Sobrien  "* return output_387_binary_op (insn, operands);"
1451390286Sobrien  [(set (attr "type") 
1451490286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1451590286Sobrien                 (const_string "fmul")
1451690286Sobrien               (match_operand:XF 3 "div_operator" "") 
1451790286Sobrien                 (const_string "fdiv")
1451890286Sobrien              ]
1451990286Sobrien              (const_string "fop")))
1452090286Sobrien   (set_attr "mode" "DF")])
1452190286Sobrien
1452290286Sobrien(define_insn "*fop_tf_7"
1452390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1452490286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1452590286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1452690286Sobrien	   (float_extend:TF
1452790286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1452818334Speter  "TARGET_80387"
1452950650Sobrien  "* return output_387_binary_op (insn, operands);"
1453050650Sobrien  [(set (attr "type") 
1453190286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1453290286Sobrien                 (const_string "fmul")
1453390286Sobrien               (match_operand:TF 3 "div_operator" "") 
1453490286Sobrien                 (const_string "fdiv")
1453550650Sobrien              ]
1453690286Sobrien              (const_string "fop")))
1453790286Sobrien   (set_attr "mode" "DF")])
1453890286Sobrien
1453990286Sobrien(define_split
1454090286Sobrien  [(set (match_operand 0 "register_operand" "")
1454190286Sobrien	(match_operator 3 "binary_fp_operator"
1454290286Sobrien	   [(float (match_operand:SI 1 "register_operand" ""))
1454390286Sobrien	    (match_operand 2 "register_operand" "")]))]
1454490286Sobrien  "TARGET_80387 && reload_completed
1454590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1454690286Sobrien  [(const_int 0)]
1454790286Sobrien{ 
1454890286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
1454990286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1455090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1455190286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1455290286Sobrien					  GET_MODE (operands[3]),
1455390286Sobrien					  operands[4],
1455490286Sobrien					  operands[2])));
1455590286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
1455690286Sobrien  DONE;
1455790286Sobrien})
1455890286Sobrien
1455990286Sobrien(define_split
1456090286Sobrien  [(set (match_operand 0 "register_operand" "")
1456190286Sobrien	(match_operator 3 "binary_fp_operator"
1456290286Sobrien	   [(match_operand 1 "register_operand" "")
1456390286Sobrien	    (float (match_operand:SI 2 "register_operand" ""))]))]
1456490286Sobrien  "TARGET_80387 && reload_completed
1456590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1456690286Sobrien  [(const_int 0)]
1456790286Sobrien{
1456890286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
1456990286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1457090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1457190286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1457290286Sobrien					  GET_MODE (operands[3]),
1457390286Sobrien					  operands[1],
1457490286Sobrien					  operands[4])));
1457590286Sobrien  ix86_free_from_memory (GET_MODE (operands[2]));
1457690286Sobrien  DONE;
1457790286Sobrien})
1457818334Speter
1457990286Sobrien;; FPU special functions.
1458090286Sobrien
1458190286Sobrien(define_expand "sqrtsf2"
1458290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1458390286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
1458490286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
1458590286Sobrien{
1458690286Sobrien  if (!TARGET_SSE_MATH)
1458790286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
1458890286Sobrien})
1458990286Sobrien
1459090286Sobrien(define_insn "sqrtsf2_1"
1459190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1459290286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
1459390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1459490286Sobrien   && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1459590286Sobrien  "@
1459690286Sobrien   fsqrt
1459790286Sobrien   sqrtss\t{%1, %0|%0, %1}"
1459890286Sobrien  [(set_attr "type" "fpspc,sse")
1459990286Sobrien   (set_attr "mode" "SF,SF")
1460090286Sobrien   (set_attr "athlon_decode" "direct,*")])
1460190286Sobrien
1460290286Sobrien(define_insn "sqrtsf2_1_sse_only"
1460390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1460490286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
1460590286Sobrien  "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1460690286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1460790286Sobrien  [(set_attr "type" "sse")
1460890286Sobrien   (set_attr "mode" "SF")
1460990286Sobrien   (set_attr "athlon_decode" "*")])
1461090286Sobrien
1461190286Sobrien(define_insn "sqrtsf2_i387"
1461290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1461390286Sobrien	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
1461490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1461590286Sobrien   && !TARGET_SSE_MATH"
1461690286Sobrien  "fsqrt"
1461790286Sobrien  [(set_attr "type" "fpspc")
1461890286Sobrien   (set_attr "mode" "SF")
1461990286Sobrien   (set_attr "athlon_decode" "direct")])
1462090286Sobrien
1462190286Sobrien(define_expand "sqrtdf2"
1462290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1462390286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
1462490286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
1462590286Sobrien   || (TARGET_SSE2 && TARGET_SSE_MATH)"
1462690286Sobrien{
1462790286Sobrien  if (!TARGET_SSE2 || !TARGET_SSE_MATH)
1462890286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
1462990286Sobrien})
1463090286Sobrien
1463190286Sobrien(define_insn "sqrtdf2_1"
1463290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1463390286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
1463490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1463590286Sobrien   && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1463690286Sobrien  "@
1463790286Sobrien   fsqrt
1463890286Sobrien   sqrtsd\t{%1, %0|%0, %1}"
1463990286Sobrien  [(set_attr "type" "fpspc,sse")
1464090286Sobrien   (set_attr "mode" "DF,DF")
1464190286Sobrien   (set_attr "athlon_decode" "direct,*")])
1464290286Sobrien
1464390286Sobrien(define_insn "sqrtdf2_1_sse_only"
1464490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1464590286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
1464690286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1464790286Sobrien  "sqrtsd\t{%1, %0|%0, %1}"
1464890286Sobrien  [(set_attr "type" "sse")
1464990286Sobrien   (set_attr "mode" "DF")
1465090286Sobrien   (set_attr "athlon_decode" "*")])
1465190286Sobrien
1465290286Sobrien(define_insn "sqrtdf2_i387"
1465390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1465490286Sobrien	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
1465590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1465690286Sobrien   && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
1465790286Sobrien  "fsqrt"
1465890286Sobrien  [(set_attr "type" "fpspc")
1465990286Sobrien   (set_attr "mode" "DF")
1466090286Sobrien   (set_attr "athlon_decode" "direct")])
1466190286Sobrien
1466290286Sobrien(define_insn "*sqrtextendsfdf2"
1466390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1466490286Sobrien	(sqrt:DF (float_extend:DF
1466590286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1466690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1466790286Sobrien   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1466890286Sobrien  "fsqrt"
1466990286Sobrien  [(set_attr "type" "fpspc")
1467090286Sobrien   (set_attr "mode" "DF")
1467190286Sobrien   (set_attr "athlon_decode" "direct")])
1467290286Sobrien
1467390286Sobrien(define_insn "sqrtxf2"
1467490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1467590286Sobrien	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
1467690286Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
1467790286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1467890286Sobrien  "fsqrt"
1467990286Sobrien  [(set_attr "type" "fpspc")
1468090286Sobrien   (set_attr "mode" "XF")
1468190286Sobrien   (set_attr "athlon_decode" "direct")])
1468290286Sobrien
1468390286Sobrien(define_insn "sqrttf2"
1468490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1468590286Sobrien	(sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
1468690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1468790286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1468890286Sobrien  "fsqrt"
1468990286Sobrien  [(set_attr "type" "fpspc")
1469090286Sobrien   (set_attr "mode" "XF")
1469190286Sobrien   (set_attr "athlon_decode" "direct")])
1469290286Sobrien
1469390286Sobrien(define_insn "*sqrtextenddfxf2"
1469490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1469590286Sobrien	(sqrt:XF (float_extend:XF
1469690286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1469796294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1469890286Sobrien  "fsqrt"
1469990286Sobrien  [(set_attr "type" "fpspc")
1470090286Sobrien   (set_attr "mode" "XF")
1470190286Sobrien   (set_attr "athlon_decode" "direct")])
1470290286Sobrien
1470390286Sobrien(define_insn "*sqrtextenddftf2"
1470490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1470590286Sobrien	(sqrt:TF (float_extend:TF
1470690286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1470790286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1470890286Sobrien  "fsqrt"
1470990286Sobrien  [(set_attr "type" "fpspc")
1471090286Sobrien   (set_attr "mode" "XF")
1471190286Sobrien   (set_attr "athlon_decode" "direct")])
1471290286Sobrien
1471390286Sobrien(define_insn "*sqrtextendsfxf2"
1471490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1471590286Sobrien	(sqrt:XF (float_extend:XF
1471690286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1471796294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1471890286Sobrien  "fsqrt"
1471990286Sobrien  [(set_attr "type" "fpspc")
1472090286Sobrien   (set_attr "mode" "XF")
1472190286Sobrien   (set_attr "athlon_decode" "direct")])
1472290286Sobrien
1472390286Sobrien(define_insn "*sqrtextendsftf2"
1472490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1472590286Sobrien	(sqrt:TF (float_extend:TF
1472690286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1472790286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1472890286Sobrien  "fsqrt"
1472990286Sobrien  [(set_attr "type" "fpspc")
1473090286Sobrien   (set_attr "mode" "XF")
1473190286Sobrien   (set_attr "athlon_decode" "direct")])
1473290286Sobrien
1473390286Sobrien(define_insn "sindf2"
1473490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
14735117404Skan	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
1473690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1473790286Sobrien   && flag_unsafe_math_optimizations"
1473890286Sobrien  "fsin"
1473990286Sobrien  [(set_attr "type" "fpspc")
1474090286Sobrien   (set_attr "mode" "DF")])
1474190286Sobrien
1474290286Sobrien(define_insn "sinsf2"
1474390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
14744117404Skan	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
1474590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1474690286Sobrien   && flag_unsafe_math_optimizations"
1474790286Sobrien  "fsin"
1474890286Sobrien  [(set_attr "type" "fpspc")
1474990286Sobrien   (set_attr "mode" "SF")])
1475090286Sobrien
1475190286Sobrien(define_insn "*sinextendsfdf2"
1475290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1475390286Sobrien	(unspec:DF [(float_extend:DF
14754117404Skan		     (match_operand:SF 1 "register_operand" "0"))]
14755117404Skan		   UNSPEC_SIN))]
1475690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1475790286Sobrien   && flag_unsafe_math_optimizations"
1475890286Sobrien  "fsin"
1475990286Sobrien  [(set_attr "type" "fpspc")
1476090286Sobrien   (set_attr "mode" "DF")])
1476190286Sobrien
1476290286Sobrien(define_insn "sinxf2"
1476390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
14764117404Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
1476596294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
1476690286Sobrien   && flag_unsafe_math_optimizations"
1476790286Sobrien  "fsin"
1476890286Sobrien  [(set_attr "type" "fpspc")
1476990286Sobrien   (set_attr "mode" "XF")])
1477090286Sobrien
1477190286Sobrien(define_insn "sintf2"
1477290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
14773117404Skan	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
1477490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1477590286Sobrien   && flag_unsafe_math_optimizations"
1477690286Sobrien  "fsin"
1477790286Sobrien  [(set_attr "type" "fpspc")
1477890286Sobrien   (set_attr "mode" "XF")])
1477990286Sobrien
1478090286Sobrien(define_insn "cosdf2"
1478190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
14782117404Skan	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
1478390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1478490286Sobrien   && flag_unsafe_math_optimizations"
1478590286Sobrien  "fcos"
1478690286Sobrien  [(set_attr "type" "fpspc")
1478790286Sobrien   (set_attr "mode" "DF")])
1478890286Sobrien
1478990286Sobrien(define_insn "cossf2"
1479090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
14791117404Skan	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
1479290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1479390286Sobrien   && flag_unsafe_math_optimizations"
1479490286Sobrien  "fcos"
1479590286Sobrien  [(set_attr "type" "fpspc")
1479690286Sobrien   (set_attr "mode" "SF")])
1479790286Sobrien
1479890286Sobrien(define_insn "*cosextendsfdf2"
1479990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1480090286Sobrien	(unspec:DF [(float_extend:DF
14801117404Skan		     (match_operand:SF 1 "register_operand" "0"))]
14802117404Skan		   UNSPEC_COS))]
1480390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1480490286Sobrien   && flag_unsafe_math_optimizations"
1480590286Sobrien  "fcos"
1480690286Sobrien  [(set_attr "type" "fpspc")
1480790286Sobrien   (set_attr "mode" "DF")])
1480890286Sobrien
1480990286Sobrien(define_insn "cosxf2"
1481090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
14811117404Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14812117404Skan  "!TARGET_64BIT && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1481390286Sobrien   && flag_unsafe_math_optimizations"
1481490286Sobrien  "fcos"
1481590286Sobrien  [(set_attr "type" "fpspc")
1481690286Sobrien   (set_attr "mode" "XF")])
1481790286Sobrien
1481890286Sobrien(define_insn "costf2"
1481990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
14820117404Skan	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
1482190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1482290286Sobrien   && flag_unsafe_math_optimizations"
1482390286Sobrien  "fcos"
1482490286Sobrien  [(set_attr "type" "fpspc")
1482590286Sobrien   (set_attr "mode" "XF")])
1482690286Sobrien
1482790286Sobrien;; Block operation instructions
1482890286Sobrien
1482990286Sobrien(define_insn "cld"
1483090286Sobrien [(set (reg:SI 19) (const_int 0))]
1483190286Sobrien ""
1483290286Sobrien "cld"
1483390286Sobrien  [(set_attr "type" "cld")])
1483490286Sobrien
1483590286Sobrien(define_expand "movstrsi"
1483690286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1483790286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1483890286Sobrien   (use (match_operand:SI 2 "nonmemory_operand" ""))
1483990286Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
1484018334Speter  ""
1484118334Speter{
1484290286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1484390286Sobrien   DONE;
1484490286Sobrien else
1484590286Sobrien   FAIL;
1484690286Sobrien})
1484790286Sobrien
1484890286Sobrien(define_expand "movstrdi"
1484990286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1485090286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1485190286Sobrien   (use (match_operand:DI 2 "nonmemory_operand" ""))
1485290286Sobrien   (use (match_operand:DI 3 "const_int_operand" ""))]
1485390286Sobrien  "TARGET_64BIT"
1485490286Sobrien{
1485590286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1485690286Sobrien   DONE;
1485790286Sobrien else
1485890286Sobrien   FAIL;
1485990286Sobrien})
1486090286Sobrien
1486190286Sobrien;; Most CPUs don't like single string operations
1486290286Sobrien;; Handle this case here to simplify previous expander.
1486390286Sobrien
1486490286Sobrien(define_expand "strmovdi_rex64"
1486590286Sobrien  [(set (match_dup 2)
1486690286Sobrien  	(mem:DI (match_operand:DI 1 "register_operand" "")))
1486790286Sobrien   (set (mem:DI (match_operand:DI 0 "register_operand" ""))
1486890286Sobrien        (match_dup 2))
1486990286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1487090286Sobrien	      (clobber (reg:CC 17))])
1487190286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
1487290286Sobrien	      (clobber (reg:CC 17))])]
1487390286Sobrien  "TARGET_64BIT"
1487490286Sobrien{
1487590286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1487650650Sobrien    {
1487790286Sobrien      emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
1487890286Sobrien				     operands[1]));
1487990286Sobrien      DONE;
1488090286Sobrien    }
1488190286Sobrien  else 
1488290286Sobrien    operands[2] = gen_reg_rtx (DImode);
1488390286Sobrien})
1488450650Sobrien
1488550650Sobrien
1488690286Sobrien(define_expand "strmovsi"
1488790286Sobrien  [(set (match_dup 2)
1488890286Sobrien  	(mem:SI (match_operand:SI 1 "register_operand" "")))
1488990286Sobrien   (set (mem:SI (match_operand:SI 0 "register_operand" ""))
1489090286Sobrien        (match_dup 2))
1489190286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1489290286Sobrien	      (clobber (reg:CC 17))])
1489390286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
1489490286Sobrien	      (clobber (reg:CC 17))])]
1489590286Sobrien  ""
1489690286Sobrien{
1489790286Sobrien  if (TARGET_64BIT)
1489890286Sobrien    {
1489990286Sobrien      emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
1490090286Sobrien      DONE;
1490190286Sobrien    }
1490290286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1490390286Sobrien    {
1490490286Sobrien      emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
1490590286Sobrien				operands[1]));
1490690286Sobrien      DONE;
1490790286Sobrien    }
1490890286Sobrien  else 
1490990286Sobrien    operands[2] = gen_reg_rtx (SImode);
1491090286Sobrien})
1491150650Sobrien
1491290286Sobrien(define_expand "strmovsi_rex64"
1491390286Sobrien  [(set (match_dup 2)
1491490286Sobrien  	(mem:SI (match_operand:DI 1 "register_operand" "")))
1491590286Sobrien   (set (mem:SI (match_operand:DI 0 "register_operand" ""))
1491690286Sobrien        (match_dup 2))
1491790286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1491890286Sobrien	      (clobber (reg:CC 17))])
1491990286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
1492090286Sobrien	      (clobber (reg:CC 17))])]
1492190286Sobrien  "TARGET_64BIT"
1492290286Sobrien{
1492390286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1492490286Sobrien    {
1492590286Sobrien      emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
1492690286Sobrien				     operands[1]));
1492790286Sobrien      DONE;
1492890286Sobrien    }
1492990286Sobrien  else 
1493090286Sobrien    operands[2] = gen_reg_rtx (SImode);
1493190286Sobrien})
1493250650Sobrien
1493390286Sobrien(define_expand "strmovhi"
1493490286Sobrien  [(set (match_dup 2)
1493590286Sobrien  	(mem:HI (match_operand:SI 1 "register_operand" "")))
1493690286Sobrien   (set (mem:HI (match_operand:SI 0 "register_operand" ""))
1493790286Sobrien        (match_dup 2))
1493890286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1493990286Sobrien	      (clobber (reg:CC 17))])
1494090286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1494190286Sobrien	      (clobber (reg:CC 17))])]
1494290286Sobrien  ""
1494390286Sobrien{
1494490286Sobrien  if (TARGET_64BIT)
1494590286Sobrien    {
1494690286Sobrien      emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
1494790286Sobrien      DONE;
1494890286Sobrien    }
1494990286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1495090286Sobrien    {
1495190286Sobrien      emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
1495290286Sobrien				operands[1]));
1495390286Sobrien      DONE;
1495490286Sobrien    }
1495590286Sobrien  else 
1495690286Sobrien    operands[2] = gen_reg_rtx (HImode);
1495790286Sobrien})
1495850650Sobrien
1495990286Sobrien(define_expand "strmovhi_rex64"
1496090286Sobrien  [(set (match_dup 2)
1496190286Sobrien  	(mem:HI (match_operand:DI 1 "register_operand" "")))
1496290286Sobrien   (set (mem:HI (match_operand:DI 0 "register_operand" ""))
1496390286Sobrien        (match_dup 2))
1496490286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1496590286Sobrien	      (clobber (reg:CC 17))])
1496690286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
1496790286Sobrien	      (clobber (reg:CC 17))])]
1496890286Sobrien  "TARGET_64BIT"
1496990286Sobrien{
1497090286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1497190286Sobrien    {
1497290286Sobrien      emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
1497390286Sobrien				     operands[1]));
1497450650Sobrien      DONE;
1497550650Sobrien    }
1497690286Sobrien  else 
1497790286Sobrien    operands[2] = gen_reg_rtx (HImode);
1497890286Sobrien})
1497950650Sobrien
1498090286Sobrien(define_expand "strmovqi"
1498190286Sobrien  [(set (match_dup 2)
1498290286Sobrien  	(mem:QI (match_operand:SI 1 "register_operand" "")))
1498390286Sobrien   (set (mem:QI (match_operand:SI 0 "register_operand" ""))
1498490286Sobrien        (match_dup 2))
1498590286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1498690286Sobrien	      (clobber (reg:CC 17))])
1498790286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
1498890286Sobrien	      (clobber (reg:CC 17))])]
1498990286Sobrien  ""
1499090286Sobrien{
1499190286Sobrien  if (TARGET_64BIT)
1499290286Sobrien    {
1499390286Sobrien      emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
1499490286Sobrien      DONE;
1499590286Sobrien    }
1499690286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1499790286Sobrien    {
1499890286Sobrien      emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
1499990286Sobrien				operands[1]));
1500090286Sobrien      DONE;
1500190286Sobrien    }
1500290286Sobrien  else 
1500390286Sobrien    operands[2] = gen_reg_rtx (QImode);
1500490286Sobrien})
1500518334Speter
1500690286Sobrien(define_expand "strmovqi_rex64"
1500790286Sobrien  [(set (match_dup 2)
1500890286Sobrien  	(mem:QI (match_operand:DI 1 "register_operand" "")))
1500990286Sobrien   (set (mem:QI (match_operand:DI 0 "register_operand" ""))
1501090286Sobrien        (match_dup 2))
1501190286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1501290286Sobrien	      (clobber (reg:CC 17))])
1501390286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
1501490286Sobrien	      (clobber (reg:CC 17))])]
1501590286Sobrien  "TARGET_64BIT"
1501690286Sobrien{
1501790286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1501890286Sobrien    {
1501990286Sobrien      emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
1502090286Sobrien				     operands[1]));
1502190286Sobrien      DONE;
1502290286Sobrien    }
1502390286Sobrien  else 
1502490286Sobrien    operands[2] = gen_reg_rtx (QImode);
1502590286Sobrien})
1502618334Speter
1502790286Sobrien(define_insn "strmovdi_rex_1"
1502890286Sobrien  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
1502990286Sobrien	(mem:DI (match_operand:DI 3 "register_operand" "1")))
1503090286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1503190286Sobrien	(plus:DI (match_dup 2)
1503290286Sobrien		 (const_int 8)))
1503390286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1503490286Sobrien	(plus:DI (match_dup 3)
1503590286Sobrien		 (const_int 8)))
1503690286Sobrien   (use (reg:SI 19))]
1503790286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1503890286Sobrien  "movsq"
1503990286Sobrien  [(set_attr "type" "str")
1504090286Sobrien   (set_attr "mode" "DI")
1504190286Sobrien   (set_attr "memory" "both")])
1504290286Sobrien
1504390286Sobrien(define_insn "strmovsi_1"
1504490286Sobrien  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
1504590286Sobrien	(mem:SI (match_operand:SI 3 "register_operand" "1")))
1504690286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1504790286Sobrien	(plus:SI (match_dup 2)
1504890286Sobrien		 (const_int 4)))
1504990286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1505090286Sobrien	(plus:SI (match_dup 3)
1505190286Sobrien		 (const_int 4)))
1505290286Sobrien   (use (reg:SI 19))]
1505390286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1505490286Sobrien  "{movsl|movsd}"
1505590286Sobrien  [(set_attr "type" "str")
1505690286Sobrien   (set_attr "mode" "SI")
1505790286Sobrien   (set_attr "memory" "both")])
1505890286Sobrien
1505990286Sobrien(define_insn "strmovsi_rex_1"
1506090286Sobrien  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
1506190286Sobrien	(mem:SI (match_operand:DI 3 "register_operand" "1")))
1506290286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1506390286Sobrien	(plus:DI (match_dup 2)
1506490286Sobrien		 (const_int 4)))
1506590286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1506690286Sobrien	(plus:DI (match_dup 3)
1506790286Sobrien		 (const_int 4)))
1506890286Sobrien   (use (reg:SI 19))]
1506990286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1507090286Sobrien  "{movsl|movsd}"
1507190286Sobrien  [(set_attr "type" "str")
1507290286Sobrien   (set_attr "mode" "SI")
1507390286Sobrien   (set_attr "memory" "both")])
1507490286Sobrien
1507590286Sobrien(define_insn "strmovhi_1"
1507690286Sobrien  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
1507790286Sobrien	(mem:HI (match_operand:SI 3 "register_operand" "1")))
1507890286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1507990286Sobrien	(plus:SI (match_dup 2)
1508090286Sobrien		 (const_int 2)))
1508190286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1508290286Sobrien	(plus:SI (match_dup 3)
1508390286Sobrien		 (const_int 2)))
1508490286Sobrien   (use (reg:SI 19))]
1508590286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1508690286Sobrien  "movsw"
1508790286Sobrien  [(set_attr "type" "str")
1508890286Sobrien   (set_attr "memory" "both")
1508990286Sobrien   (set_attr "mode" "HI")])
1509090286Sobrien
1509190286Sobrien(define_insn "strmovhi_rex_1"
1509290286Sobrien  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
1509390286Sobrien	(mem:HI (match_operand:DI 3 "register_operand" "1")))
1509490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1509590286Sobrien	(plus:DI (match_dup 2)
1509690286Sobrien		 (const_int 2)))
1509790286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1509890286Sobrien	(plus:DI (match_dup 3)
1509990286Sobrien		 (const_int 2)))
1510090286Sobrien   (use (reg:SI 19))]
1510190286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1510290286Sobrien  "movsw"
1510390286Sobrien  [(set_attr "type" "str")
1510490286Sobrien   (set_attr "memory" "both")
1510590286Sobrien   (set_attr "mode" "HI")])
1510690286Sobrien
1510790286Sobrien(define_insn "strmovqi_1"
1510890286Sobrien  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
1510990286Sobrien	(mem:QI (match_operand:SI 3 "register_operand" "1")))
1511090286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1511190286Sobrien	(plus:SI (match_dup 2)
1511290286Sobrien		 (const_int 1)))
1511390286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1511490286Sobrien	(plus:SI (match_dup 3)
1511590286Sobrien		 (const_int 1)))
1511690286Sobrien   (use (reg:SI 19))]
1511790286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1511890286Sobrien  "movsb"
1511990286Sobrien  [(set_attr "type" "str")
1512090286Sobrien   (set_attr "memory" "both")
1512190286Sobrien   (set_attr "mode" "QI")])
1512290286Sobrien
1512390286Sobrien(define_insn "strmovqi_rex_1"
1512490286Sobrien  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
1512590286Sobrien	(mem:QI (match_operand:DI 3 "register_operand" "1")))
1512690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1512790286Sobrien	(plus:DI (match_dup 2)
1512890286Sobrien		 (const_int 1)))
1512990286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1513090286Sobrien	(plus:DI (match_dup 3)
1513190286Sobrien		 (const_int 1)))
1513290286Sobrien   (use (reg:SI 19))]
1513390286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1513490286Sobrien  "movsb"
1513590286Sobrien  [(set_attr "type" "str")
1513690286Sobrien   (set_attr "memory" "both")
1513790286Sobrien   (set_attr "mode" "QI")])
1513890286Sobrien
1513990286Sobrien(define_insn "rep_movdi_rex64"
1514090286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1514190286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1514290286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1514390286Sobrien			    (const_int 3))
1514490286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1514590286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1514690286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
1514790286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1514890286Sobrien   (set (mem:BLK (match_dup 3))
1514990286Sobrien	(mem:BLK (match_dup 4)))
1515090286Sobrien   (use (match_dup 5))
1515190286Sobrien   (use (reg:SI 19))]
1515290286Sobrien  "TARGET_64BIT"
1515390286Sobrien  "{rep\;movsq|rep movsq}"
1515490286Sobrien  [(set_attr "type" "str")
1515590286Sobrien   (set_attr "prefix_rep" "1")
1515690286Sobrien   (set_attr "memory" "both")
1515790286Sobrien   (set_attr "mode" "DI")])
1515890286Sobrien
1515990286Sobrien(define_insn "rep_movsi"
1516090286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1516190286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1516290286Sobrien        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
1516390286Sobrien			    (const_int 2))
1516490286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1516590286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1516690286Sobrien        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
1516790286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1516890286Sobrien   (set (mem:BLK (match_dup 3))
1516990286Sobrien	(mem:BLK (match_dup 4)))
1517090286Sobrien   (use (match_dup 5))
1517190286Sobrien   (use (reg:SI 19))]
1517290286Sobrien  "!TARGET_64BIT"
1517390286Sobrien  "{rep\;movsl|rep movsd}"
1517490286Sobrien  [(set_attr "type" "str")
1517590286Sobrien   (set_attr "prefix_rep" "1")
1517690286Sobrien   (set_attr "memory" "both")
1517790286Sobrien   (set_attr "mode" "SI")])
1517890286Sobrien
1517990286Sobrien(define_insn "rep_movsi_rex64"
1518090286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1518190286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1518290286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1518390286Sobrien			    (const_int 2))
1518490286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1518590286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1518690286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
1518790286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1518890286Sobrien   (set (mem:BLK (match_dup 3))
1518990286Sobrien	(mem:BLK (match_dup 4)))
1519090286Sobrien   (use (match_dup 5))
1519190286Sobrien   (use (reg:SI 19))]
1519290286Sobrien  "TARGET_64BIT"
1519390286Sobrien  "{rep\;movsl|rep movsd}"
1519490286Sobrien  [(set_attr "type" "str")
1519590286Sobrien   (set_attr "prefix_rep" "1")
1519690286Sobrien   (set_attr "memory" "both")
1519790286Sobrien   (set_attr "mode" "SI")])
1519890286Sobrien
1519990286Sobrien(define_insn "rep_movqi"
1520090286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1520190286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1520290286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1520390286Sobrien		 (match_operand:SI 5 "register_operand" "2")))
1520490286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1520590286Sobrien        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
1520690286Sobrien   (set (mem:BLK (match_dup 3))
1520790286Sobrien	(mem:BLK (match_dup 4)))
1520890286Sobrien   (use (match_dup 5))
1520990286Sobrien   (use (reg:SI 19))]
1521090286Sobrien  "!TARGET_64BIT"
1521190286Sobrien  "{rep\;movsb|rep movsb}"
1521290286Sobrien  [(set_attr "type" "str")
1521390286Sobrien   (set_attr "prefix_rep" "1")
1521490286Sobrien   (set_attr "memory" "both")
1521590286Sobrien   (set_attr "mode" "SI")])
1521690286Sobrien
1521790286Sobrien(define_insn "rep_movqi_rex64"
1521890286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1521990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1522090286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1522190286Sobrien		 (match_operand:DI 5 "register_operand" "2")))
1522290286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1522390286Sobrien        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
1522490286Sobrien   (set (mem:BLK (match_dup 3))
1522590286Sobrien	(mem:BLK (match_dup 4)))
1522690286Sobrien   (use (match_dup 5))
1522790286Sobrien   (use (reg:SI 19))]
1522890286Sobrien  "TARGET_64BIT"
1522990286Sobrien  "{rep\;movsb|rep movsb}"
1523090286Sobrien  [(set_attr "type" "str")
1523190286Sobrien   (set_attr "prefix_rep" "1")
1523290286Sobrien   (set_attr "memory" "both")
1523390286Sobrien   (set_attr "mode" "SI")])
1523490286Sobrien
1523590286Sobrien(define_expand "clrstrsi"
1523690286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1523790286Sobrien    (use (match_operand:SI 1 "nonmemory_operand" ""))
1523890286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1523918334Speter  ""
1524018334Speter{
1524190286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1524290286Sobrien   DONE;
1524390286Sobrien else
1524490286Sobrien   FAIL;
1524590286Sobrien})
1524618334Speter
1524790286Sobrien(define_expand "clrstrdi"
1524890286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1524990286Sobrien    (use (match_operand:DI 1 "nonmemory_operand" ""))
1525090286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1525190286Sobrien  "TARGET_64BIT"
1525290286Sobrien{
1525390286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1525490286Sobrien   DONE;
1525590286Sobrien else
1525690286Sobrien   FAIL;
1525790286Sobrien})
1525850650Sobrien
1525990286Sobrien;; Most CPUs don't like single string operations
1526090286Sobrien;; Handle this case here to simplify previous expander.
1526150650Sobrien
1526290286Sobrien(define_expand "strsetdi_rex64"
1526390286Sobrien  [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
1526490286Sobrien	(match_operand:DI 1 "register_operand" ""))
1526590286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1526690286Sobrien	      (clobber (reg:CC 17))])]
1526790286Sobrien  "TARGET_64BIT"
1526890286Sobrien{
1526990286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1527090286Sobrien    {
1527190286Sobrien      emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
1527290286Sobrien      DONE;
1527390286Sobrien    }
1527490286Sobrien})
1527590286Sobrien
1527690286Sobrien(define_expand "strsetsi"
1527790286Sobrien  [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
1527890286Sobrien	(match_operand:SI 1 "register_operand" ""))
1527990286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1528090286Sobrien	      (clobber (reg:CC 17))])]
1528190286Sobrien  ""
1528290286Sobrien{
1528390286Sobrien  if (TARGET_64BIT)
1528490286Sobrien    {
1528590286Sobrien      emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
1528690286Sobrien      DONE;
1528790286Sobrien    }
1528890286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1528990286Sobrien    {
1529090286Sobrien      emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
1529190286Sobrien      DONE;
1529290286Sobrien    }
1529390286Sobrien})
1529490286Sobrien
1529590286Sobrien(define_expand "strsetsi_rex64"
1529690286Sobrien  [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
1529790286Sobrien	(match_operand:SI 1 "register_operand" ""))
1529890286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1529990286Sobrien	      (clobber (reg:CC 17))])]
1530090286Sobrien  "TARGET_64BIT"
1530190286Sobrien{
1530290286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1530390286Sobrien    {
1530490286Sobrien      emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
1530590286Sobrien      DONE;
1530690286Sobrien    }
1530790286Sobrien})
1530890286Sobrien
1530990286Sobrien(define_expand "strsethi"
1531090286Sobrien  [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
1531190286Sobrien	(match_operand:HI 1 "register_operand" ""))
1531290286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1531390286Sobrien	      (clobber (reg:CC 17))])]
1531490286Sobrien  ""
1531590286Sobrien{
1531690286Sobrien  if (TARGET_64BIT)
1531790286Sobrien    {
1531890286Sobrien      emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
1531990286Sobrien      DONE;
1532090286Sobrien    }
1532190286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1532290286Sobrien    {
1532390286Sobrien      emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
1532490286Sobrien      DONE;
1532590286Sobrien    }
1532690286Sobrien})
1532790286Sobrien
1532890286Sobrien(define_expand "strsethi_rex64"
1532990286Sobrien  [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
1533090286Sobrien	(match_operand:HI 1 "register_operand" ""))
1533190286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1533290286Sobrien	      (clobber (reg:CC 17))])]
1533390286Sobrien  "TARGET_64BIT"
1533490286Sobrien{
1533590286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1533690286Sobrien    {
1533790286Sobrien      emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
1533890286Sobrien      DONE;
1533990286Sobrien    }
1534090286Sobrien})
1534190286Sobrien
1534290286Sobrien(define_expand "strsetqi"
1534390286Sobrien  [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
1534490286Sobrien	(match_operand:QI 1 "register_operand" ""))
1534590286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1534690286Sobrien	      (clobber (reg:CC 17))])]
1534790286Sobrien  ""
1534890286Sobrien{
1534990286Sobrien  if (TARGET_64BIT)
1535090286Sobrien    {
1535190286Sobrien      emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
1535290286Sobrien      DONE;
1535390286Sobrien    }
1535490286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1535590286Sobrien    {
1535690286Sobrien      emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
1535790286Sobrien      DONE;
1535890286Sobrien    }
1535990286Sobrien})
1536090286Sobrien
1536190286Sobrien(define_expand "strsetqi_rex64"
1536290286Sobrien  [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
1536390286Sobrien	(match_operand:QI 1 "register_operand" ""))
1536490286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1536590286Sobrien	      (clobber (reg:CC 17))])]
1536690286Sobrien  "TARGET_64BIT"
1536790286Sobrien{
1536890286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1536990286Sobrien    {
1537090286Sobrien      emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
1537190286Sobrien      DONE;
1537290286Sobrien    }
1537390286Sobrien})
1537490286Sobrien
1537590286Sobrien(define_insn "strsetdi_rex_1"
1537690286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1537790286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1537890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1537990286Sobrien	(plus:DI (match_dup 1)
1538090286Sobrien		 (const_int 8)))
1538190286Sobrien   (use (reg:SI 19))]
1538290286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1538390286Sobrien  "stosq"
1538490286Sobrien  [(set_attr "type" "str")
1538590286Sobrien   (set_attr "memory" "store")
1538690286Sobrien   (set_attr "mode" "DI")])
1538790286Sobrien
1538890286Sobrien(define_insn "strsetsi_1"
1538990286Sobrien  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
1539090286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1539190286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1539290286Sobrien	(plus:SI (match_dup 1)
1539390286Sobrien		 (const_int 4)))
1539490286Sobrien   (use (reg:SI 19))]
1539590286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1539690286Sobrien  "{stosl|stosd}"
1539790286Sobrien  [(set_attr "type" "str")
1539890286Sobrien   (set_attr "memory" "store")
1539990286Sobrien   (set_attr "mode" "SI")])
1540090286Sobrien
1540190286Sobrien(define_insn "strsetsi_rex_1"
1540290286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1540390286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1540490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1540590286Sobrien	(plus:DI (match_dup 1)
1540690286Sobrien		 (const_int 4)))
1540790286Sobrien   (use (reg:SI 19))]
1540890286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1540990286Sobrien  "{stosl|stosd}"
1541090286Sobrien  [(set_attr "type" "str")
1541190286Sobrien   (set_attr "memory" "store")
1541290286Sobrien   (set_attr "mode" "SI")])
1541390286Sobrien
1541490286Sobrien(define_insn "strsethi_1"
1541590286Sobrien  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
1541690286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1541790286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1541890286Sobrien	(plus:SI (match_dup 1)
1541990286Sobrien		 (const_int 2)))
1542090286Sobrien   (use (reg:SI 19))]
1542190286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1542290286Sobrien  "stosw"
1542390286Sobrien  [(set_attr "type" "str")
1542490286Sobrien   (set_attr "memory" "store")
1542590286Sobrien   (set_attr "mode" "HI")])
1542690286Sobrien
1542790286Sobrien(define_insn "strsethi_rex_1"
1542890286Sobrien  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
1542990286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1543090286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1543190286Sobrien	(plus:DI (match_dup 1)
1543290286Sobrien		 (const_int 2)))
1543390286Sobrien   (use (reg:SI 19))]
1543490286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1543590286Sobrien  "stosw"
1543690286Sobrien  [(set_attr "type" "str")
1543790286Sobrien   (set_attr "memory" "store")
1543890286Sobrien   (set_attr "mode" "HI")])
1543990286Sobrien
1544090286Sobrien(define_insn "strsetqi_1"
1544190286Sobrien  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
1544290286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1544390286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1544490286Sobrien	(plus:SI (match_dup 1)
1544590286Sobrien		 (const_int 1)))
1544690286Sobrien   (use (reg:SI 19))]
1544790286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1544890286Sobrien  "stosb"
1544990286Sobrien  [(set_attr "type" "str")
1545090286Sobrien   (set_attr "memory" "store")
1545190286Sobrien   (set_attr "mode" "QI")])
1545290286Sobrien
1545390286Sobrien(define_insn "strsetqi_rex_1"
1545490286Sobrien  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
1545590286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1545690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1545790286Sobrien	(plus:DI (match_dup 1)
1545890286Sobrien		 (const_int 1)))
1545990286Sobrien   (use (reg:SI 19))]
1546090286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1546190286Sobrien  "stosb"
1546290286Sobrien  [(set_attr "type" "str")
1546390286Sobrien   (set_attr "memory" "store")
1546490286Sobrien   (set_attr "mode" "QI")])
1546590286Sobrien
1546690286Sobrien(define_insn "rep_stosdi_rex64"
1546790286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1546890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1546990286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1547090286Sobrien			    (const_int 3))
1547190286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1547290286Sobrien   (set (mem:BLK (match_dup 3))
1547390286Sobrien	(const_int 0))
1547490286Sobrien   (use (match_operand:DI 2 "register_operand" "a"))
1547590286Sobrien   (use (match_dup 4))
1547690286Sobrien   (use (reg:SI 19))]
1547790286Sobrien  "TARGET_64BIT"
1547890286Sobrien  "{rep\;stosq|rep stosq}"
1547990286Sobrien  [(set_attr "type" "str")
1548090286Sobrien   (set_attr "prefix_rep" "1")
1548190286Sobrien   (set_attr "memory" "store")
1548290286Sobrien   (set_attr "mode" "DI")])
1548390286Sobrien
1548490286Sobrien(define_insn "rep_stossi"
1548590286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1548690286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1548790286Sobrien        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
1548890286Sobrien			    (const_int 2))
1548990286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1549090286Sobrien   (set (mem:BLK (match_dup 3))
1549190286Sobrien	(const_int 0))
1549290286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1549390286Sobrien   (use (match_dup 4))
1549490286Sobrien   (use (reg:SI 19))]
1549590286Sobrien  "!TARGET_64BIT"
1549690286Sobrien  "{rep\;stosl|rep stosd}"
1549790286Sobrien  [(set_attr "type" "str")
1549890286Sobrien   (set_attr "prefix_rep" "1")
1549990286Sobrien   (set_attr "memory" "store")
1550090286Sobrien   (set_attr "mode" "SI")])
1550190286Sobrien
1550290286Sobrien(define_insn "rep_stossi_rex64"
1550390286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1550490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1550590286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1550690286Sobrien			    (const_int 2))
1550790286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1550890286Sobrien   (set (mem:BLK (match_dup 3))
1550990286Sobrien	(const_int 0))
1551090286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1551190286Sobrien   (use (match_dup 4))
1551290286Sobrien   (use (reg:SI 19))]
1551390286Sobrien  "TARGET_64BIT"
1551490286Sobrien  "{rep\;stosl|rep stosd}"
1551590286Sobrien  [(set_attr "type" "str")
1551690286Sobrien   (set_attr "prefix_rep" "1")
1551790286Sobrien   (set_attr "memory" "store")
1551890286Sobrien   (set_attr "mode" "SI")])
1551990286Sobrien
1552090286Sobrien(define_insn "rep_stosqi"
1552190286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1552290286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1552390286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1552490286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1552590286Sobrien   (set (mem:BLK (match_dup 3))
1552690286Sobrien	(const_int 0))
1552790286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1552890286Sobrien   (use (match_dup 4))
1552990286Sobrien   (use (reg:SI 19))]
1553090286Sobrien  "!TARGET_64BIT"
1553190286Sobrien  "{rep\;stosb|rep stosb}"
1553290286Sobrien  [(set_attr "type" "str")
1553390286Sobrien   (set_attr "prefix_rep" "1")
1553490286Sobrien   (set_attr "memory" "store")
1553590286Sobrien   (set_attr "mode" "QI")])
1553690286Sobrien
1553790286Sobrien(define_insn "rep_stosqi_rex64"
1553890286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1553990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1554090286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1554190286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1554290286Sobrien   (set (mem:BLK (match_dup 3))
1554390286Sobrien	(const_int 0))
1554490286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1554590286Sobrien   (use (match_dup 4))
1554690286Sobrien   (use (reg:DI 19))]
1554790286Sobrien  "TARGET_64BIT"
1554890286Sobrien  "{rep\;stosb|rep stosb}"
1554990286Sobrien  [(set_attr "type" "str")
1555090286Sobrien   (set_attr "prefix_rep" "1")
1555190286Sobrien   (set_attr "memory" "store")
1555290286Sobrien   (set_attr "mode" "QI")])
1555390286Sobrien
1555490286Sobrien(define_expand "cmpstrsi"
1555550650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1555690286Sobrien	(compare:SI (match_operand:BLK 1 "general_operand" "")
1555790286Sobrien		    (match_operand:BLK 2 "general_operand" "")))
1555890286Sobrien   (use (match_operand 3 "general_operand" ""))
1555990286Sobrien   (use (match_operand 4 "immediate_operand" ""))]
1556090286Sobrien  ""
1556150650Sobrien{
1556290286Sobrien  rtx addr1, addr2, out, outlow, count, countreg, align;
1556350650Sobrien
1556490286Sobrien  out = operands[0];
1556590286Sobrien  if (GET_CODE (out) != REG)
1556690286Sobrien    out = gen_reg_rtx (SImode);
1556750650Sobrien
1556890286Sobrien  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1556990286Sobrien  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
1557090286Sobrien  
1557190286Sobrien  count = operands[3];
1557290286Sobrien  countreg = ix86_zero_extend_to_Pmode (count);
1557350650Sobrien
1557490286Sobrien  /* %%% Iff we are testing strict equality, we can use known alignment
1557590286Sobrien     to good advantage.  This may be possible with combine, particularly
1557690286Sobrien     once cc0 is dead.  */
1557790286Sobrien  align = operands[4];
1557850650Sobrien
1557990286Sobrien  emit_insn (gen_cld ());
1558090286Sobrien  if (GET_CODE (count) == CONST_INT)
1558190286Sobrien    {
1558290286Sobrien      if (INTVAL (count) == 0)
1558390286Sobrien	{
1558490286Sobrien	  emit_move_insn (operands[0], const0_rtx);
1558590286Sobrien	  DONE;
1558690286Sobrien	}
1558790286Sobrien      if (TARGET_64BIT)
1558890286Sobrien	emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
1558990286Sobrien					  addr1, addr2, countreg));
1559090286Sobrien      else
1559190286Sobrien	emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
1559290286Sobrien				      addr1, addr2, countreg));
1559390286Sobrien    }
1559490286Sobrien  else
1559590286Sobrien    {
1559690286Sobrien      if (TARGET_64BIT)
1559790286Sobrien	{
1559890286Sobrien	  emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
1559990286Sobrien	  emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
1560090286Sobrien					 addr1, addr2, countreg));
1560190286Sobrien	}
1560290286Sobrien      else
1560390286Sobrien	{
1560490286Sobrien	  emit_insn (gen_cmpsi_1 (countreg, countreg));
1560590286Sobrien	  emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
1560690286Sobrien				     addr1, addr2, countreg));
1560790286Sobrien	}
1560890286Sobrien    }
1560990286Sobrien
1561090286Sobrien  outlow = gen_lowpart (QImode, out);
1561190286Sobrien  emit_insn (gen_cmpintqi (outlow));
1561290286Sobrien  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
1561390286Sobrien
1561490286Sobrien  if (operands[0] != out)
1561590286Sobrien    emit_move_insn (operands[0], out);
1561690286Sobrien
1561790286Sobrien  DONE;
1561890286Sobrien})
1561990286Sobrien
1562090286Sobrien;; Produce a tri-state integer (-1, 0, 1) from condition codes.
1562190286Sobrien
1562290286Sobrien(define_expand "cmpintqi"
1562390286Sobrien  [(set (match_dup 1)
1562490286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1562590286Sobrien   (set (match_dup 2)
1562690286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1562790286Sobrien   (parallel [(set (match_operand:QI 0 "register_operand" "")
1562890286Sobrien		   (minus:QI (match_dup 1)
1562990286Sobrien			     (match_dup 2)))
1563090286Sobrien	      (clobber (reg:CC 17))])]
1563190286Sobrien  ""
1563290286Sobrien  "operands[1] = gen_reg_rtx (QImode);
1563390286Sobrien   operands[2] = gen_reg_rtx (QImode);")
1563490286Sobrien
1563590286Sobrien;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
1563690286Sobrien;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
1563790286Sobrien
1563890286Sobrien(define_insn "cmpstrqi_nz_1"
1563990286Sobrien  [(set (reg:CC 17)
1564090286Sobrien	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1564190286Sobrien		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
1564290286Sobrien   (use (match_operand:SI 6 "register_operand" "2"))
1564390286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1564490286Sobrien   (use (reg:SI 19))
1564590286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1564690286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1564790286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1564890286Sobrien  "!TARGET_64BIT"
1564990286Sobrien  "repz{\;| }cmpsb"
1565090286Sobrien  [(set_attr "type" "str")
1565190286Sobrien   (set_attr "mode" "QI")
1565290286Sobrien   (set_attr "prefix_rep" "1")])
1565390286Sobrien
1565490286Sobrien(define_insn "cmpstrqi_nz_rex_1"
1565590286Sobrien  [(set (reg:CC 17)
1565690286Sobrien	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1565790286Sobrien		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
1565890286Sobrien   (use (match_operand:DI 6 "register_operand" "2"))
1565990286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1566090286Sobrien   (use (reg:SI 19))
1566190286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1566290286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1566390286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1566490286Sobrien  "TARGET_64BIT"
1566590286Sobrien  "repz{\;| }cmpsb"
1566690286Sobrien  [(set_attr "type" "str")
1566790286Sobrien   (set_attr "mode" "QI")
1566890286Sobrien   (set_attr "prefix_rep" "1")])
1566990286Sobrien
1567090286Sobrien;; The same, but the count is not known to not be zero.
1567190286Sobrien
1567290286Sobrien(define_insn "cmpstrqi_1"
1567390286Sobrien  [(set (reg:CC 17)
1567490286Sobrien	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
1567590286Sobrien			     (const_int 0))
1567690286Sobrien	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1567790286Sobrien		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
1567890286Sobrien	  (const_int 0)))
1567990286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1568090286Sobrien   (use (reg:CC 17))
1568190286Sobrien   (use (reg:SI 19))
1568290286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1568390286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1568490286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1568590286Sobrien  "!TARGET_64BIT"
1568690286Sobrien  "repz{\;| }cmpsb"
1568790286Sobrien  [(set_attr "type" "str")
1568890286Sobrien   (set_attr "mode" "QI")
1568990286Sobrien   (set_attr "prefix_rep" "1")])
1569090286Sobrien
1569190286Sobrien(define_insn "cmpstrqi_rex_1"
1569290286Sobrien  [(set (reg:CC 17)
1569390286Sobrien	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
1569490286Sobrien			     (const_int 0))
1569590286Sobrien	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1569690286Sobrien		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
1569790286Sobrien	  (const_int 0)))
1569890286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1569990286Sobrien   (use (reg:CC 17))
1570090286Sobrien   (use (reg:SI 19))
1570190286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1570290286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1570390286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1570490286Sobrien  "TARGET_64BIT"
1570590286Sobrien  "repz{\;| }cmpsb"
1570690286Sobrien  [(set_attr "type" "str")
1570790286Sobrien   (set_attr "mode" "QI")
1570890286Sobrien   (set_attr "prefix_rep" "1")])
1570990286Sobrien
1571090286Sobrien(define_expand "strlensi"
1571152296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1571290286Sobrien	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
1571390286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
15714117404Skan		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
1571590286Sobrien  ""
1571690286Sobrien{
1571790286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1571890286Sobrien   DONE;
1571990286Sobrien else
1572090286Sobrien   FAIL;
1572190286Sobrien})
1572290286Sobrien
1572390286Sobrien(define_expand "strlendi"
1572490286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1572590286Sobrien	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
1572690286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
15727117404Skan		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
1572890286Sobrien  ""
1572990286Sobrien{
1573090286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1573190286Sobrien   DONE;
1573290286Sobrien else
1573390286Sobrien   FAIL;
1573490286Sobrien})
1573590286Sobrien
1573690286Sobrien(define_insn "strlenqi_1"
1573790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&c")
1573890286Sobrien	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
1573990286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1574090286Sobrien		    (match_operand:SI 3 "immediate_operand" "i")
15741117404Skan		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
1574290286Sobrien   (use (reg:SI 19))
1574390286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1574490286Sobrien   (clobber (reg:CC 17))]
1574590286Sobrien  "!TARGET_64BIT"
1574690286Sobrien  "repnz{\;| }scasb"
1574790286Sobrien  [(set_attr "type" "str")
1574890286Sobrien   (set_attr "mode" "QI")
1574990286Sobrien   (set_attr "prefix_rep" "1")])
1575090286Sobrien
1575190286Sobrien(define_insn "strlenqi_rex_1"
1575290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&c")
1575390286Sobrien	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
1575490286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1575590286Sobrien		    (match_operand:DI 3 "immediate_operand" "i")
15756117404Skan		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
1575790286Sobrien   (use (reg:SI 19))
1575890286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1575990286Sobrien   (clobber (reg:CC 17))]
1576090286Sobrien  "TARGET_64BIT"
1576190286Sobrien  "repnz{\;| }scasb"
1576290286Sobrien  [(set_attr "type" "str")
1576390286Sobrien   (set_attr "mode" "QI")
1576490286Sobrien   (set_attr "prefix_rep" "1")])
1576590286Sobrien
1576690286Sobrien;; Peephole optimizations to clean up after cmpstr*.  This should be
1576790286Sobrien;; handled in combine, but it is not currently up to the task.
1576890286Sobrien;; When used for their truth value, the cmpstr* expanders generate
1576990286Sobrien;; code like this:
1577090286Sobrien;;
1577190286Sobrien;;   repz cmpsb
1577290286Sobrien;;   seta 	%al
1577390286Sobrien;;   setb 	%dl
1577490286Sobrien;;   cmpb 	%al, %dl
1577590286Sobrien;;   jcc	label
1577690286Sobrien;;
1577790286Sobrien;; The intermediate three instructions are unnecessary.
1577890286Sobrien
1577990286Sobrien;; This one handles cmpstr*_nz_1...
1578090286Sobrien(define_peephole2
1578190286Sobrien  [(parallel[
1578290286Sobrien     (set (reg:CC 17)
1578390286Sobrien	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1578490286Sobrien		      (mem:BLK (match_operand 5 "register_operand" ""))))
1578590286Sobrien     (use (match_operand 6 "register_operand" ""))
1578690286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1578790286Sobrien     (use (reg:SI 19))
1578890286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1578990286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1579090286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1579190286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1579290286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1579390286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1579490286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1579590286Sobrien   (set (reg 17)
1579690286Sobrien	(compare (match_dup 7) (match_dup 8)))
1579790286Sobrien  ]
1579890286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1579990286Sobrien  [(parallel[
1580090286Sobrien     (set (reg:CC 17)
1580190286Sobrien	  (compare:CC (mem:BLK (match_dup 4))
1580290286Sobrien		      (mem:BLK (match_dup 5))))
1580390286Sobrien     (use (match_dup 6))
1580490286Sobrien     (use (match_dup 3))
1580590286Sobrien     (use (reg:SI 19))
1580690286Sobrien     (clobber (match_dup 0))
1580790286Sobrien     (clobber (match_dup 1))
1580890286Sobrien     (clobber (match_dup 2))])]
1580950650Sobrien  "")
1581050650Sobrien
1581190286Sobrien;; ...and this one handles cmpstr*_1.
1581290286Sobrien(define_peephole2
1581390286Sobrien  [(parallel[
1581490286Sobrien     (set (reg:CC 17)
1581590286Sobrien	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
1581690286Sobrien			       (const_int 0))
1581790286Sobrien	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1581890286Sobrien		        (mem:BLK (match_operand 5 "register_operand" "")))
1581990286Sobrien	    (const_int 0)))
1582090286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1582190286Sobrien     (use (reg:CC 17))
1582290286Sobrien     (use (reg:SI 19))
1582390286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1582490286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1582590286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1582690286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1582790286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1582890286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1582990286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1583090286Sobrien   (set (reg 17)
1583190286Sobrien	(compare (match_dup 7) (match_dup 8)))
1583290286Sobrien  ]
1583390286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1583490286Sobrien  [(parallel[
1583590286Sobrien     (set (reg:CC 17)
1583690286Sobrien	  (if_then_else:CC (ne (match_dup 6)
1583790286Sobrien			       (const_int 0))
1583890286Sobrien	    (compare:CC (mem:BLK (match_dup 4))
1583990286Sobrien			(mem:BLK (match_dup 5)))
1584090286Sobrien	    (const_int 0)))
1584190286Sobrien     (use (match_dup 3))
1584290286Sobrien     (use (reg:CC 17))
1584390286Sobrien     (use (reg:SI 19))
1584490286Sobrien     (clobber (match_dup 0))
1584590286Sobrien     (clobber (match_dup 1))
1584690286Sobrien     (clobber (match_dup 2))])]
1584750650Sobrien  "")
1584850650Sobrien
1584990286Sobrien
1585090286Sobrien
1585190286Sobrien;; Conditional move instructions.
1585290286Sobrien
1585390286Sobrien(define_expand "movdicc"
1585490286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1585590286Sobrien	(if_then_else:DI (match_operand 1 "comparison_operator" "")
1585690286Sobrien			 (match_operand:DI 2 "general_operand" "")
1585790286Sobrien			 (match_operand:DI 3 "general_operand" "")))]
1585890286Sobrien  "TARGET_64BIT"
1585990286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1586090286Sobrien
1586190286Sobrien(define_insn "x86_movdicc_0_m1_rex64"
1586290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1586390286Sobrien	(if_then_else:DI (ltu (reg:CC 17) (const_int 0))
1586490286Sobrien	  (const_int -1)
1586590286Sobrien	  (const_int 0)))
1586690286Sobrien   (clobber (reg:CC 17))]
1586790286Sobrien  "TARGET_64BIT"
1586890286Sobrien  "sbb{q}\t%0, %0"
1586990286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1587090286Sobrien  ; fill in all the blanks.
1587190286Sobrien  [(set_attr "type" "alu")
15872117404Skan   (set_attr "pent_pair" "pu")
1587390286Sobrien   (set_attr "memory" "none")
1587490286Sobrien   (set_attr "imm_disp" "false")
1587590286Sobrien   (set_attr "mode" "DI")
1587690286Sobrien   (set_attr "length_immediate" "0")])
1587790286Sobrien
1587890286Sobrien(define_insn "*movdicc_c_rex64"
1587990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1588090286Sobrien	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
1588190286Sobrien				[(reg 17) (const_int 0)])
1588290286Sobrien		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
1588390286Sobrien		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
1588490286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1588590286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1588690286Sobrien  "@
1588796294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1588896294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1588990286Sobrien  [(set_attr "type" "icmov")
1589090286Sobrien   (set_attr "mode" "DI")])
1589190286Sobrien
1589290286Sobrien(define_expand "movsicc"
1589390286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1589490286Sobrien	(if_then_else:SI (match_operand 1 "comparison_operator" "")
1589590286Sobrien			 (match_operand:SI 2 "general_operand" "")
1589690286Sobrien			 (match_operand:SI 3 "general_operand" "")))]
1589790286Sobrien  ""
1589890286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1589990286Sobrien
1590090286Sobrien;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
1590190286Sobrien;; the register first winds up with `sbbl $0,reg', which is also weird.
1590290286Sobrien;; So just document what we're doing explicitly.
1590390286Sobrien
1590490286Sobrien(define_insn "x86_movsicc_0_m1"
1590590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1590690286Sobrien	(if_then_else:SI (ltu (reg:CC 17) (const_int 0))
1590790286Sobrien	  (const_int -1)
1590890286Sobrien	  (const_int 0)))
1590990286Sobrien   (clobber (reg:CC 17))]
1591090286Sobrien  ""
1591190286Sobrien  "sbb{l}\t%0, %0"
1591290286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1591390286Sobrien  ; fill in all the blanks.
1591490286Sobrien  [(set_attr "type" "alu")
15915117404Skan   (set_attr "pent_pair" "pu")
1591690286Sobrien   (set_attr "memory" "none")
1591790286Sobrien   (set_attr "imm_disp" "false")
1591890286Sobrien   (set_attr "mode" "SI")
1591990286Sobrien   (set_attr "length_immediate" "0")])
1592090286Sobrien
1592190286Sobrien(define_insn "*movsicc_noc"
1592250650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1592390286Sobrien	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
1592490286Sobrien				[(reg 17) (const_int 0)])
1592550650Sobrien		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
1592650650Sobrien		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
1592790286Sobrien  "TARGET_CMOVE
1592890286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1592990286Sobrien  "@
1593096294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1593196294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1593290286Sobrien  [(set_attr "type" "icmov")
1593390286Sobrien   (set_attr "mode" "SI")])
1593450650Sobrien
1593550650Sobrien(define_expand "movhicc"
1593650650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
1593750650Sobrien	(if_then_else:HI (match_operand 1 "comparison_operator" "")
1593850650Sobrien			 (match_operand:HI 2 "nonimmediate_operand" "")
1593950650Sobrien			 (match_operand:HI 3 "nonimmediate_operand" "")))]
1594090286Sobrien  "TARGET_CMOVE && TARGET_HIMODE_MATH"
1594190286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1594250650Sobrien
1594390286Sobrien(define_insn "*movhicc_noc"
1594450650Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
1594590286Sobrien	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
1594690286Sobrien				[(reg 17) (const_int 0)])
1594750650Sobrien		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
1594850650Sobrien		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
1594990286Sobrien  "TARGET_CMOVE
1595090286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1595190286Sobrien  "@
1595296294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1595396294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1595490286Sobrien  [(set_attr "type" "icmov")
1595590286Sobrien   (set_attr "mode" "HI")])
1595650650Sobrien
1595750650Sobrien(define_expand "movsfcc"
1595850650Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1595950650Sobrien	(if_then_else:SF (match_operand 1 "comparison_operator" "")
1596050650Sobrien			 (match_operand:SF 2 "register_operand" "")
1596150650Sobrien			 (match_operand:SF 3 "register_operand" "")))]
1596250650Sobrien  "TARGET_CMOVE"
1596390286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1596450650Sobrien
1596590286Sobrien(define_insn "*movsfcc_1"
1596690286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
1596790286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
1596890286Sobrien				[(reg 17) (const_int 0)])
1596990286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
1597090286Sobrien		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
1597190286Sobrien  "TARGET_CMOVE
1597290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1597390286Sobrien  "@
1597490286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1597590286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1597696294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1597796294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1597890286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1597990286Sobrien   (set_attr "mode" "SF,SF,SI,SI")])
1598050650Sobrien
1598190286Sobrien(define_expand "movdfcc"
1598290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1598390286Sobrien	(if_then_else:DF (match_operand 1 "comparison_operator" "")
1598490286Sobrien			 (match_operand:DF 2 "register_operand" "")
1598590286Sobrien			 (match_operand:DF 3 "register_operand" "")))]
1598690286Sobrien  "TARGET_CMOVE"
1598790286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1598850650Sobrien
1598990286Sobrien(define_insn "*movdfcc_1"
1599090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1599190286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1599290286Sobrien				[(reg 17) (const_int 0)])
1599390286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1599490286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1599590286Sobrien  "!TARGET_64BIT && TARGET_CMOVE
1599690286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1599790286Sobrien  "@
1599890286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1599990286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1600090286Sobrien   #
1600190286Sobrien   #"
1600290286Sobrien  [(set_attr "type" "fcmov,fcmov,multi,multi")
1600390286Sobrien   (set_attr "mode" "DF")])
1600450650Sobrien
1600590286Sobrien(define_insn "*movdfcc_1_rex64"
1600690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1600790286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1600890286Sobrien				[(reg 17) (const_int 0)])
1600990286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1601090286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1601190286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1601290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1601390286Sobrien  "@
1601490286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1601590286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1601696294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1601796294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1601890286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1601990286Sobrien   (set_attr "mode" "DF")])
1602050650Sobrien
1602190286Sobrien(define_split
16022117404Skan  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
1602390286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1602490286Sobrien				[(match_operand 4 "" "") (const_int 0)])
1602590286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "")
1602690286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "")))]
16027117404Skan  "!TARGET_64BIT && reload_completed"
1602890286Sobrien  [(set (match_dup 2)
1602990286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1603090286Sobrien		      (match_dup 5)
1603190286Sobrien		      (match_dup 7)))
1603290286Sobrien   (set (match_dup 3)
1603390286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1603490286Sobrien		      (match_dup 6)
1603590286Sobrien		      (match_dup 8)))]
1603690286Sobrien  "split_di (operands+2, 1, operands+5, operands+6);
1603790286Sobrien   split_di (operands+3, 1, operands+7, operands+8);
1603890286Sobrien   split_di (operands, 1, operands+2, operands+3);")
1603950650Sobrien
1604090286Sobrien(define_expand "movxfcc"
1604190286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1604290286Sobrien	(if_then_else:XF (match_operand 1 "comparison_operator" "")
1604390286Sobrien			 (match_operand:XF 2 "register_operand" "")
1604490286Sobrien			 (match_operand:XF 3 "register_operand" "")))]
1604590286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1604690286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1604750650Sobrien
1604890286Sobrien(define_expand "movtfcc"
1604990286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1605090286Sobrien	(if_then_else:TF (match_operand 1 "comparison_operator" "")
1605190286Sobrien			 (match_operand:TF 2 "register_operand" "")
1605290286Sobrien			 (match_operand:TF 3 "register_operand" "")))]
1605390286Sobrien  "TARGET_CMOVE"
1605490286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1605590286Sobrien
1605690286Sobrien(define_insn "*movxfcc_1"
1605790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1605890286Sobrien	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
1605990286Sobrien				[(reg 17) (const_int 0)])
1606090286Sobrien		      (match_operand:XF 2 "register_operand" "f,0")
1606190286Sobrien		      (match_operand:XF 3 "register_operand" "0,f")))]
1606290286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1606390286Sobrien  "@
1606490286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1606590286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1606690286Sobrien  [(set_attr "type" "fcmov")
1606790286Sobrien   (set_attr "mode" "XF")])
1606890286Sobrien
1606990286Sobrien(define_insn "*movtfcc_1"
1607090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1607190286Sobrien	(if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
1607290286Sobrien				[(reg 17) (const_int 0)])
1607390286Sobrien		      (match_operand:TF 2 "register_operand" "f,0")
1607490286Sobrien		      (match_operand:TF 3 "register_operand" "0,f")))]
1607590286Sobrien  "TARGET_CMOVE"
1607690286Sobrien  "@
1607790286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1607890286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1607990286Sobrien  [(set_attr "type" "fcmov")
1608090286Sobrien   (set_attr "mode" "XF")])
1608190286Sobrien
1608290286Sobrien(define_expand "minsf3"
1608390286Sobrien  [(parallel [
1608490286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1608590286Sobrien	  (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1608690286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1608790286Sobrien			   (match_dup 1)
1608890286Sobrien			   (match_dup 2)))
1608990286Sobrien     (clobber (reg:CC 17))])]
1609090286Sobrien  "TARGET_SSE"
1609190286Sobrien  "")
1609290286Sobrien
1609390286Sobrien(define_insn "*minsf"
1609490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1609590286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
1609690286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1609790286Sobrien			 (match_dup 1)
1609890286Sobrien			 (match_dup 2)))
1609990286Sobrien   (clobber (reg:CC 17))]
1610090286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1610150650Sobrien  "#")
1610250650Sobrien
1610390286Sobrien(define_insn "*minsf_nonieee"
1610490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1610596294Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1610690286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1610790286Sobrien			 (match_dup 1)
1610890286Sobrien			 (match_dup 2)))
1610990286Sobrien   (clobber (reg:CC 17))]
1611096294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1611196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1611250650Sobrien  "#")
1611350650Sobrien
1611450650Sobrien(define_split
1611552296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1611690286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1611790286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1611890286Sobrien			 (match_operand:SF 3 "register_operand" "")
1611990286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1612090286Sobrien   (clobber (reg:CC 17))]
1612190286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1612290286Sobrien   && ((operands_match_p (operands[1], operands[3])
1612390286Sobrien	&& operands_match_p (operands[2], operands[4]))
1612490286Sobrien       || (operands_match_p (operands[1], operands[4])
1612590286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1612690286Sobrien  [(set (match_dup 0)
1612790286Sobrien	(if_then_else:SF (lt (match_dup 1)
1612890286Sobrien			     (match_dup 2))
1612990286Sobrien			 (match_dup 1)
1613090286Sobrien			 (match_dup 2)))])
1613150650Sobrien
1613290286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1613390286Sobrien
1613450650Sobrien(define_split
16135117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
1613690286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1613790286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1613890286Sobrien			 (match_operand:SF 3 "register_operand" "")
1613990286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1614090286Sobrien   (clobber (reg:CC 17))]
16141117404Skan  "reload_completed
1614290286Sobrien   && ((operands_match_p (operands[1], operands[3])
1614390286Sobrien	&& operands_match_p (operands[2], operands[4]))
1614490286Sobrien       || (operands_match_p (operands[1], operands[4])
1614590286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1614690286Sobrien  [(set (reg:CCFP 17)
1614790286Sobrien	(compare:CCFP (match_dup 2)
1614890286Sobrien		      (match_dup 1)))
1614950650Sobrien   (set (match_dup 0)
1615090286Sobrien	(if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
1615190286Sobrien			 (match_dup 1)
1615290286Sobrien			 (match_dup 2)))])
1615350650Sobrien
1615490286Sobrien(define_insn "*minsf_sse"
1615590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1615690286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
1615790286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1615890286Sobrien			 (match_dup 1)
1615990286Sobrien			 (match_dup 2)))]
1616090286Sobrien  "TARGET_SSE && reload_completed"
1616190286Sobrien  "minss\t{%2, %0|%0, %2}"
1616290286Sobrien  [(set_attr "type" "sse")
1616390286Sobrien   (set_attr "mode" "SF")])
1616450650Sobrien
1616590286Sobrien(define_expand "mindf3"
1616690286Sobrien  [(parallel [
1616790286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1616890286Sobrien	  (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1616990286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1617090286Sobrien			   (match_dup 1)
1617190286Sobrien			   (match_dup 2)))
1617290286Sobrien     (clobber (reg:CC 17))])]
1617390286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1617490286Sobrien  "#")
1617590286Sobrien
1617690286Sobrien(define_insn "*mindf"
1617790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1617890286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1617990286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1618090286Sobrien			 (match_dup 1)
1618190286Sobrien			 (match_dup 2)))
1618290286Sobrien   (clobber (reg:CC 17))]
1618390286Sobrien  "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
1618490286Sobrien  "#")
1618590286Sobrien
1618690286Sobrien(define_insn "*mindf_nonieee"
1618790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1618896294Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1618990286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1619090286Sobrien			 (match_dup 1)
1619190286Sobrien			 (match_dup 2)))
1619290286Sobrien   (clobber (reg:CC 17))]
1619396294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1619496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1619590286Sobrien  "#")
1619690286Sobrien
1619790286Sobrien(define_split
1619850650Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1619990286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1620090286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1620190286Sobrien			 (match_operand:DF 3 "register_operand" "")
1620290286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1620390286Sobrien   (clobber (reg:CC 17))]
1620490286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1620590286Sobrien   && ((operands_match_p (operands[1], operands[3])
1620690286Sobrien	&& operands_match_p (operands[2], operands[4]))
1620790286Sobrien       || (operands_match_p (operands[1], operands[4])
1620890286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1620990286Sobrien  [(set (match_dup 0)
1621090286Sobrien	(if_then_else:DF (lt (match_dup 1)
1621190286Sobrien			     (match_dup 2))
1621290286Sobrien			 (match_dup 1)
1621390286Sobrien			 (match_dup 2)))])
1621450650Sobrien
1621590286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1621690286Sobrien(define_split
16217117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
1621890286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1621990286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1622090286Sobrien			 (match_operand:DF 3 "register_operand" "")
1622190286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1622290286Sobrien   (clobber (reg:CC 17))]
16223117404Skan  "reload_completed
1622490286Sobrien   && ((operands_match_p (operands[1], operands[3])
1622590286Sobrien	&& operands_match_p (operands[2], operands[4]))
1622690286Sobrien       || (operands_match_p (operands[1], operands[4])
1622790286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1622890286Sobrien  [(set (reg:CCFP 17)
1622990286Sobrien	(compare:CCFP (match_dup 2)
1623090286Sobrien		      (match_dup 2)))
1623190286Sobrien   (set (match_dup 0)
1623290286Sobrien	(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
1623390286Sobrien			 (match_dup 1)
1623490286Sobrien			 (match_dup 2)))])
1623550650Sobrien
1623690286Sobrien(define_insn "*mindf_sse"
1623790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1623890286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
1623990286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1624090286Sobrien			 (match_dup 1)
1624190286Sobrien			 (match_dup 2)))]
1624290286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1624390286Sobrien  "minsd\t{%2, %0|%0, %2}"
1624490286Sobrien  [(set_attr "type" "sse")
1624590286Sobrien   (set_attr "mode" "DF")])
1624650650Sobrien
1624790286Sobrien(define_expand "maxsf3"
1624890286Sobrien  [(parallel [
1624990286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1625090286Sobrien	  (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1625190286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1625290286Sobrien			   (match_dup 1)
1625390286Sobrien			   (match_dup 2)))
1625490286Sobrien     (clobber (reg:CC 17))])]
1625590286Sobrien  "TARGET_SSE"
1625690286Sobrien  "#")
1625750650Sobrien
1625890286Sobrien(define_insn "*maxsf"
1625990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1626090286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
1626190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1626290286Sobrien			 (match_dup 1)
1626390286Sobrien			 (match_dup 2)))
1626490286Sobrien   (clobber (reg:CC 17))]
1626590286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1626690286Sobrien  "#")
1626750650Sobrien
1626890286Sobrien(define_insn "*maxsf_nonieee"
1626990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1627096294Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1627190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1627290286Sobrien			 (match_dup 1)
1627390286Sobrien			 (match_dup 2)))
1627490286Sobrien   (clobber (reg:CC 17))]
1627596294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1627696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1627790286Sobrien  "#")
1627850650Sobrien
1627990286Sobrien(define_split
1628090286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1628190286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1628290286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1628390286Sobrien			 (match_operand:SF 3 "register_operand" "")
1628490286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1628590286Sobrien   (clobber (reg:CC 17))]
1628690286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1628790286Sobrien   && ((operands_match_p (operands[1], operands[3])
1628890286Sobrien	&& operands_match_p (operands[2], operands[4]))
1628990286Sobrien       || (operands_match_p (operands[1], operands[4])
1629090286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1629190286Sobrien  [(set (match_dup 0)
1629290286Sobrien	(if_then_else:SF (gt (match_dup 1)
1629390286Sobrien			     (match_dup 2))
1629490286Sobrien			 (match_dup 1)
1629590286Sobrien			 (match_dup 2)))])
1629650650Sobrien
1629790286Sobrien(define_split
16298117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
1629990286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1630090286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1630190286Sobrien			 (match_operand:SF 3 "register_operand" "")
1630290286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1630390286Sobrien   (clobber (reg:CC 17))]
16304117404Skan  "reload_completed
1630590286Sobrien   && ((operands_match_p (operands[1], operands[3])
1630690286Sobrien	&& operands_match_p (operands[2], operands[4]))
1630790286Sobrien       || (operands_match_p (operands[1], operands[4])
1630890286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1630990286Sobrien  [(set (reg:CCFP 17)
1631090286Sobrien	(compare:CCFP (match_dup 1)
1631190286Sobrien		      (match_dup 2)))
1631290286Sobrien   (set (match_dup 0)
1631390286Sobrien	(if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
1631490286Sobrien			 (match_dup 1)
1631590286Sobrien			 (match_dup 2)))])
1631690286Sobrien
1631790286Sobrien(define_insn "*maxsf_sse"
1631890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1631990286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
1632090286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1632190286Sobrien			 (match_dup 1)
1632290286Sobrien			 (match_dup 2)))]
1632390286Sobrien  "TARGET_SSE && reload_completed"
1632490286Sobrien  "maxss\t{%2, %0|%0, %2}"
1632590286Sobrien  [(set_attr "type" "sse")
1632690286Sobrien   (set_attr "mode" "SF")])
1632790286Sobrien
1632890286Sobrien(define_expand "maxdf3"
1632990286Sobrien  [(parallel [
1633090286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1633190286Sobrien	  (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1633290286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1633390286Sobrien			   (match_dup 1)
1633490286Sobrien			   (match_dup 2)))
1633590286Sobrien     (clobber (reg:CC 17))])]
1633690286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1633750650Sobrien  "#")
1633850650Sobrien
1633990286Sobrien(define_insn "*maxdf"
1634090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1634190286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1634290286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1634390286Sobrien			 (match_dup 1)
1634490286Sobrien			 (match_dup 2)))
1634590286Sobrien   (clobber (reg:CC 17))]
1634690286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
1634750650Sobrien  "#")
1634850650Sobrien
1634990286Sobrien(define_insn "*maxdf_nonieee"
1635090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1635196294Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1635290286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1635390286Sobrien			 (match_dup 1)
1635490286Sobrien			 (match_dup 2)))
1635590286Sobrien   (clobber (reg:CC 17))]
1635696294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1635796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1635890286Sobrien  "#")
1635990286Sobrien
1636050650Sobrien(define_split
1636152296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1636290286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1636390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1636490286Sobrien			 (match_operand:DF 3 "register_operand" "")
1636590286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1636690286Sobrien   (clobber (reg:CC 17))]
1636790286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1636890286Sobrien   && ((operands_match_p (operands[1], operands[3])
1636990286Sobrien	&& operands_match_p (operands[2], operands[4]))
1637090286Sobrien       || (operands_match_p (operands[1], operands[4])
1637190286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1637290286Sobrien  [(set (match_dup 0)
1637390286Sobrien	(if_then_else:DF (gt (match_dup 1)
1637490286Sobrien			     (match_dup 2))
1637590286Sobrien			 (match_dup 1)
1637690286Sobrien			 (match_dup 2)))])
1637750650Sobrien
1637850650Sobrien(define_split
16379117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
1638090286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1638190286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1638290286Sobrien			 (match_operand:DF 3 "register_operand" "")
1638390286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1638490286Sobrien   (clobber (reg:CC 17))]
16385117404Skan  "reload_completed
1638690286Sobrien   && ((operands_match_p (operands[1], operands[3])
1638790286Sobrien	&& operands_match_p (operands[2], operands[4]))
1638890286Sobrien       || (operands_match_p (operands[1], operands[4])
1638990286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1639090286Sobrien  [(set (reg:CCFP 17)
1639190286Sobrien	(compare:CCFP (match_dup 1)
1639290286Sobrien		      (match_dup 2)))
1639350650Sobrien   (set (match_dup 0)
1639490286Sobrien	(if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
1639590286Sobrien			 (match_dup 1)
1639690286Sobrien			 (match_dup 2)))])
1639750650Sobrien
1639890286Sobrien(define_insn "*maxdf_sse"
1639990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1640090286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
1640190286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1640290286Sobrien			 (match_dup 1)
1640390286Sobrien			 (match_dup 2)))]
1640490286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1640590286Sobrien  "maxsd\t{%2, %0|%0, %2}"
1640690286Sobrien  [(set_attr "type" "sse")
1640790286Sobrien   (set_attr "mode" "DF")])
1640890286Sobrien
1640990286Sobrien;; Misc patterns (?)
1641050650Sobrien
1641190286Sobrien;; This pattern exists to put a dependency on all ebp-based memory accesses.
1641290286Sobrien;; Otherwise there will be nothing to keep
1641390286Sobrien;; 
1641490286Sobrien;; [(set (reg ebp) (reg esp))]
1641590286Sobrien;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
1641690286Sobrien;;  (clobber (eflags)]
1641790286Sobrien;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
1641890286Sobrien;;
1641990286Sobrien;; in proper program order.
1642090286Sobrien(define_expand "pro_epilogue_adjust_stack"
1642190286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
1642290286Sobrien		   (plus:SI (match_operand:SI 1 "register_operand" "0,r")
1642390286Sobrien			    (match_operand:SI 2 "immediate_operand" "i,i")))
1642490286Sobrien	      (clobber (reg:CC 17))
1642590286Sobrien	      (clobber (mem:BLK (scratch)))])]
1642690286Sobrien ""
1642750650Sobrien{
1642890286Sobrien  if (TARGET_64BIT)
1642990286Sobrien    {
1643090286Sobrien      emit_insn (gen_pro_epilogue_adjust_stack_rex64
1643190286Sobrien		 (operands[0], operands[1], operands[2]));
1643290286Sobrien      DONE;
1643390286Sobrien    }
1643490286Sobrien})
1643550650Sobrien
1643690286Sobrien(define_insn "*pro_epilogue_adjust_stack_1"
1643790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1643890286Sobrien	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
1643990286Sobrien	         (match_operand:SI 2 "immediate_operand" "i,i")))
1644090286Sobrien   (clobber (reg:CC 17))
1644190286Sobrien   (clobber (mem:BLK (scratch)))]
1644290286Sobrien  "!TARGET_64BIT"
1644390286Sobrien{
1644490286Sobrien  switch (get_attr_type (insn))
1644590286Sobrien    {
1644690286Sobrien    case TYPE_IMOV:
1644790286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
1644850650Sobrien
1644990286Sobrien    case TYPE_ALU:
1645090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1645190286Sobrien          && (INTVAL (operands[2]) == 128
1645290286Sobrien	      || (INTVAL (operands[2]) < 0
1645390286Sobrien	          && INTVAL (operands[2]) != -128)))
1645490286Sobrien	{
1645590286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1645690286Sobrien	  return "sub{l}\t{%2, %0|%0, %2}";
1645790286Sobrien	}
1645890286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
1645950650Sobrien
1646090286Sobrien    case TYPE_LEA:
1646190286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1646290286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
1646390286Sobrien
1646490286Sobrien    default:
1646590286Sobrien      abort ();
1646690286Sobrien    }
1646790286Sobrien}
1646890286Sobrien  [(set (attr "type")
1646990286Sobrien	(cond [(eq_attr "alternative" "0")
1647090286Sobrien		 (const_string "alu")
1647190286Sobrien	       (match_operand:SI 2 "const0_operand" "")
1647290286Sobrien		 (const_string "imov")
1647390286Sobrien	      ]
1647490286Sobrien	      (const_string "lea")))
1647590286Sobrien   (set_attr "mode" "SI")])
1647690286Sobrien
1647790286Sobrien(define_insn "pro_epilogue_adjust_stack_rex64"
1647890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1647990286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
1648090286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
1648190286Sobrien   (clobber (reg:CC 17))
1648290286Sobrien   (clobber (mem:BLK (scratch)))]
1648390286Sobrien  "TARGET_64BIT"
1648490286Sobrien{
1648590286Sobrien  switch (get_attr_type (insn))
1648650650Sobrien    {
1648790286Sobrien    case TYPE_IMOV:
1648890286Sobrien      return "mov{q}\t{%1, %0|%0, %1}";
1648950650Sobrien
1649090286Sobrien    case TYPE_ALU:
1649190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1649290286Sobrien          && (INTVAL (operands[2]) == 128
1649390286Sobrien	      || (INTVAL (operands[2]) < 0
1649490286Sobrien	          && INTVAL (operands[2]) != -128)))
1649590286Sobrien	{
1649690286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1649790286Sobrien	  return "sub{q}\t{%2, %0|%0, %2}";
1649890286Sobrien	}
1649990286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
1650050650Sobrien
1650190286Sobrien    case TYPE_LEA:
1650290286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1650390286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
1650450650Sobrien
1650550650Sobrien    default:
1650690286Sobrien      abort ();
1650750650Sobrien    }
1650890286Sobrien}
1650990286Sobrien  [(set (attr "type")
1651090286Sobrien	(cond [(eq_attr "alternative" "0")
1651190286Sobrien		 (const_string "alu")
1651290286Sobrien	       (match_operand:DI 2 "const0_operand" "")
1651390286Sobrien		 (const_string "imov")
1651490286Sobrien	      ]
1651590286Sobrien	      (const_string "lea")))
1651690286Sobrien   (set_attr "mode" "DI")])
1651750650Sobrien
1651890286Sobrien
1651990286Sobrien;; Placeholder for the conditional moves.  This one is split either to SSE
1652090286Sobrien;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
1652190286Sobrien;; fact is that compares supported by the cmp??ss instructions are exactly
1652290286Sobrien;; swapped of those supported by cmove sequence.
1652390286Sobrien;; The EQ/NE comparisons also needs bit care, since they are not directly
1652490286Sobrien;; supported by i387 comparisons and we do need to emit two conditional moves
1652590286Sobrien;; in tandem.
1652690286Sobrien
1652790286Sobrien(define_insn "sse_movsfcc"
1652890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
1652990286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1653090286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
1653190286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
1653290286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
1653390286Sobrien		      (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
1653490286Sobrien   (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1653590286Sobrien   (clobber (reg:CC 17))]
1653690286Sobrien  "TARGET_SSE
1653790286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1653890286Sobrien   && (!TARGET_IEEE_FP
1653990286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1654050650Sobrien  "#")
1654150650Sobrien
1654290286Sobrien(define_insn "sse_movsfcc_eq"
1654390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
1654490286Sobrien	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
1654590286Sobrien			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
1654690286Sobrien		      (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
1654790286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
1654890286Sobrien   (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
1654990286Sobrien   (clobber (reg:CC 17))]
1655090286Sobrien  "TARGET_SSE
1655190286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1655250650Sobrien  "#")
1655350650Sobrien
1655490286Sobrien(define_insn "sse_movdfcc"
16555102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
1655690286Sobrien	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16557102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
16558102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
16559102802Skan		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
16560102802Skan		      (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
1656190286Sobrien   (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1656290286Sobrien   (clobber (reg:CC 17))]
1656390286Sobrien  "TARGET_SSE2
1656490286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1656590286Sobrien   && (!TARGET_IEEE_FP
1656690286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1656790286Sobrien  "#")
1656890286Sobrien
1656990286Sobrien(define_insn "sse_movdfcc_eq"
16570102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16571102802Skan	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16572102802Skan			     (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16573102802Skan		      (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16574102802Skan		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
1657590286Sobrien   (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
1657690286Sobrien   (clobber (reg:CC 17))]
1657790286Sobrien  "TARGET_SSE
1657890286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1657990286Sobrien  "#")
1658090286Sobrien
1658190286Sobrien;; For non-sse moves just expand the usual cmove sequence.
1658250650Sobrien(define_split
1658390286Sobrien  [(set (match_operand 0 "register_operand" "")
1658490286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1658590286Sobrien			[(match_operand 4 "nonimmediate_operand" "")
1658690286Sobrien			 (match_operand 5 "register_operand" "")])
1658790286Sobrien		      (match_operand 2 "nonimmediate_operand" "")
1658890286Sobrien		      (match_operand 3 "nonimmediate_operand" "")))
1658990286Sobrien   (clobber (match_operand 6 "" ""))
1659090286Sobrien   (clobber (reg:CC 17))]
1659190286Sobrien  "!SSE_REG_P (operands[0]) && reload_completed
1659290286Sobrien   && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
1659390286Sobrien  [(const_int 0)]
1659490286Sobrien{
1659590286Sobrien   ix86_compare_op0 = operands[5];
1659690286Sobrien   ix86_compare_op1 = operands[4];
1659790286Sobrien   operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
1659890286Sobrien				 VOIDmode, operands[5], operands[4]);
1659990286Sobrien   ix86_expand_fp_movcc (operands);
1660090286Sobrien   DONE;
1660190286Sobrien})
1660250650Sobrien
1660390286Sobrien;; Split SSE based conditional move into seqence:
1660490286Sobrien;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
1660590286Sobrien;; and   op2, op0   -  zero op2 if comparison was false
1660690286Sobrien;; nand  op0, op3   -  load op3 to op0 if comparison was false
16607117404Skan;; or	 op2, op0   -  get the nonzero one into the result.
1660850650Sobrien(define_split
1660990286Sobrien  [(set (match_operand 0 "register_operand" "")
1661090286Sobrien	(if_then_else (match_operator 1 "sse_comparison_operator"
1661190286Sobrien			[(match_operand 4 "register_operand" "")
1661290286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1661390286Sobrien		      (match_operand 2 "register_operand" "")
1661490286Sobrien		      (match_operand 3 "register_operand" "")))
1661590286Sobrien   (clobber (match_operand 6 "" ""))
1661690286Sobrien   (clobber (reg:CC 17))]
1661790286Sobrien  "SSE_REG_P (operands[0]) && reload_completed"
1661890286Sobrien  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
1661990286Sobrien   (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
1662090286Sobrien					    (subreg:TI (match_dup 4) 0)))
1662190286Sobrien   (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
1662290286Sobrien					    (subreg:TI (match_dup 3) 0)))
1662390286Sobrien   (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
1662490286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1662590286Sobrien{
16626102802Skan  /* If op2 == op3, op3 will be clobbered before it is used.
16627102802Skan     This should be optimized out though.  */
16628102802Skan  if (operands_match_p (operands[2], operands[3]))
16629102802Skan    abort ();
1663090286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1663190286Sobrien  if (operands_match_p (operands[0], operands[4]))
1663290286Sobrien    operands[6] = operands[4], operands[7] = operands[2];
1663390286Sobrien  else
1663490286Sobrien    operands[6] = operands[2], operands[7] = operands[4];
1663590286Sobrien})
1663650650Sobrien
1663790286Sobrien;; Special case of conditional move we can handle effectivly.
1663890286Sobrien;; Do not brother with the integer/floating point case, since these are
1663990286Sobrien;; bot considerably slower, unlike in the generic case.
1664090286Sobrien(define_insn "*sse_movsfcc_const0_1"
16641102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1664290286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1664390286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1664490286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1664590286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1664690286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1664790286Sobrien  "TARGET_SSE"
1664890286Sobrien  "#")
1664950650Sobrien
1665090286Sobrien(define_insn "*sse_movsfcc_const0_2"
16651102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1665290286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1665390286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1665490286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1665590286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1665690286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1665790286Sobrien  "TARGET_SSE"
1665890286Sobrien  "#")
1665950650Sobrien
1666090286Sobrien(define_insn "*sse_movsfcc_const0_3"
16661102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1666290286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1666390286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1666490286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1666590286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1666690286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1666790286Sobrien  "TARGET_SSE"
1666890286Sobrien  "#")
1666950650Sobrien
1667090286Sobrien(define_insn "*sse_movsfcc_const0_4"
16671102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1667290286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1667390286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1667490286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1667590286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1667690286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1667790286Sobrien  "TARGET_SSE"
1667850650Sobrien  "#")
1667950650Sobrien
1668090286Sobrien(define_insn "*sse_movdfcc_const0_1"
16681102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16682102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16683102802Skan			[(match_operand:DF 4 "register_operand" "0")
16684102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16685102802Skan		      (match_operand:DF 2 "register_operand" "Y")
16686102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1668790286Sobrien  "TARGET_SSE2"
1668850650Sobrien  "#")
1668950650Sobrien
1669090286Sobrien(define_insn "*sse_movdfcc_const0_2"
16691102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16692102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16693102802Skan			[(match_operand:DF 4 "register_operand" "0")
16694102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16695102802Skan		      (match_operand:DF 2 "const0_operand" "X")
16696102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1669790286Sobrien  "TARGET_SSE2"
1669890286Sobrien  "#")
1669950650Sobrien
1670090286Sobrien(define_insn "*sse_movdfcc_const0_3"
16701102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16702102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16703102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16704102802Skan			 (match_operand:DF 5 "register_operand" "0")])
16705102802Skan		      (match_operand:DF 2 "register_operand" "Y")
16706102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1670790286Sobrien  "TARGET_SSE2"
1670890286Sobrien  "#")
1670950650Sobrien
1671090286Sobrien(define_insn "*sse_movdfcc_const0_4"
16711102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16712102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16713102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16714102802Skan			 (match_operand:DF 5 "register_operand" "0")])
16715102802Skan		      (match_operand:DF 2 "const0_operand" "X")
16716102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1671790286Sobrien  "TARGET_SSE2"
1671890286Sobrien  "#")
1671950650Sobrien
1672090286Sobrien(define_split
1672190286Sobrien  [(set (match_operand 0 "register_operand" "")
1672290286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
16723117404Skan			[(match_operand 4 "nonimmediate_operand" "")
1672490286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1672590286Sobrien		      (match_operand 2 "nonmemory_operand" "")
1672690286Sobrien		      (match_operand 3 "nonmemory_operand" "")))]
1672790286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1672890286Sobrien   && (const0_operand (operands[2], GET_MODE (operands[0]))
1672990286Sobrien       || const0_operand (operands[3], GET_MODE (operands[0])))"
1673090286Sobrien  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
1673190286Sobrien   (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
1673290286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1673390286Sobrien{
1673490286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
16735117404Skan  if (!sse_comparison_operator (operands[1], VOIDmode)
16736117404Skan      || !rtx_equal_p (operands[0], operands[4]))
1673790286Sobrien    {
1673890286Sobrien      rtx tmp = operands[5];
1673990286Sobrien      operands[5] = operands[4];
1674090286Sobrien      operands[4] = tmp;
1674190286Sobrien      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
1674290286Sobrien    }
16743117404Skan  if (!rtx_equal_p (operands[0], operands[4]))
16744117404Skan    abort ();
1674590286Sobrien  if (const0_operand (operands[2], GET_MODE (operands[0])))
1674690286Sobrien    {
1674790286Sobrien      operands[7] = operands[3];
1674890286Sobrien      operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
1674990286Sobrien							 0));
1675090286Sobrien    }
1675190286Sobrien  else
1675290286Sobrien    {
1675390286Sobrien      operands[7] = operands[2];
1675490286Sobrien      operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
1675590286Sobrien    }
1675690286Sobrien})
1675750650Sobrien
1675890286Sobrien(define_expand "allocate_stack_worker"
1675990286Sobrien  [(match_operand:SI 0 "register_operand" "")]
1676090286Sobrien  "TARGET_STACK_PROBE"
1676190286Sobrien{
1676290286Sobrien  if (TARGET_64BIT)
1676390286Sobrien    emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
1676490286Sobrien  else
1676590286Sobrien    emit_insn (gen_allocate_stack_worker_1 (operands[0]));
1676690286Sobrien  DONE;
1676790286Sobrien})
1676850650Sobrien
1676990286Sobrien(define_insn "allocate_stack_worker_1"
16770117404Skan  [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
1677150650Sobrien   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
1677290286Sobrien   (clobber (match_dup 0))
1677390286Sobrien   (clobber (reg:CC 17))]
1677490286Sobrien  "!TARGET_64BIT && TARGET_STACK_PROBE"
1677590286Sobrien  "call\t__alloca"
1677690286Sobrien  [(set_attr "type" "multi")
1677790286Sobrien   (set_attr "length" "5")])
1677850650Sobrien
1677990286Sobrien(define_insn "allocate_stack_worker_rex64"
16780117404Skan  [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
1678190286Sobrien   (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
1678290286Sobrien   (clobber (match_dup 0))
1678390286Sobrien   (clobber (reg:CC 17))]
1678490286Sobrien  "TARGET_64BIT && TARGET_STACK_PROBE"
1678590286Sobrien  "call\t__alloca"
1678690286Sobrien  [(set_attr "type" "multi")
1678790286Sobrien   (set_attr "length" "5")])
1678890286Sobrien
1678950650Sobrien(define_expand "allocate_stack"
1679090286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
1679190286Sobrien		   (minus:SI (reg:SI 7)
1679290286Sobrien			     (match_operand:SI 1 "general_operand" "")))
1679390286Sobrien	      (clobber (reg:CC 17))])
1679490286Sobrien   (parallel [(set (reg:SI 7)
1679590286Sobrien		   (minus:SI (reg:SI 7) (match_dup 1)))
1679690286Sobrien	      (clobber (reg:CC 17))])]
1679790286Sobrien  "TARGET_STACK_PROBE"
1679850650Sobrien{
1679950650Sobrien#ifdef CHECK_STACK_LIMIT
1680050650Sobrien  if (GET_CODE (operands[1]) == CONST_INT
1680150650Sobrien      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
1680250650Sobrien    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
1680350650Sobrien			   operands[1]));
1680450650Sobrien  else 
1680550650Sobrien#endif
1680650650Sobrien    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
1680750650Sobrien							    operands[1])));
1680850650Sobrien
1680950650Sobrien  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
1681050650Sobrien  DONE;
1681190286Sobrien})
1681250650Sobrien
1681390286Sobrien(define_expand "builtin_setjmp_receiver"
1681490286Sobrien  [(label_ref (match_operand 0 "" ""))]
1681590286Sobrien  "!TARGET_64BIT && flag_pic"
1681650650Sobrien{
16817117404Skan  emit_insn (gen_set_got (pic_offset_table_rtx));
1681856391Sobrien  DONE;
1681990286Sobrien})
1682090286Sobrien
1682190286Sobrien;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
1682256391Sobrien
1682390286Sobrien(define_split
1682490286Sobrien  [(set (match_operand 0 "register_operand" "")
1682590286Sobrien	(match_operator 3 "promotable_binary_operator"
1682690286Sobrien	   [(match_operand 1 "register_operand" "")
1682790286Sobrien	    (match_operand 2 "aligned_operand" "")]))
1682890286Sobrien   (clobber (reg:CC 17))]
1682990286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1683090286Sobrien   && ((GET_MODE (operands[0]) == HImode 
16831117404Skan	&& ((!optimize_size && !TARGET_FAST_PREFIX)
16832117404Skan	    || GET_CODE (operands[2]) != CONST_INT
1683390286Sobrien	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
1683490286Sobrien       || (GET_MODE (operands[0]) == QImode 
1683590286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1683690286Sobrien  [(parallel [(set (match_dup 0)
1683790286Sobrien		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1683890286Sobrien	      (clobber (reg:CC 17))])]
1683990286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1684090286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);
1684190286Sobrien   if (GET_CODE (operands[3]) != ASHIFT)
1684290286Sobrien     operands[2] = gen_lowpart (SImode, operands[2]);
1684390286Sobrien   PUT_MODE (operands[3], SImode);")
1684490286Sobrien
16845117404Skan; Promote the QImode tests, as i386 has encoding of the AND
16846117404Skan; instruction with 32-bit sign-extended immediate and thus the
16847117404Skan; instruction size is unchanged, except in the %eax case for
16848117404Skan; which it is increased by one byte, hence the ! optimize_size.
1684990286Sobrien(define_split
1685090286Sobrien  [(set (reg 17)
1685190286Sobrien	(compare (and (match_operand 1 "aligned_operand" "")
1685290286Sobrien		      (match_operand 2 "const_int_operand" ""))
1685390286Sobrien		 (const_int 0)))
1685490286Sobrien   (set (match_operand 0 "register_operand" "")
1685590286Sobrien	(and (match_dup 1) (match_dup 2)))]
1685690286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
16857117404Skan   /* Ensure that the operand will remain sign-extended immediate.  */
16858117404Skan   && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
16859117404Skan   && ! optimize_size
16860117404Skan   && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
16861117404Skan       || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
1686290286Sobrien  [(parallel [(set (reg:CCNO 17)
1686390286Sobrien		   (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
1686490286Sobrien			         (const_int 0)))
1686590286Sobrien	      (set (match_dup 0)
1686690286Sobrien		   (and:SI (match_dup 1) (match_dup 2)))])]
1686790286Sobrien  "operands[2]
16868117404Skan     = gen_int_mode (INTVAL (operands[2])
16869117404Skan		     & GET_MODE_MASK (GET_MODE (operands[0])),
16870117404Skan		     SImode);
1687190286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);
1687290286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1687390286Sobrien
16874117404Skan; Don't promote the QImode tests, as i386 doesn't have encoding of
16875117404Skan; the TEST instruction with 32-bit sign-extended immediate and thus
16876117404Skan; the instruction size would at least double, which is not what we
16877117404Skan; want even with ! optimize_size.
1687890286Sobrien(define_split
1687990286Sobrien  [(set (reg 17)
16880117404Skan	(compare (and (match_operand:HI 0 "aligned_operand" "")
16881117404Skan		      (match_operand:HI 1 "const_int_operand" ""))
1688290286Sobrien		 (const_int 0)))]
1688390286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
16884117404Skan   /* Ensure that the operand will remain sign-extended immediate.  */
16885117404Skan   && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
16886117404Skan   && ! TARGET_FAST_PREFIX
16887117404Skan   && ! optimize_size"
1688890286Sobrien  [(set (reg:CCNO 17)
1688990286Sobrien	(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
1689090286Sobrien		      (const_int 0)))]
1689190286Sobrien  "operands[1]
16892117404Skan     = gen_int_mode (INTVAL (operands[1])
16893117404Skan		     & GET_MODE_MASK (GET_MODE (operands[0])),
16894117404Skan		     SImode);
1689590286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);")
1689690286Sobrien
1689790286Sobrien(define_split
1689890286Sobrien  [(set (match_operand 0 "register_operand" "")
1689990286Sobrien	(neg (match_operand 1 "register_operand" "")))
1690090286Sobrien   (clobber (reg:CC 17))]
1690190286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1690290286Sobrien   && (GET_MODE (operands[0]) == HImode
1690390286Sobrien       || (GET_MODE (operands[0]) == QImode 
1690490286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1690590286Sobrien  [(parallel [(set (match_dup 0)
1690690286Sobrien		   (neg:SI (match_dup 1)))
1690790286Sobrien	      (clobber (reg:CC 17))])]
1690890286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1690990286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1691090286Sobrien
1691190286Sobrien(define_split
1691290286Sobrien  [(set (match_operand 0 "register_operand" "")
1691390286Sobrien	(not (match_operand 1 "register_operand" "")))]
1691490286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1691590286Sobrien   && (GET_MODE (operands[0]) == HImode
1691690286Sobrien       || (GET_MODE (operands[0]) == QImode 
1691790286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1691890286Sobrien  [(set (match_dup 0)
1691990286Sobrien	(not:SI (match_dup 1)))]
1692090286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1692190286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1692290286Sobrien
1692390286Sobrien(define_split 
1692490286Sobrien  [(set (match_operand 0 "register_operand" "")
1692590286Sobrien	(if_then_else (match_operator 1 "comparison_operator" 
1692690286Sobrien				[(reg 17) (const_int 0)])
1692790286Sobrien		      (match_operand 2 "register_operand" "")
1692890286Sobrien		      (match_operand 3 "register_operand" "")))]
1692990286Sobrien  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
1693090286Sobrien   && (GET_MODE (operands[0]) == HImode
1693190286Sobrien       || (GET_MODE (operands[0]) == QImode 
1693290286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1693390286Sobrien  [(set (match_dup 0)
1693490286Sobrien	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
1693590286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1693690286Sobrien   operands[2] = gen_lowpart (SImode, operands[2]);
1693790286Sobrien   operands[3] = gen_lowpart (SImode, operands[3]);")
1693890286Sobrien			
1693990286Sobrien
1694090286Sobrien;; RTL Peephole optimizations, run before sched2.  These primarily look to
1694190286Sobrien;; transform a complex memory operation into two memory to register operations.
1694290286Sobrien
1694390286Sobrien;; Don't push memory operands
1694490286Sobrien(define_peephole2
1694590286Sobrien  [(set (match_operand:SI 0 "push_operand" "")
1694690286Sobrien	(match_operand:SI 1 "memory_operand" ""))
1694790286Sobrien   (match_scratch:SI 2 "r")]
1694890286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1694990286Sobrien  [(set (match_dup 2) (match_dup 1))
1695090286Sobrien   (set (match_dup 0) (match_dup 2))]
1695190286Sobrien  "")
1695290286Sobrien
1695390286Sobrien(define_peephole2
1695490286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
1695590286Sobrien	(match_operand:DI 1 "memory_operand" ""))
1695690286Sobrien   (match_scratch:DI 2 "r")]
1695790286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1695890286Sobrien  [(set (match_dup 2) (match_dup 1))
1695990286Sobrien   (set (match_dup 0) (match_dup 2))]
1696090286Sobrien  "")
1696190286Sobrien
1696290286Sobrien;; We need to handle SFmode only, because DFmode and XFmode is split to
1696390286Sobrien;; SImode pushes.
1696490286Sobrien(define_peephole2
1696590286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
1696690286Sobrien	(match_operand:SF 1 "memory_operand" ""))
1696790286Sobrien   (match_scratch:SF 2 "r")]
1696890286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1696990286Sobrien  [(set (match_dup 2) (match_dup 1))
1697090286Sobrien   (set (match_dup 0) (match_dup 2))]
1697190286Sobrien  "")
1697290286Sobrien
1697390286Sobrien(define_peephole2
1697490286Sobrien  [(set (match_operand:HI 0 "push_operand" "")
1697590286Sobrien	(match_operand:HI 1 "memory_operand" ""))
1697690286Sobrien   (match_scratch:HI 2 "r")]
1697790286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1697890286Sobrien  [(set (match_dup 2) (match_dup 1))
1697990286Sobrien   (set (match_dup 0) (match_dup 2))]
1698090286Sobrien  "")
1698190286Sobrien
1698290286Sobrien(define_peephole2
1698390286Sobrien  [(set (match_operand:QI 0 "push_operand" "")
1698490286Sobrien	(match_operand:QI 1 "memory_operand" ""))
1698590286Sobrien   (match_scratch:QI 2 "q")]
1698690286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1698790286Sobrien  [(set (match_dup 2) (match_dup 1))
1698890286Sobrien   (set (match_dup 0) (match_dup 2))]
1698990286Sobrien  "")
1699090286Sobrien
1699190286Sobrien;; Don't move an immediate directly to memory when the instruction
1699290286Sobrien;; gets too big.
1699390286Sobrien(define_peephole2
1699490286Sobrien  [(match_scratch:SI 1 "r")
1699590286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1699690286Sobrien        (const_int 0))]
1699790286Sobrien  "! optimize_size
1699890286Sobrien   && ! TARGET_USE_MOV0
1699990286Sobrien   && TARGET_SPLIT_LONG_MOVES
1700090286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1700190286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1700290286Sobrien  [(parallel [(set (match_dup 1) (const_int 0))
1700390286Sobrien	      (clobber (reg:CC 17))])
1700490286Sobrien   (set (match_dup 0) (match_dup 1))]
1700590286Sobrien  "")
1700690286Sobrien
1700790286Sobrien(define_peephole2
1700890286Sobrien  [(match_scratch:HI 1 "r")
1700990286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1701090286Sobrien        (const_int 0))]
1701190286Sobrien  "! optimize_size
1701290286Sobrien   && ! TARGET_USE_MOV0
1701390286Sobrien   && TARGET_SPLIT_LONG_MOVES
1701490286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1701590286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1701690286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1701790286Sobrien	      (clobber (reg:CC 17))])
1701890286Sobrien   (set (match_dup 0) (match_dup 1))]
1701990286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1702090286Sobrien
1702190286Sobrien(define_peephole2
1702290286Sobrien  [(match_scratch:QI 1 "q")
1702390286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1702490286Sobrien        (const_int 0))]
1702590286Sobrien  "! optimize_size
1702690286Sobrien   && ! TARGET_USE_MOV0
1702790286Sobrien   && TARGET_SPLIT_LONG_MOVES
1702890286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1702990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1703090286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1703190286Sobrien	      (clobber (reg:CC 17))])
1703290286Sobrien   (set (match_dup 0) (match_dup 1))]
1703390286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1703490286Sobrien
1703590286Sobrien(define_peephole2
1703690286Sobrien  [(match_scratch:SI 2 "r")
1703790286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1703890286Sobrien        (match_operand:SI 1 "immediate_operand" ""))]
1703990286Sobrien  "! optimize_size
1704090286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1704190286Sobrien   && TARGET_SPLIT_LONG_MOVES"
1704290286Sobrien  [(set (match_dup 2) (match_dup 1))
1704390286Sobrien   (set (match_dup 0) (match_dup 2))]
1704490286Sobrien  "")
1704590286Sobrien
1704690286Sobrien(define_peephole2
1704790286Sobrien  [(match_scratch:HI 2 "r")
1704890286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1704990286Sobrien        (match_operand:HI 1 "immediate_operand" ""))]
1705090286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1705190286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1705290286Sobrien  [(set (match_dup 2) (match_dup 1))
1705390286Sobrien   (set (match_dup 0) (match_dup 2))]
1705490286Sobrien  "")
1705590286Sobrien
1705690286Sobrien(define_peephole2
1705790286Sobrien  [(match_scratch:QI 2 "q")
1705890286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1705990286Sobrien        (match_operand:QI 1 "immediate_operand" ""))]
1706090286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1706190286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1706290286Sobrien  [(set (match_dup 2) (match_dup 1))
1706390286Sobrien   (set (match_dup 0) (match_dup 2))]
1706490286Sobrien  "")
1706590286Sobrien
1706690286Sobrien;; Don't compare memory with zero, load and use a test instead.
1706790286Sobrien(define_peephole2
1706890286Sobrien  [(set (reg 17)
1706990286Sobrien	(compare (match_operand:SI 0 "memory_operand" "")
1707090286Sobrien	         (const_int 0)))
1707190286Sobrien   (match_scratch:SI 3 "r")]
1707290286Sobrien  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
1707390286Sobrien  [(set (match_dup 3) (match_dup 0))
1707490286Sobrien   (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
1707590286Sobrien  "")
1707690286Sobrien
1707790286Sobrien;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
1707890286Sobrien;; Don't split NOTs with a displacement operand, because resulting XOR
1707990286Sobrien;; will not be pariable anyway.
1708090286Sobrien;;
1708190286Sobrien;; On AMD K6, NOT is vector decoded with memory operand that can not be
1708290286Sobrien;; represented using a modRM byte.  The XOR replacement is long decoded,
1708390286Sobrien;; so this split helps here as well.
1708490286Sobrien;;
1708590286Sobrien;; Note: Can't do this as a regular split because we can't get proper
1708690286Sobrien;; lifetime information then.
1708790286Sobrien
1708890286Sobrien(define_peephole2
1708990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1709090286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1709190286Sobrien  "!optimize_size
1709290286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1709390286Sobrien   && ((TARGET_PENTIUM 
1709490286Sobrien        && (GET_CODE (operands[0]) != MEM
1709590286Sobrien            || !memory_displacement_operand (operands[0], SImode)))
1709690286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
1709790286Sobrien  [(parallel [(set (match_dup 0)
1709890286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))
1709990286Sobrien	      (clobber (reg:CC 17))])]
1710090286Sobrien  "")
1710190286Sobrien
1710290286Sobrien(define_peephole2
1710390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1710490286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1710590286Sobrien  "!optimize_size
1710690286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1710790286Sobrien   && ((TARGET_PENTIUM 
1710890286Sobrien        && (GET_CODE (operands[0]) != MEM
1710990286Sobrien            || !memory_displacement_operand (operands[0], HImode)))
1711090286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
1711190286Sobrien  [(parallel [(set (match_dup 0)
1711290286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))
1711390286Sobrien	      (clobber (reg:CC 17))])]
1711490286Sobrien  "")
1711590286Sobrien
1711690286Sobrien(define_peephole2
1711790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1711890286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1711990286Sobrien  "!optimize_size
1712090286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1712190286Sobrien   && ((TARGET_PENTIUM 
1712290286Sobrien        && (GET_CODE (operands[0]) != MEM
1712390286Sobrien            || !memory_displacement_operand (operands[0], QImode)))
1712490286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
1712590286Sobrien  [(parallel [(set (match_dup 0)
1712690286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))
1712790286Sobrien	      (clobber (reg:CC 17))])]
1712890286Sobrien  "")
1712990286Sobrien
1713090286Sobrien;; Non pairable "test imm, reg" instructions can be translated to
1713190286Sobrien;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
1713290286Sobrien;; byte opcode instead of two, have a short form for byte operands),
1713390286Sobrien;; so do it for other CPUs as well.  Given that the value was dead,
1713490286Sobrien;; this should not create any new dependencies.  Pass on the sub-word
1713590286Sobrien;; versions if we're concerned about partial register stalls.
1713690286Sobrien
1713790286Sobrien(define_peephole2
1713890286Sobrien  [(set (reg 17)
1713990286Sobrien	(compare (and:SI (match_operand:SI 0 "register_operand" "")
1714090286Sobrien			 (match_operand:SI 1 "immediate_operand" ""))
1714190286Sobrien		 (const_int 0)))]
1714290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1714390286Sobrien   && (true_regnum (operands[0]) != 0
17144117404Skan       || (GET_CODE (operands[1]) == CONST_INT
17145117404Skan	   && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
1714690286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1714790286Sobrien  [(parallel
1714890286Sobrien     [(set (reg:CCNO 17)
1714990286Sobrien	   (compare:CCNO (and:SI (match_dup 0)
1715090286Sobrien			         (match_dup 1))
1715190286Sobrien		         (const_int 0)))
1715290286Sobrien      (set (match_dup 0)
1715390286Sobrien	   (and:SI (match_dup 0) (match_dup 1)))])]
1715490286Sobrien  "")
1715590286Sobrien
1715690286Sobrien;; We don't need to handle HImode case, because it will be promoted to SImode
1715790286Sobrien;; on ! TARGET_PARTIAL_REG_STALL
1715890286Sobrien
1715990286Sobrien(define_peephole2
1716090286Sobrien  [(set (reg 17)
1716190286Sobrien	(compare (and:QI (match_operand:QI 0 "register_operand" "")
1716290286Sobrien			 (match_operand:QI 1 "immediate_operand" ""))
1716390286Sobrien		 (const_int 0)))]
1716490286Sobrien  "! TARGET_PARTIAL_REG_STALL
1716590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1716690286Sobrien   && true_regnum (operands[0]) != 0
1716790286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1716890286Sobrien  [(parallel
1716990286Sobrien     [(set (reg:CCNO 17)
1717090286Sobrien	   (compare:CCNO (and:QI (match_dup 0)
1717190286Sobrien 			         (match_dup 1))
1717290286Sobrien		         (const_int 0)))
1717390286Sobrien      (set (match_dup 0)
1717490286Sobrien	   (and:QI (match_dup 0) (match_dup 1)))])]
1717590286Sobrien  "")
1717690286Sobrien
1717790286Sobrien(define_peephole2
1717890286Sobrien  [(set (reg 17)
1717990286Sobrien	(compare
1718090286Sobrien	  (and:SI
1718190286Sobrien	    (zero_extract:SI
1718290286Sobrien	      (match_operand 0 "ext_register_operand" "")
1718390286Sobrien	      (const_int 8)
1718490286Sobrien	      (const_int 8))
1718590286Sobrien	    (match_operand 1 "const_int_operand" ""))
1718690286Sobrien	  (const_int 0)))]
1718790286Sobrien  "! TARGET_PARTIAL_REG_STALL
1718890286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1718990286Sobrien   && true_regnum (operands[0]) != 0
1719090286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1719190286Sobrien  [(parallel [(set (reg:CCNO 17)
1719290286Sobrien		   (compare:CCNO
1719390286Sobrien		       (and:SI
1719490286Sobrien			 (zero_extract:SI
1719590286Sobrien			 (match_dup 0)
1719690286Sobrien			 (const_int 8)
1719790286Sobrien			 (const_int 8))
1719890286Sobrien			(match_dup 1))
1719990286Sobrien		   (const_int 0)))
1720090286Sobrien	      (set (zero_extract:SI (match_dup 0)
1720190286Sobrien				    (const_int 8)
1720290286Sobrien				    (const_int 8))
1720390286Sobrien		   (and:SI 
1720490286Sobrien		     (zero_extract:SI
1720590286Sobrien		       (match_dup 0)
1720690286Sobrien		       (const_int 8)
1720790286Sobrien		       (const_int 8))
1720890286Sobrien		     (match_dup 1)))])]
1720990286Sobrien  "")
1721090286Sobrien
1721190286Sobrien;; Don't do logical operations with memory inputs.
1721290286Sobrien(define_peephole2
1721390286Sobrien  [(match_scratch:SI 2 "r")
1721490286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1721590286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1721690286Sobrien                     [(match_dup 0)
1721790286Sobrien                      (match_operand:SI 1 "memory_operand" "")]))
1721890286Sobrien              (clobber (reg:CC 17))])]
1721990286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1722090286Sobrien  [(set (match_dup 2) (match_dup 1))
1722190286Sobrien   (parallel [(set (match_dup 0)
1722290286Sobrien                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
1722390286Sobrien              (clobber (reg:CC 17))])]
1722490286Sobrien  "")
1722590286Sobrien
1722690286Sobrien(define_peephole2
1722790286Sobrien  [(match_scratch:SI 2 "r")
1722890286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1722990286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1723090286Sobrien                     [(match_operand:SI 1 "memory_operand" "")
1723190286Sobrien                      (match_dup 0)]))
1723290286Sobrien              (clobber (reg:CC 17))])]
1723390286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1723490286Sobrien  [(set (match_dup 2) (match_dup 1))
1723590286Sobrien   (parallel [(set (match_dup 0)
1723690286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
1723790286Sobrien              (clobber (reg:CC 17))])]
1723890286Sobrien  "")
1723990286Sobrien
1724090286Sobrien; Don't do logical operations with memory outputs
1724190286Sobrien;
1724290286Sobrien; These two don't make sense for PPro/PII -- we're expanding a 4-uop
1724390286Sobrien; instruction into two 1-uop insns plus a 2-uop insn.  That last has
1724490286Sobrien; the same decoder scheduling characteristics as the original.
1724590286Sobrien
1724690286Sobrien(define_peephole2
1724790286Sobrien  [(match_scratch:SI 2 "r")
1724890286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1724990286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1725090286Sobrien                     [(match_dup 0)
1725190286Sobrien                      (match_operand:SI 1 "nonmemory_operand" "")]))
1725290286Sobrien              (clobber (reg:CC 17))])]
1725390286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1725490286Sobrien  [(set (match_dup 2) (match_dup 0))
1725590286Sobrien   (parallel [(set (match_dup 2)
1725690286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
1725790286Sobrien              (clobber (reg:CC 17))])
1725890286Sobrien   (set (match_dup 0) (match_dup 2))]
1725990286Sobrien  "")
1726090286Sobrien
1726190286Sobrien(define_peephole2
1726290286Sobrien  [(match_scratch:SI 2 "r")
1726390286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1726490286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1726590286Sobrien                     [(match_operand:SI 1 "nonmemory_operand" "")
1726690286Sobrien                      (match_dup 0)]))
1726790286Sobrien              (clobber (reg:CC 17))])]
1726890286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1726990286Sobrien  [(set (match_dup 2) (match_dup 0))
1727090286Sobrien   (parallel [(set (match_dup 2)
1727190286Sobrien                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1727290286Sobrien              (clobber (reg:CC 17))])
1727390286Sobrien   (set (match_dup 0) (match_dup 2))]
1727490286Sobrien  "")
1727590286Sobrien
1727690286Sobrien;; Attempt to always use XOR for zeroing registers.
1727790286Sobrien(define_peephole2
1727890286Sobrien  [(set (match_operand 0 "register_operand" "")
1727990286Sobrien	(const_int 0))]
1728090286Sobrien  "(GET_MODE (operands[0]) == QImode
1728190286Sobrien    || GET_MODE (operands[0]) == HImode
1728290286Sobrien    || GET_MODE (operands[0]) == SImode
1728390286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1728490286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1728590286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1728690286Sobrien  [(parallel [(set (match_dup 0) (const_int 0))
1728790286Sobrien	      (clobber (reg:CC 17))])]
1728890286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1728990286Sobrien			      true_regnum (operands[0]));")
1729090286Sobrien
1729190286Sobrien(define_peephole2
1729290286Sobrien  [(set (strict_low_part (match_operand 0 "register_operand" ""))
1729390286Sobrien	(const_int 0))]
1729490286Sobrien  "(GET_MODE (operands[0]) == QImode
1729590286Sobrien    || GET_MODE (operands[0]) == HImode)
1729690286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1729790286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1729890286Sobrien  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
1729990286Sobrien	      (clobber (reg:CC 17))])])
1730090286Sobrien
1730190286Sobrien;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
1730290286Sobrien(define_peephole2
1730390286Sobrien  [(set (match_operand 0 "register_operand" "")
1730490286Sobrien	(const_int -1))]
1730590286Sobrien  "(GET_MODE (operands[0]) == HImode
1730690286Sobrien    || GET_MODE (operands[0]) == SImode 
1730790286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1730890286Sobrien   && (optimize_size || TARGET_PENTIUM)
1730990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1731090286Sobrien  [(parallel [(set (match_dup 0) (const_int -1))
1731190286Sobrien	      (clobber (reg:CC 17))])]
1731290286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1731390286Sobrien			      true_regnum (operands[0]));")
1731490286Sobrien
1731590286Sobrien;; Attempt to convert simple leas to adds. These can be created by
1731690286Sobrien;; move expanders.
1731790286Sobrien(define_peephole2
1731890286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1731990286Sobrien  	(plus:SI (match_dup 0)
1732090286Sobrien		 (match_operand:SI 1 "nonmemory_operand" "")))]
1732190286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1732290286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1732390286Sobrien	      (clobber (reg:CC 17))])]
1732490286Sobrien  "")
1732590286Sobrien
1732690286Sobrien(define_peephole2
1732790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1732890286Sobrien  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
1732990286Sobrien			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
1733090286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
1733190286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
1733290286Sobrien	      (clobber (reg:CC 17))])]
1733390286Sobrien  "operands[2] = gen_lowpart (SImode, operands[2]);")
1733490286Sobrien
1733590286Sobrien(define_peephole2
1733690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1733790286Sobrien  	(plus:DI (match_dup 0)
1733890286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "")))]
1733990286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1734090286Sobrien  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1734190286Sobrien	      (clobber (reg:CC 17))])]
1734290286Sobrien  "")
1734390286Sobrien
1734490286Sobrien(define_peephole2
1734590286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1734690286Sobrien  	(mult:SI (match_dup 0)
1734790286Sobrien		 (match_operand:SI 1 "const_int_operand" "")))]
1734890286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1734990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1735090286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1735190286Sobrien	      (clobber (reg:CC 17))])]
1735290286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1735390286Sobrien
1735490286Sobrien(define_peephole2
1735590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1735690286Sobrien  	(mult:DI (match_dup 0)
1735790286Sobrien		 (match_operand:DI 1 "const_int_operand" "")))]
1735890286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1735990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1736090286Sobrien  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
1736190286Sobrien	      (clobber (reg:CC 17))])]
1736290286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1736390286Sobrien
1736490286Sobrien(define_peephole2
1736590286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1736690286Sobrien  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
1736790286Sobrien		   (match_operand:DI 2 "const_int_operand" "")) 0))]
17368117404Skan  "exact_log2 (INTVAL (operands[2])) >= 0
1736990286Sobrien   && REGNO (operands[0]) == REGNO (operands[1])
1737090286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1737190286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1737290286Sobrien	      (clobber (reg:CC 17))])]
1737390286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
1737490286Sobrien
1737590286Sobrien;; The ESP adjustments can be done by the push and pop instructions.  Resulting
1737690286Sobrien;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
1737790286Sobrien;; many CPUs it is also faster, since special hardware to avoid esp
1737890286Sobrien;; dependencies is present.
1737990286Sobrien
1738090286Sobrien;; While some of these conversions may be done using splitters, we use peepholes
1738190286Sobrien;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
1738290286Sobrien
1738390286Sobrien;; Convert prologue esp subtractions to push.
1738490286Sobrien;; We need register to push.  In order to keep verify_flow_info happy we have
1738590286Sobrien;; two choices
1738690286Sobrien;; - use scratch and clobber it in order to avoid dependencies
1738790286Sobrien;; - use already live register
1738890286Sobrien;; We can't use the second way right now, since there is no reliable way how to
1738990286Sobrien;; verify that given register is live.  First choice will also most likely in
1739090286Sobrien;; fewer dependencies.  On the place of esp adjustments it is very likely that
1739190286Sobrien;; call clobbered registers are dead.  We may want to use base pointer as an
1739290286Sobrien;; alternative when no register is available later.
1739390286Sobrien
1739490286Sobrien(define_peephole2
1739590286Sobrien  [(match_scratch:SI 0 "r")
1739690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1739790286Sobrien	      (clobber (reg:CC 17))
1739890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1739990286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1740090286Sobrien  [(clobber (match_dup 0))
1740190286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1740290286Sobrien	      (clobber (mem:BLK (scratch)))])])
1740390286Sobrien
1740490286Sobrien(define_peephole2
1740590286Sobrien  [(match_scratch:SI 0 "r")
1740690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1740790286Sobrien	      (clobber (reg:CC 17))
1740890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1740990286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1741090286Sobrien  [(clobber (match_dup 0))
1741190286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1741290286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1741390286Sobrien	      (clobber (mem:BLK (scratch)))])])
1741490286Sobrien
1741590286Sobrien;; Convert esp subtractions to push.
1741690286Sobrien(define_peephole2
1741790286Sobrien  [(match_scratch:SI 0 "r")
1741890286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1741990286Sobrien	      (clobber (reg:CC 17))])]
1742090286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1742190286Sobrien  [(clobber (match_dup 0))
1742290286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1742390286Sobrien
1742490286Sobrien(define_peephole2
1742590286Sobrien  [(match_scratch:SI 0 "r")
1742690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1742790286Sobrien	      (clobber (reg:CC 17))])]
1742890286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1742990286Sobrien  [(clobber (match_dup 0))
1743090286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1743190286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1743290286Sobrien
1743390286Sobrien;; Convert epilogue deallocator to pop.
1743490286Sobrien(define_peephole2
1743590286Sobrien  [(match_scratch:SI 0 "r")
1743690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1743790286Sobrien	      (clobber (reg:CC 17))
1743890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1743990286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1744090286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1744190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1744290286Sobrien	      (clobber (mem:BLK (scratch)))])]
1744390286Sobrien  "")
1744490286Sobrien
1744590286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1744690286Sobrien;; We use two registers if available.
1744790286Sobrien(define_peephole2
1744890286Sobrien  [(match_scratch:SI 0 "r")
1744990286Sobrien   (match_scratch:SI 1 "r")
1745090286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1745190286Sobrien	      (clobber (reg:CC 17))
1745290286Sobrien	      (clobber (mem:BLK (scratch)))])]
1745390286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1745490286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1745590286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1745690286Sobrien	      (clobber (mem:BLK (scratch)))])
1745790286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1745890286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1745990286Sobrien  "")
1746090286Sobrien
1746190286Sobrien(define_peephole2
1746290286Sobrien  [(match_scratch:SI 0 "r")
1746390286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1746490286Sobrien	      (clobber (reg:CC 17))
1746590286Sobrien	      (clobber (mem:BLK (scratch)))])]
1746690286Sobrien  "optimize_size"
1746790286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1746890286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1746990286Sobrien	      (clobber (mem:BLK (scratch)))])
1747090286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1747190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1747290286Sobrien  "")
1747390286Sobrien
1747490286Sobrien;; Convert esp additions to pop.
1747590286Sobrien(define_peephole2
1747690286Sobrien  [(match_scratch:SI 0 "r")
1747790286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1747890286Sobrien	      (clobber (reg:CC 17))])]
1747990286Sobrien  ""
1748090286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1748190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1748290286Sobrien  "")
1748390286Sobrien
1748490286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1748590286Sobrien;; We use two registers if available.
1748690286Sobrien(define_peephole2
1748790286Sobrien  [(match_scratch:SI 0 "r")
1748890286Sobrien   (match_scratch:SI 1 "r")
1748990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1749090286Sobrien	      (clobber (reg:CC 17))])]
1749190286Sobrien  ""
1749290286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1749390286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1749490286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1749590286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1749690286Sobrien  "")
1749790286Sobrien
1749890286Sobrien(define_peephole2
1749990286Sobrien  [(match_scratch:SI 0 "r")
1750090286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1750190286Sobrien	      (clobber (reg:CC 17))])]
1750290286Sobrien  "optimize_size"
1750390286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1750490286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1750590286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1750690286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1750790286Sobrien  "")
1750890286Sobrien
1750990286Sobrien;; Convert compares with 1 to shorter inc/dec operations when CF is not
1751090286Sobrien;; required and register dies.
1751190286Sobrien(define_peephole2
1751290286Sobrien  [(set (reg 17)
1751390286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1751490286Sobrien		 (match_operand:SI 1 "incdec_operand" "")))]
1751590286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1751690286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1751790286Sobrien  [(parallel [(set (reg:CCGC 17)
1751890286Sobrien		   (compare:CCGC (match_dup 0)
1751990286Sobrien				 (match_dup 1)))
1752090286Sobrien	      (clobber (match_dup 0))])]
1752190286Sobrien  "")
1752290286Sobrien
1752390286Sobrien(define_peephole2
1752490286Sobrien  [(set (reg 17)
1752590286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1752690286Sobrien		 (match_operand:HI 1 "incdec_operand" "")))]
1752790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1752890286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1752990286Sobrien  [(parallel [(set (reg:CCGC 17)
1753090286Sobrien		   (compare:CCGC (match_dup 0)
1753190286Sobrien				 (match_dup 1)))
1753290286Sobrien	      (clobber (match_dup 0))])]
1753390286Sobrien  "")
1753490286Sobrien
1753590286Sobrien(define_peephole2
1753690286Sobrien  [(set (reg 17)
1753790286Sobrien	(compare (match_operand:QI 0 "register_operand" "")
1753890286Sobrien		 (match_operand:QI 1 "incdec_operand" "")))]
1753990286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1754090286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1754190286Sobrien  [(parallel [(set (reg:CCGC 17)
1754290286Sobrien		   (compare:CCGC (match_dup 0)
1754390286Sobrien				 (match_dup 1)))
1754490286Sobrien	      (clobber (match_dup 0))])]
1754590286Sobrien  "")
1754690286Sobrien
1754790286Sobrien;; Convert compares with 128 to shorter add -128
1754890286Sobrien(define_peephole2
1754990286Sobrien  [(set (reg 17)
1755090286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1755190286Sobrien		 (const_int 128)))]
1755290286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1755390286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1755490286Sobrien  [(parallel [(set (reg:CCGC 17)
1755590286Sobrien		   (compare:CCGC (match_dup 0)
1755690286Sobrien			         (const_int 128)))
1755790286Sobrien	      (clobber (match_dup 0))])]
1755890286Sobrien  "")
1755990286Sobrien
1756090286Sobrien(define_peephole2
1756190286Sobrien  [(set (reg 17)
1756290286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1756390286Sobrien		 (const_int 128)))]
1756490286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1756590286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1756690286Sobrien  [(parallel [(set (reg:CCGC 17)
1756790286Sobrien		   (compare:CCGC (match_dup 0)
1756890286Sobrien			         (const_int 128)))
1756990286Sobrien	      (clobber (match_dup 0))])]
1757090286Sobrien  "")
1757190286Sobrien
1757290286Sobrien(define_peephole2
1757390286Sobrien  [(match_scratch:DI 0 "r")
1757490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1757590286Sobrien	      (clobber (reg:CC 17))
1757690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1757790286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1757890286Sobrien  [(clobber (match_dup 0))
1757990286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1758090286Sobrien	      (clobber (mem:BLK (scratch)))])])
1758190286Sobrien
1758290286Sobrien(define_peephole2
1758390286Sobrien  [(match_scratch:DI 0 "r")
1758490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1758590286Sobrien	      (clobber (reg:CC 17))
1758690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1758790286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1758890286Sobrien  [(clobber (match_dup 0))
1758990286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1759090286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1759190286Sobrien	      (clobber (mem:BLK (scratch)))])])
1759290286Sobrien
1759390286Sobrien;; Convert esp subtractions to push.
1759490286Sobrien(define_peephole2
1759590286Sobrien  [(match_scratch:DI 0 "r")
1759690286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1759790286Sobrien	      (clobber (reg:CC 17))])]
1759890286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1759990286Sobrien  [(clobber (match_dup 0))
1760090286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1760190286Sobrien
1760290286Sobrien(define_peephole2
1760390286Sobrien  [(match_scratch:DI 0 "r")
1760490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1760590286Sobrien	      (clobber (reg:CC 17))])]
1760690286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1760790286Sobrien  [(clobber (match_dup 0))
1760890286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1760990286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1761090286Sobrien
1761190286Sobrien;; Convert epilogue deallocator to pop.
1761290286Sobrien(define_peephole2
1761390286Sobrien  [(match_scratch:DI 0 "r")
1761490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1761590286Sobrien	      (clobber (reg:CC 17))
1761690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1761790286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1761890286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1761990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1762090286Sobrien	      (clobber (mem:BLK (scratch)))])]
1762190286Sobrien  "")
1762290286Sobrien
1762390286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1762490286Sobrien;; We use two registers if available.
1762590286Sobrien(define_peephole2
1762690286Sobrien  [(match_scratch:DI 0 "r")
1762790286Sobrien   (match_scratch:DI 1 "r")
1762890286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1762990286Sobrien	      (clobber (reg:CC 17))
1763090286Sobrien	      (clobber (mem:BLK (scratch)))])]
1763190286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1763290286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1763390286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1763490286Sobrien	      (clobber (mem:BLK (scratch)))])
1763590286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1763690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1763790286Sobrien  "")
1763890286Sobrien
1763990286Sobrien(define_peephole2
1764090286Sobrien  [(match_scratch:DI 0 "r")
1764190286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1764290286Sobrien	      (clobber (reg:CC 17))
1764390286Sobrien	      (clobber (mem:BLK (scratch)))])]
1764490286Sobrien  "optimize_size"
1764590286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1764690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1764790286Sobrien	      (clobber (mem:BLK (scratch)))])
1764890286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1764990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1765090286Sobrien  "")
1765190286Sobrien
1765290286Sobrien;; Convert esp additions to pop.
1765390286Sobrien(define_peephole2
1765490286Sobrien  [(match_scratch:DI 0 "r")
1765590286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1765690286Sobrien	      (clobber (reg:CC 17))])]
1765790286Sobrien  ""
1765890286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1765990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1766090286Sobrien  "")
1766190286Sobrien
1766290286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1766390286Sobrien;; We use two registers if available.
1766490286Sobrien(define_peephole2
1766590286Sobrien  [(match_scratch:DI 0 "r")
1766690286Sobrien   (match_scratch:DI 1 "r")
1766790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1766890286Sobrien	      (clobber (reg:CC 17))])]
1766990286Sobrien  ""
1767090286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1767190286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1767290286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1767390286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1767490286Sobrien  "")
1767590286Sobrien
1767690286Sobrien(define_peephole2
1767790286Sobrien  [(match_scratch:DI 0 "r")
1767890286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1767990286Sobrien	      (clobber (reg:CC 17))])]
1768090286Sobrien  "optimize_size"
1768190286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1768290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1768390286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1768490286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1768590286Sobrien  "")
1768690286Sobrien
1768790286Sobrien;; Call-value patterns last so that the wildcard operand does not
1768890286Sobrien;; disrupt insn-recog's switch tables.
1768990286Sobrien
1769090286Sobrien(define_insn "*call_value_pop_0"
1769190286Sobrien  [(set (match_operand 0 "" "")
1769290286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1769390286Sobrien	      (match_operand:SI 2 "" "")))
1769490286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1769590286Sobrien			    (match_operand:SI 3 "immediate_operand" "")))]
1769690286Sobrien  "!TARGET_64BIT"
1769790286Sobrien{
1769890286Sobrien  if (SIBLING_CALL_P (insn))
1769990286Sobrien    return "jmp\t%P1";
1770090286Sobrien  else
1770190286Sobrien    return "call\t%P1";
1770290286Sobrien}
1770390286Sobrien  [(set_attr "type" "callv")])
1770490286Sobrien
1770590286Sobrien(define_insn "*call_value_pop_1"
1770690286Sobrien  [(set (match_operand 0 "" "")
1770790286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1770890286Sobrien	      (match_operand:SI 2 "" "")))
1770990286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1771090286Sobrien			    (match_operand:SI 3 "immediate_operand" "i")))]
1771190286Sobrien  "!TARGET_64BIT"
1771290286Sobrien{
1771390286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1771490286Sobrien    {
1771590286Sobrien      if (SIBLING_CALL_P (insn))
1771690286Sobrien	return "jmp\t%P1";
1771790286Sobrien      else
1771890286Sobrien	return "call\t%P1";
1771990286Sobrien    }
1772090286Sobrien  if (SIBLING_CALL_P (insn))
1772190286Sobrien    return "jmp\t%A1";
1772290286Sobrien  else
1772390286Sobrien    return "call\t%A1";
1772490286Sobrien}
1772590286Sobrien  [(set_attr "type" "callv")])
1772690286Sobrien
1772790286Sobrien(define_insn "*call_value_0"
1772890286Sobrien  [(set (match_operand 0 "" "")
1772990286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1773090286Sobrien	      (match_operand:SI 2 "" "")))]
1773190286Sobrien  "!TARGET_64BIT"
1773290286Sobrien{
1773390286Sobrien  if (SIBLING_CALL_P (insn))
1773490286Sobrien    return "jmp\t%P1";
1773590286Sobrien  else
1773690286Sobrien    return "call\t%P1";
1773790286Sobrien}
1773890286Sobrien  [(set_attr "type" "callv")])
1773990286Sobrien
1774090286Sobrien(define_insn "*call_value_0_rex64"
1774190286Sobrien  [(set (match_operand 0 "" "")
1774290286Sobrien	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
1774390286Sobrien	      (match_operand:DI 2 "const_int_operand" "")))]
1774490286Sobrien  "TARGET_64BIT"
1774590286Sobrien{
1774690286Sobrien  if (SIBLING_CALL_P (insn))
1774790286Sobrien    return "jmp\t%P1";
1774890286Sobrien  else
1774990286Sobrien    return "call\t%P1";
1775090286Sobrien}
1775190286Sobrien  [(set_attr "type" "callv")])
1775290286Sobrien
1775390286Sobrien(define_insn "*call_value_1"
1775490286Sobrien  [(set (match_operand 0 "" "")
1775590286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1775690286Sobrien	      (match_operand:SI 2 "" "")))]
1775790286Sobrien  "!TARGET_64BIT"
1775890286Sobrien{
1775990286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1776090286Sobrien    {
1776190286Sobrien      if (SIBLING_CALL_P (insn))
1776290286Sobrien	return "jmp\t%P1";
1776390286Sobrien      else
1776490286Sobrien	return "call\t%P1";
1776590286Sobrien    }
1776690286Sobrien  if (SIBLING_CALL_P (insn))
1776790286Sobrien    return "jmp\t%*%1";
1776890286Sobrien  else
1776990286Sobrien    return "call\t%*%1";
1777090286Sobrien}
1777190286Sobrien  [(set_attr "type" "callv")])
1777290286Sobrien
1777390286Sobrien(define_insn "*call_value_1_rex64"
1777490286Sobrien  [(set (match_operand 0 "" "")
1777590286Sobrien	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
1777690286Sobrien	      (match_operand:DI 2 "" "")))]
1777790286Sobrien  "TARGET_64BIT"
1777890286Sobrien{
1777990286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1778090286Sobrien    {
1778190286Sobrien      if (SIBLING_CALL_P (insn))
1778290286Sobrien	return "jmp\t%P1";
1778390286Sobrien      else
1778490286Sobrien	return "call\t%P1";
1778590286Sobrien    }
1778690286Sobrien  if (SIBLING_CALL_P (insn))
1778790286Sobrien    return "jmp\t%A1";
1778890286Sobrien  else
1778990286Sobrien    return "call\t%A1";
1779090286Sobrien}
1779190286Sobrien  [(set_attr "type" "callv")])
1779290286Sobrien
1779390286Sobrien(define_insn "trap"
1779490286Sobrien  [(trap_if (const_int 1) (const_int 5))]
1779590286Sobrien  ""
1779690286Sobrien  "int\t$5")
1779790286Sobrien
1779890286Sobrien;;; ix86 doesn't have conditional trap instructions, but we fake them
1779990286Sobrien;;; for the sake of bounds checking.  By emitting bounds checks as
1780090286Sobrien;;; conditional traps rather than as conditional jumps around
1780190286Sobrien;;; unconditional traps we avoid introducing spurious basic-block
1780290286Sobrien;;; boundaries and facilitate elimination of redundant checks.  In
1780390286Sobrien;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
1780490286Sobrien;;; interrupt 5.
1780590286Sobrien;;; 
1780690286Sobrien;;; FIXME: Static branch prediction rules for ix86 are such that
1780790286Sobrien;;; forward conditional branches predict as untaken.  As implemented
1780890286Sobrien;;; below, pseudo conditional traps violate that rule.  We should use
1780990286Sobrien;;; .pushsection/.popsection to place all of the `int 5's in a special
1781090286Sobrien;;; section loaded at the end of the text segment and branch forward
1781190286Sobrien;;; there on bounds-failure, and then jump back immediately (in case
1781290286Sobrien;;; the system chooses to ignore bounds violations, or to report
1781390286Sobrien;;; violations and continue execution).
1781490286Sobrien
1781590286Sobrien(define_expand "conditional_trap"
1781690286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1781790286Sobrien	     [(match_dup 2) (const_int 0)])
1781890286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1781990286Sobrien  ""
1782090286Sobrien{
1782190286Sobrien  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
1782290286Sobrien			      ix86_expand_compare (GET_CODE (operands[0]),
1782390286Sobrien						   NULL, NULL),
1782490286Sobrien			      operands[1]));
1782590286Sobrien  DONE;
1782690286Sobrien})
1782790286Sobrien
1782890286Sobrien(define_insn "*conditional_trap_1"
1782990286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1783090286Sobrien	     [(reg 17) (const_int 0)])
1783190286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1783290286Sobrien  ""
1783390286Sobrien{
1783490286Sobrien  operands[2] = gen_label_rtx ();
1783590286Sobrien  output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
1783690286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1783790286Sobrien			     CODE_LABEL_NUMBER (operands[2]));
1783890286Sobrien  RET;
1783990286Sobrien})
1784090286Sobrien
1784190286Sobrien	;; Pentium III SIMD instructions.
1784290286Sobrien
1784390286Sobrien;; Moves for SSE/MMX regs.
1784490286Sobrien
1784590286Sobrien(define_insn "movv4sf_internal"
17846117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
17847117404Skan	(match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
1784890286Sobrien  "TARGET_SSE"
1784990286Sobrien  ;; @@@ let's try to use movaps here.
17850117404Skan  "@
17851117404Skan   xorps\t%0, %0
17852117404Skan   movaps\t{%1, %0|%0, %1}
17853117404Skan   movaps\t{%1, %0|%0, %1}"
17854117404Skan  [(set_attr "type" "ssemov")
17855117404Skan   (set_attr "mode" "V4SF")])
1785690286Sobrien
1785790286Sobrien(define_insn "movv4si_internal"
17858117404Skan  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
17859117404Skan	(match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
1786090286Sobrien  "TARGET_SSE"
1786190286Sobrien  ;; @@@ let's try to use movaps here.
17862117404Skan  "@
17863117404Skan   xorps\t%0, %0
17864117404Skan   movaps\t{%1, %0|%0, %1}
17865117404Skan   movaps\t{%1, %0|%0, %1}"
17866117404Skan  [(set_attr "type" "ssemov")
17867117404Skan   (set_attr "mode" "V4SF")])
1786890286Sobrien
17869117404Skan(define_insn "movv2di_internal"
17870117404Skan  [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
17871117404Skan	(match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
17872117404Skan  "TARGET_SSE"
17873117404Skan  ;; @@@ let's try to use movaps here.
17874117404Skan  "@
17875117404Skan   pxor\t%0, %0
17876117404Skan   movdqa\t{%1, %0|%0, %1} 
17877117404Skan   movdqa\t{%1, %0|%0, %1}"
17878117404Skan  [(set_attr "type" "ssemov")
17879117404Skan   (set_attr "mode" "V4SF")])
17880117404Skan
1788190286Sobrien(define_insn "movv8qi_internal"
17882117404Skan  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
17883117404Skan	(match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
17884117404Skan  "TARGET_MMX
17885117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17886117404Skan  "@
17887117404Skan    pxor\t%0, %0
17888117404Skan    movq\t{%1, %0|%0, %1}
17889117404Skan    movq\t{%1, %0|%0, %1}"
17890117404Skan  [(set_attr "type" "mmxmov")
17891117404Skan   (set_attr "mode" "DI")])
1789290286Sobrien
1789390286Sobrien(define_insn "movv4hi_internal"
17894117404Skan  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
17895117404Skan	(match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
17896117404Skan  "TARGET_MMX
17897117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17898117404Skan  "@
17899117404Skan    pxor\t%0, %0
17900117404Skan    movq\t{%1, %0|%0, %1}
17901117404Skan    movq\t{%1, %0|%0, %1}"
17902117404Skan  [(set_attr "type" "mmxmov")
17903117404Skan   (set_attr "mode" "DI")])
1790490286Sobrien
1790590286Sobrien(define_insn "movv2si_internal"
17906117404Skan  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
17907117404Skan	(match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
17908117404Skan  "TARGET_MMX
17909117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17910117404Skan  "@
17911117404Skan    pxor\t%0, %0
17912117404Skan    movq\t{%1, %0|%0, %1}
17913117404Skan    movq\t{%1, %0|%0, %1}"
17914117404Skan  [(set_attr "type" "mmxcvt")
17915117404Skan   (set_attr "mode" "DI")])
1791690286Sobrien
1791790286Sobrien(define_insn "movv2sf_internal"
17918117404Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
17919117404Skan        (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
17920117404Skan  "TARGET_3DNOW
17921117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17922117404Skan  "@
17923117404Skan    pxor\t%0, %0
17924117404Skan    movq\t{%1, %0|%0, %1}
17925117404Skan    movq\t{%1, %0|%0, %1}"
17926117404Skan  [(set_attr "type" "mmxcvt")
17927117404Skan   (set_attr "mode" "DI")])
1792890286Sobrien
1792990286Sobrien(define_expand "movti"
17930117404Skan  [(set (match_operand:TI 0 "nonimmediate_operand" "")
17931117404Skan	(match_operand:TI 1 "nonimmediate_operand" ""))]
1793290286Sobrien  "TARGET_SSE || TARGET_64BIT"
1793390286Sobrien{
1793490286Sobrien  if (TARGET_64BIT)
1793590286Sobrien    ix86_expand_move (TImode, operands);
1793690286Sobrien  else
1793790286Sobrien    ix86_expand_vector_move (TImode, operands);
1793890286Sobrien  DONE;
1793990286Sobrien})
1794090286Sobrien
17941117404Skan(define_insn "movv2df_internal"
17942117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
17943117404Skan	(match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
17944117404Skan  "TARGET_SSE2
17945117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17946117404Skan  "@
17947117404Skan   xorpd\t%0, %0
17948117404Skan   movapd\t{%1, %0|%0, %1}
17949117404Skan   movapd\t{%1, %0|%0, %1}"
17950117404Skan  [(set_attr "type" "ssemov")
17951117404Skan   (set_attr "mode" "V2DF")])
17952117404Skan
17953117404Skan(define_insn "movv8hi_internal"
17954117404Skan  [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
17955117404Skan	(match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
17956117404Skan  "TARGET_SSE2
17957117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17958117404Skan  "@
17959117404Skan   xorps\t%0, %0
17960117404Skan   movaps\t{%1, %0|%0, %1}
17961117404Skan   movaps\t{%1, %0|%0, %1}"
17962117404Skan  [(set_attr "type" "ssemov")
17963117404Skan   (set_attr "mode" "V4SF")])
17964117404Skan
17965117404Skan(define_insn "movv16qi_internal"
17966117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
17967117404Skan	(match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
17968117404Skan  "TARGET_SSE2
17969117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17970117404Skan  "@
17971117404Skan   xorps\t%0, %0
17972117404Skan   movaps\t{%1, %0|%0, %1}
17973117404Skan   movaps\t{%1, %0|%0, %1}"
17974117404Skan  [(set_attr "type" "ssemov")
17975117404Skan   (set_attr "mode" "V4SF")])
17976117404Skan
17977117404Skan(define_expand "movv2df"
17978117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
17979117404Skan	(match_operand:V2DF 1 "nonimmediate_operand" ""))]
17980117404Skan  "TARGET_SSE2"
17981117404Skan{
17982117404Skan  ix86_expand_vector_move (V2DFmode, operands);
17983117404Skan  DONE;
17984117404Skan})
17985117404Skan
17986117404Skan(define_expand "movv8hi"
17987117404Skan  [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
17988117404Skan	(match_operand:V8HI 1 "nonimmediate_operand" ""))]
17989117404Skan  "TARGET_SSE2"
17990117404Skan{
17991117404Skan  ix86_expand_vector_move (V8HImode, operands);
17992117404Skan  DONE;
17993117404Skan})
17994117404Skan
17995117404Skan(define_expand "movv16qi"
17996117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
17997117404Skan	(match_operand:V16QI 1 "nonimmediate_operand" ""))]
17998117404Skan  "TARGET_SSE2"
17999117404Skan{
18000117404Skan  ix86_expand_vector_move (V16QImode, operands);
18001117404Skan  DONE;
18002117404Skan})
18003117404Skan
1800490286Sobrien(define_expand "movv4sf"
18005117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18006117404Skan	(match_operand:V4SF 1 "nonimmediate_operand" ""))]
1800790286Sobrien  "TARGET_SSE"
1800890286Sobrien{
1800990286Sobrien  ix86_expand_vector_move (V4SFmode, operands);
1801090286Sobrien  DONE;
1801190286Sobrien})
1801290286Sobrien
1801390286Sobrien(define_expand "movv4si"
18014117404Skan  [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18015117404Skan	(match_operand:V4SI 1 "nonimmediate_operand" ""))]
18016117404Skan  "TARGET_SSE"
1801790286Sobrien{
1801890286Sobrien  ix86_expand_vector_move (V4SImode, operands);
1801990286Sobrien  DONE;
1802090286Sobrien})
1802190286Sobrien
18022117404Skan(define_expand "movv2di"
18023117404Skan  [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18024117404Skan	(match_operand:V2DI 1 "nonimmediate_operand" ""))]
18025117404Skan  "TARGET_SSE"
18026117404Skan{
18027117404Skan  ix86_expand_vector_move (V2DImode, operands);
18028117404Skan  DONE;
18029117404Skan})
18030117404Skan
1803190286Sobrien(define_expand "movv2si"
18032117404Skan  [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18033117404Skan	(match_operand:V2SI 1 "nonimmediate_operand" ""))]
1803490286Sobrien  "TARGET_MMX"
1803590286Sobrien{
1803690286Sobrien  ix86_expand_vector_move (V2SImode, operands);
1803790286Sobrien  DONE;
1803890286Sobrien})
1803990286Sobrien
1804090286Sobrien(define_expand "movv4hi"
18041117404Skan  [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18042117404Skan	(match_operand:V4HI 1 "nonimmediate_operand" ""))]
1804390286Sobrien  "TARGET_MMX"
1804490286Sobrien{
1804590286Sobrien  ix86_expand_vector_move (V4HImode, operands);
1804690286Sobrien  DONE;
1804790286Sobrien})
1804890286Sobrien
1804990286Sobrien(define_expand "movv8qi"
18050117404Skan  [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18051117404Skan	(match_operand:V8QI 1 "nonimmediate_operand" ""))]
1805290286Sobrien  "TARGET_MMX"
1805390286Sobrien{
1805490286Sobrien  ix86_expand_vector_move (V8QImode, operands);
1805590286Sobrien  DONE;
1805690286Sobrien})
1805790286Sobrien
1805890286Sobrien(define_expand "movv2sf"
18059117404Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18060117404Skan	(match_operand:V2SF 1 "nonimmediate_operand" ""))]
1806190286Sobrien   "TARGET_3DNOW"
1806290286Sobrien{
1806390286Sobrien  ix86_expand_vector_move (V2SFmode, operands);
1806490286Sobrien  DONE;
1806590286Sobrien})
1806690286Sobrien
18067117404Skan(define_insn "*pushv2df"
18068117404Skan  [(set (match_operand:V2DF 0 "push_operand" "=<")
18069117404Skan	(match_operand:V2DF 1 "register_operand" "x"))]
18070117404Skan  "TARGET_SSE"
18071117404Skan  "#")
18072117404Skan
18073117404Skan(define_insn "*pushv2di"
18074117404Skan  [(set (match_operand:V2DI 0 "push_operand" "=<")
18075117404Skan	(match_operand:V2DI 1 "register_operand" "x"))]
18076117404Skan  "TARGET_SSE2"
18077117404Skan  "#")
18078117404Skan
18079117404Skan(define_insn "*pushv8hi"
18080117404Skan  [(set (match_operand:V8HI 0 "push_operand" "=<")
18081117404Skan	(match_operand:V8HI 1 "register_operand" "x"))]
18082117404Skan  "TARGET_SSE2"
18083117404Skan  "#")
18084117404Skan
18085117404Skan(define_insn "*pushv16qi"
18086117404Skan  [(set (match_operand:V16QI 0 "push_operand" "=<")
18087117404Skan	(match_operand:V16QI 1 "register_operand" "x"))]
18088117404Skan  "TARGET_SSE2"
18089117404Skan  "#")
18090117404Skan
18091117404Skan(define_insn "*pushv4sf"
18092117404Skan  [(set (match_operand:V4SF 0 "push_operand" "=<")
18093117404Skan	(match_operand:V4SF 1 "register_operand" "x"))]
18094117404Skan  "TARGET_SSE"
18095117404Skan  "#")
18096117404Skan
18097117404Skan(define_insn "*pushv4si"
18098117404Skan  [(set (match_operand:V4SI 0 "push_operand" "=<")
18099117404Skan	(match_operand:V4SI 1 "register_operand" "x"))]
18100117404Skan  "TARGET_SSE2"
18101117404Skan  "#")
18102117404Skan
18103117404Skan(define_insn "*pushv2si"
18104117404Skan  [(set (match_operand:V2SI 0 "push_operand" "=<")
18105117404Skan	(match_operand:V2SI 1 "register_operand" "y"))]
18106117404Skan  "TARGET_MMX"
18107117404Skan  "#")
18108117404Skan
18109117404Skan(define_insn "*pushv4hi"
18110117404Skan  [(set (match_operand:V4HI 0 "push_operand" "=<")
18111117404Skan	(match_operand:V4HI 1 "register_operand" "y"))]
18112117404Skan  "TARGET_MMX"
18113117404Skan  "#")
18114117404Skan
18115117404Skan(define_insn "*pushv8qi"
18116117404Skan  [(set (match_operand:V8QI 0 "push_operand" "=<")
18117117404Skan	(match_operand:V8QI 1 "register_operand" "y"))]
18118117404Skan  "TARGET_MMX"
18119117404Skan  "#")
18120117404Skan
18121117404Skan(define_insn "*pushv2sf"
18122117404Skan  [(set (match_operand:V2SF 0 "push_operand" "=<")
18123117404Skan	(match_operand:V2SF 1 "register_operand" "y"))]
18124117404Skan  "TARGET_3DNOW"
18125117404Skan  "#")
18126117404Skan
18127117404Skan(define_split
18128117404Skan  [(set (match_operand 0 "push_operand" "")
18129117404Skan	(match_operand 1 "register_operand" ""))]
18130117404Skan  "!TARGET_64BIT && reload_completed
18131117404Skan   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18132117404Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
18133117404Skan   (set (match_dup 2) (match_dup 1))]
18134117404Skan  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18135117404Skan				 stack_pointer_rtx);
18136117404Skan   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18137117404Skan
18138117404Skan(define_split
18139117404Skan  [(set (match_operand 0 "push_operand" "")
18140117404Skan	(match_operand 1 "register_operand" ""))]
18141117404Skan  "TARGET_64BIT && reload_completed
18142117404Skan   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18143117404Skan  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
18144117404Skan   (set (match_dup 2) (match_dup 1))]
18145117404Skan  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18146117404Skan				 stack_pointer_rtx);
18147117404Skan   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18148117404Skan
18149117404Skan
1815090286Sobrien(define_insn_and_split "*pushti"
1815190286Sobrien  [(set (match_operand:TI 0 "push_operand" "=<")
1815290286Sobrien	(match_operand:TI 1 "nonmemory_operand" "x"))]
1815390286Sobrien  "TARGET_SSE"
1815490286Sobrien  "#"
1815590286Sobrien  ""
1815690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1815790286Sobrien   (set (mem:TI (reg:SI 7)) (match_dup 1))]
1815890286Sobrien  ""
18159117404Skan  [(set_attr "type" "multi")])
1816090286Sobrien
18161117404Skan(define_insn_and_split "*pushv2df"
18162117404Skan  [(set (match_operand:V2DF 0 "push_operand" "=<")
18163117404Skan	(match_operand:V2DF 1 "nonmemory_operand" "x"))]
18164117404Skan  "TARGET_SSE2"
18165117404Skan  "#"
18166117404Skan  ""
18167117404Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18168117404Skan   (set (mem:V2DF (reg:SI 7)) (match_dup 1))]
18169117404Skan  ""
18170117404Skan  [(set_attr "type" "multi")])
18171117404Skan
18172117404Skan(define_insn_and_split "*pushv2di"
18173117404Skan  [(set (match_operand:V2DI 0 "push_operand" "=<")
18174117404Skan	(match_operand:V2DI 1 "nonmemory_operand" "x"))]
18175117404Skan  "TARGET_SSE2"
18176117404Skan  "#"
18177117404Skan  ""
18178117404Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18179117404Skan   (set (mem:V2DI (reg:SI 7)) (match_dup 1))]
18180117404Skan  ""
18181117404Skan  [(set_attr "type" "multi")])
18182117404Skan
18183117404Skan(define_insn_and_split "*pushv8hi"
18184117404Skan  [(set (match_operand:V8HI 0 "push_operand" "=<")
18185117404Skan	(match_operand:V8HI 1 "nonmemory_operand" "x"))]
18186117404Skan  "TARGET_SSE2"
18187117404Skan  "#"
18188117404Skan  ""
18189117404Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18190117404Skan   (set (mem:V8HI (reg:SI 7)) (match_dup 1))]
18191117404Skan  ""
18192117404Skan  [(set_attr "type" "multi")])
18193117404Skan
18194117404Skan(define_insn_and_split "*pushv16qi"
18195117404Skan  [(set (match_operand:V16QI 0 "push_operand" "=<")
18196117404Skan	(match_operand:V16QI 1 "nonmemory_operand" "x"))]
18197117404Skan  "TARGET_SSE2"
18198117404Skan  "#"
18199117404Skan  ""
18200117404Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
18201117404Skan   (set (mem:V16QI (reg:SI 7)) (match_dup 1))]
18202117404Skan  ""
18203117404Skan  [(set_attr "type" "multi")])
18204117404Skan
1820590286Sobrien(define_insn_and_split "*pushv4sf"
1820690286Sobrien  [(set (match_operand:V4SF 0 "push_operand" "=<")
1820790286Sobrien	(match_operand:V4SF 1 "nonmemory_operand" "x"))]
1820890286Sobrien  "TARGET_SSE"
1820990286Sobrien  "#"
1821090286Sobrien  ""
1821190286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1821290286Sobrien   (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
1821390286Sobrien  ""
18214117404Skan  [(set_attr "type" "multi")])
1821590286Sobrien
1821690286Sobrien(define_insn_and_split "*pushv4si"
1821790286Sobrien  [(set (match_operand:V4SI 0 "push_operand" "=<")
1821890286Sobrien	(match_operand:V4SI 1 "nonmemory_operand" "x"))]
1821990286Sobrien  "TARGET_SSE"
1822090286Sobrien  "#"
1822190286Sobrien  ""
1822290286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1822390286Sobrien   (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
1822490286Sobrien  ""
18225117404Skan  [(set_attr "type" "multi")])
1822690286Sobrien
1822790286Sobrien(define_insn_and_split "*pushv2si"
1822890286Sobrien  [(set (match_operand:V2SI 0 "push_operand" "=<")
1822990286Sobrien	(match_operand:V2SI 1 "nonmemory_operand" "y"))]
1823090286Sobrien  "TARGET_MMX"
1823190286Sobrien  "#"
1823290286Sobrien  ""
1823390286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1823490286Sobrien   (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
1823590286Sobrien  ""
1823690286Sobrien  [(set_attr "type" "mmx")])
1823790286Sobrien
1823890286Sobrien(define_insn_and_split "*pushv4hi"
1823990286Sobrien  [(set (match_operand:V4HI 0 "push_operand" "=<")
1824090286Sobrien	(match_operand:V4HI 1 "nonmemory_operand" "y"))]
1824190286Sobrien  "TARGET_MMX"
1824290286Sobrien  "#"
1824390286Sobrien  ""
1824490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1824590286Sobrien   (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
1824690286Sobrien  ""
1824790286Sobrien  [(set_attr "type" "mmx")])
1824890286Sobrien
1824990286Sobrien(define_insn_and_split "*pushv8qi"
1825090286Sobrien  [(set (match_operand:V8QI 0 "push_operand" "=<")
1825190286Sobrien	(match_operand:V8QI 1 "nonmemory_operand" "y"))]
1825290286Sobrien  "TARGET_MMX"
1825390286Sobrien  "#"
1825490286Sobrien  ""
1825590286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1825690286Sobrien   (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
1825790286Sobrien  ""
1825890286Sobrien  [(set_attr "type" "mmx")])
1825990286Sobrien
1826090286Sobrien(define_insn_and_split "*pushv2sf"
1826190286Sobrien  [(set (match_operand:V2SF 0 "push_operand" "=<")
1826290286Sobrien	(match_operand:V2SF 1 "nonmemory_operand" "y"))]
1826390286Sobrien  "TARGET_3DNOW"
1826490286Sobrien  "#"
1826590286Sobrien  ""
1826690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1826790286Sobrien   (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
1826890286Sobrien  ""
1826990286Sobrien  [(set_attr "type" "mmx")])
1827090286Sobrien
1827190286Sobrien(define_insn "movti_internal"
1827290286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18273117404Skan	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
18274117404Skan  "TARGET_SSE && !TARGET_64BIT
18275117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1827690286Sobrien  "@
1827790286Sobrien   xorps\t%0, %0
1827890286Sobrien   movaps\t{%1, %0|%0, %1}
1827990286Sobrien   movaps\t{%1, %0|%0, %1}"
18280117404Skan  [(set_attr "type" "ssemov,ssemov,ssemov")
18281117404Skan   (set_attr "mode" "V4SF")])
1828290286Sobrien
1828390286Sobrien(define_insn "*movti_rex64"
1828490286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
18285117404Skan	(match_operand:TI 1 "general_operand" "riFo,riF,C,x,m"))]
1828690286Sobrien  "TARGET_64BIT
1828790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1828890286Sobrien  "@
1828990286Sobrien   #
1829090286Sobrien   #
1829190286Sobrien   xorps\t%0, %0
1829290286Sobrien   movaps\\t{%1, %0|%0, %1}
1829390286Sobrien   movaps\\t{%1, %0|%0, %1}"
18294117404Skan  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18295117404Skan   (set_attr "mode" "V4SF")])
1829690286Sobrien
1829790286Sobrien(define_split
1829890286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1829990286Sobrien        (match_operand:TI 1 "general_operand" ""))]
1830090286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
1830190286Sobrien   && !SSE_REG_P (operands[1])"
1830290286Sobrien  [(const_int 0)]
1830390286Sobrien  "ix86_split_long_move (operands); DONE;")
1830490286Sobrien
1830590286Sobrien;; These two patterns are useful for specifying exactly whether to use
1830690286Sobrien;; movaps or movups
18307117404Skan(define_expand "sse_movaps"
18308117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18309117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
18310117404Skan		     UNSPEC_MOVA))]
1831190286Sobrien  "TARGET_SSE"
18312117404Skan{
18313117404Skan  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
18314117404Skan    {
18315117404Skan      rtx tmp = gen_reg_rtx (V4SFmode);
18316117404Skan      emit_insn (gen_sse_movaps (tmp, operands[1]));
18317117404Skan      emit_move_insn (operands[0], tmp);
18318117404Skan      DONE;
18319117404Skan    }
18320117404Skan})
1832190286Sobrien
18322117404Skan(define_insn "*sse_movaps_1"
1832390286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18324117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
18325117404Skan		     UNSPEC_MOVA))]
18326117404Skan  "TARGET_SSE
18327117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18328117404Skan  "movaps\t{%1, %0|%0, %1}"
18329117404Skan  [(set_attr "type" "ssemov,ssemov")
18330117404Skan   (set_attr "mode" "V4SF")])
18331117404Skan
18332117404Skan(define_expand "sse_movups"
18333117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18334117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
18335117404Skan		     UNSPEC_MOVU))]
1833690286Sobrien  "TARGET_SSE"
18337117404Skan{
18338117404Skan  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
18339117404Skan    {
18340117404Skan      rtx tmp = gen_reg_rtx (V4SFmode);
18341117404Skan      emit_insn (gen_sse_movups (tmp, operands[1]));
18342117404Skan      emit_move_insn (operands[0], tmp);
18343117404Skan      DONE;
18344117404Skan    }
18345117404Skan})
1834690286Sobrien
18347117404Skan(define_insn "*sse_movups_1"
18348117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18349117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
18350117404Skan		     UNSPEC_MOVU))]
18351117404Skan  "TARGET_SSE
18352117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18353117404Skan  "movups\t{%1, %0|%0, %1}"
18354117404Skan  [(set_attr "type" "ssecvt,ssecvt")
18355117404Skan   (set_attr "mode" "V4SF")])
1835690286Sobrien
1835790286Sobrien;; SSE Strange Moves.
1835890286Sobrien
1835990286Sobrien(define_insn "sse_movmskps"
1836090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
18361117404Skan	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
18362117404Skan		   UNSPEC_MOVMSK))]
1836390286Sobrien  "TARGET_SSE"
1836490286Sobrien  "movmskps\t{%1, %0|%0, %1}"
18365117404Skan  [(set_attr "type" "ssecvt")
18366117404Skan   (set_attr "mode" "V4SF")])
1836790286Sobrien
1836890286Sobrien(define_insn "mmx_pmovmskb"
1836990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
18370117404Skan	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
18371117404Skan		   UNSPEC_MOVMSK))]
1837290286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1837390286Sobrien  "pmovmskb\t{%1, %0|%0, %1}"
18374117404Skan  [(set_attr "type" "ssecvt")
18375117404Skan   (set_attr "mode" "V4SF")])
1837690286Sobrien
18377117404Skan
1837890286Sobrien(define_insn "mmx_maskmovq"
1837990286Sobrien  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1838090286Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18381117404Skan		      (match_operand:V8QI 2 "register_operand" "y")]
18382117404Skan		     UNSPEC_MASKMOV))]
1838396294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1838490286Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1838590286Sobrien  "maskmovq\t{%2, %1|%1, %2}"
18386117404Skan  [(set_attr "type" "mmxcvt")
18387117404Skan   (set_attr "mode" "DI")])
1838890286Sobrien
1838996294Sobrien(define_insn "mmx_maskmovq_rex"
1839096294Sobrien  [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1839196294Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18392117404Skan		      (match_operand:V8QI 2 "register_operand" "y")]
18393117404Skan		     UNSPEC_MASKMOV))]
1839496294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1839596294Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1839696294Sobrien  "maskmovq\t{%2, %1|%1, %2}"
18397117404Skan  [(set_attr "type" "mmxcvt")
18398117404Skan   (set_attr "mode" "DI")])
1839996294Sobrien
1840090286Sobrien(define_insn "sse_movntv4sf"
1840190286Sobrien  [(set (match_operand:V4SF 0 "memory_operand" "=m")
18402117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
18403117404Skan		     UNSPEC_MOVNT))]
1840490286Sobrien  "TARGET_SSE"
1840590286Sobrien  "movntps\t{%1, %0|%0, %1}"
18406117404Skan  [(set_attr "type" "ssemov")
18407117404Skan   (set_attr "mode" "V4SF")])
1840890286Sobrien
1840990286Sobrien(define_insn "sse_movntdi"
1841090286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
18411117404Skan	(unspec:DI [(match_operand:DI 1 "register_operand" "y")]
18412117404Skan		   UNSPEC_MOVNT))]
1841390286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1841490286Sobrien  "movntq\t{%1, %0|%0, %1}"
18415117404Skan  [(set_attr "type" "mmxmov")
18416117404Skan   (set_attr "mode" "DI")])
1841790286Sobrien
1841890286Sobrien(define_insn "sse_movhlps"
1841990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1842090286Sobrien	(vec_merge:V4SF
1842190286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1842290286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1842390286Sobrien			  (parallel [(const_int 2)
1842490286Sobrien				     (const_int 3)
1842590286Sobrien				     (const_int 0)
1842690286Sobrien				     (const_int 1)]))
1842790286Sobrien	 (const_int 3)))]
1842890286Sobrien  "TARGET_SSE"
1842990286Sobrien  "movhlps\t{%2, %0|%0, %2}"
18430117404Skan  [(set_attr "type" "ssecvt")
18431117404Skan   (set_attr "mode" "V4SF")])
1843290286Sobrien
1843390286Sobrien(define_insn "sse_movlhps"
1843490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1843590286Sobrien	(vec_merge:V4SF
1843690286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1843790286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1843890286Sobrien			  (parallel [(const_int 2)
1843990286Sobrien				     (const_int 3)
1844090286Sobrien				     (const_int 0)
1844190286Sobrien				     (const_int 1)]))
1844290286Sobrien	 (const_int 12)))]
1844390286Sobrien  "TARGET_SSE"
1844490286Sobrien  "movlhps\t{%2, %0|%0, %2}"
18445117404Skan  [(set_attr "type" "ssecvt")
18446117404Skan   (set_attr "mode" "V4SF")])
1844790286Sobrien
1844890286Sobrien(define_insn "sse_movhps"
1844990286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1845090286Sobrien	(vec_merge:V4SF
1845190286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1845290286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1845390286Sobrien	 (const_int 12)))]
1845490286Sobrien  "TARGET_SSE
1845590286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1845690286Sobrien  "movhps\t{%2, %0|%0, %2}"
18457117404Skan  [(set_attr "type" "ssecvt")
18458117404Skan   (set_attr "mode" "V4SF")])
1845990286Sobrien
1846090286Sobrien(define_insn "sse_movlps"
1846190286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1846290286Sobrien	(vec_merge:V4SF
1846390286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1846490286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1846590286Sobrien	 (const_int 3)))]
1846690286Sobrien  "TARGET_SSE
1846790286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1846890286Sobrien  "movlps\t{%2, %0|%0, %2}"
18469117404Skan  [(set_attr "type" "ssecvt")
18470117404Skan   (set_attr "mode" "V4SF")])
1847190286Sobrien
18472117404Skan(define_expand "sse_loadss"
18473117404Skan  [(match_operand:V4SF 0 "register_operand" "")
18474117404Skan   (match_operand:SF 1 "memory_operand" "")]
18475117404Skan  "TARGET_SSE"
18476117404Skan{
18477117404Skan  emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
18478117404Skan			       CONST0_RTX (V4SFmode)));
18479117404Skan  DONE;
18480117404Skan})
18481117404Skan
18482117404Skan(define_insn "sse_loadss_1"
1848390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1848490286Sobrien	(vec_merge:V4SF
18485117404Skan	 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
18486117404Skan	 (match_operand:V4SF 2 "const0_operand" "X")
1848790286Sobrien	 (const_int 1)))]
1848890286Sobrien  "TARGET_SSE"
1848990286Sobrien  "movss\t{%1, %0|%0, %1}"
18490117404Skan  [(set_attr "type" "ssemov")
18491117404Skan   (set_attr "mode" "SF")])
1849290286Sobrien
1849390286Sobrien(define_insn "sse_movss"
1849490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1849590286Sobrien	(vec_merge:V4SF
1849690286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1849790286Sobrien	 (match_operand:V4SF 2 "register_operand" "x")
1849890286Sobrien	 (const_int 1)))]
1849990286Sobrien  "TARGET_SSE"
1850090286Sobrien  "movss\t{%2, %0|%0, %2}"
18501117404Skan  [(set_attr "type" "ssemov")
18502117404Skan   (set_attr "mode" "SF")])
1850390286Sobrien
1850490286Sobrien(define_insn "sse_storess"
1850590286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
1850690286Sobrien	(vec_select:SF
1850790286Sobrien	 (match_operand:V4SF 1 "register_operand" "x")
1850890286Sobrien	 (parallel [(const_int 0)])))]
1850990286Sobrien  "TARGET_SSE"
1851090286Sobrien  "movss\t{%1, %0|%0, %1}"
18511117404Skan  [(set_attr "type" "ssemov")
18512117404Skan   (set_attr "mode" "SF")])
1851390286Sobrien
1851490286Sobrien(define_insn "sse_shufps"
1851590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1851690286Sobrien        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
1851790286Sobrien		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")
18518117404Skan		      (match_operand:SI 3 "immediate_operand" "i")]
18519117404Skan		     UNSPEC_SHUFFLE))]
1852090286Sobrien  "TARGET_SSE"
1852190286Sobrien  ;; @@@ check operand order for intel/nonintel syntax
1852290286Sobrien  "shufps\t{%3, %2, %0|%0, %2, %3}"
18523117404Skan  [(set_attr "type" "ssecvt")
18524117404Skan   (set_attr "mode" "V4SF")])
1852590286Sobrien
1852690286Sobrien
1852790286Sobrien;; SSE arithmetic
1852890286Sobrien
1852990286Sobrien(define_insn "addv4sf3"
1853090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1853190286Sobrien        (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1853290286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1853390286Sobrien  "TARGET_SSE"
1853490286Sobrien  "addps\t{%2, %0|%0, %2}"
18535117404Skan  [(set_attr "type" "sseadd")
18536117404Skan   (set_attr "mode" "V4SF")])
1853790286Sobrien
1853890286Sobrien(define_insn "vmaddv4sf3"
1853990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1854090286Sobrien	(vec_merge:V4SF
1854190286Sobrien	 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1854290286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1854390286Sobrien	 (match_dup 1)
1854490286Sobrien	 (const_int 1)))]
1854590286Sobrien  "TARGET_SSE"
1854690286Sobrien  "addss\t{%2, %0|%0, %2}"
18547117404Skan  [(set_attr "type" "sseadd")
18548117404Skan   (set_attr "mode" "SF")])
1854990286Sobrien
1855090286Sobrien(define_insn "subv4sf3"
1855190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1855290286Sobrien        (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1855390286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1855490286Sobrien  "TARGET_SSE"
1855590286Sobrien  "subps\t{%2, %0|%0, %2}"
18556117404Skan  [(set_attr "type" "sseadd")
18557117404Skan   (set_attr "mode" "V4SF")])
1855890286Sobrien
1855990286Sobrien(define_insn "vmsubv4sf3"
1856090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1856190286Sobrien	(vec_merge:V4SF
1856290286Sobrien	 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1856390286Sobrien		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1856490286Sobrien	 (match_dup 1)
1856590286Sobrien	 (const_int 1)))]
1856690286Sobrien  "TARGET_SSE"
1856790286Sobrien  "subss\t{%2, %0|%0, %2}"
18568117404Skan  [(set_attr "type" "sseadd")
18569117404Skan   (set_attr "mode" "SF")])
1857090286Sobrien
1857190286Sobrien(define_insn "mulv4sf3"
1857290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1857390286Sobrien        (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1857490286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1857590286Sobrien  "TARGET_SSE"
1857690286Sobrien  "mulps\t{%2, %0|%0, %2}"
18577117404Skan  [(set_attr "type" "ssemul")
18578117404Skan   (set_attr "mode" "V4SF")])
1857990286Sobrien
1858090286Sobrien(define_insn "vmmulv4sf3"
1858190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1858290286Sobrien	(vec_merge:V4SF
1858390286Sobrien	 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1858490286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1858590286Sobrien	 (match_dup 1)
1858690286Sobrien	 (const_int 1)))]
1858790286Sobrien  "TARGET_SSE"
1858890286Sobrien  "mulss\t{%2, %0|%0, %2}"
18589117404Skan  [(set_attr "type" "ssemul")
18590117404Skan   (set_attr "mode" "SF")])
1859190286Sobrien
1859290286Sobrien(define_insn "divv4sf3"
1859390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1859490286Sobrien        (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1859590286Sobrien	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1859690286Sobrien  "TARGET_SSE"
1859790286Sobrien  "divps\t{%2, %0|%0, %2}"
18598117404Skan  [(set_attr "type" "ssediv")
18599117404Skan   (set_attr "mode" "V4SF")])
1860090286Sobrien
1860190286Sobrien(define_insn "vmdivv4sf3"
1860290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1860390286Sobrien	(vec_merge:V4SF
1860490286Sobrien	 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1860590286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1860690286Sobrien	 (match_dup 1)
1860790286Sobrien	 (const_int 1)))]
1860890286Sobrien  "TARGET_SSE"
1860990286Sobrien  "divss\t{%2, %0|%0, %2}"
18610117404Skan  [(set_attr "type" "ssediv")
18611117404Skan   (set_attr "mode" "SF")])
1861290286Sobrien
1861390286Sobrien
1861490286Sobrien;; SSE square root/reciprocal
1861590286Sobrien
1861690286Sobrien(define_insn "rcpv4sf2"
1861790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1861890286Sobrien        (unspec:V4SF
18619117404Skan	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
1862090286Sobrien  "TARGET_SSE"
1862190286Sobrien  "rcpps\t{%1, %0|%0, %1}"
18622117404Skan  [(set_attr "type" "sse")
18623117404Skan   (set_attr "mode" "V4SF")])
1862490286Sobrien
1862590286Sobrien(define_insn "vmrcpv4sf2"
1862690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1862790286Sobrien	(vec_merge:V4SF
18628117404Skan	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
18629117404Skan		      UNSPEC_RCP)
1863090286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1863190286Sobrien	 (const_int 1)))]
1863290286Sobrien  "TARGET_SSE"
1863390286Sobrien  "rcpss\t{%1, %0|%0, %1}"
18634117404Skan  [(set_attr "type" "sse")
18635117404Skan   (set_attr "mode" "SF")])
1863690286Sobrien
1863790286Sobrien(define_insn "rsqrtv4sf2"
1863890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1863990286Sobrien        (unspec:V4SF
18640117404Skan	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
1864190286Sobrien  "TARGET_SSE"
1864290286Sobrien  "rsqrtps\t{%1, %0|%0, %1}"
18643117404Skan  [(set_attr "type" "sse")
18644117404Skan   (set_attr "mode" "V4SF")])
1864590286Sobrien
1864690286Sobrien(define_insn "vmrsqrtv4sf2"
1864790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1864890286Sobrien	(vec_merge:V4SF
18649117404Skan	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
18650117404Skan		      UNSPEC_RSQRT)
1865190286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1865290286Sobrien	 (const_int 1)))]
1865390286Sobrien  "TARGET_SSE"
1865490286Sobrien  "rsqrtss\t{%1, %0|%0, %1}"
18655117404Skan  [(set_attr "type" "sse")
18656117404Skan   (set_attr "mode" "SF")])
1865790286Sobrien
1865890286Sobrien(define_insn "sqrtv4sf2"
1865990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1866090286Sobrien        (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1866190286Sobrien  "TARGET_SSE"
1866290286Sobrien  "sqrtps\t{%1, %0|%0, %1}"
18663117404Skan  [(set_attr "type" "sse")
18664117404Skan   (set_attr "mode" "V4SF")])
1866590286Sobrien
1866690286Sobrien(define_insn "vmsqrtv4sf2"
1866790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1866890286Sobrien	(vec_merge:V4SF
1866990286Sobrien	 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1867090286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1867190286Sobrien	 (const_int 1)))]
1867290286Sobrien  "TARGET_SSE"
1867390286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
18674117404Skan  [(set_attr "type" "sse")
18675117404Skan   (set_attr "mode" "SF")])
1867690286Sobrien
1867790286Sobrien;; SSE logical operations.
1867890286Sobrien
18679117404Skan;; SSE defines logical operations on floating point values.  This brings
18680117404Skan;; interesting challenge to RTL representation where logicals are only valid
18681117404Skan;; on integral types.  We deal with this by representing the floating point
18682117404Skan;; logical as logical on arguments casted to TImode as this is what hardware
18683117404Skan;; really does.  Unfortunately hardware requires the type information to be
18684117404Skan;; present and thus we must avoid subregs from being simplified and elliminated
18685117404Skan;; in later compilation phases.
18686117404Skan;;
18687117404Skan;; We have following variants from each instruction:
18688117404Skan;; sse_andsf3 - the operation taking V4SF vector operands
18689117404Skan;;              and doing TImode cast on them
18690117404Skan;; *sse_andsf3_memory - the operation taking one memory operand casted to
18691117404Skan;;                      TImode, since backend insist on elliminating casts
18692117404Skan;;                      on memory operands
18693117404Skan;; sse_andti3_sf_1 - the operation taking SF scalar operands.
18694117404Skan;;                   We can not accept memory operand here as instruction reads
18695117404Skan;;		     whole scalar.  This is generated only post reload by GCC
18696117404Skan;;		     scalar float operations that expands to logicals (fabs)
18697117404Skan;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
18698117404Skan;;		     memory operand.  Eventually combine can be able
18699117404Skan;;		     to synthetize these using splitter.
18700117404Skan;; sse2_anddf3, *sse2_anddf3_memory
18701117404Skan;;              
18702117404Skan;; 
1870390286Sobrien;; These are not called andti3 etc. because we really really don't want
1870490286Sobrien;; the compiler to widen DImode ands to TImode ands and then try to move
1870590286Sobrien;; into DImode subregs of SSE registers, and them together, and move out
1870690286Sobrien;; of DImode subregs again!
18707117404Skan;; SSE1 single precision floating point logical operation
18708117404Skan(define_expand "sse_andv4sf3"
18709117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
18710117404Skan        (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
18711117404Skan		(subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
18712117404Skan  "TARGET_SSE"
18713117404Skan  "")
1871490286Sobrien
18715117404Skan(define_insn "*sse_andv4sf3"
18716117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
18717117404Skan        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18718117404Skan		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18719117404Skan  "TARGET_SSE
18720117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18721117404Skan  "andps\t{%2, %0|%0, %2}"
18722117404Skan  [(set_attr "type" "sselog")
18723117404Skan   (set_attr "mode" "V4SF")])
1872490286Sobrien
18725117404Skan(define_insn "*sse_andsf3"
18726117404Skan  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18727117404Skan        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18728117404Skan		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18729117404Skan  "TARGET_SSE
18730117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18731117404Skan  "andps\t{%2, %0|%0, %2}"
18732117404Skan  [(set_attr "type" "sselog")
18733117404Skan   (set_attr "mode" "V4SF")])
1873490286Sobrien
18735117404Skan(define_expand "sse_nandv4sf3"
18736117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
18737117404Skan        (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
18738117404Skan	        (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
18739117404Skan  "TARGET_SSE"
18740117404Skan  "")
18741117404Skan
18742117404Skan(define_insn "*sse_nandv4sf3"
18743117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
18744117404Skan        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18745117404Skan	        (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18746117404Skan  "TARGET_SSE"
18747117404Skan  "andnps\t{%2, %0|%0, %2}"
18748117404Skan  [(set_attr "type" "sselog")
18749117404Skan   (set_attr "mode" "V4SF")])
18750117404Skan
18751117404Skan(define_insn "*sse_nandsf3"
1875290286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18753117404Skan        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18754117404Skan	        (match_operand:TI 2 "nonimmediate_operand" "xm")))]
1875590286Sobrien  "TARGET_SSE"
18756117404Skan  "andnps\t{%2, %0|%0, %2}"
18757117404Skan  [(set_attr "type" "sselog")
18758117404Skan   (set_attr "mode" "V4SF")])
1875990286Sobrien
18760117404Skan(define_expand "sse_iorv4sf3"
18761117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
18762117404Skan        (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
18763117404Skan		(subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
18764117404Skan  "TARGET_SSE"
18765117404Skan  "")
18766117404Skan
18767117404Skan(define_insn "*sse_iorv4sf3"
18768117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
18769117404Skan        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18770117404Skan		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18771117404Skan  "TARGET_SSE
18772117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18773117404Skan  "orps\t{%2, %0|%0, %2}"
18774117404Skan  [(set_attr "type" "sselog")
18775117404Skan   (set_attr "mode" "V4SF")])
18776117404Skan
18777117404Skan(define_insn "*sse_iorsf3"
1877890286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18779117404Skan        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1878090286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18781117404Skan  "TARGET_SSE
18782117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18783117404Skan  "orps\t{%2, %0|%0, %2}"
18784117404Skan  [(set_attr "type" "sselog")
18785117404Skan   (set_attr "mode" "V4SF")])
1878690286Sobrien
18787117404Skan(define_expand "sse_xorv4sf3"
18788117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
18789117404Skan        (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
18790117404Skan		(subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
18791117404Skan  "TARGET_SSE
18792117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18793117404Skan  "")
18794117404Skan
18795117404Skan(define_insn "*sse_xorv4sf3"
18796117404Skan  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
18797117404Skan        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1879890286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18799117404Skan  "TARGET_SSE
1880096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18801117404Skan  "xorps\t{%2, %0|%0, %2}"
18802117404Skan  [(set_attr "type" "sselog")
18803117404Skan   (set_attr "mode" "V4SF")])
1880490286Sobrien
18805117404Skan(define_insn "*sse_xorsf3"
18806117404Skan  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18807117404Skan        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1880890286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18809117404Skan  "TARGET_SSE
1881096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18811117404Skan  "xorps\t{%2, %0|%0, %2}"
18812117404Skan  [(set_attr "type" "sselog")
18813117404Skan   (set_attr "mode" "V4SF")])
1881490286Sobrien
18815117404Skan;; SSE2 double precision floating point logical operation
18816117404Skan
18817117404Skan(define_expand "sse2_andv2df3"
18818117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
18819117404Skan        (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
18820117404Skan	        (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
1882190286Sobrien  "TARGET_SSE2"
18822117404Skan  "")
1882390286Sobrien
18824117404Skan(define_insn "*sse2_andv2df3"
18825117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
18826117404Skan        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1882790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18828117404Skan  "TARGET_SSE2
18829117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18830117404Skan  "andpd\t{%2, %0|%0, %2}"
18831117404Skan  [(set_attr "type" "sselog")
18832117404Skan   (set_attr "mode" "V2DF")])
1883390286Sobrien
18834117404Skan(define_insn "*sse2_andv2df3"
18835117404Skan  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
18836117404Skan        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1883790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18838117404Skan  "TARGET_SSE2
18839117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18840117404Skan  "andpd\t{%2, %0|%0, %2}"
18841117404Skan  [(set_attr "type" "sselog")
18842117404Skan   (set_attr "mode" "V2DF")])
1884390286Sobrien
18844117404Skan(define_expand "sse2_nandv2df3"
18845117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
18846117404Skan        (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
18847117404Skan	        (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
1884890286Sobrien  "TARGET_SSE2"
18849117404Skan  "")
1885090286Sobrien
18851117404Skan(define_insn "*sse2_nandv2df3"
18852117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
18853117404Skan        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18854117404Skan	        (match_operand:TI 2 "nonimmediate_operand" "xm")))]
1885590286Sobrien  "TARGET_SSE2"
18856117404Skan  "andnpd\t{%2, %0|%0, %2}"
18857117404Skan  [(set_attr "type" "sselog")
18858117404Skan   (set_attr "mode" "V2DF")])
1885990286Sobrien
18860117404Skan(define_insn "*sse_nandti3_df"
1886190286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18862117404Skan        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1886390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1886490286Sobrien  "TARGET_SSE2"
18865117404Skan  "andnpd\t{%2, %0|%0, %2}"
18866117404Skan  [(set_attr "type" "sselog")
18867117404Skan   (set_attr "mode" "V2DF")])
1886890286Sobrien
18869117404Skan(define_expand "sse2_iorv2df3"
18870117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
18871117404Skan        (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
18872117404Skan		(subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
18873117404Skan  "TARGET_SSE2"
18874117404Skan  "")
1887590286Sobrien
18876117404Skan(define_insn "*sse2_iorv2df3"
18877117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
1887896294Sobrien        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1887990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18880117404Skan  "TARGET_SSE2
1888196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18882117404Skan  "orpd\t{%2, %0|%0, %2}"
18883117404Skan  [(set_attr "type" "sselog")
18884117404Skan   (set_attr "mode" "V2DF")])
1888590286Sobrien
18886117404Skan(define_insn "*sse2_iordf3"
18887117404Skan  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
1888896294Sobrien        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1888990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1889096294Sobrien  "TARGET_SSE2
1889196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18892117404Skan  "orpd\t{%2, %0|%0, %2}"
18893117404Skan  [(set_attr "type" "sselog")
18894117404Skan   (set_attr "mode" "V2DF")])
1889590286Sobrien
18896117404Skan(define_expand "sse2_xorv2df3"
18897117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
18898117404Skan        (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
18899117404Skan		(subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
1890090286Sobrien  "TARGET_SSE2"
18901117404Skan  "")
18902117404Skan
18903117404Skan(define_insn "*sse2_xorv2df3"
18904117404Skan  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
18905117404Skan        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18906117404Skan		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18907117404Skan  "TARGET_SSE2
18908117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1890990286Sobrien  "xorpd\t{%2, %0|%0, %2}"
18910117404Skan  [(set_attr "type" "sselog")
18911117404Skan   (set_attr "mode" "V2DF")])
1891290286Sobrien
18913117404Skan(define_insn "*sse2_xordf3"
18914117404Skan  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
18915117404Skan        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18916117404Skan		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18917117404Skan  "TARGET_SSE2
18918117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1891990286Sobrien  "xorpd\t{%2, %0|%0, %2}"
18920117404Skan  [(set_attr "type" "sselog")
18921117404Skan   (set_attr "mode" "V2DF")])
1892290286Sobrien
18923117404Skan;; SSE2 integral logicals.  These patterns must always come after floating
18924117404Skan;; point ones since we don't want compiler to use integer opcodes on floating
18925117404Skan;; point SSE values to avoid matching of subregs in the match_operand.
18926117404Skan(define_insn "*sse2_andti3"
18927117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
18928117404Skan        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18929117404Skan		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18930117404Skan  "TARGET_SSE2
18931117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18932117404Skan  "pand\t{%2, %0|%0, %2}"
18933117404Skan  [(set_attr "type" "sselog")
18934117404Skan   (set_attr "mode" "TI")])
1893590286Sobrien
18936117404Skan(define_insn "sse2_andv2di3"
18937117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
18938117404Skan        (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18939117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18940117404Skan  "TARGET_SSE2
18941117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18942117404Skan  "pand\t{%2, %0|%0, %2}"
18943117404Skan  [(set_attr "type" "sselog")
18944117404Skan   (set_attr "mode" "TI")])
18945117404Skan
18946117404Skan(define_insn "*sse2_nandti3"
18947117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
18948117404Skan        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1894990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18950117404Skan  "TARGET_SSE2"
18951117404Skan  "pandn\t{%2, %0|%0, %2}"
18952117404Skan  [(set_attr "type" "sselog")
18953117404Skan   (set_attr "mode" "TI")])
1895490286Sobrien
18955117404Skan(define_insn "sse2_nandv2di3"
18956117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
18957117404Skan        (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "0"))
18958117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18959117404Skan  "TARGET_SSE2
18960117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18961117404Skan  "pandn\t{%2, %0|%0, %2}"
18962117404Skan  [(set_attr "type" "sselog")
18963117404Skan   (set_attr "mode" "TI")])
18964117404Skan
18965117404Skan(define_insn "*sse2_iorti3"
1896690286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
18967117404Skan        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1896890286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18969117404Skan  "TARGET_SSE2
1897096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18971117404Skan  "por\t{%2, %0|%0, %2}"
18972117404Skan  [(set_attr "type" "sselog")
18973117404Skan   (set_attr "mode" "TI")])
1897490286Sobrien
18975117404Skan(define_insn "sse2_iorv2di3"
18976117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
18977117404Skan        (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18978117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18979117404Skan  "TARGET_SSE2
18980117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18981117404Skan  "por\t{%2, %0|%0, %2}"
18982117404Skan  [(set_attr "type" "sselog")
18983117404Skan   (set_attr "mode" "TI")])
18984117404Skan
18985117404Skan(define_insn "*sse2_xorti3"
1898690286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1898796294Sobrien        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1898890286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1898996294Sobrien  "TARGET_SSE2
1899096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1899190286Sobrien  "pxor\t{%2, %0|%0, %2}"
18992117404Skan  [(set_attr "type" "sselog")
18993117404Skan   (set_attr "mode" "TI")])
1899490286Sobrien
18995117404Skan(define_insn "sse2_xorv2di3"
18996117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
18997117404Skan        (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18998117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18999117404Skan  "TARGET_SSE2
19000117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19001117404Skan  "pxor\t{%2, %0|%0, %2}"
19002117404Skan  [(set_attr "type" "sselog")
19003117404Skan   (set_attr "mode" "TI")])
19004117404Skan
1900590286Sobrien;; Use xor, but don't show input operands so they aren't live before
1900690286Sobrien;; this insn.
1900790286Sobrien(define_insn "sse_clrv4sf"
1900890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
19009117404Skan        (unspec:V4SF [(const_int 0)] UNSPEC_NOP))]
1901090286Sobrien  "TARGET_SSE"
1901190286Sobrien  "xorps\t{%0, %0|%0, %0}"
19012117404Skan  [(set_attr "type" "sselog")
19013117404Skan   (set_attr "memory" "none")
19014117404Skan   (set_attr "mode" "V4SF")])
1901590286Sobrien
19016117404Skan;; Use xor, but don't show input operands so they aren't live before
19017117404Skan;; this insn.
19018117404Skan(define_insn "sse_clrv2df"
19019117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
19020117404Skan        (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19021117404Skan  "TARGET_SSE2"
19022117404Skan  "xorpd\t{%0, %0|%0, %0}"
19023117404Skan  [(set_attr "type" "sselog")
19024117404Skan   (set_attr "memory" "none")
19025117404Skan   (set_attr "mode" "V4SF")])
19026117404Skan
1902790286Sobrien;; SSE mask-generating compares
1902890286Sobrien
1902990286Sobrien(define_insn "maskcmpv4sf3"
1903090286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1903190286Sobrien        (match_operator:V4SI 3 "sse_comparison_operator"
1903290286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1903390286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))]
1903490286Sobrien  "TARGET_SSE"
1903590286Sobrien  "cmp%D3ps\t{%2, %0|%0, %2}"
19036117404Skan  [(set_attr "type" "ssecmp")
19037117404Skan   (set_attr "mode" "V4SF")])
1903890286Sobrien
1903990286Sobrien(define_insn "maskncmpv4sf3"
1904090286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1904190286Sobrien        (not:V4SI
1904290286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1904390286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1904490286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])))]
1904590286Sobrien  "TARGET_SSE"
1904690286Sobrien{
1904790286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1904890286Sobrien    return "cmpordps\t{%2, %0|%0, %2}";
1904990286Sobrien  else
1905090286Sobrien    return "cmpn%D3ps\t{%2, %0|%0, %2}";
1905190286Sobrien}
19052117404Skan  [(set_attr "type" "ssecmp")
19053117404Skan   (set_attr "mode" "V4SF")])
1905490286Sobrien
1905590286Sobrien(define_insn "vmmaskcmpv4sf3"
1905690286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1905790286Sobrien	(vec_merge:V4SI
1905890286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1905990286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1906090286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])
19061117404Skan	 (subreg:V4SI (match_dup 1) 0)
1906290286Sobrien	 (const_int 1)))]
1906390286Sobrien  "TARGET_SSE"
1906490286Sobrien  "cmp%D3ss\t{%2, %0|%0, %2}"
19065117404Skan  [(set_attr "type" "ssecmp")
19066117404Skan   (set_attr "mode" "SF")])
1906790286Sobrien
1906890286Sobrien(define_insn "vmmaskncmpv4sf3"
1906990286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1907090286Sobrien	(vec_merge:V4SI
1907190286Sobrien	 (not:V4SI
1907290286Sobrien	  (match_operator:V4SI 3 "sse_comparison_operator"
1907390286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1907490286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))
1907590286Sobrien	 (subreg:V4SI (match_dup 1) 0)
1907690286Sobrien	 (const_int 1)))]
1907790286Sobrien  "TARGET_SSE"
1907890286Sobrien{
1907990286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1908090286Sobrien    return "cmpordss\t{%2, %0|%0, %2}";
1908190286Sobrien  else
1908290286Sobrien    return "cmpn%D3ss\t{%2, %0|%0, %2}";
1908390286Sobrien}
19084117404Skan  [(set_attr "type" "ssecmp")
19085117404Skan   (set_attr "mode" "SF")])
1908690286Sobrien
1908790286Sobrien(define_insn "sse_comi"
1908890286Sobrien  [(set (reg:CCFP 17)
19089117404Skan        (compare:CCFP (vec_select:SF
19090117404Skan		       (match_operand:V4SF 0 "register_operand" "x")
19091117404Skan		       (parallel [(const_int 0)]))
19092117404Skan		      (vec_select:SF
19093117404Skan		       (match_operand:V4SF 1 "register_operand" "x")
19094117404Skan		       (parallel [(const_int 0)]))))]
1909590286Sobrien  "TARGET_SSE"
1909690286Sobrien  "comiss\t{%1, %0|%0, %1}"
19097117404Skan  [(set_attr "type" "ssecmp")
19098117404Skan   (set_attr "mode" "SF")])
1909990286Sobrien
1910090286Sobrien(define_insn "sse_ucomi"
1910190286Sobrien  [(set (reg:CCFPU 17)
19102117404Skan	(compare:CCFPU (vec_select:SF
19103117404Skan			(match_operand:V4SF 0 "register_operand" "x")
19104117404Skan			(parallel [(const_int 0)]))
19105117404Skan		       (vec_select:SF
19106117404Skan			(match_operand:V4SF 1 "register_operand" "x")
19107117404Skan			(parallel [(const_int 0)]))))]
1910890286Sobrien  "TARGET_SSE"
1910990286Sobrien  "ucomiss\t{%1, %0|%0, %1}"
19110117404Skan  [(set_attr "type" "ssecmp")
19111117404Skan   (set_attr "mode" "SF")])
1911290286Sobrien
1911390286Sobrien
1911490286Sobrien;; SSE unpack
1911590286Sobrien
1911690286Sobrien(define_insn "sse_unpckhps"
1911790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1911890286Sobrien	(vec_merge:V4SF
1911990286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1912090286Sobrien			  (parallel [(const_int 2)
1912190286Sobrien				     (const_int 0)
1912290286Sobrien				     (const_int 3)
1912390286Sobrien				     (const_int 1)]))
1912490286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1912590286Sobrien			  (parallel [(const_int 0)
1912690286Sobrien				     (const_int 2)
1912790286Sobrien				     (const_int 1)
1912890286Sobrien				     (const_int 3)]))
1912990286Sobrien	 (const_int 5)))]
1913090286Sobrien  "TARGET_SSE"
1913190286Sobrien  "unpckhps\t{%2, %0|%0, %2}"
19132117404Skan  [(set_attr "type" "ssecvt")
19133117404Skan   (set_attr "mode" "V4SF")])
1913490286Sobrien
1913590286Sobrien(define_insn "sse_unpcklps"
1913690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1913790286Sobrien	(vec_merge:V4SF
1913890286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1913990286Sobrien			  (parallel [(const_int 0)
1914090286Sobrien				     (const_int 2)
1914190286Sobrien				     (const_int 1)
1914290286Sobrien				     (const_int 3)]))
1914390286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1914490286Sobrien			  (parallel [(const_int 2)
1914590286Sobrien				     (const_int 0)
1914690286Sobrien				     (const_int 3)
1914790286Sobrien				     (const_int 1)]))
1914890286Sobrien	 (const_int 5)))]
1914990286Sobrien  "TARGET_SSE"
1915090286Sobrien  "unpcklps\t{%2, %0|%0, %2}"
19151117404Skan  [(set_attr "type" "ssecvt")
19152117404Skan   (set_attr "mode" "V4SF")])
1915390286Sobrien
1915490286Sobrien
1915590286Sobrien;; SSE min/max
1915690286Sobrien
1915790286Sobrien(define_insn "smaxv4sf3"
1915890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1915990286Sobrien        (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1916090286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1916190286Sobrien  "TARGET_SSE"
1916290286Sobrien  "maxps\t{%2, %0|%0, %2}"
19163117404Skan  [(set_attr "type" "sse")
19164117404Skan   (set_attr "mode" "V4SF")])
1916590286Sobrien
1916690286Sobrien(define_insn "vmsmaxv4sf3"
1916790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1916890286Sobrien	(vec_merge:V4SF
1916990286Sobrien	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1917090286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1917190286Sobrien	 (match_dup 1)
1917290286Sobrien	 (const_int 1)))]
1917390286Sobrien  "TARGET_SSE"
1917490286Sobrien  "maxss\t{%2, %0|%0, %2}"
19175117404Skan  [(set_attr "type" "sse")
19176117404Skan   (set_attr "mode" "SF")])
1917790286Sobrien
1917890286Sobrien(define_insn "sminv4sf3"
1917990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1918090286Sobrien        (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1918190286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1918290286Sobrien  "TARGET_SSE"
1918390286Sobrien  "minps\t{%2, %0|%0, %2}"
19184117404Skan  [(set_attr "type" "sse")
19185117404Skan   (set_attr "mode" "V4SF")])
1918690286Sobrien
1918790286Sobrien(define_insn "vmsminv4sf3"
1918890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1918990286Sobrien	(vec_merge:V4SF
1919090286Sobrien	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1919190286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1919290286Sobrien	 (match_dup 1)
1919390286Sobrien	 (const_int 1)))]
1919490286Sobrien  "TARGET_SSE"
1919590286Sobrien  "minss\t{%2, %0|%0, %2}"
19196117404Skan  [(set_attr "type" "sse")
19197117404Skan   (set_attr "mode" "SF")])
1919890286Sobrien
1919990286Sobrien;; SSE <-> integer/MMX conversions
1920090286Sobrien
1920190286Sobrien(define_insn "cvtpi2ps"
1920290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1920390286Sobrien	(vec_merge:V4SF
1920490286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1920590286Sobrien	 (vec_duplicate:V4SF
1920690286Sobrien	  (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
1920790286Sobrien	 (const_int 12)))]
1920890286Sobrien  "TARGET_SSE"
1920990286Sobrien  "cvtpi2ps\t{%2, %0|%0, %2}"
19210117404Skan  [(set_attr "type" "ssecvt")
19211117404Skan   (set_attr "mode" "V4SF")])
1921290286Sobrien
1921390286Sobrien(define_insn "cvtps2pi"
1921490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1921590286Sobrien	(vec_select:V2SI
1921690286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1921790286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1921890286Sobrien  "TARGET_SSE"
1921990286Sobrien  "cvtps2pi\t{%1, %0|%0, %1}"
19220117404Skan  [(set_attr "type" "ssecvt")
19221117404Skan   (set_attr "mode" "V4SF")])
1922290286Sobrien
1922390286Sobrien(define_insn "cvttps2pi"
1922490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1922590286Sobrien	(vec_select:V2SI
19226117404Skan	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19227117404Skan		      UNSPEC_FIX)
1922890286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1922990286Sobrien  "TARGET_SSE"
1923090286Sobrien  "cvttps2pi\t{%1, %0|%0, %1}"
19231117404Skan  [(set_attr "type" "ssecvt")
19232117404Skan   (set_attr "mode" "SF")])
1923390286Sobrien
1923490286Sobrien(define_insn "cvtsi2ss"
1923590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1923690286Sobrien	(vec_merge:V4SF
1923790286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1923890286Sobrien	 (vec_duplicate:V4SF
1923990286Sobrien	  (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
1924090286Sobrien	 (const_int 14)))]
1924190286Sobrien  "TARGET_SSE"
1924290286Sobrien  "cvtsi2ss\t{%2, %0|%0, %2}"
19243117404Skan  [(set_attr "type" "ssecvt")
19244117404Skan   (set_attr "mode" "SF")])
1924590286Sobrien
19246117404Skan(define_insn "cvtsi2ssq"
19247117404Skan  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
19248117404Skan	(vec_merge:V4SF
19249117404Skan	 (match_operand:V4SF 1 "register_operand" "0,0")
19250117404Skan	 (vec_duplicate:V4SF
19251117404Skan	  (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
19252117404Skan	 (const_int 14)))]
19253117404Skan  "TARGET_SSE && TARGET_64BIT"
19254117404Skan  "cvtsi2ssq\t{%2, %0|%0, %2}"
19255117404Skan  [(set_attr "type" "ssecvt")
19256117404Skan   (set_attr "athlon_decode" "vector,vector")
19257117404Skan   (set_attr "mode" "SF")])
19258117404Skan
1925990286Sobrien(define_insn "cvtss2si"
1926090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1926190286Sobrien	(vec_select:SI
1926290286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1926390286Sobrien	 (parallel [(const_int 0)])))]
1926490286Sobrien  "TARGET_SSE"
1926590286Sobrien  "cvtss2si\t{%1, %0|%0, %1}"
19266117404Skan  [(set_attr "type" "ssecvt")
19267117404Skan   (set_attr "mode" "SF")])
1926890286Sobrien
19269117404Skan(define_insn "cvtss2siq"
19270117404Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
19271117404Skan	(vec_select:DI
19272117404Skan	 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
19273117404Skan	 (parallel [(const_int 0)])))]
19274117404Skan  "TARGET_SSE"
19275117404Skan  "cvtss2siq\t{%1, %0|%0, %1}"
19276117404Skan  [(set_attr "type" "ssecvt")
19277117404Skan   (set_attr "athlon_decode" "vector,vector")
19278117404Skan   (set_attr "mode" "SF")])
19279117404Skan
1928090286Sobrien(define_insn "cvttss2si"
1928190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1928290286Sobrien	(vec_select:SI
19283117404Skan	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19284117404Skan		      UNSPEC_FIX)
1928590286Sobrien	 (parallel [(const_int 0)])))]
1928690286Sobrien  "TARGET_SSE"
1928790286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
19288117404Skan  [(set_attr "type" "ssecvt")
19289117404Skan   (set_attr "mode" "SF")])
1929090286Sobrien
19291117404Skan(define_insn "cvttss2siq"
19292117404Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
19293117404Skan	(vec_select:DI
19294117404Skan	 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
19295117404Skan		      UNSPEC_FIX)
19296117404Skan	 (parallel [(const_int 0)])))]
19297117404Skan  "TARGET_SSE && TARGET_64BIT"
19298117404Skan  "cvttss2siq\t{%1, %0|%0, %1}"
19299117404Skan  [(set_attr "type" "ssecvt")
19300117404Skan   (set_attr "mode" "SF")
19301117404Skan   (set_attr "athlon_decode" "vector,vector")])
1930290286Sobrien
19303117404Skan
1930490286Sobrien;; MMX insns
1930590286Sobrien
1930690286Sobrien;; MMX arithmetic
1930790286Sobrien
1930890286Sobrien(define_insn "addv8qi3"
1930990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
19310117404Skan        (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
1931190286Sobrien	           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1931290286Sobrien  "TARGET_MMX"
1931390286Sobrien  "paddb\t{%2, %0|%0, %2}"
19314117404Skan  [(set_attr "type" "mmxadd")
19315117404Skan   (set_attr "mode" "DI")])
1931690286Sobrien
1931790286Sobrien(define_insn "addv4hi3"
1931890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
19319117404Skan        (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
1932090286Sobrien	           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1932190286Sobrien  "TARGET_MMX"
1932290286Sobrien  "paddw\t{%2, %0|%0, %2}"
19323117404Skan  [(set_attr "type" "mmxadd")
19324117404Skan   (set_attr "mode" "DI")])
1932590286Sobrien
1932690286Sobrien(define_insn "addv2si3"
1932790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
19328117404Skan        (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
1932990286Sobrien	           (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1933090286Sobrien  "TARGET_MMX"
1933190286Sobrien  "paddd\t{%2, %0|%0, %2}"
19332117404Skan  [(set_attr "type" "mmxadd")
19333117404Skan   (set_attr "mode" "DI")])
1933490286Sobrien
19335117404Skan(define_insn "mmx_adddi3"
19336117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
19337117404Skan        (unspec:DI
19338117404Skan	 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
19339117404Skan		   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19340117404Skan	 UNSPEC_NOP))]
19341117404Skan  "TARGET_MMX"
19342117404Skan  "paddq\t{%2, %0|%0, %2}"
19343117404Skan  [(set_attr "type" "mmxadd")
19344117404Skan   (set_attr "mode" "DI")])
19345117404Skan
1934690286Sobrien(define_insn "ssaddv8qi3"
1934790286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
19348117404Skan        (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
1934990286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1935090286Sobrien  "TARGET_MMX"
1935190286Sobrien  "paddsb\t{%2, %0|%0, %2}"
19352117404Skan  [(set_attr "type" "mmxadd")
19353117404Skan   (set_attr "mode" "DI")])
1935490286Sobrien
1935590286Sobrien(define_insn "ssaddv4hi3"
1935690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
19357117404Skan        (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
1935890286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1935990286Sobrien  "TARGET_MMX"
1936090286Sobrien  "paddsw\t{%2, %0|%0, %2}"
19361117404Skan  [(set_attr "type" "mmxadd")
19362117404Skan   (set_attr "mode" "DI")])
1936390286Sobrien
1936490286Sobrien(define_insn "usaddv8qi3"
1936590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
19366117404Skan        (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
1936790286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1936890286Sobrien  "TARGET_MMX"
1936990286Sobrien  "paddusb\t{%2, %0|%0, %2}"
19370117404Skan  [(set_attr "type" "mmxadd")
19371117404Skan   (set_attr "mode" "DI")])
1937290286Sobrien
1937390286Sobrien(define_insn "usaddv4hi3"
1937490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
19375117404Skan        (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
1937690286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1937790286Sobrien  "TARGET_MMX"
1937890286Sobrien  "paddusw\t{%2, %0|%0, %2}"
19379117404Skan  [(set_attr "type" "mmxadd")
19380117404Skan   (set_attr "mode" "DI")])
1938190286Sobrien
1938290286Sobrien(define_insn "subv8qi3"
1938390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1938490286Sobrien        (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1938590286Sobrien		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1938690286Sobrien  "TARGET_MMX"
1938790286Sobrien  "psubb\t{%2, %0|%0, %2}"
19388117404Skan  [(set_attr "type" "mmxadd")
19389117404Skan   (set_attr "mode" "DI")])
1939090286Sobrien
1939190286Sobrien(define_insn "subv4hi3"
1939290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1939390286Sobrien        (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1939490286Sobrien		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1939590286Sobrien  "TARGET_MMX"
1939690286Sobrien  "psubw\t{%2, %0|%0, %2}"
19397117404Skan  [(set_attr "type" "mmxadd")
19398117404Skan   (set_attr "mode" "DI")])
1939990286Sobrien
1940090286Sobrien(define_insn "subv2si3"
1940190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1940290286Sobrien        (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
1940390286Sobrien		    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1940490286Sobrien  "TARGET_MMX"
1940590286Sobrien  "psubd\t{%2, %0|%0, %2}"
19406117404Skan  [(set_attr "type" "mmxadd")
19407117404Skan   (set_attr "mode" "DI")])
1940890286Sobrien
19409117404Skan(define_insn "mmx_subdi3"
19410117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
19411117404Skan        (unspec:DI
19412117404Skan	 [(minus:DI (match_operand:DI 1 "register_operand" "0")
19413117404Skan		    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19414117404Skan	 UNSPEC_NOP))]
19415117404Skan  "TARGET_MMX"
19416117404Skan  "psubq\t{%2, %0|%0, %2}"
19417117404Skan  [(set_attr "type" "mmxadd")
19418117404Skan   (set_attr "mode" "DI")])
19419117404Skan
1942090286Sobrien(define_insn "sssubv8qi3"
1942190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1942290286Sobrien        (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1942390286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1942490286Sobrien  "TARGET_MMX"
1942590286Sobrien  "psubsb\t{%2, %0|%0, %2}"
19426117404Skan  [(set_attr "type" "mmxadd")
19427117404Skan   (set_attr "mode" "DI")])
1942890286Sobrien
1942990286Sobrien(define_insn "sssubv4hi3"
1943090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1943190286Sobrien        (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1943290286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1943390286Sobrien  "TARGET_MMX"
1943490286Sobrien  "psubsw\t{%2, %0|%0, %2}"
19435117404Skan  [(set_attr "type" "mmxadd")
19436117404Skan   (set_attr "mode" "DI")])
1943790286Sobrien
1943890286Sobrien(define_insn "ussubv8qi3"
1943990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1944090286Sobrien        (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1944190286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1944290286Sobrien  "TARGET_MMX"
1944390286Sobrien  "psubusb\t{%2, %0|%0, %2}"
19444117404Skan  [(set_attr "type" "mmxadd")
19445117404Skan   (set_attr "mode" "DI")])
1944690286Sobrien
1944790286Sobrien(define_insn "ussubv4hi3"
1944890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1944990286Sobrien        (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1945090286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1945190286Sobrien  "TARGET_MMX"
1945290286Sobrien  "psubusw\t{%2, %0|%0, %2}"
19453117404Skan  [(set_attr "type" "mmxadd")
19454117404Skan   (set_attr "mode" "DI")])
1945590286Sobrien
1945690286Sobrien(define_insn "mulv4hi3"
1945790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1945890286Sobrien        (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
1945990286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1946090286Sobrien  "TARGET_MMX"
1946190286Sobrien  "pmullw\t{%2, %0|%0, %2}"
19462117404Skan  [(set_attr "type" "mmxmul")
19463117404Skan   (set_attr "mode" "DI")])
1946490286Sobrien
1946590286Sobrien(define_insn "smulv4hi3_highpart"
1946690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1946790286Sobrien	(truncate:V4HI
1946890286Sobrien	 (lshiftrt:V4SI
1946990286Sobrien	  (mult:V4SI (sign_extend:V4SI
1947090286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1947190286Sobrien		     (sign_extend:V4SI
1947290286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1947390286Sobrien	  (const_int 16))))]
1947490286Sobrien  "TARGET_MMX"
1947590286Sobrien  "pmulhw\t{%2, %0|%0, %2}"
19476117404Skan  [(set_attr "type" "mmxmul")
19477117404Skan   (set_attr "mode" "DI")])
1947890286Sobrien
1947990286Sobrien(define_insn "umulv4hi3_highpart"
1948090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1948190286Sobrien	(truncate:V4HI
1948290286Sobrien	 (lshiftrt:V4SI
1948390286Sobrien	  (mult:V4SI (zero_extend:V4SI
1948490286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1948590286Sobrien		     (zero_extend:V4SI
1948690286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1948790286Sobrien	  (const_int 16))))]
1948890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1948990286Sobrien  "pmulhuw\t{%2, %0|%0, %2}"
19490117404Skan  [(set_attr "type" "mmxmul")
19491117404Skan   (set_attr "mode" "DI")])
1949290286Sobrien
1949390286Sobrien(define_insn "mmx_pmaddwd"
1949490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1949590286Sobrien        (plus:V2SI
1949690286Sobrien	 (mult:V2SI
1949790286Sobrien	  (sign_extend:V2SI
1949890286Sobrien	   (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
1949990286Sobrien			    (parallel [(const_int 0) (const_int 2)])))
1950090286Sobrien	  (sign_extend:V2SI
1950190286Sobrien	   (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
1950290286Sobrien			    (parallel [(const_int 0) (const_int 2)]))))
1950390286Sobrien	 (mult:V2SI
1950490286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
1950590286Sobrien					     (parallel [(const_int 1)
1950690286Sobrien							(const_int 3)])))
1950790286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
1950890286Sobrien					     (parallel [(const_int 1)
1950990286Sobrien							(const_int 3)]))))))]
1951090286Sobrien  "TARGET_MMX"
1951190286Sobrien  "pmaddwd\t{%2, %0|%0, %2}"
19512117404Skan  [(set_attr "type" "mmxmul")
19513117404Skan   (set_attr "mode" "DI")])
1951490286Sobrien
1951590286Sobrien
1951690286Sobrien;; MMX logical operations
1951790286Sobrien;; Note we don't want to declare these as regular iordi3 insns to prevent
1951890286Sobrien;; normal code that also wants to use the FPU from getting broken.
1951990286Sobrien;; The UNSPECs are there to prevent the combiner from getting overly clever.
1952090286Sobrien(define_insn "mmx_iordi3"
1952190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1952290286Sobrien        (unspec:DI
19523117404Skan	 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
19524117404Skan		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19525117404Skan	 UNSPEC_NOP))]
1952690286Sobrien  "TARGET_MMX"
1952790286Sobrien  "por\t{%2, %0|%0, %2}"
19528117404Skan  [(set_attr "type" "mmxadd")
19529117404Skan   (set_attr "mode" "DI")])
1953090286Sobrien
1953190286Sobrien(define_insn "mmx_xordi3"
1953290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1953390286Sobrien        (unspec:DI
19534117404Skan	 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
19535117404Skan		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19536117404Skan	 UNSPEC_NOP))]
1953790286Sobrien  "TARGET_MMX"
1953890286Sobrien  "pxor\t{%2, %0|%0, %2}"
19539117404Skan  [(set_attr "type" "mmxadd")
19540117404Skan   (set_attr "mode" "DI")
1954190286Sobrien   (set_attr "memory" "none")])
1954290286Sobrien
1954390286Sobrien;; Same as pxor, but don't show input operands so that we don't think
1954490286Sobrien;; they are live.
1954590286Sobrien(define_insn "mmx_clrdi"
1954690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
19547117404Skan        (unspec:DI [(const_int 0)] UNSPEC_NOP))]
1954890286Sobrien  "TARGET_MMX"
1954990286Sobrien  "pxor\t{%0, %0|%0, %0}"
19550117404Skan  [(set_attr "type" "mmxadd")
19551117404Skan   (set_attr "mode" "DI")
1955290286Sobrien   (set_attr "memory" "none")])
1955390286Sobrien
1955490286Sobrien(define_insn "mmx_anddi3"
1955590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1955690286Sobrien        (unspec:DI
19557117404Skan	 [(and:DI (match_operand:DI 1 "register_operand" "%0")
19558117404Skan		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19559117404Skan	 UNSPEC_NOP))]
1956090286Sobrien  "TARGET_MMX"
1956190286Sobrien  "pand\t{%2, %0|%0, %2}"
19562117404Skan  [(set_attr "type" "mmxadd")
19563117404Skan   (set_attr "mode" "DI")])
1956490286Sobrien
1956590286Sobrien(define_insn "mmx_nanddi3"
1956690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1956790286Sobrien        (unspec:DI
1956890286Sobrien	 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
19569117404Skan			  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19570117404Skan	 UNSPEC_NOP))]
1957190286Sobrien  "TARGET_MMX"
1957290286Sobrien  "pandn\t{%2, %0|%0, %2}"
19573117404Skan  [(set_attr "type" "mmxadd")
19574117404Skan   (set_attr "mode" "DI")])
1957590286Sobrien
1957690286Sobrien
1957790286Sobrien;; MMX unsigned averages/sum of absolute differences
1957890286Sobrien
1957990286Sobrien(define_insn "mmx_uavgv8qi3"
1958090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1958190286Sobrien        (ashiftrt:V8QI
1958290286Sobrien	 (plus:V8QI (plus:V8QI
1958390286Sobrien		     (match_operand:V8QI 1 "register_operand" "0")
1958490286Sobrien		     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1958596294Sobrien		    (const_vector:V8QI [(const_int 1)
1958696294Sobrien					(const_int 1)
1958796294Sobrien					(const_int 1)
1958896294Sobrien					(const_int 1)
1958996294Sobrien					(const_int 1)
1959096294Sobrien					(const_int 1)
1959196294Sobrien					(const_int 1)
1959296294Sobrien					(const_int 1)]))
1959390286Sobrien	 (const_int 1)))]
1959490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1959590286Sobrien  "pavgb\t{%2, %0|%0, %2}"
19596117404Skan  [(set_attr "type" "mmxshft")
19597117404Skan   (set_attr "mode" "DI")])
1959890286Sobrien
1959990286Sobrien(define_insn "mmx_uavgv4hi3"
1960090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1960190286Sobrien        (ashiftrt:V4HI
1960290286Sobrien	 (plus:V4HI (plus:V4HI
1960390286Sobrien		     (match_operand:V4HI 1 "register_operand" "0")
1960490286Sobrien		     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1960596294Sobrien		    (const_vector:V4HI [(const_int 1)
1960696294Sobrien					(const_int 1)
1960796294Sobrien					(const_int 1)
1960896294Sobrien					(const_int 1)]))
1960990286Sobrien	 (const_int 1)))]
1961090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1961190286Sobrien  "pavgw\t{%2, %0|%0, %2}"
19612117404Skan  [(set_attr "type" "mmxshft")
19613117404Skan   (set_attr "mode" "DI")])
1961490286Sobrien
1961590286Sobrien(define_insn "mmx_psadbw"
19616117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
19617117404Skan        (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
19618117404Skan		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
19619117404Skan		   UNSPEC_PSADBW))]
1962090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1962190286Sobrien  "psadbw\t{%2, %0|%0, %2}"
19622117404Skan  [(set_attr "type" "mmxshft")
19623117404Skan   (set_attr "mode" "DI")])
1962490286Sobrien
1962590286Sobrien
1962690286Sobrien;; MMX insert/extract/shuffle
1962790286Sobrien
1962890286Sobrien(define_insn "mmx_pinsrw"
1962990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1963090286Sobrien        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
1963190286Sobrien			(vec_duplicate:V4HI
1963290286Sobrien			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
1963390286Sobrien			(match_operand:SI 3 "immediate_operand" "i")))]
1963490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1963590286Sobrien  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
19636117404Skan  [(set_attr "type" "mmxcvt")
19637117404Skan   (set_attr "mode" "DI")])
1963890286Sobrien
1963990286Sobrien(define_insn "mmx_pextrw"
1964090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1964190286Sobrien        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
1964290286Sobrien				       (parallel
1964390286Sobrien					[(match_operand:SI 2 "immediate_operand" "i")]))))]
1964490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1964590286Sobrien  "pextrw\t{%2, %1, %0|%0, %1, %2}"
19646117404Skan  [(set_attr "type" "mmxcvt")
19647117404Skan   (set_attr "mode" "DI")])
1964890286Sobrien
1964990286Sobrien(define_insn "mmx_pshufw"
1965090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1965190286Sobrien        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
19652117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
19653117404Skan		     UNSPEC_SHUFFLE))]
1965490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1965590286Sobrien  "pshufw\t{%2, %1, %0|%0, %1, %2}"
19656117404Skan  [(set_attr "type" "mmxcvt")
19657117404Skan   (set_attr "mode" "DI")])
1965890286Sobrien
1965990286Sobrien
1966090286Sobrien;; MMX mask-generating comparisons
1966190286Sobrien
1966290286Sobrien(define_insn "eqv8qi3"
1966390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1966490286Sobrien        (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
1966590286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1966690286Sobrien  "TARGET_MMX"
1966790286Sobrien  "pcmpeqb\t{%2, %0|%0, %2}"
19668117404Skan  [(set_attr "type" "mmxcmp")
19669117404Skan   (set_attr "mode" "DI")])
1967090286Sobrien
1967190286Sobrien(define_insn "eqv4hi3"
1967290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1967390286Sobrien        (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
1967490286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1967590286Sobrien  "TARGET_MMX"
1967690286Sobrien  "pcmpeqw\t{%2, %0|%0, %2}"
19677117404Skan  [(set_attr "type" "mmxcmp")
19678117404Skan   (set_attr "mode" "DI")])
1967990286Sobrien
1968090286Sobrien(define_insn "eqv2si3"
1968190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1968290286Sobrien        (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
1968390286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1968490286Sobrien  "TARGET_MMX"
1968590286Sobrien  "pcmpeqd\t{%2, %0|%0, %2}"
19686117404Skan  [(set_attr "type" "mmxcmp")
19687117404Skan   (set_attr "mode" "DI")])
1968890286Sobrien
1968990286Sobrien(define_insn "gtv8qi3"
1969090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1969190286Sobrien        (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
1969290286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1969390286Sobrien  "TARGET_MMX"
1969490286Sobrien  "pcmpgtb\t{%2, %0|%0, %2}"
19695117404Skan  [(set_attr "type" "mmxcmp")
19696117404Skan   (set_attr "mode" "DI")])
1969790286Sobrien
1969890286Sobrien(define_insn "gtv4hi3"
1969990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1970090286Sobrien        (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1970190286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1970290286Sobrien  "TARGET_MMX"
1970390286Sobrien  "pcmpgtw\t{%2, %0|%0, %2}"
19704117404Skan  [(set_attr "type" "mmxcmp")
19705117404Skan   (set_attr "mode" "DI")])
1970690286Sobrien
1970790286Sobrien(define_insn "gtv2si3"
1970890286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1970990286Sobrien        (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1971090286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1971190286Sobrien  "TARGET_MMX"
1971290286Sobrien  "pcmpgtd\t{%2, %0|%0, %2}"
19713117404Skan  [(set_attr "type" "mmxcmp")
19714117404Skan   (set_attr "mode" "DI")])
1971590286Sobrien
1971690286Sobrien
1971790286Sobrien;; MMX max/min insns
1971890286Sobrien
1971990286Sobrien(define_insn "umaxv8qi3"
1972090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1972190286Sobrien        (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
1972290286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1972390286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1972490286Sobrien  "pmaxub\t{%2, %0|%0, %2}"
19725117404Skan  [(set_attr "type" "mmxadd")
19726117404Skan   (set_attr "mode" "DI")])
1972790286Sobrien
1972890286Sobrien(define_insn "smaxv4hi3"
1972990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1973090286Sobrien        (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
1973190286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1973290286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1973390286Sobrien  "pmaxsw\t{%2, %0|%0, %2}"
19734117404Skan  [(set_attr "type" "mmxadd")
19735117404Skan   (set_attr "mode" "DI")])
1973690286Sobrien
1973790286Sobrien(define_insn "uminv8qi3"
1973890286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1973990286Sobrien        (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
1974090286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1974190286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1974290286Sobrien  "pminub\t{%2, %0|%0, %2}"
19743117404Skan  [(set_attr "type" "mmxadd")
19744117404Skan   (set_attr "mode" "DI")])
1974590286Sobrien
1974690286Sobrien(define_insn "sminv4hi3"
1974790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1974890286Sobrien        (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
1974990286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1975090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1975190286Sobrien  "pminsw\t{%2, %0|%0, %2}"
19752117404Skan  [(set_attr "type" "mmxadd")
19753117404Skan   (set_attr "mode" "DI")])
1975490286Sobrien
1975590286Sobrien
1975690286Sobrien;; MMX shifts
1975790286Sobrien
1975890286Sobrien(define_insn "ashrv4hi3"
1975990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1976090286Sobrien        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1976190286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1976290286Sobrien  "TARGET_MMX"
1976390286Sobrien  "psraw\t{%2, %0|%0, %2}"
19764117404Skan  [(set_attr "type" "mmxshft")
19765117404Skan   (set_attr "mode" "DI")])
1976690286Sobrien
1976790286Sobrien(define_insn "ashrv2si3"
1976890286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1976990286Sobrien        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1977090286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1977190286Sobrien  "TARGET_MMX"
1977290286Sobrien  "psrad\t{%2, %0|%0, %2}"
19773117404Skan  [(set_attr "type" "mmxshft")
19774117404Skan   (set_attr "mode" "DI")])
1977590286Sobrien
1977690286Sobrien(define_insn "lshrv4hi3"
1977790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1977890286Sobrien        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1977990286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1978090286Sobrien  "TARGET_MMX"
1978190286Sobrien  "psrlw\t{%2, %0|%0, %2}"
19782117404Skan  [(set_attr "type" "mmxshft")
19783117404Skan   (set_attr "mode" "DI")])
1978490286Sobrien
1978590286Sobrien(define_insn "lshrv2si3"
1978690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1978790286Sobrien        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1978890286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1978990286Sobrien  "TARGET_MMX"
1979090286Sobrien  "psrld\t{%2, %0|%0, %2}"
19791117404Skan  [(set_attr "type" "mmxshft")
19792117404Skan   (set_attr "mode" "DI")])
1979390286Sobrien
1979490286Sobrien;; See logical MMX insns.
1979590286Sobrien(define_insn "mmx_lshrdi3"
1979690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1979790286Sobrien        (unspec:DI
1979890286Sobrien	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
19799117404Skan		       (match_operand:DI 2 "nonmemory_operand" "yi"))]
19800117404Skan	  UNSPEC_NOP))]
1980190286Sobrien  "TARGET_MMX"
1980290286Sobrien  "psrlq\t{%2, %0|%0, %2}"
19803117404Skan  [(set_attr "type" "mmxshft")
19804117404Skan   (set_attr "mode" "DI")])
1980590286Sobrien
1980690286Sobrien(define_insn "ashlv4hi3"
1980790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1980890286Sobrien        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
1980990286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1981090286Sobrien  "TARGET_MMX"
1981190286Sobrien  "psllw\t{%2, %0|%0, %2}"
19812117404Skan  [(set_attr "type" "mmxshft")
19813117404Skan   (set_attr "mode" "DI")])
1981490286Sobrien
1981590286Sobrien(define_insn "ashlv2si3"
1981690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1981790286Sobrien        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
1981890286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1981990286Sobrien  "TARGET_MMX"
1982090286Sobrien  "pslld\t{%2, %0|%0, %2}"
19821117404Skan  [(set_attr "type" "mmxshft")
19822117404Skan   (set_attr "mode" "DI")])
1982390286Sobrien
1982490286Sobrien;; See logical MMX insns.
1982590286Sobrien(define_insn "mmx_ashldi3"
1982690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1982790286Sobrien        (unspec:DI
1982890286Sobrien	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
19829117404Skan		     (match_operand:DI 2 "nonmemory_operand" "yi"))]
19830117404Skan	 UNSPEC_NOP))]
1983190286Sobrien  "TARGET_MMX"
1983290286Sobrien  "psllq\t{%2, %0|%0, %2}"
19833117404Skan  [(set_attr "type" "mmxshft")
19834117404Skan   (set_attr "mode" "DI")])
1983590286Sobrien
1983690286Sobrien
1983790286Sobrien;; MMX pack/unpack insns.
1983890286Sobrien
1983990286Sobrien(define_insn "mmx_packsswb"
1984090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1984190286Sobrien	(vec_concat:V8QI
1984290286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1984390286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1984490286Sobrien  "TARGET_MMX"
1984590286Sobrien  "packsswb\t{%2, %0|%0, %2}"
19846117404Skan  [(set_attr "type" "mmxshft")
19847117404Skan   (set_attr "mode" "DI")])
1984890286Sobrien
1984990286Sobrien(define_insn "mmx_packssdw"
1985090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1985190286Sobrien	(vec_concat:V4HI
1985290286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
1985390286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
1985490286Sobrien  "TARGET_MMX"
1985590286Sobrien  "packssdw\t{%2, %0|%0, %2}"
19856117404Skan  [(set_attr "type" "mmxshft")
19857117404Skan   (set_attr "mode" "DI")])
1985890286Sobrien
1985990286Sobrien(define_insn "mmx_packuswb"
1986090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1986190286Sobrien	(vec_concat:V8QI
1986290286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1986390286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1986490286Sobrien  "TARGET_MMX"
1986590286Sobrien  "packuswb\t{%2, %0|%0, %2}"
19866117404Skan  [(set_attr "type" "mmxshft")
19867117404Skan   (set_attr "mode" "DI")])
1986890286Sobrien
1986990286Sobrien(define_insn "mmx_punpckhbw"
1987090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1987190286Sobrien	(vec_merge:V8QI
1987290286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1987390286Sobrien			  (parallel [(const_int 4)
1987490286Sobrien				     (const_int 0)
1987590286Sobrien				     (const_int 5)
1987690286Sobrien				     (const_int 1)
1987790286Sobrien				     (const_int 6)
1987890286Sobrien				     (const_int 2)
1987990286Sobrien				     (const_int 7)
1988090286Sobrien				     (const_int 3)]))
1988190286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1988290286Sobrien			  (parallel [(const_int 0)
1988390286Sobrien				     (const_int 4)
1988490286Sobrien				     (const_int 1)
1988590286Sobrien				     (const_int 5)
1988690286Sobrien				     (const_int 2)
1988790286Sobrien				     (const_int 6)
1988890286Sobrien				     (const_int 3)
1988990286Sobrien				     (const_int 7)]))
1989090286Sobrien	 (const_int 85)))]
1989190286Sobrien  "TARGET_MMX"
1989290286Sobrien  "punpckhbw\t{%2, %0|%0, %2}"
19893117404Skan  [(set_attr "type" "mmxcvt")
19894117404Skan   (set_attr "mode" "DI")])
1989590286Sobrien
1989690286Sobrien(define_insn "mmx_punpckhwd"
1989790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1989890286Sobrien	(vec_merge:V4HI
1989990286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1990090286Sobrien			  (parallel [(const_int 0)
1990190286Sobrien				     (const_int 2)
1990290286Sobrien				     (const_int 1)
1990390286Sobrien				     (const_int 3)]))
1990490286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1990590286Sobrien			  (parallel [(const_int 2)
1990690286Sobrien				     (const_int 0)
1990790286Sobrien				     (const_int 3)
1990890286Sobrien				     (const_int 1)]))
1990990286Sobrien	 (const_int 5)))]
1991090286Sobrien  "TARGET_MMX"
1991190286Sobrien  "punpckhwd\t{%2, %0|%0, %2}"
19912117404Skan  [(set_attr "type" "mmxcvt")
19913117404Skan   (set_attr "mode" "DI")])
1991490286Sobrien
1991590286Sobrien(define_insn "mmx_punpckhdq"
1991690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1991790286Sobrien	(vec_merge:V2SI
19918117404Skan	 (match_operand:V2SI 1 "register_operand" "0")
1991990286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
1992090286Sobrien			  (parallel [(const_int 1)
1992190286Sobrien				     (const_int 0)]))
1992290286Sobrien	 (const_int 1)))]
1992390286Sobrien  "TARGET_MMX"
1992490286Sobrien  "punpckhdq\t{%2, %0|%0, %2}"
19925117404Skan  [(set_attr "type" "mmxcvt")
19926117404Skan   (set_attr "mode" "DI")])
1992790286Sobrien
1992890286Sobrien(define_insn "mmx_punpcklbw"
1992990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1993090286Sobrien	(vec_merge:V8QI
1993190286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1993290286Sobrien			  (parallel [(const_int 0)
1993390286Sobrien				     (const_int 4)
1993490286Sobrien				     (const_int 1)
1993590286Sobrien				     (const_int 5)
1993690286Sobrien				     (const_int 2)
1993790286Sobrien				     (const_int 6)
1993890286Sobrien				     (const_int 3)
1993990286Sobrien				     (const_int 7)]))
1994090286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1994190286Sobrien			  (parallel [(const_int 4)
1994290286Sobrien				     (const_int 0)
1994390286Sobrien				     (const_int 5)
1994490286Sobrien				     (const_int 1)
1994590286Sobrien				     (const_int 6)
1994690286Sobrien				     (const_int 2)
1994790286Sobrien				     (const_int 7)
1994890286Sobrien				     (const_int 3)]))
1994990286Sobrien	 (const_int 85)))]
1995090286Sobrien  "TARGET_MMX"
1995190286Sobrien  "punpcklbw\t{%2, %0|%0, %2}"
19952117404Skan  [(set_attr "type" "mmxcvt")
19953117404Skan   (set_attr "mode" "DI")])
1995490286Sobrien
1995590286Sobrien(define_insn "mmx_punpcklwd"
1995690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1995790286Sobrien	(vec_merge:V4HI
1995890286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1995990286Sobrien			  (parallel [(const_int 2)
1996090286Sobrien				     (const_int 0)
1996190286Sobrien				     (const_int 3)
1996290286Sobrien				     (const_int 1)]))
1996390286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1996490286Sobrien			  (parallel [(const_int 0)
1996590286Sobrien				     (const_int 2)
1996690286Sobrien				     (const_int 1)
1996790286Sobrien				     (const_int 3)]))
1996890286Sobrien	 (const_int 5)))]
1996990286Sobrien  "TARGET_MMX"
1997090286Sobrien  "punpcklwd\t{%2, %0|%0, %2}"
19971117404Skan  [(set_attr "type" "mmxcvt")
19972117404Skan   (set_attr "mode" "DI")])
1997390286Sobrien
1997490286Sobrien(define_insn "mmx_punpckldq"
1997590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1997690286Sobrien	(vec_merge:V2SI
1997790286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
1997890286Sobrien			   (parallel [(const_int 1)
1997990286Sobrien				      (const_int 0)]))
19980117404Skan	 (match_operand:V2SI 2 "register_operand" "y")
1998190286Sobrien	 (const_int 1)))]
1998290286Sobrien  "TARGET_MMX"
1998390286Sobrien  "punpckldq\t{%2, %0|%0, %2}"
19984117404Skan  [(set_attr "type" "mmxcvt")
19985117404Skan   (set_attr "mode" "DI")])
1998690286Sobrien
1998790286Sobrien
1998890286Sobrien;; Miscellaneous stuff
1998990286Sobrien
1999090286Sobrien(define_insn "emms"
19991117404Skan  [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1999290286Sobrien   (clobber (reg:XF 8))
1999390286Sobrien   (clobber (reg:XF 9))
1999490286Sobrien   (clobber (reg:XF 10))
1999590286Sobrien   (clobber (reg:XF 11))
1999690286Sobrien   (clobber (reg:XF 12))
1999790286Sobrien   (clobber (reg:XF 13))
1999890286Sobrien   (clobber (reg:XF 14))
1999990286Sobrien   (clobber (reg:XF 15))
2000090286Sobrien   (clobber (reg:DI 29))
2000190286Sobrien   (clobber (reg:DI 30))
2000290286Sobrien   (clobber (reg:DI 31))
2000390286Sobrien   (clobber (reg:DI 32))
2000490286Sobrien   (clobber (reg:DI 33))
2000590286Sobrien   (clobber (reg:DI 34))
2000690286Sobrien   (clobber (reg:DI 35))
2000790286Sobrien   (clobber (reg:DI 36))]
2000890286Sobrien  "TARGET_MMX"
2000990286Sobrien  "emms"
2001090286Sobrien  [(set_attr "type" "mmx")
2001190286Sobrien   (set_attr "memory" "unknown")])
2001290286Sobrien
2001390286Sobrien(define_insn "ldmxcsr"
20014117404Skan  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20015117404Skan		    UNSPECV_LDMXCSR)]
20016117404Skan  "TARGET_SSE"
2001790286Sobrien  "ldmxcsr\t%0"
20018117404Skan  [(set_attr "type" "sse")
2001990286Sobrien   (set_attr "memory" "load")])
2002090286Sobrien
2002190286Sobrien(define_insn "stmxcsr"
2002290286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
20023117404Skan	(unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20024117404Skan  "TARGET_SSE"
2002590286Sobrien  "stmxcsr\t%0"
20026117404Skan  [(set_attr "type" "sse")
2002790286Sobrien   (set_attr "memory" "store")])
2002890286Sobrien
2002990286Sobrien(define_expand "sfence"
2003090286Sobrien  [(set (match_dup 0)
20031117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
2003290286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2003390286Sobrien{
2003490286Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2003590286Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
2003690286Sobrien})
2003790286Sobrien
2003890286Sobrien(define_insn "*sfence_insn"
2003990286Sobrien  [(set (match_operand:BLK 0 "" "")
20040117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
2004190286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2004290286Sobrien  "sfence"
2004390286Sobrien  [(set_attr "type" "sse")
2004490286Sobrien   (set_attr "memory" "unknown")])
2004590286Sobrien
2004690286Sobrien(define_expand "sse_prologue_save"
2004790286Sobrien  [(parallel [(set (match_operand:BLK 0 "" "")
2004890286Sobrien		   (unspec:BLK [(reg:DI 21)
2004990286Sobrien				(reg:DI 22)
2005090286Sobrien				(reg:DI 23)
2005190286Sobrien				(reg:DI 24)
2005290286Sobrien				(reg:DI 25)
2005390286Sobrien				(reg:DI 26)
2005490286Sobrien				(reg:DI 27)
20055117404Skan				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
2005690286Sobrien	      (use (match_operand:DI 1 "register_operand" ""))
2005790286Sobrien	      (use (match_operand:DI 2 "immediate_operand" ""))
2005890286Sobrien	      (use (label_ref:DI (match_operand 3 "" "")))])]
2005990286Sobrien  "TARGET_64BIT"
2006090286Sobrien  "")
2006190286Sobrien
2006290286Sobrien(define_insn "*sse_prologue_save_insn"
2006390286Sobrien  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
2006490286Sobrien			  (match_operand:DI 4 "const_int_operand" "n")))
2006590286Sobrien	(unspec:BLK [(reg:DI 21)
2006690286Sobrien		     (reg:DI 22)
2006790286Sobrien		     (reg:DI 23)
2006890286Sobrien		     (reg:DI 24)
2006990286Sobrien		     (reg:DI 25)
2007090286Sobrien		     (reg:DI 26)
2007190286Sobrien		     (reg:DI 27)
20072117404Skan		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
2007390286Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
2007490286Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
2007590286Sobrien   (use (label_ref:DI (match_operand 3 "" "X")))]
2007690286Sobrien  "TARGET_64BIT
2007790286Sobrien   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
2007890286Sobrien   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
2007990286Sobrien  "*
2008090286Sobrien{
2008190286Sobrien  int i;
2008290286Sobrien  operands[0] = gen_rtx_MEM (Pmode,
2008390286Sobrien			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
2008490286Sobrien  output_asm_insn (\"jmp\\t%A1\", operands);
2008590286Sobrien  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
2008690286Sobrien    {
2008790286Sobrien      operands[4] = adjust_address (operands[0], DImode, i*16);
2008890286Sobrien      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
2008990286Sobrien      PUT_MODE (operands[4], TImode);
2009090286Sobrien      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
2009190286Sobrien        output_asm_insn (\"rex\", operands);
2009290286Sobrien      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
2009390286Sobrien    }
2009490286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
2009590286Sobrien			     CODE_LABEL_NUMBER (operands[3]));
2009690286Sobrien  RET;
2009790286Sobrien}
2009856391Sobrien  "
2009990286Sobrien  [(set_attr "type" "other")
2010090286Sobrien   (set_attr "length_immediate" "0")
2010190286Sobrien   (set_attr "length_address" "0")
2010290286Sobrien   (set_attr "length" "135")
2010390286Sobrien   (set_attr "memory" "store")
2010490286Sobrien   (set_attr "modrm" "0")
2010590286Sobrien   (set_attr "mode" "DI")])
2010690286Sobrien
2010790286Sobrien;; 3Dnow! instructions
2010890286Sobrien
2010990286Sobrien(define_insn "addv2sf3"
2011090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2011190286Sobrien	(plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
2011290286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2011390286Sobrien  "TARGET_3DNOW"
2011490286Sobrien  "pfadd\\t{%2, %0|%0, %2}"
20115117404Skan  [(set_attr "type" "mmxadd")
20116117404Skan   (set_attr "mode" "V2SF")])
2011790286Sobrien
2011890286Sobrien(define_insn "subv2sf3"
2011990286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2012090286Sobrien        (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
2012190286Sobrien		    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2012290286Sobrien  "TARGET_3DNOW"
2012390286Sobrien  "pfsub\\t{%2, %0|%0, %2}"
20124117404Skan  [(set_attr "type" "mmxadd")
20125117404Skan   (set_attr "mode" "V2SF")])
2012690286Sobrien
2012790286Sobrien(define_insn "subrv2sf3"
2012890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2012990286Sobrien        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
2013090286Sobrien                    (match_operand:V2SF 1 "register_operand" "0")))]
2013190286Sobrien  "TARGET_3DNOW"
2013290286Sobrien  "pfsubr\\t{%2, %0|%0, %2}"
20133117404Skan  [(set_attr "type" "mmxadd")
20134117404Skan   (set_attr "mode" "V2SF")])
2013590286Sobrien
2013690286Sobrien(define_insn "gtv2sf3"
2013790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2013890286Sobrien	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
2013990286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2014090286Sobrien "TARGET_3DNOW"
2014190286Sobrien  "pfcmpgt\\t{%2, %0|%0, %2}"
20142117404Skan  [(set_attr "type" "mmxcmp")
20143117404Skan   (set_attr "mode" "V2SF")])
2014490286Sobrien
2014590286Sobrien(define_insn "gev2sf3"
2014690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2014790286Sobrien	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
2014890286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2014990286Sobrien  "TARGET_3DNOW"
2015090286Sobrien  "pfcmpge\\t{%2, %0|%0, %2}"
20151117404Skan  [(set_attr "type" "mmxcmp")
20152117404Skan   (set_attr "mode" "V2SF")])
2015390286Sobrien
2015490286Sobrien(define_insn "eqv2sf3"
2015590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2015690286Sobrien	(eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
2015790286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2015890286Sobrien  "TARGET_3DNOW"
2015990286Sobrien  "pfcmpeq\\t{%2, %0|%0, %2}"
20160117404Skan  [(set_attr "type" "mmxcmp")
20161117404Skan   (set_attr "mode" "V2SF")])
2016290286Sobrien
2016390286Sobrien(define_insn "pfmaxv2sf3"
2016490286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2016590286Sobrien        (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
2016690286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2016790286Sobrien  "TARGET_3DNOW"
2016890286Sobrien  "pfmax\\t{%2, %0|%0, %2}"
20169117404Skan  [(set_attr "type" "mmxadd")
20170117404Skan   (set_attr "mode" "V2SF")])
2017190286Sobrien
2017290286Sobrien(define_insn "pfminv2sf3"
2017390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2017490286Sobrien        (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
2017590286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2017690286Sobrien  "TARGET_3DNOW"
2017790286Sobrien  "pfmin\\t{%2, %0|%0, %2}"
20178117404Skan  [(set_attr "type" "mmxadd")
20179117404Skan   (set_attr "mode" "V2SF")])
2018090286Sobrien
2018190286Sobrien(define_insn "mulv2sf3"
2018290286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2018390286Sobrien	(mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
2018490286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2018590286Sobrien  "TARGET_3DNOW"
2018690286Sobrien  "pfmul\\t{%2, %0|%0, %2}"
20187117404Skan  [(set_attr "type" "mmxmul")
20188117404Skan   (set_attr "mode" "V2SF")])
2018990286Sobrien
2019090286Sobrien(define_insn "femms"
20191117404Skan  [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
2019290286Sobrien   (clobber (reg:XF 8))
2019390286Sobrien   (clobber (reg:XF 9))
2019490286Sobrien   (clobber (reg:XF 10))
2019590286Sobrien   (clobber (reg:XF 11))
2019690286Sobrien   (clobber (reg:XF 12))
2019790286Sobrien   (clobber (reg:XF 13))
2019890286Sobrien   (clobber (reg:XF 14))
2019990286Sobrien   (clobber (reg:XF 15))
2020090286Sobrien   (clobber (reg:DI 29))
2020190286Sobrien   (clobber (reg:DI 30))
2020290286Sobrien   (clobber (reg:DI 31))
2020390286Sobrien   (clobber (reg:DI 32))
2020490286Sobrien   (clobber (reg:DI 33))
2020590286Sobrien   (clobber (reg:DI 34))
2020690286Sobrien   (clobber (reg:DI 35))
2020790286Sobrien   (clobber (reg:DI 36))]
2020890286Sobrien  "TARGET_3DNOW"
2020990286Sobrien  "femms"
20210117404Skan  [(set_attr "type" "mmx")
20211117404Skan   (set_attr "memory" "none")]) 
2021290286Sobrien
2021390286Sobrien(define_insn "pf2id"
2021490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2021590286Sobrien	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
2021690286Sobrien  "TARGET_3DNOW"
2021790286Sobrien  "pf2id\\t{%1, %0|%0, %1}"
20218117404Skan  [(set_attr "type" "mmxcvt")
20219117404Skan   (set_attr "mode" "V2SF")])
2022090286Sobrien
2022190286Sobrien(define_insn "pf2iw"
2022290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2022390286Sobrien	(sign_extend:V2SI
2022490286Sobrien	   (ss_truncate:V2HI
2022590286Sobrien	      (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
2022690286Sobrien  "TARGET_3DNOW_A"
2022790286Sobrien  "pf2iw\\t{%1, %0|%0, %1}"
20228117404Skan  [(set_attr "type" "mmxcvt")
20229117404Skan   (set_attr "mode" "V2SF")])
2023090286Sobrien
2023190286Sobrien(define_insn "pfacc"
2023290286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2023390286Sobrien	(vec_concat:V2SF
2023490286Sobrien	   (plus:SF
2023590286Sobrien	      (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
2023690286Sobrien			     (parallel [(const_int  0)]))
2023790286Sobrien	      (vec_select:SF (match_dup 1)
2023890286Sobrien			     (parallel [(const_int 1)])))
2023990286Sobrien           (plus:SF
2024090286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
2024190286Sobrien			     (parallel [(const_int  0)]))
2024290286Sobrien              (vec_select:SF (match_dup 2)
2024390286Sobrien			     (parallel [(const_int 1)])))))]
2024490286Sobrien  "TARGET_3DNOW"
2024590286Sobrien  "pfacc\\t{%2, %0|%0, %2}"
20246117404Skan  [(set_attr "type" "mmxadd")
20247117404Skan   (set_attr "mode" "V2SF")])
2024890286Sobrien
2024990286Sobrien(define_insn "pfnacc"
2025090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2025190286Sobrien  	(vec_concat:V2SF
2025290286Sobrien           (minus:SF
2025390286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
2025490286Sobrien			     (parallel [(const_int 0)]))
2025590286Sobrien              (vec_select:SF (match_dup 1)
2025690286Sobrien			     (parallel [(const_int 1)])))
2025790286Sobrien           (minus:SF
2025890286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
2025990286Sobrien			     (parallel [(const_int  0)]))
2026090286Sobrien              (vec_select:SF (match_dup 2)
2026190286Sobrien			     (parallel [(const_int 1)])))))]
2026290286Sobrien  "TARGET_3DNOW_A"
2026390286Sobrien  "pfnacc\\t{%2, %0|%0, %2}"
20264117404Skan  [(set_attr "type" "mmxadd")
20265117404Skan   (set_attr "mode" "V2SF")])
2026690286Sobrien
2026790286Sobrien(define_insn "pfpnacc"
2026890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2026990286Sobrien        (vec_concat:V2SF
2027090286Sobrien           (minus:SF
2027190286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
2027290286Sobrien			     (parallel [(const_int 0)]))
2027390286Sobrien              (vec_select:SF (match_dup 1)
2027490286Sobrien			     (parallel [(const_int 1)])))
2027590286Sobrien           (plus:SF
2027690286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
2027790286Sobrien			     (parallel [(const_int 0)]))
2027890286Sobrien              (vec_select:SF (match_dup 2)
2027990286Sobrien			     (parallel [(const_int 1)])))))]
2028090286Sobrien  "TARGET_3DNOW_A"
2028190286Sobrien  "pfpnacc\\t{%2, %0|%0, %2}"
20282117404Skan  [(set_attr "type" "mmxadd")
20283117404Skan   (set_attr "mode" "V2SF")])
2028490286Sobrien
2028590286Sobrien(define_insn "pi2fw"
2028690286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2028790286Sobrien	(float:V2SF
2028890286Sobrien	   (vec_concat:V2SI
2028990286Sobrien	      (sign_extend:SI
2029090286Sobrien		 (truncate:HI
2029190286Sobrien		    (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
2029290286Sobrien				   (parallel [(const_int 0)]))))
2029390286Sobrien              (sign_extend:SI
2029490286Sobrien		 (truncate:HI
2029590286Sobrien                    (vec_select:SI (match_dup 1)
2029690286Sobrien				   (parallel [(const_int  1)])))))))]
2029790286Sobrien  "TARGET_3DNOW_A"
2029890286Sobrien  "pi2fw\\t{%1, %0|%0, %1}"
20299117404Skan  [(set_attr "type" "mmxcvt")
20300117404Skan   (set_attr "mode" "V2SF")])
2030190286Sobrien
2030290286Sobrien(define_insn "floatv2si2"
2030390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2030490286Sobrien	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
2030590286Sobrien  "TARGET_3DNOW"
2030690286Sobrien  "pi2fd\\t{%1, %0|%0, %1}"
20307117404Skan  [(set_attr "type" "mmxcvt")
20308117404Skan   (set_attr "mode" "V2SF")])
2030990286Sobrien
2031090286Sobrien;; This insn is identical to pavgb in operation, but the opcode is
2031190286Sobrien;; different.  To avoid accidentally matching pavgb, use an unspec.
2031290286Sobrien
2031390286Sobrien(define_insn "pavgusb"
2031490286Sobrien [(set (match_operand:V8QI 0 "register_operand" "=y")
2031590286Sobrien       (unspec:V8QI
2031690286Sobrien          [(match_operand:V8QI 1 "register_operand" "0")
20317117404Skan           (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20318117404Skan	  UNSPEC_PAVGUSB))]
2031990286Sobrien  "TARGET_3DNOW"
2032090286Sobrien  "pavgusb\\t{%2, %0|%0, %2}"
20321117404Skan  [(set_attr "type" "mmxshft")
20322117404Skan   (set_attr "mode" "TI")])
2032390286Sobrien
2032490286Sobrien;; 3DNow reciprical and sqrt
2032590286Sobrien 
2032690286Sobrien(define_insn "pfrcpv2sf2"
2032790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
20328117404Skan        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
20329117404Skan	UNSPEC_PFRCP))]
2033090286Sobrien  "TARGET_3DNOW"
2033190286Sobrien  "pfrcp\\t{%1, %0|%0, %1}"
20332117404Skan  [(set_attr "type" "mmx")
20333117404Skan   (set_attr "mode" "TI")])
2033490286Sobrien
2033590286Sobrien(define_insn "pfrcpit1v2sf3"
2033690286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2033790286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20338117404Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20339117404Skan		     UNSPEC_PFRCPIT1))]
2034090286Sobrien  "TARGET_3DNOW"
2034190286Sobrien  "pfrcpit1\\t{%2, %0|%0, %2}"
20342117404Skan  [(set_attr "type" "mmx")
20343117404Skan   (set_attr "mode" "TI")])
2034490286Sobrien
2034590286Sobrien(define_insn "pfrcpit2v2sf3"
2034690286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2034790286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20348117404Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20349117404Skan		     UNSPEC_PFRCPIT2))]
2035090286Sobrien  "TARGET_3DNOW"
2035190286Sobrien  "pfrcpit2\\t{%2, %0|%0, %2}"
20352117404Skan  [(set_attr "type" "mmx")
20353117404Skan   (set_attr "mode" "TI")])
2035490286Sobrien
2035590286Sobrien(define_insn "pfrsqrtv2sf2"
2035690286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
20357117404Skan	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
20358117404Skan		     UNSPEC_PFRSQRT))]
2035990286Sobrien  "TARGET_3DNOW"
20360117404Skan  "pfrsqrt\\t{%1, %0|%0, %1}"
20361117404Skan  [(set_attr "type" "mmx")
20362117404Skan   (set_attr "mode" "TI")])
2036390286Sobrien		
2036490286Sobrien(define_insn "pfrsqit1v2sf3"
2036590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2036690286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20367117404Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20368117404Skan		     UNSPEC_PFRSQIT1))]
2036990286Sobrien  "TARGET_3DNOW"
2037090286Sobrien  "pfrsqit1\\t{%2, %0|%0, %2}"
20371117404Skan  [(set_attr "type" "mmx")
20372117404Skan   (set_attr "mode" "TI")])
2037390286Sobrien
2037490286Sobrien(define_insn "pmulhrwv4hi3"
2037590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2037690286Sobrien	(truncate:V4HI
2037790286Sobrien	   (lshiftrt:V4SI
2037890286Sobrien	      (plus:V4SI
2037990286Sobrien	         (mult:V4SI
2038090286Sobrien	            (sign_extend:V4SI
2038190286Sobrien		       (match_operand:V4HI 1 "register_operand" "0"))
2038290286Sobrien	            (sign_extend:V4SI
2038390286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
2038496294Sobrien		 (const_vector:V4SI [(const_int 32768)
2038596294Sobrien				     (const_int 32768)
2038696294Sobrien				     (const_int 32768)
2038796294Sobrien				     (const_int 32768)]))
2038896294Sobrien	      (const_int 16))))]
2038990286Sobrien  "TARGET_3DNOW"
2039090286Sobrien  "pmulhrw\\t{%2, %0|%0, %2}"
20391117404Skan  [(set_attr "type" "mmxmul")
20392117404Skan   (set_attr "mode" "TI")])
2039390286Sobrien
2039490286Sobrien(define_insn "pswapdv2si2"
2039590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2039690286Sobrien	(vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
2039790286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
2039890286Sobrien  "TARGET_3DNOW_A"
2039990286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
20400117404Skan  [(set_attr "type" "mmxcvt")
20401117404Skan   (set_attr "mode" "TI")])
2040290286Sobrien
2040390286Sobrien(define_insn "pswapdv2sf2"
2040490286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2040590286Sobrien	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
2040690286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
2040790286Sobrien  "TARGET_3DNOW_A"
2040890286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
20409117404Skan  [(set_attr "type" "mmxcvt")
20410117404Skan   (set_attr "mode" "TI")])
2041190286Sobrien
2041290286Sobrien(define_expand "prefetch"
20413102802Skan  [(prefetch (match_operand 0 "address_operand" "")
2041490286Sobrien	     (match_operand:SI 1 "const_int_operand" "")
2041590286Sobrien	     (match_operand:SI 2 "const_int_operand" ""))]
2041690286Sobrien  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
2041756391Sobrien{
2041890286Sobrien  int rw = INTVAL (operands[1]);
2041990286Sobrien  int locality = INTVAL (operands[2]);
2042090286Sobrien
2042190286Sobrien  if (rw != 0 && rw != 1)
2042290286Sobrien    abort ();
2042390286Sobrien  if (locality < 0 || locality > 3)
2042490286Sobrien    abort ();
20425102802Skan  if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
20426102802Skan    abort ();
2042790286Sobrien
2042890286Sobrien  /* Use 3dNOW prefetch in case we are asking for write prefetch not
2042990286Sobrien     suported by SSE counterpart or the SSE prefetch is not available
2043090286Sobrien     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
2043190286Sobrien     of locality.  */
2043290286Sobrien  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
2043390286Sobrien    operands[2] = GEN_INT (3);
2043490286Sobrien  else
2043590286Sobrien    operands[1] = const0_rtx;
2043690286Sobrien})
2043790286Sobrien
2043890286Sobrien(define_insn "*prefetch_sse"
2043990286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
2044090286Sobrien	     (const_int 0)
2044190286Sobrien	     (match_operand:SI 1 "const_int_operand" ""))]
20442102802Skan  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
2044390286Sobrien{
2044490286Sobrien  static const char * const patterns[4] = {
2044590286Sobrien   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
2044690286Sobrien  };
2044790286Sobrien
2044890286Sobrien  int locality = INTVAL (operands[1]);
2044990286Sobrien  if (locality < 0 || locality > 3)
2045090286Sobrien    abort ();
2045190286Sobrien
2045290286Sobrien  return patterns[locality];  
2045390286Sobrien}
20454102802Skan  [(set_attr "type" "sse")
20455102802Skan   (set_attr "memory" "none")])
20456102802Skan
20457102802Skan(define_insn "*prefetch_sse_rex"
20458102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
20459102802Skan	     (const_int 0)
20460102802Skan	     (match_operand:SI 1 "const_int_operand" ""))]
20461102802Skan  "TARGET_PREFETCH_SSE && TARGET_64BIT"
20462102802Skan{
20463102802Skan  static const char * const patterns[4] = {
20464102802Skan   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20465102802Skan  };
20466102802Skan
20467102802Skan  int locality = INTVAL (operands[1]);
20468102802Skan  if (locality < 0 || locality > 3)
20469102802Skan    abort ();
20470102802Skan
20471102802Skan  return patterns[locality];  
20472102802Skan}
20473117404Skan  [(set_attr "type" "sse")
20474117404Skan   (set_attr "memory" "none")])
2047590286Sobrien
2047690286Sobrien(define_insn "*prefetch_3dnow"
2047790286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
2047890286Sobrien	     (match_operand:SI 1 "const_int_operand" "n")
2047990286Sobrien	     (const_int 3))]
20480102802Skan  "TARGET_3DNOW && !TARGET_64BIT"
2048190286Sobrien{
2048290286Sobrien  if (INTVAL (operands[1]) == 0)
2048390286Sobrien    return "prefetch\t%a0";
2048490286Sobrien  else
2048590286Sobrien    return "prefetchw\t%a0";
2048690286Sobrien}
20487102802Skan  [(set_attr "type" "mmx")
20488102802Skan   (set_attr "memory" "none")])
20489102802Skan
20490102802Skan(define_insn "*prefetch_3dnow_rex"
20491102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
20492102802Skan	     (match_operand:SI 1 "const_int_operand" "n")
20493102802Skan	     (const_int 3))]
20494102802Skan  "TARGET_3DNOW && TARGET_64BIT"
20495102802Skan{
20496102802Skan  if (INTVAL (operands[1]) == 0)
20497102802Skan    return "prefetch\t%a0";
20498102802Skan  else
20499102802Skan    return "prefetchw\t%a0";
20500102802Skan}
20501117404Skan  [(set_attr "type" "mmx")
20502117404Skan   (set_attr "memory" "none")])
20503117404Skan
20504117404Skan;; SSE2 support
20505117404Skan
20506117404Skan(define_insn "addv2df3"
20507117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20508117404Skan        (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20509117404Skan	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20510117404Skan  "TARGET_SSE2"
20511117404Skan  "addpd\t{%2, %0|%0, %2}"
20512117404Skan  [(set_attr "type" "sseadd")
20513117404Skan   (set_attr "mode" "V2DF")])
20514117404Skan
20515117404Skan(define_insn "vmaddv2df3"
20516117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20517117404Skan	(vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20518117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20519117404Skan                        (match_dup 1)
20520117404Skan			(const_int 1)))]
20521117404Skan  "TARGET_SSE2"
20522117404Skan  "addsd\t{%2, %0|%0, %2}"
20523117404Skan  [(set_attr "type" "sseadd")
20524117404Skan   (set_attr "mode" "DF")])
20525117404Skan
20526117404Skan(define_insn "subv2df3"
20527117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20528117404Skan        (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20529117404Skan	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20530117404Skan  "TARGET_SSE2"
20531117404Skan  "subpd\t{%2, %0|%0, %2}"
20532117404Skan  [(set_attr "type" "sseadd")
20533117404Skan   (set_attr "mode" "V2DF")])
20534117404Skan
20535117404Skan(define_insn "vmsubv2df3"
20536117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20537117404Skan	(vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
20538117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20539117404Skan                        (match_dup 1)
20540117404Skan			(const_int 1)))]
20541117404Skan  "TARGET_SSE2"
20542117404Skan  "subsd\t{%2, %0|%0, %2}"
20543117404Skan  [(set_attr "type" "sseadd")
20544117404Skan   (set_attr "mode" "DF")])
20545117404Skan
20546117404Skan(define_insn "mulv2df3"
20547117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20548117404Skan        (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
20549117404Skan	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20550117404Skan  "TARGET_SSE2"
20551117404Skan  "mulpd\t{%2, %0|%0, %2}"
20552117404Skan  [(set_attr "type" "ssemul")
20553117404Skan   (set_attr "mode" "V2DF")])
20554117404Skan
20555117404Skan(define_insn "vmmulv2df3"
20556117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20557117404Skan	(vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
20558117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20559117404Skan                        (match_dup 1)
20560117404Skan			(const_int 1)))]
20561117404Skan  "TARGET_SSE2"
20562117404Skan  "mulsd\t{%2, %0|%0, %2}"
20563117404Skan  [(set_attr "type" "ssemul")
20564117404Skan   (set_attr "mode" "DF")])
20565117404Skan
20566117404Skan(define_insn "divv2df3"
20567117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20568117404Skan        (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
20569117404Skan	          (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20570117404Skan  "TARGET_SSE2"
20571117404Skan  "divpd\t{%2, %0|%0, %2}"
20572117404Skan  [(set_attr "type" "ssediv")
20573117404Skan   (set_attr "mode" "V2DF")])
20574117404Skan
20575117404Skan(define_insn "vmdivv2df3"
20576117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20577117404Skan	(vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
20578117404Skan				  (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20579117404Skan                        (match_dup 1)
20580117404Skan			(const_int 1)))]
20581117404Skan  "TARGET_SSE2"
20582117404Skan  "divsd\t{%2, %0|%0, %2}"
20583117404Skan  [(set_attr "type" "ssediv")
20584117404Skan   (set_attr "mode" "DF")])
20585117404Skan
20586117404Skan;; SSE min/max
20587117404Skan
20588117404Skan(define_insn "smaxv2df3"
20589117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20590117404Skan        (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
20591117404Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20592117404Skan  "TARGET_SSE2"
20593117404Skan  "maxpd\t{%2, %0|%0, %2}"
20594117404Skan  [(set_attr "type" "sseadd")
20595117404Skan   (set_attr "mode" "V2DF")])
20596117404Skan
20597117404Skan(define_insn "vmsmaxv2df3"
20598117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20599117404Skan	(vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
20600117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20601117404Skan                        (match_dup 1)
20602117404Skan			(const_int 1)))]
20603117404Skan  "TARGET_SSE2"
20604117404Skan  "maxsd\t{%2, %0|%0, %2}"
20605117404Skan  [(set_attr "type" "sseadd")
20606117404Skan   (set_attr "mode" "DF")])
20607117404Skan
20608117404Skan(define_insn "sminv2df3"
20609117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20610117404Skan        (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
20611117404Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20612117404Skan  "TARGET_SSE2"
20613117404Skan  "minpd\t{%2, %0|%0, %2}"
20614117404Skan  [(set_attr "type" "sseadd")
20615117404Skan   (set_attr "mode" "V2DF")])
20616117404Skan
20617117404Skan(define_insn "vmsminv2df3"
20618117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20619117404Skan	(vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
20620117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
20621117404Skan                        (match_dup 1)
20622117404Skan			(const_int 1)))]
20623117404Skan  "TARGET_SSE2"
20624117404Skan  "minsd\t{%2, %0|%0, %2}"
20625117404Skan  [(set_attr "type" "sseadd")
20626117404Skan   (set_attr "mode" "DF")])
20627117404Skan;; SSE2 square root.  There doesn't appear to be an extension for the
20628117404Skan;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
20629117404Skan
20630117404Skan(define_insn "sqrtv2df2"
20631117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20632117404Skan        (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
20633117404Skan  "TARGET_SSE2"
20634117404Skan  "sqrtpd\t{%1, %0|%0, %1}"
20635117404Skan  [(set_attr "type" "sse")
20636117404Skan   (set_attr "mode" "V2DF")])
20637117404Skan
20638117404Skan(define_insn "vmsqrtv2df2"
20639117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20640117404Skan	(vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
20641117404Skan                        (match_operand:V2DF 2 "register_operand" "0")
20642117404Skan			(const_int 1)))]
20643117404Skan  "TARGET_SSE2"
20644117404Skan  "sqrtsd\t{%1, %0|%0, %1}"
20645117404Skan  [(set_attr "type" "sse")
20646117404Skan   (set_attr "mode" "SF")])
20647117404Skan
20648117404Skan;; SSE mask-generating compares
20649117404Skan
20650117404Skan(define_insn "maskcmpv2df3"
20651117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
20652117404Skan        (match_operator:V2DI 3 "sse_comparison_operator"
20653117404Skan			     [(match_operand:V2DF 1 "register_operand" "0")
20654117404Skan			      (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
20655117404Skan  "TARGET_SSE2"
20656117404Skan  "cmp%D3pd\t{%2, %0|%0, %2}"
20657117404Skan  [(set_attr "type" "ssecmp")
20658117404Skan   (set_attr "mode" "V2DF")])
20659117404Skan
20660117404Skan(define_insn "maskncmpv2df3"
20661117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
20662117404Skan        (not:V2DI
20663117404Skan	 (match_operator:V2DI 3 "sse_comparison_operator"
20664117404Skan			      [(match_operand:V2DF 1 "register_operand" "0")
20665117404Skan			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
20666117404Skan  "TARGET_SSE2"
20667117404Skan{
20668117404Skan  if (GET_CODE (operands[3]) == UNORDERED)
20669117404Skan    return "cmpordps\t{%2, %0|%0, %2}";
20670117404Skan  else
20671117404Skan    return "cmpn%D3pd\t{%2, %0|%0, %2}";
20672117404Skan}
20673117404Skan  [(set_attr "type" "ssecmp")
20674117404Skan   (set_attr "mode" "V2DF")])
20675117404Skan
20676117404Skan(define_insn "vmmaskcmpv2df3"
20677117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
20678117404Skan	(vec_merge:V2DI
20679117404Skan	 (match_operator:V2DI 3 "sse_comparison_operator"
20680117404Skan			      [(match_operand:V2DF 1 "register_operand" "0")
20681117404Skan			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])
20682117404Skan	 (subreg:V2DI (match_dup 1) 0)
20683117404Skan	 (const_int 1)))]
20684117404Skan  "TARGET_SSE2"
20685117404Skan  "cmp%D3sd\t{%2, %0|%0, %2}"
20686117404Skan  [(set_attr "type" "ssecmp")
20687117404Skan   (set_attr "mode" "DF")])
20688117404Skan
20689117404Skan(define_insn "vmmaskncmpv2df3"
20690117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
20691117404Skan	(vec_merge:V2DI
20692117404Skan	 (not:V2DI
20693117404Skan	  (match_operator:V2DI 3 "sse_comparison_operator"
20694117404Skan			       [(match_operand:V2DF 1 "register_operand" "0")
20695117404Skan				(match_operand:V2DF 2 "nonimmediate_operand" "x")]))
20696117404Skan	 (subreg:V2DI (match_dup 1) 0)
20697117404Skan	 (const_int 1)))]
20698117404Skan  "TARGET_SSE2"
20699117404Skan{
20700117404Skan  if (GET_CODE (operands[3]) == UNORDERED)
20701117404Skan    return "cmpordsd\t{%2, %0|%0, %2}";
20702117404Skan  else
20703117404Skan    return "cmpn%D3sd\t{%2, %0|%0, %2}";
20704117404Skan}
20705117404Skan  [(set_attr "type" "ssecmp")
20706117404Skan   (set_attr "mode" "DF")])
20707117404Skan
20708117404Skan(define_insn "sse2_comi"
20709117404Skan  [(set (reg:CCFP 17)
20710117404Skan        (compare:CCFP (vec_select:DF
20711117404Skan		       (match_operand:V2DF 0 "register_operand" "x")
20712117404Skan		       (parallel [(const_int 0)]))
20713117404Skan		      (vec_select:DF
20714117404Skan		       (match_operand:V2DF 1 "register_operand" "x")
20715117404Skan		       (parallel [(const_int 0)]))))]
20716117404Skan  "TARGET_SSE2"
20717117404Skan  "comisd\t{%1, %0|%0, %1}"
20718117404Skan  [(set_attr "type" "ssecmp")
20719117404Skan   (set_attr "mode" "DF")])
20720117404Skan
20721117404Skan(define_insn "sse2_ucomi"
20722117404Skan  [(set (reg:CCFPU 17)
20723117404Skan	(compare:CCFPU (vec_select:DF
20724117404Skan			 (match_operand:V2DF 0 "register_operand" "x")
20725117404Skan			 (parallel [(const_int 0)]))
20726117404Skan			(vec_select:DF
20727117404Skan			 (match_operand:V2DF 1 "register_operand" "x")
20728117404Skan			 (parallel [(const_int 0)]))))]
20729117404Skan  "TARGET_SSE2"
20730117404Skan  "ucomisd\t{%1, %0|%0, %1}"
20731117404Skan  [(set_attr "type" "ssecmp")
20732117404Skan   (set_attr "mode" "DF")])
20733117404Skan
20734117404Skan;; SSE Strange Moves.
20735117404Skan
20736117404Skan(define_insn "sse2_movmskpd"
20737117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
20738117404Skan	(unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
20739117404Skan		   UNSPEC_MOVMSK))]
20740117404Skan  "TARGET_SSE2"
20741117404Skan  "movmskpd\t{%1, %0|%0, %1}"
20742117404Skan  [(set_attr "type" "ssecvt")
20743117404Skan   (set_attr "mode" "V2DF")])
20744117404Skan
20745117404Skan(define_insn "sse2_pmovmskb"
20746117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
20747117404Skan	(unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
20748117404Skan		   UNSPEC_MOVMSK))]
20749117404Skan  "TARGET_SSE2"
20750117404Skan  "pmovmskb\t{%1, %0|%0, %1}"
20751117404Skan  [(set_attr "type" "ssecvt")
20752117404Skan   (set_attr "mode" "V2DF")])
20753117404Skan
20754117404Skan(define_insn "sse2_maskmovdqu"
20755117404Skan  [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
20756117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
20757117404Skan		       (match_operand:V16QI 2 "register_operand" "x")]
20758117404Skan		      UNSPEC_MASKMOV))]
20759117404Skan  "TARGET_SSE2"
20760117404Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
20761117404Skan  "maskmovdqu\t{%2, %1|%1, %2}"
20762117404Skan  [(set_attr "type" "ssecvt")
20763117404Skan   (set_attr "mode" "TI")])
20764117404Skan
20765117404Skan(define_insn "sse2_maskmovdqu_rex64"
20766117404Skan  [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
20767117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
20768117404Skan		       (match_operand:V16QI 2 "register_operand" "x")]
20769117404Skan		      UNSPEC_MASKMOV))]
20770117404Skan  "TARGET_SSE2"
20771117404Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
20772117404Skan  "maskmovdqu\t{%2, %1|%1, %2}"
20773117404Skan  [(set_attr "type" "ssecvt")
20774117404Skan   (set_attr "mode" "TI")])
20775117404Skan
20776117404Skan(define_insn "sse2_movntv2df"
20777117404Skan  [(set (match_operand:V2DF 0 "memory_operand" "=m")
20778117404Skan	(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
20779117404Skan		     UNSPEC_MOVNT))]
20780117404Skan  "TARGET_SSE2"
20781117404Skan  "movntpd\t{%1, %0|%0, %1}"
20782117404Skan  [(set_attr "type" "ssecvt")
20783117404Skan   (set_attr "mode" "V2DF")])
20784117404Skan
20785117404Skan(define_insn "sse2_movntv2di"
20786117404Skan  [(set (match_operand:V2DI 0 "memory_operand" "=m")
20787117404Skan	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
20788117404Skan		     UNSPEC_MOVNT))]
20789117404Skan  "TARGET_SSE2"
20790117404Skan  "movntdq\t{%1, %0|%0, %1}"
20791117404Skan  [(set_attr "type" "ssecvt")
20792117404Skan   (set_attr "mode" "TI")])
20793117404Skan
20794117404Skan(define_insn "sse2_movntsi"
20795117404Skan  [(set (match_operand:SI 0 "memory_operand" "=m")
20796117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
20797117404Skan		   UNSPEC_MOVNT))]
20798117404Skan  "TARGET_SSE2"
20799117404Skan  "movnti\t{%1, %0|%0, %1}"
20800117404Skan  [(set_attr "type" "ssecvt")
20801117404Skan   (set_attr "mode" "V2DF")])
20802117404Skan
20803117404Skan;; SSE <-> integer/MMX conversions
20804117404Skan
20805117404Skan;; Conversions between SI and SF
20806117404Skan
20807117404Skan(define_insn "cvtdq2ps"
20808117404Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
20809117404Skan	(float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
20810117404Skan  "TARGET_SSE2"
20811117404Skan  "cvtdq2ps\t{%1, %0|%0, %1}"
20812117404Skan  [(set_attr "type" "ssecvt")
20813117404Skan   (set_attr "mode" "V2DF")])
20814117404Skan
20815117404Skan(define_insn "cvtps2dq"
20816117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
20817117404Skan	(fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20818117404Skan  "TARGET_SSE2"
20819117404Skan  "cvtps2dq\t{%1, %0|%0, %1}"
20820117404Skan  [(set_attr "type" "ssecvt")
20821117404Skan   (set_attr "mode" "TI")])
20822117404Skan
20823117404Skan(define_insn "cvttps2dq"
20824117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
20825117404Skan	(unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20826117404Skan		     UNSPEC_FIX))]
20827117404Skan  "TARGET_SSE2"
20828117404Skan  "cvttps2dq\t{%1, %0|%0, %1}"
20829117404Skan  [(set_attr "type" "ssecvt")
20830117404Skan   (set_attr "mode" "TI")])
20831117404Skan
20832117404Skan;; Conversions between SI and DF
20833117404Skan
20834117404Skan(define_insn "cvtdq2pd"
20835117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20836117404Skan	(float:V2DF (vec_select:V2SI
20837117404Skan		     (match_operand:V4SI 1 "nonimmediate_operand" "xm")
20838117404Skan		     (parallel
20839117404Skan		      [(const_int 0)
20840117404Skan		       (const_int 1)]))))]
20841117404Skan  "TARGET_SSE2"
20842117404Skan  "cvtdq2pd\t{%1, %0|%0, %1}"
20843117404Skan  [(set_attr "type" "ssecvt")
20844117404Skan   (set_attr "mode" "V2DF")])
20845117404Skan
20846117404Skan(define_insn "cvtpd2dq"
20847117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
20848117404Skan	(vec_concat:V4SI
20849117404Skan	 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
20850117404Skan	 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
20851117404Skan  "TARGET_SSE2"
20852117404Skan  "cvtpd2dq\t{%1, %0|%0, %1}"
20853117404Skan  [(set_attr "type" "ssecvt")
20854117404Skan   (set_attr "mode" "TI")])
20855117404Skan
20856117404Skan(define_insn "cvttpd2dq"
20857117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
20858117404Skan	(vec_concat:V4SI
20859117404Skan	 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
20860117404Skan		      UNSPEC_FIX)
20861117404Skan	 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
20862117404Skan  "TARGET_SSE2"
20863117404Skan  "cvttpd2dq\t{%1, %0|%0, %1}"
20864117404Skan  [(set_attr "type" "ssecvt")
20865117404Skan   (set_attr "mode" "TI")])
20866117404Skan
20867117404Skan(define_insn "cvtpd2pi"
20868117404Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
20869117404Skan	(fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
20870117404Skan  "TARGET_SSE2"
20871117404Skan  "cvtpd2pi\t{%1, %0|%0, %1}"
20872117404Skan  [(set_attr "type" "ssecvt")
20873117404Skan   (set_attr "mode" "TI")])
20874117404Skan
20875117404Skan(define_insn "cvttpd2pi"
20876117404Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
20877117404Skan	(unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
20878117404Skan		     UNSPEC_FIX))]
20879117404Skan  "TARGET_SSE2"
20880117404Skan  "cvttpd2pi\t{%1, %0|%0, %1}"
20881117404Skan  [(set_attr "type" "ssecvt")
20882117404Skan   (set_attr "mode" "TI")])
20883117404Skan
20884117404Skan(define_insn "cvtpi2pd"
20885117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20886117404Skan	(float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
20887117404Skan  "TARGET_SSE2"
20888117404Skan  "cvtpi2pd\t{%1, %0|%0, %1}"
20889117404Skan  [(set_attr "type" "ssecvt")
20890117404Skan   (set_attr "mode" "TI")])
20891117404Skan
20892117404Skan;; Conversions between SI and DF
20893117404Skan
20894117404Skan(define_insn "cvtsd2si"
20895117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
20896117404Skan	(fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
20897117404Skan			       (parallel [(const_int 0)]))))]
20898117404Skan  "TARGET_SSE2"
20899117404Skan  "cvtsd2si\t{%1, %0|%0, %1}"
20900117404Skan  [(set_attr "type" "ssecvt")
20901117404Skan   (set_attr "mode" "SI")])
20902117404Skan
20903117404Skan(define_insn "cvtsd2siq"
20904117404Skan  [(set (match_operand:DI 0 "register_operand" "=r")
20905117404Skan	(fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
20906117404Skan			       (parallel [(const_int 0)]))))]
20907117404Skan  "TARGET_SSE2 && TARGET_64BIT"
20908117404Skan  "cvtsd2siq\t{%1, %0|%0, %1}"
20909117404Skan  [(set_attr "type" "ssecvt")
20910117404Skan   (set_attr "mode" "SI")])
20911117404Skan
20912117404Skan(define_insn "cvttsd2si"
20913117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
20914117404Skan	(unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
20915117404Skan				   (parallel [(const_int 0)]))] UNSPEC_FIX))]
20916117404Skan  "TARGET_SSE2"
20917117404Skan  "cvttsd2si\t{%1, %0|%0, %1}"
20918117404Skan  [(set_attr "type" "ssecvt")
20919117404Skan   (set_attr "mode" "SI")])
20920117404Skan
20921117404Skan(define_insn "cvttsd2siq"
20922117404Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
20923117404Skan	(unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
20924117404Skan				   (parallel [(const_int 0)]))] UNSPEC_FIX))]
20925117404Skan  "TARGET_SSE2 && TARGET_64BIT"
20926117404Skan  "cvttsd2siq\t{%1, %0|%0, %1}"
20927117404Skan  [(set_attr "type" "ssecvt")
20928117404Skan   (set_attr "mode" "DI")
20929117404Skan   (set_attr "athlon_decode" "vector,vector")])
20930117404Skan
20931117404Skan(define_insn "cvtsi2sd"
20932117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20933117404Skan	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
20934117404Skan	 		(vec_duplicate:V2DF
20935117404Skan			  (float:DF
20936117404Skan			    (match_operand:SI 2 "nonimmediate_operand" "rm")))
20937117404Skan			(const_int 2)))]
20938117404Skan  "TARGET_SSE2"
20939117404Skan  "cvtsi2sd\t{%2, %0|%0, %2}"
20940117404Skan  [(set_attr "type" "ssecvt")
20941117404Skan   (set_attr "mode" "DF")])
20942117404Skan
20943117404Skan(define_insn "cvtsi2sdq"
20944117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
20945117404Skan	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
20946117404Skan	 		(vec_duplicate:V2DF
20947117404Skan			  (float:DF
20948117404Skan			    (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20949117404Skan			(const_int 2)))]
20950117404Skan  "TARGET_SSE2 && TARGET_64BIT"
20951117404Skan  "cvtsi2sdq\t{%2, %0|%0, %2}"
20952117404Skan  [(set_attr "type" "ssecvt")
20953117404Skan   (set_attr "mode" "DF")
20954117404Skan   (set_attr "athlon_decode" "vector,direct")])
20955117404Skan
20956117404Skan;; Conversions between SF and DF
20957117404Skan
20958117404Skan(define_insn "cvtsd2ss"
20959117404Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
20960117404Skan	(vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
20961117404Skan	 		(vec_duplicate:V4SF
20962117404Skan			  (float_truncate:V2SF
20963117404Skan			    (match_operand:V2DF 2 "register_operand" "xm")))
20964117404Skan			(const_int 14)))]
20965117404Skan  "TARGET_SSE2"
20966117404Skan  "cvtsd2ss\t{%2, %0|%0, %2}"
20967117404Skan  [(set_attr "type" "ssecvt")
20968117404Skan   (set_attr "mode" "SF")])
20969117404Skan
20970117404Skan(define_insn "cvtss2sd"
20971117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20972117404Skan	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
20973117404Skan	 		(float_extend:V2DF
20974117404Skan			  (vec_select:V2SF
20975117404Skan			    (match_operand:V4SF 2 "register_operand" "xm")
20976117404Skan			    (parallel [(const_int 0)
20977117404Skan				       (const_int 1)])))
20978117404Skan			(const_int 2)))]
20979117404Skan  "TARGET_SSE2"
20980117404Skan  "cvtss2sd\t{%2, %0|%0, %2}"
20981117404Skan  [(set_attr "type" "ssecvt")
20982117404Skan   (set_attr "mode" "DF")])
20983117404Skan
20984117404Skan(define_insn "cvtpd2ps"
20985117404Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
20986117404Skan	(subreg:V4SF
20987117404Skan	  (vec_concat:V4SI
20988117404Skan	    (subreg:V2SI (float_truncate:V2SF
20989117404Skan			   (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
20990117404Skan	    (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
20991117404Skan  "TARGET_SSE2"
20992117404Skan  "cvtpd2ps\t{%1, %0|%0, %1}"
20993117404Skan  [(set_attr "type" "ssecvt")
20994117404Skan   (set_attr "mode" "V4SF")])
20995117404Skan
20996117404Skan(define_insn "cvtps2pd"
20997117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
20998117404Skan	(float_extend:V2DF
20999117404Skan	  (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21000117404Skan			   (parallel [(const_int 0)
21001117404Skan				      (const_int 1)]))))]
21002117404Skan  "TARGET_SSE2"
21003117404Skan  "cvtps2pd\t{%1, %0|%0, %1}"
21004117404Skan  [(set_attr "type" "ssecvt")
21005117404Skan   (set_attr "mode" "V2DF")])
21006117404Skan
21007117404Skan;; SSE2 variants of MMX insns
21008117404Skan
21009117404Skan;; MMX arithmetic
21010117404Skan
21011117404Skan(define_insn "addv16qi3"
21012117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21013117404Skan        (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21014117404Skan		    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21015117404Skan  "TARGET_SSE2"
21016117404Skan  "paddb\t{%2, %0|%0, %2}"
21017117404Skan  [(set_attr "type" "sseiadd")
21018117404Skan   (set_attr "mode" "TI")])
21019117404Skan
21020117404Skan(define_insn "addv8hi3"
21021117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21022117404Skan        (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21023117404Skan	           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21024117404Skan  "TARGET_SSE2"
21025117404Skan  "paddw\t{%2, %0|%0, %2}"
21026117404Skan  [(set_attr "type" "sseiadd")
21027117404Skan   (set_attr "mode" "TI")])
21028117404Skan
21029117404Skan(define_insn "addv4si3"
21030117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21031117404Skan        (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21032117404Skan	           (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21033117404Skan  "TARGET_SSE2"
21034117404Skan  "paddd\t{%2, %0|%0, %2}"
21035117404Skan  [(set_attr "type" "sseiadd")
21036117404Skan   (set_attr "mode" "TI")])
21037117404Skan
21038117404Skan(define_insn "addv2di3"
21039117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21040117404Skan        (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21041117404Skan	           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21042117404Skan  "TARGET_SSE2"
21043117404Skan  "paddq\t{%2, %0|%0, %2}"
21044117404Skan  [(set_attr "type" "sseiadd")
21045117404Skan   (set_attr "mode" "TI")])
21046117404Skan
21047117404Skan(define_insn "ssaddv16qi3"
21048117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21049117404Skan        (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21050117404Skan		       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21051117404Skan  "TARGET_SSE2"
21052117404Skan  "paddsb\t{%2, %0|%0, %2}"
21053117404Skan  [(set_attr "type" "sseiadd")
21054117404Skan   (set_attr "mode" "TI")])
21055117404Skan
21056117404Skan(define_insn "ssaddv8hi3"
21057117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21058117404Skan        (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21059117404Skan		      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21060117404Skan  "TARGET_SSE2"
21061117404Skan  "paddsw\t{%2, %0|%0, %2}"
21062117404Skan  [(set_attr "type" "sseiadd")
21063117404Skan   (set_attr "mode" "TI")])
21064117404Skan
21065117404Skan(define_insn "usaddv16qi3"
21066117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21067117404Skan        (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21068117404Skan		       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21069117404Skan  "TARGET_SSE2"
21070117404Skan  "paddusb\t{%2, %0|%0, %2}"
21071117404Skan  [(set_attr "type" "sseiadd")
21072117404Skan   (set_attr "mode" "TI")])
21073117404Skan
21074117404Skan(define_insn "usaddv8hi3"
21075117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21076117404Skan        (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21077117404Skan		      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21078117404Skan  "TARGET_SSE2"
21079117404Skan  "paddusw\t{%2, %0|%0, %2}"
21080117404Skan  [(set_attr "type" "sseiadd")
21081117404Skan   (set_attr "mode" "TI")])
21082117404Skan
21083117404Skan(define_insn "subv16qi3"
21084117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21085117404Skan        (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21086117404Skan		     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21087117404Skan  "TARGET_SSE2"
21088117404Skan  "psubb\t{%2, %0|%0, %2}"
21089117404Skan  [(set_attr "type" "sseiadd")
21090117404Skan   (set_attr "mode" "TI")])
21091117404Skan
21092117404Skan(define_insn "subv8hi3"
21093117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21094117404Skan        (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21095117404Skan		    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21096117404Skan  "TARGET_SSE2"
21097117404Skan  "psubw\t{%2, %0|%0, %2}"
21098117404Skan  [(set_attr "type" "sseiadd")
21099117404Skan   (set_attr "mode" "TI")])
21100117404Skan
21101117404Skan(define_insn "subv4si3"
21102117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21103117404Skan        (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21104117404Skan		    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21105117404Skan  "TARGET_SSE2"
21106117404Skan  "psubd\t{%2, %0|%0, %2}"
21107117404Skan  [(set_attr "type" "sseiadd")
21108117404Skan   (set_attr "mode" "TI")])
21109117404Skan
21110117404Skan(define_insn "subv2di3"
21111117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21112117404Skan        (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21113117404Skan		    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21114117404Skan  "TARGET_SSE2"
21115117404Skan  "psubq\t{%2, %0|%0, %2}"
21116117404Skan  [(set_attr "type" "sseiadd")
21117117404Skan   (set_attr "mode" "TI")])
21118117404Skan
21119117404Skan(define_insn "sssubv16qi3"
21120117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21121117404Skan        (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21122117404Skan			(match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21123117404Skan  "TARGET_SSE2"
21124117404Skan  "psubsb\t{%2, %0|%0, %2}"
21125117404Skan  [(set_attr "type" "sseiadd")
21126117404Skan   (set_attr "mode" "TI")])
21127117404Skan
21128117404Skan(define_insn "sssubv8hi3"
21129117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21130117404Skan        (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21131117404Skan		       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21132117404Skan  "TARGET_SSE2"
21133117404Skan  "psubsw\t{%2, %0|%0, %2}"
21134117404Skan  [(set_attr "type" "sseiadd")
21135117404Skan   (set_attr "mode" "TI")])
21136117404Skan
21137117404Skan(define_insn "ussubv16qi3"
21138117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21139117404Skan        (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21140117404Skan			(match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21141117404Skan  "TARGET_SSE2"
21142117404Skan  "psubusb\t{%2, %0|%0, %2}"
21143117404Skan  [(set_attr "type" "sseiadd")
21144117404Skan   (set_attr "mode" "TI")])
21145117404Skan
21146117404Skan(define_insn "ussubv8hi3"
21147117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21148117404Skan        (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21149117404Skan		       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21150117404Skan  "TARGET_SSE2"
21151117404Skan  "psubusw\t{%2, %0|%0, %2}"
21152117404Skan  [(set_attr "type" "sseiadd")
21153117404Skan   (set_attr "mode" "TI")])
21154117404Skan
21155117404Skan(define_insn "mulv8hi3"
21156117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21157117404Skan        (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21158117404Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21159117404Skan  "TARGET_SSE2"
21160117404Skan  "pmullw\t{%2, %0|%0, %2}"
21161117404Skan  [(set_attr "type" "sseimul")
21162117404Skan   (set_attr "mode" "TI")])
21163117404Skan
21164117404Skan(define_insn "smulv8hi3_highpart"
21165117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21166117404Skan	(truncate:V8HI
21167117404Skan	 (lshiftrt:V8SI
21168117404Skan	  (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21169117404Skan		     (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21170117404Skan	  (const_int 16))))]
21171117404Skan  "TARGET_SSE2"
21172117404Skan  "pmulhw\t{%2, %0|%0, %2}"
21173117404Skan  [(set_attr "type" "sseimul")
21174117404Skan   (set_attr "mode" "TI")])
21175117404Skan
21176117404Skan(define_insn "umulv8hi3_highpart"
21177117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21178117404Skan	(truncate:V8HI
21179117404Skan	 (lshiftrt:V8SI
21180117404Skan	  (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21181117404Skan		     (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21182117404Skan	  (const_int 16))))]
21183117404Skan  "TARGET_SSE2"
21184117404Skan  "pmulhuw\t{%2, %0|%0, %2}"
21185117404Skan  [(set_attr "type" "sseimul")
21186117404Skan   (set_attr "mode" "TI")])
21187117404Skan
21188117404Skan(define_insn "sse2_umulsidi3"
21189117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
21190117404Skan        (mult:DI (zero_extend:DI (vec_select:SI
21191117404Skan				  (match_operand:V2SI 1 "register_operand" "0")
21192117404Skan				  (parallel [(const_int 0)])))
21193117404Skan		 (zero_extend:DI (vec_select:SI
21194117404Skan				  (match_operand:V2SI 2 "nonimmediate_operand" "ym")
21195117404Skan				  (parallel [(const_int 0)])))))]
21196117404Skan  "TARGET_SSE2"
21197117404Skan  "pmuludq\t{%2, %0|%0, %2}"
21198117404Skan  [(set_attr "type" "sseimul")
21199117404Skan   (set_attr "mode" "TI")])
21200117404Skan
21201117404Skan(define_insn "sse2_umulv2siv2di3"
21202117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21203117404Skan        (mult:V2DI (zero_extend:V2DI
21204117404Skan		     (vec_select:V2SI
21205117404Skan		       (match_operand:V4SI 1 "register_operand" "0")
21206117404Skan		       (parallel [(const_int 0) (const_int 2)])))
21207117404Skan		   (zero_extend:V2DI
21208117404Skan		     (vec_select:V2SI
21209117404Skan		       (match_operand:V4SI 2 "nonimmediate_operand" "xm")
21210117404Skan		       (parallel [(const_int 0) (const_int 2)])))))]
21211117404Skan  "TARGET_SSE2"
21212117404Skan  "pmuludq\t{%2, %0|%0, %2}"
21213117404Skan  [(set_attr "type" "sseimul")
21214117404Skan   (set_attr "mode" "TI")])
21215117404Skan
21216117404Skan(define_insn "sse2_pmaddwd"
21217117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21218117404Skan        (plus:V4SI
21219117404Skan	 (mult:V4SI
21220117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
21221117404Skan					     (parallel [(const_int 0)
21222117404Skan							(const_int 2)
21223117404Skan							(const_int 4)
21224117404Skan							(const_int 6)])))
21225117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
21226117404Skan					     (parallel [(const_int 0)
21227117404Skan							(const_int 2)
21228117404Skan							(const_int 4)
21229117404Skan							(const_int 6)]))))
21230117404Skan	 (mult:V4SI
21231117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
21232117404Skan					     (parallel [(const_int 1)
21233117404Skan							(const_int 3)
21234117404Skan							(const_int 5)
21235117404Skan							(const_int 7)])))
21236117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
21237117404Skan					     (parallel [(const_int 1)
21238117404Skan							(const_int 3)
21239117404Skan							(const_int 5)
21240117404Skan							(const_int 7)]))))))]
21241117404Skan  "TARGET_SSE2"
21242117404Skan  "pmaddwd\t{%2, %0|%0, %2}"
21243117404Skan  [(set_attr "type" "sseiadd")
21244117404Skan   (set_attr "mode" "TI")])
21245117404Skan
21246117404Skan;; Same as pxor, but don't show input operands so that we don't think
21247117404Skan;; they are live.
21248117404Skan(define_insn "sse2_clrti"
21249117404Skan  [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
21250117404Skan  "TARGET_SSE2"
21251117404Skan  "pxor\t{%0, %0|%0, %0}"
21252117404Skan  [(set_attr "type" "sseiadd")
21253117404Skan   (set_attr "memory" "none")
21254117404Skan   (set_attr "mode" "TI")])
21255117404Skan
21256117404Skan;; MMX unsigned averages/sum of absolute differences
21257117404Skan
21258117404Skan(define_insn "sse2_uavgv16qi3"
21259117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21260117404Skan        (ashiftrt:V16QI
21261117404Skan	 (plus:V16QI (plus:V16QI
21262117404Skan		     (match_operand:V16QI 1 "register_operand" "0")
21263117404Skan		     (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
21264117404Skan		     (const_vector:V16QI [(const_int 1) (const_int 1)
21265117404Skan					  (const_int 1) (const_int 1)
21266117404Skan					  (const_int 1) (const_int 1)
21267117404Skan					  (const_int 1) (const_int 1)
21268117404Skan					  (const_int 1) (const_int 1)
21269117404Skan					  (const_int 1) (const_int 1)
21270117404Skan					  (const_int 1) (const_int 1)
21271117404Skan					  (const_int 1) (const_int 1)]))
21272117404Skan	 (const_int 1)))]
21273117404Skan  "TARGET_SSE2"
21274117404Skan  "pavgb\t{%2, %0|%0, %2}"
21275117404Skan  [(set_attr "type" "sseiadd")
21276117404Skan   (set_attr "mode" "TI")])
21277117404Skan
21278117404Skan(define_insn "sse2_uavgv8hi3"
21279117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21280117404Skan        (ashiftrt:V8HI
21281117404Skan	 (plus:V8HI (plus:V8HI
21282117404Skan		     (match_operand:V8HI 1 "register_operand" "0")
21283117404Skan		     (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
21284117404Skan		    (const_vector:V8HI [(const_int 1) (const_int 1)
21285117404Skan				        (const_int 1) (const_int 1)
21286117404Skan				        (const_int 1) (const_int 1)
21287117404Skan				        (const_int 1) (const_int 1)]))
21288117404Skan	 (const_int 1)))]
21289117404Skan  "TARGET_SSE2"
21290117404Skan  "pavgw\t{%2, %0|%0, %2}"
21291117404Skan  [(set_attr "type" "sseiadd")
21292117404Skan   (set_attr "mode" "TI")])
21293117404Skan
21294117404Skan;; @@@ this isn't the right representation.
21295117404Skan(define_insn "sse2_psadbw"
21296117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21297117404Skan        (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
21298117404Skan		      (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
21299117404Skan		     UNSPEC_PSADBW))]
21300117404Skan  "TARGET_SSE2"
21301117404Skan  "psadbw\t{%2, %0|%0, %2}"
21302117404Skan  [(set_attr "type" "sseiadd")
21303117404Skan   (set_attr "mode" "TI")])
21304117404Skan
21305117404Skan
21306117404Skan;; MMX insert/extract/shuffle
21307117404Skan
21308117404Skan(define_insn "sse2_pinsrw"
21309117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21310117404Skan        (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
21311117404Skan			(vec_duplicate:V8HI
21312117404Skan			 (truncate:HI
21313117404Skan			   (match_operand:SI 2 "nonimmediate_operand" "rm")))
21314117404Skan			(match_operand:SI 3 "immediate_operand" "i")))]
21315117404Skan  "TARGET_SSE2"
21316117404Skan  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21317117404Skan  [(set_attr "type" "ssecvt")
21318117404Skan   (set_attr "mode" "TI")])
21319117404Skan
21320117404Skan(define_insn "sse2_pextrw"
21321117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
21322117404Skan        (zero_extend:SI
21323117404Skan	  (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
21324117404Skan			 (parallel
21325117404Skan			  [(match_operand:SI 2 "immediate_operand" "i")]))))]
21326117404Skan  "TARGET_SSE2"
21327117404Skan  "pextrw\t{%2, %1, %0|%0, %1, %2}"
21328117404Skan  [(set_attr "type" "ssecvt")
21329117404Skan   (set_attr "mode" "TI")])
21330117404Skan
21331117404Skan(define_insn "sse2_pshufd"
21332117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21333117404Skan        (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
21334117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
21335117404Skan		     UNSPEC_SHUFFLE))]
21336117404Skan  "TARGET_SSE2"
21337117404Skan  "pshufd\t{%2, %1, %0|%0, %1, %2}"
21338117404Skan  [(set_attr "type" "ssecvt")
21339117404Skan   (set_attr "mode" "TI")])
21340117404Skan
21341117404Skan(define_insn "sse2_pshuflw"
21342117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21343117404Skan        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
21344117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
21345117404Skan		     UNSPEC_PSHUFLW))]
21346117404Skan  "TARGET_SSE2"
21347117404Skan  "pshuflw\t{%2, %1, %0|%0, %1, %2}"
21348117404Skan  [(set_attr "type" "ssecvt")
21349117404Skan   (set_attr "mode" "TI")])
21350117404Skan
21351117404Skan(define_insn "sse2_pshufhw"
21352117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21353117404Skan        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
21354117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
21355117404Skan		     UNSPEC_PSHUFHW))]
21356117404Skan  "TARGET_SSE2"
21357117404Skan  "pshufhw\t{%2, %1, %0|%0, %1, %2}"
21358117404Skan  [(set_attr "type" "ssecvt")
21359117404Skan   (set_attr "mode" "TI")])
21360117404Skan
21361117404Skan;; MMX mask-generating comparisons
21362117404Skan
21363117404Skan(define_insn "eqv16qi3"
21364117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21365117404Skan        (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
21366117404Skan		 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21367117404Skan  "TARGET_SSE2"
21368117404Skan  "pcmpeqb\t{%2, %0|%0, %2}"
21369117404Skan  [(set_attr "type" "ssecmp")
21370117404Skan   (set_attr "mode" "TI")])
21371117404Skan
21372117404Skan(define_insn "eqv8hi3"
21373117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21374117404Skan        (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
21375117404Skan		 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21376117404Skan  "TARGET_SSE2"
21377117404Skan  "pcmpeqw\t{%2, %0|%0, %2}"
21378117404Skan  [(set_attr "type" "ssecmp")
21379117404Skan   (set_attr "mode" "TI")])
21380117404Skan
21381117404Skan(define_insn "eqv4si3"
21382117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21383117404Skan        (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
21384117404Skan		 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21385117404Skan  "TARGET_SSE2"
21386117404Skan  "pcmpeqd\t{%2, %0|%0, %2}"
21387117404Skan  [(set_attr "type" "ssecmp")
21388117404Skan   (set_attr "mode" "TI")])
21389117404Skan
21390117404Skan(define_insn "gtv16qi3"
21391117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21392117404Skan        (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
21393117404Skan		 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21394117404Skan  "TARGET_SSE2"
21395117404Skan  "pcmpgtb\t{%2, %0|%0, %2}"
21396117404Skan  [(set_attr "type" "ssecmp")
21397117404Skan   (set_attr "mode" "TI")])
21398117404Skan
21399117404Skan(define_insn "gtv8hi3"
21400117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21401117404Skan        (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21402117404Skan		 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21403117404Skan  "TARGET_SSE2"
21404117404Skan  "pcmpgtw\t{%2, %0|%0, %2}"
21405117404Skan  [(set_attr "type" "ssecmp")
21406117404Skan   (set_attr "mode" "TI")])
21407117404Skan
21408117404Skan(define_insn "gtv4si3"
21409117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21410117404Skan        (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21411117404Skan		 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21412117404Skan  "TARGET_SSE2"
21413117404Skan  "pcmpgtd\t{%2, %0|%0, %2}"
21414117404Skan  [(set_attr "type" "ssecmp")
21415117404Skan   (set_attr "mode" "TI")])
21416117404Skan
21417117404Skan
21418117404Skan;; MMX max/min insns
21419117404Skan
21420117404Skan(define_insn "umaxv16qi3"
21421117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21422117404Skan        (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
21423117404Skan		   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21424117404Skan  "TARGET_SSE2"
21425117404Skan  "pmaxub\t{%2, %0|%0, %2}"
21426117404Skan  [(set_attr "type" "sseiadd")
21427117404Skan   (set_attr "mode" "TI")])
21428117404Skan
21429117404Skan(define_insn "smaxv8hi3"
21430117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21431117404Skan        (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
21432117404Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21433117404Skan  "TARGET_SSE2"
21434117404Skan  "pmaxsw\t{%2, %0|%0, %2}"
21435117404Skan  [(set_attr "type" "sseiadd")
21436117404Skan   (set_attr "mode" "TI")])
21437117404Skan
21438117404Skan(define_insn "uminv16qi3"
21439117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21440117404Skan        (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
21441117404Skan		   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21442117404Skan  "TARGET_SSE2"
21443117404Skan  "pminub\t{%2, %0|%0, %2}"
21444117404Skan  [(set_attr "type" "sseiadd")
21445117404Skan   (set_attr "mode" "TI")])
21446117404Skan
21447117404Skan(define_insn "sminv8hi3"
21448117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21449117404Skan        (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
21450117404Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21451117404Skan  "TARGET_SSE2"
21452117404Skan  "pminsw\t{%2, %0|%0, %2}"
21453117404Skan  [(set_attr "type" "sseiadd")
21454117404Skan   (set_attr "mode" "TI")])
21455117404Skan
21456117404Skan
21457117404Skan;; MMX shifts
21458117404Skan
21459117404Skan(define_insn "ashrv8hi3"
21460117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21461117404Skan        (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21462117404Skan		       (match_operand:TI 2 "nonmemory_operand" "xi")))]
21463117404Skan  "TARGET_SSE2"
21464117404Skan  "psraw\t{%2, %0|%0, %2}"
21465117404Skan  [(set_attr "type" "sseishft")
21466117404Skan   (set_attr "mode" "TI")])
21467117404Skan
21468117404Skan(define_insn "ashrv4si3"
21469117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21470117404Skan        (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21471117404Skan		       (match_operand:TI 2 "nonmemory_operand" "xi")))]
21472117404Skan  "TARGET_SSE2"
21473117404Skan  "psrad\t{%2, %0|%0, %2}"
21474117404Skan  [(set_attr "type" "sseishft")
21475117404Skan   (set_attr "mode" "TI")])
21476117404Skan
21477117404Skan(define_insn "lshrv8hi3"
21478117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21479117404Skan        (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21480117404Skan		       (match_operand:TI 2 "nonmemory_operand" "xi")))]
21481117404Skan  "TARGET_SSE2"
21482117404Skan  "psrlw\t{%2, %0|%0, %2}"
21483117404Skan  [(set_attr "type" "sseishft")
21484117404Skan   (set_attr "mode" "TI")])
21485117404Skan
21486117404Skan(define_insn "lshrv4si3"
21487117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21488117404Skan        (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21489117404Skan		       (match_operand:TI 2 "nonmemory_operand" "xi")))]
21490117404Skan  "TARGET_SSE2"
21491117404Skan  "psrld\t{%2, %0|%0, %2}"
21492117404Skan  [(set_attr "type" "sseishft")
21493117404Skan   (set_attr "mode" "TI")])
21494117404Skan
21495117404Skan(define_insn "lshrv2di3"
21496117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21497117404Skan        (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
21498117404Skan		       (match_operand:TI 2 "nonmemory_operand" "xi")))]
21499117404Skan  "TARGET_SSE2"
21500117404Skan  "psrlq\t{%2, %0|%0, %2}"
21501117404Skan  [(set_attr "type" "sseishft")
21502117404Skan   (set_attr "mode" "TI")])
21503117404Skan
21504117404Skan(define_insn "ashlv8hi3"
21505117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21506117404Skan        (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
21507117404Skan		     (match_operand:TI 2 "nonmemory_operand" "xi")))]
21508117404Skan  "TARGET_SSE2"
21509117404Skan  "psllw\t{%2, %0|%0, %2}"
21510117404Skan  [(set_attr "type" "sseishft")
21511117404Skan   (set_attr "mode" "TI")])
21512117404Skan
21513117404Skan(define_insn "ashlv4si3"
21514117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21515117404Skan        (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
21516117404Skan		     (match_operand:TI 2 "nonmemory_operand" "xi")))]
21517117404Skan  "TARGET_SSE2"
21518117404Skan  "pslld\t{%2, %0|%0, %2}"
21519117404Skan  [(set_attr "type" "sseishft")
21520117404Skan   (set_attr "mode" "TI")])
21521117404Skan
21522117404Skan(define_insn "ashlv2di3"
21523117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21524117404Skan        (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
21525117404Skan		     (match_operand:TI 2 "nonmemory_operand" "xi")))]
21526117404Skan  "TARGET_SSE2"
21527117404Skan  "psllq\t{%2, %0|%0, %2}"
21528117404Skan  [(set_attr "type" "sseishft")
21529117404Skan   (set_attr "mode" "TI")])
21530117404Skan
21531117404Skan(define_insn "ashrv8hi3_ti"
21532117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21533117404Skan        (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21534117404Skan		       (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21535117404Skan  "TARGET_SSE2"
21536117404Skan  "psraw\t{%2, %0|%0, %2}"
21537117404Skan  [(set_attr "type" "sseishft")
21538117404Skan   (set_attr "mode" "TI")])
21539117404Skan
21540117404Skan(define_insn "ashrv4si3_ti"
21541117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21542117404Skan        (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21543117404Skan		       (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21544117404Skan  "TARGET_SSE2"
21545117404Skan  "psrad\t{%2, %0|%0, %2}"
21546117404Skan  [(set_attr "type" "sseishft")
21547117404Skan   (set_attr "mode" "TI")])
21548117404Skan
21549117404Skan(define_insn "lshrv8hi3_ti"
21550117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21551117404Skan        (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
21552117404Skan		       (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21553117404Skan  "TARGET_SSE2"
21554117404Skan  "psrlw\t{%2, %0|%0, %2}"
21555117404Skan  [(set_attr "type" "sseishft")
21556117404Skan   (set_attr "mode" "TI")])
21557117404Skan
21558117404Skan(define_insn "lshrv4si3_ti"
21559117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21560117404Skan        (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
21561117404Skan		       (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21562117404Skan  "TARGET_SSE2"
21563117404Skan  "psrld\t{%2, %0|%0, %2}"
21564117404Skan  [(set_attr "type" "sseishft")
21565117404Skan   (set_attr "mode" "TI")])
21566117404Skan
21567117404Skan(define_insn "lshrv2di3_ti"
21568117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21569117404Skan        (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
21570117404Skan		       (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21571117404Skan  "TARGET_SSE2"
21572117404Skan  "psrlq\t{%2, %0|%0, %2}"
21573117404Skan  [(set_attr "type" "sseishft")
21574117404Skan   (set_attr "mode" "TI")])
21575117404Skan
21576117404Skan(define_insn "ashlv8hi3_ti"
21577117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21578117404Skan        (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
21579117404Skan		     (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21580117404Skan  "TARGET_SSE2"
21581117404Skan  "psllw\t{%2, %0|%0, %2}"
21582117404Skan  [(set_attr "type" "sseishft")
21583117404Skan   (set_attr "mode" "TI")])
21584117404Skan
21585117404Skan(define_insn "ashlv4si3_ti"
21586117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21587117404Skan        (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
21588117404Skan		     (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21589117404Skan  "TARGET_SSE2"
21590117404Skan  "pslld\t{%2, %0|%0, %2}"
21591117404Skan  [(set_attr "type" "sseishft")
21592117404Skan   (set_attr "mode" "TI")])
21593117404Skan
21594117404Skan(define_insn "ashlv2di3_ti"
21595117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21596117404Skan        (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
21597117404Skan		     (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
21598117404Skan  "TARGET_SSE2"
21599117404Skan  "psllq\t{%2, %0|%0, %2}"
21600117404Skan  [(set_attr "type" "sseishft")
21601117404Skan   (set_attr "mode" "TI")])
21602117404Skan
21603117404Skan;; See logical MMX insns for the reason for the unspec.  Strictly speaking
21604117404Skan;; we wouldn't need here it since we never generate TImode arithmetic.
21605117404Skan
21606117404Skan;; There has to be some kind of prize for the weirdest new instruction...
21607117404Skan(define_insn "sse2_ashlti3"
21608117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
21609117404Skan        (unspec:TI
21610117404Skan	 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
21611117404Skan		     (mult:SI (match_operand:SI 2 "immediate_operand" "i")
21612117404Skan			       (const_int 8)))] UNSPEC_NOP))]
21613117404Skan  "TARGET_SSE2"
21614117404Skan  "pslldq\t{%2, %0|%0, %2}"
21615117404Skan  [(set_attr "type" "sseishft")
21616117404Skan   (set_attr "mode" "TI")])
21617117404Skan
21618117404Skan(define_insn "sse2_lshrti3"
21619117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
21620117404Skan        (unspec:TI
21621117404Skan	 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
21622117404Skan		       (mult:SI (match_operand:SI 2 "immediate_operand" "i")
21623117404Skan				(const_int 8)))] UNSPEC_NOP))]
21624117404Skan  "TARGET_SSE2"
21625117404Skan  "psrldq\t{%2, %0|%0, %2}"
21626117404Skan  [(set_attr "type" "sseishft")
21627117404Skan   (set_attr "mode" "TI")])
21628117404Skan
21629117404Skan;; SSE unpack
21630117404Skan
21631117404Skan(define_insn "sse2_unpckhpd"
21632117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21633117404Skan	(vec_concat:V2DF
21634117404Skan	 (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
21635117404Skan			  (parallel [(const_int 1)]))
21636117404Skan	 (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
21637117404Skan			  (parallel [(const_int 0)]))))]
21638117404Skan  "TARGET_SSE2"
21639117404Skan  "unpckhpd\t{%2, %0|%0, %2}"
21640117404Skan  [(set_attr "type" "ssecvt")
21641117404Skan   (set_attr "mode" "TI")])
21642117404Skan
21643117404Skan(define_insn "sse2_unpcklpd"
21644117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21645117404Skan	(vec_concat:V2DF
21646117404Skan	 (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
21647117404Skan			  (parallel [(const_int 0)]))
21648117404Skan	 (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
21649117404Skan			  (parallel [(const_int 1)]))))]
21650117404Skan  "TARGET_SSE2"
21651117404Skan  "unpcklpd\t{%2, %0|%0, %2}"
21652117404Skan  [(set_attr "type" "ssecvt")
21653117404Skan   (set_attr "mode" "TI")])
21654117404Skan
21655117404Skan;; MMX pack/unpack insns.
21656117404Skan
21657117404Skan(define_insn "sse2_packsswb"
21658117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21659117404Skan	(vec_concat:V16QI
21660117404Skan	 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
21661117404Skan	 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
21662117404Skan  "TARGET_SSE2"
21663117404Skan  "packsswb\t{%2, %0|%0, %2}"
21664117404Skan  [(set_attr "type" "ssecvt")
21665117404Skan   (set_attr "mode" "TI")])
21666117404Skan
21667117404Skan(define_insn "sse2_packssdw"
21668117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21669117404Skan	(vec_concat:V8HI
21670117404Skan	 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
21671117404Skan	 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
21672117404Skan  "TARGET_SSE2"
21673117404Skan  "packssdw\t{%2, %0|%0, %2}"
21674117404Skan  [(set_attr "type" "ssecvt")
21675117404Skan   (set_attr "mode" "TI")])
21676117404Skan
21677117404Skan(define_insn "sse2_packuswb"
21678117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21679117404Skan	(vec_concat:V16QI
21680117404Skan	 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
21681117404Skan	 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
21682117404Skan  "TARGET_SSE2"
21683117404Skan  "packuswb\t{%2, %0|%0, %2}"
21684117404Skan  [(set_attr "type" "ssecvt")
21685117404Skan   (set_attr "mode" "TI")])
21686117404Skan
21687117404Skan(define_insn "sse2_punpckhbw"
21688117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21689117404Skan	(vec_merge:V16QI
21690117404Skan	 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
21691117404Skan			   (parallel [(const_int 8) (const_int 0)
21692117404Skan				      (const_int 9) (const_int 1)
21693117404Skan				      (const_int 10) (const_int 2)
21694117404Skan				      (const_int 11) (const_int 3)
21695117404Skan				      (const_int 12) (const_int 4)
21696117404Skan				      (const_int 13) (const_int 5)
21697117404Skan				      (const_int 14) (const_int 6)
21698117404Skan				      (const_int 15) (const_int 7)]))
21699117404Skan	 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
21700117404Skan			   (parallel [(const_int 0) (const_int 8)
21701117404Skan				      (const_int 1) (const_int 9)
21702117404Skan				      (const_int 2) (const_int 10)
21703117404Skan				      (const_int 3) (const_int 11)
21704117404Skan				      (const_int 4) (const_int 12)
21705117404Skan				      (const_int 5) (const_int 13)
21706117404Skan				      (const_int 6) (const_int 14)
21707117404Skan				      (const_int 7) (const_int 15)]))
21708117404Skan	 (const_int 21845)))]
21709117404Skan  "TARGET_SSE2"
21710117404Skan  "punpckhbw\t{%2, %0|%0, %2}"
21711117404Skan  [(set_attr "type" "ssecvt")
21712117404Skan   (set_attr "mode" "TI")])
21713117404Skan
21714117404Skan(define_insn "sse2_punpckhwd"
21715117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21716117404Skan	(vec_merge:V8HI
21717117404Skan	 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
21718117404Skan			  (parallel [(const_int 4) (const_int 0)
21719117404Skan				     (const_int 5) (const_int 1)
21720117404Skan				     (const_int 6) (const_int 2)
21721117404Skan				     (const_int 7) (const_int 3)]))
21722117404Skan	 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
21723117404Skan			  (parallel [(const_int 0) (const_int 4)
21724117404Skan				     (const_int 1) (const_int 5)
21725117404Skan				     (const_int 2) (const_int 6)
21726117404Skan				     (const_int 3) (const_int 7)]))
21727117404Skan	 (const_int 85)))]
21728117404Skan  "TARGET_SSE2"
21729117404Skan  "punpckhwd\t{%2, %0|%0, %2}"
21730117404Skan  [(set_attr "type" "ssecvt")
21731117404Skan   (set_attr "mode" "TI")])
21732117404Skan
21733117404Skan(define_insn "sse2_punpckhdq"
21734117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21735117404Skan	(vec_merge:V4SI
21736117404Skan	 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
21737117404Skan			  (parallel [(const_int 2) (const_int 0)
21738117404Skan				     (const_int 3) (const_int 1)]))
21739117404Skan	 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
21740117404Skan			  (parallel [(const_int 0) (const_int 2)
21741117404Skan				     (const_int 1) (const_int 3)]))
21742117404Skan	 (const_int 5)))]
21743117404Skan  "TARGET_SSE2"
21744117404Skan  "punpckhdq\t{%2, %0|%0, %2}"
21745117404Skan  [(set_attr "type" "ssecvt")
21746117404Skan   (set_attr "mode" "TI")])
21747117404Skan
21748117404Skan(define_insn "sse2_punpcklbw"
21749117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21750117404Skan	(vec_merge:V16QI
21751117404Skan	 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
21752117404Skan			   (parallel [(const_int 0) (const_int 8)
21753117404Skan				      (const_int 1) (const_int 9)
21754117404Skan				      (const_int 2) (const_int 10)
21755117404Skan				      (const_int 3) (const_int 11)
21756117404Skan				      (const_int 4) (const_int 12)
21757117404Skan				      (const_int 5) (const_int 13)
21758117404Skan				      (const_int 6) (const_int 14)
21759117404Skan				      (const_int 7) (const_int 15)]))
21760117404Skan	 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
21761117404Skan			   (parallel [(const_int 8) (const_int 0)
21762117404Skan				      (const_int 9) (const_int 1)
21763117404Skan				      (const_int 10) (const_int 2)
21764117404Skan				      (const_int 11) (const_int 3)
21765117404Skan				      (const_int 12) (const_int 4)
21766117404Skan				      (const_int 13) (const_int 5)
21767117404Skan				      (const_int 14) (const_int 6)
21768117404Skan				      (const_int 15) (const_int 7)]))
21769117404Skan	 (const_int 21845)))]
21770117404Skan  "TARGET_SSE2"
21771117404Skan  "punpcklbw\t{%2, %0|%0, %2}"
21772117404Skan  [(set_attr "type" "ssecvt")
21773117404Skan   (set_attr "mode" "TI")])
21774117404Skan
21775117404Skan(define_insn "sse2_punpcklwd"
21776117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21777117404Skan	(vec_merge:V8HI
21778117404Skan	 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
21779117404Skan			  (parallel [(const_int 0) (const_int 4)
21780117404Skan				     (const_int 1) (const_int 5)
21781117404Skan				     (const_int 2) (const_int 6)
21782117404Skan				     (const_int 3) (const_int 7)]))
21783117404Skan	 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
21784117404Skan			  (parallel [(const_int 4) (const_int 0)
21785117404Skan				     (const_int 5) (const_int 1)
21786117404Skan				     (const_int 6) (const_int 2)
21787117404Skan				     (const_int 7) (const_int 3)]))
21788117404Skan	 (const_int 85)))]
21789117404Skan  "TARGET_SSE2"
21790117404Skan  "punpcklwd\t{%2, %0|%0, %2}"
21791117404Skan  [(set_attr "type" "ssecvt")
21792117404Skan   (set_attr "mode" "TI")])
21793117404Skan
21794117404Skan(define_insn "sse2_punpckldq"
21795117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21796117404Skan	(vec_merge:V4SI
21797117404Skan	 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
21798117404Skan			  (parallel [(const_int 0) (const_int 2)
21799117404Skan				     (const_int 1) (const_int 3)]))
21800117404Skan	 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
21801117404Skan			  (parallel [(const_int 2) (const_int 0)
21802117404Skan				     (const_int 3) (const_int 1)]))
21803117404Skan	 (const_int 5)))]
21804117404Skan  "TARGET_SSE2"
21805117404Skan  "punpckldq\t{%2, %0|%0, %2}"
21806117404Skan  [(set_attr "type" "ssecvt")
21807117404Skan   (set_attr "mode" "TI")])
21808117404Skan
21809117404Skan(define_insn "sse2_punpcklqdq"
21810117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21811117404Skan	(vec_merge:V2DI
21812117404Skan	 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
21813117404Skan			  (parallel [(const_int 1)
21814117404Skan				     (const_int 0)]))
21815117404Skan	 (match_operand:V2DI 1 "register_operand" "0")
21816117404Skan	 (const_int 1)))]
21817117404Skan  "TARGET_SSE2"
21818117404Skan  "punpcklqdq\t{%2, %0|%0, %2}"
21819117404Skan  [(set_attr "type" "ssecvt")
21820117404Skan   (set_attr "mode" "TI")])
21821117404Skan
21822117404Skan(define_insn "sse2_punpckhqdq"
21823117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21824117404Skan	(vec_merge:V2DI
21825117404Skan	 (match_operand:V2DI 1 "register_operand" "0")
21826117404Skan	 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
21827117404Skan			  (parallel [(const_int 1)
21828117404Skan				     (const_int 0)]))
21829117404Skan	 (const_int 1)))]
21830117404Skan  "TARGET_SSE2"
21831117404Skan  "punpckhqdq\t{%2, %0|%0, %2}"
21832117404Skan  [(set_attr "type" "ssecvt")
21833117404Skan   (set_attr "mode" "TI")])
21834117404Skan
21835117404Skan;; SSE2 moves
21836117404Skan
21837117404Skan(define_insn "sse2_movapd"
21838117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21839117404Skan	(unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
21840117404Skan		     UNSPEC_MOVA))]
21841117404Skan  "TARGET_SSE2
21842117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
21843117404Skan  "movapd\t{%1, %0|%0, %1}"
21844117404Skan  [(set_attr "type" "ssemov")
21845117404Skan   (set_attr "mode" "V2DF")])
21846117404Skan
21847117404Skan(define_insn "sse2_movupd"
21848117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21849117404Skan	(unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
21850117404Skan		     UNSPEC_MOVU))]
21851117404Skan  "TARGET_SSE2
21852117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
21853117404Skan  "movupd\t{%1, %0|%0, %1}"
21854117404Skan  [(set_attr "type" "ssecvt")
21855117404Skan   (set_attr "mode" "V2DF")])
21856117404Skan
21857117404Skan(define_insn "sse2_movdqa"
21858117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
21859117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
21860117404Skan		       UNSPEC_MOVA))]
21861117404Skan  "TARGET_SSE2
21862117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
21863117404Skan  "movdqa\t{%1, %0|%0, %1}"
21864117404Skan  [(set_attr "type" "ssemov")
21865117404Skan   (set_attr "mode" "TI")])
21866117404Skan
21867117404Skan(define_insn "sse2_movdqu"
21868117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
21869117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
21870117404Skan		       UNSPEC_MOVU))]
21871117404Skan  "TARGET_SSE2
21872117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
21873117404Skan  "movdqu\t{%1, %0|%0, %1}"
21874117404Skan  [(set_attr "type" "ssecvt")
21875117404Skan   (set_attr "mode" "TI")])
21876117404Skan
21877117404Skan(define_insn "sse2_movdq2q"
21878117404Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
21879117404Skan	(vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
21880117404Skan		       (parallel [(const_int 0)])))]
21881117404Skan  "TARGET_SSE2 && !TARGET_64BIT"
21882117404Skan  "@
21883117404Skan   movq\t{%1, %0|%0, %1}
21884117404Skan   movdq2q\t{%1, %0|%0, %1}"
21885117404Skan  [(set_attr "type" "ssecvt")
21886117404Skan   (set_attr "mode" "TI")])
21887117404Skan
21888117404Skan(define_insn "sse2_movdq2q_rex64"
21889117404Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
21890117404Skan	(vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
21891117404Skan		       (parallel [(const_int 0)])))]
21892117404Skan  "TARGET_SSE2 && TARGET_64BIT"
21893117404Skan  "@
21894117404Skan   movq\t{%1, %0|%0, %1}
21895117404Skan   movdq2q\t{%1, %0|%0, %1}
21896117404Skan   movd\t{%1, %0|%0, %1}"
21897117404Skan  [(set_attr "type" "ssecvt")
21898117404Skan   (set_attr "mode" "TI")])
21899117404Skan
21900117404Skan(define_insn "sse2_movq2dq"
21901117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
21902117404Skan	(vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
21903117404Skan			 (const_int 0)))]
21904117404Skan  "TARGET_SSE2 && !TARGET_64BIT"
21905117404Skan  "@
21906117404Skan   movq\t{%1, %0|%0, %1}
21907117404Skan   movq2dq\t{%1, %0|%0, %1}"
21908117404Skan  [(set_attr "type" "ssecvt,ssemov")
21909117404Skan   (set_attr "mode" "TI")])
21910117404Skan
21911117404Skan(define_insn "sse2_movq2dq_rex64"
21912117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
21913117404Skan	(vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
21914117404Skan			 (const_int 0)))]
21915117404Skan  "TARGET_SSE2 && TARGET_64BIT"
21916117404Skan  "@
21917117404Skan   movq\t{%1, %0|%0, %1}
21918117404Skan   movq2dq\t{%1, %0|%0, %1}
21919117404Skan   movd\t{%1, %0|%0, %1}"
21920117404Skan  [(set_attr "type" "ssecvt,ssemov,ssecvt")
21921117404Skan   (set_attr "mode" "TI")])
21922117404Skan
21923117404Skan(define_insn "sse2_movq"
21924117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21925117404Skan	(vec_concat:V2DI (vec_select:DI
21926117404Skan			  (match_operand:V2DI 1 "nonimmediate_operand" "xm")
21927117404Skan			  (parallel [(const_int 0)]))
21928117404Skan			 (const_int 0)))]
21929117404Skan  "TARGET_SSE2"
21930117404Skan  "movq\t{%1, %0|%0, %1}"
21931117404Skan  [(set_attr "type" "ssemov")
21932117404Skan   (set_attr "mode" "TI")])
21933117404Skan
21934117404Skan(define_insn "sse2_loadd"
21935117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21936117404Skan	(vec_merge:V4SI
21937117404Skan	 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
21938117404Skan	 (const_vector:V4SI [(const_int 0)
21939117404Skan			     (const_int 0)
21940117404Skan			     (const_int 0)
21941117404Skan			     (const_int 0)])
21942117404Skan	 (const_int 1)))]
21943117404Skan  "TARGET_SSE2"
21944117404Skan  "movd\t{%1, %0|%0, %1}"
21945117404Skan  [(set_attr "type" "ssemov")
21946117404Skan   (set_attr "mode" "TI")])
21947117404Skan
21948117404Skan(define_insn "sse2_stored"
21949117404Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
21950117404Skan	(vec_select:SI
21951117404Skan	 (match_operand:V4SI 1 "register_operand" "x")
21952117404Skan	 (parallel [(const_int 0)])))]
21953117404Skan  "TARGET_SSE2"
21954117404Skan  "movd\t{%1, %0|%0, %1}"
21955117404Skan  [(set_attr "type" "ssemov")
21956117404Skan   (set_attr "mode" "TI")])
21957117404Skan
21958117404Skan(define_insn "sse2_movhpd"
21959117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21960117404Skan	(vec_merge:V2DF
21961117404Skan	 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
21962117404Skan	 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
21963117404Skan	 (const_int 2)))]
21964117404Skan  "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
21965117404Skan  "movhpd\t{%2, %0|%0, %2}"
21966117404Skan  [(set_attr "type" "ssecvt")
21967117404Skan   (set_attr "mode" "V2DF")])
21968117404Skan
21969117404Skan(define_insn "sse2_movlpd"
21970117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21971117404Skan	(vec_merge:V2DF
21972117404Skan	 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
21973117404Skan	 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
21974117404Skan	 (const_int 1)))]
21975117404Skan  "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
21976117404Skan  "movlpd\t{%2, %0|%0, %2}"
21977117404Skan  [(set_attr "type" "ssecvt")
21978117404Skan   (set_attr "mode" "V2DF")])
21979117404Skan
21980117404Skan(define_expand "sse2_loadsd"
21981117404Skan  [(match_operand:V2DF 0 "register_operand" "")
21982117404Skan   (match_operand:DF 1 "memory_operand" "")]
21983117404Skan  "TARGET_SSE2"
21984117404Skan{
21985117404Skan  emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
21986117404Skan			        CONST0_RTX (V2DFmode)));
21987117404Skan  DONE;
21988117404Skan})
21989117404Skan
21990117404Skan(define_insn "sse2_loadsd_1"
21991117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21992117404Skan	(vec_merge:V2DF
21993117404Skan	 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
21994117404Skan	 (match_operand:V2DF 2 "const0_operand" "X")
21995117404Skan	 (const_int 1)))]
21996117404Skan  "TARGET_SSE2"
21997117404Skan  "movsd\t{%1, %0|%0, %1}"
21998117404Skan  [(set_attr "type" "ssecvt")
21999117404Skan   (set_attr "mode" "DF")])
22000117404Skan
22001117404Skan(define_insn "sse2_movsd"
22002117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22003117404Skan	(vec_merge:V2DF
22004117404Skan	 (match_operand:V2DF 1 "register_operand" "0")
22005117404Skan	 (match_operand:V2DF 2 "register_operand" "x")
22006117404Skan	 (const_int 1)))]
22007117404Skan  "TARGET_SSE2"
22008117404Skan  "movsd\t{%2, %0|%0, %2}"
22009117404Skan  [(set_attr "type" "ssecvt")
22010117404Skan   (set_attr "mode" "DF")])
22011117404Skan
22012117404Skan(define_insn "sse2_storesd"
22013117404Skan  [(set (match_operand:DF 0 "memory_operand" "=m")
22014117404Skan	(vec_select:DF
22015117404Skan	 (match_operand:V2DF 1 "register_operand" "x")
22016117404Skan	 (parallel [(const_int 0)])))]
22017117404Skan  "TARGET_SSE2"
22018117404Skan  "movsd\t{%1, %0|%0, %1}"
22019117404Skan  [(set_attr "type" "ssecvt")
22020117404Skan   (set_attr "mode" "DF")])
22021117404Skan
22022117404Skan(define_insn "sse2_shufpd"
22023117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22024117404Skan        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22025117404Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22026117404Skan		      (match_operand:SI 3 "immediate_operand" "i")]
22027117404Skan		     UNSPEC_SHUFFLE))]
22028117404Skan  "TARGET_SSE2"
22029117404Skan  ;; @@@ check operand order for intel/nonintel syntax
22030117404Skan  "shufpd\t{%3, %2, %0|%0, %2, %3}"
22031117404Skan  [(set_attr "type" "ssecvt")
22032117404Skan   (set_attr "mode" "V2DF")])
22033117404Skan
22034117404Skan(define_insn "sse2_clflush"
22035117404Skan  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22036117404Skan		    UNSPECV_CLFLUSH)]
22037117404Skan  "TARGET_SSE2"
22038117404Skan  "clflush %0"
22039117404Skan  [(set_attr "type" "sse")
22040117404Skan   (set_attr "memory" "unknown")])
22041117404Skan
22042117404Skan(define_expand "sse2_mfence"
22043117404Skan  [(set (match_dup 0)
22044117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22045117404Skan  "TARGET_SSE2"
22046117404Skan{
22047117404Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22048117404Skan  MEM_VOLATILE_P (operands[0]) = 1;
22049117404Skan})
22050117404Skan
22051117404Skan(define_insn "*mfence_insn"
22052117404Skan  [(set (match_operand:BLK 0 "" "")
22053117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22054117404Skan  "TARGET_SSE2"
22055117404Skan  "mfence"
22056117404Skan  [(set_attr "type" "sse")
22057117404Skan   (set_attr "memory" "unknown")])
22058117404Skan
22059117404Skan(define_expand "sse2_lfence"
22060117404Skan  [(set (match_dup 0)
22061117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22062117404Skan  "TARGET_SSE2"
22063117404Skan{
22064117404Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22065117404Skan  MEM_VOLATILE_P (operands[0]) = 1;
22066117404Skan})
22067117404Skan
22068117404Skan(define_insn "*lfence_insn"
22069117404Skan  [(set (match_operand:BLK 0 "" "")
22070117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22071117404Skan  "TARGET_SSE2"
22072117404Skan  "lfence"
22073117404Skan  [(set_attr "type" "sse")
22074117404Skan   (set_attr "memory" "unknown")])
22075