i386.md revision 146906
190286Sobrien;; GCC machine description for IA-32 and x86-64.
2117404Skan;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3132727Skan;; 2001, 2002, 2003, 2004
490286Sobrien;; Free Software Foundation, Inc.
518334Speter;; Mostly by William Schelter.
690286Sobrien;; x86_64 support added by Jan Hubicka
790286Sobrien;;
8132727Skan;; This file is part of GCC.
990286Sobrien;;
10132727Skan;; GCC 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;;
15132727Skan;; GCC 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
21132727Skan;; along with GCC; 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 REG_CLASS_FROM_LETTER in file i386.h defines the register
3118334Speter;; constraint letters.
3290286Sobrien;;
3390286Sobrien;; The special asm out single letter directives following a '%' are:
3418334Speter;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
3518334Speter;;     operands[1].
3618334Speter;; 'L' Print the opcode suffix for a 32-bit integer opcode.
3718334Speter;; 'W' Print the opcode suffix for a 16-bit integer opcode.
3818334Speter;; 'B' Print the opcode suffix for an 8-bit integer opcode.
3950650Sobrien;; 'Q' Print the opcode suffix for a 64-bit float opcode.
4018334Speter;; 'S' Print the opcode suffix for a 32-bit float opcode.
4118334Speter;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
4218334Speter;; 'J' Print the appropriate jump operand.
4390286Sobrien;;
4418334Speter;; 'b' Print the QImode name of the register for the indicated operand.
4518334Speter;;     %b0 would print %al if operands[0] is reg 0.
4618334Speter;; 'w' Likewise, print the HImode name of the register.
4718334Speter;; 'k' Likewise, print the SImode name of the register.
4818334Speter;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
4918334Speter;; 'y' Print "st(0)" instead of "st" as a register.
50117404Skan
5118334Speter;; UNSPEC usage:
5290286Sobrien
53117404Skan(define_constants
54117404Skan  [; Relocation specifiers
55117404Skan   (UNSPEC_GOT			0)
56117404Skan   (UNSPEC_GOTOFF		1)
57117404Skan   (UNSPEC_GOTPCREL		2)
58117404Skan   (UNSPEC_GOTTPOFF		3)
59117404Skan   (UNSPEC_TPOFF		4)
60117404Skan   (UNSPEC_NTPOFF		5)
61117404Skan   (UNSPEC_DTPOFF		6)
62117404Skan   (UNSPEC_GOTNTPOFF		7)
63117404Skan   (UNSPEC_INDNTPOFF		8)
6490286Sobrien
65117404Skan   ; Prologue support
66117404Skan   (UNSPEC_STACK_ALLOC		11)
67117404Skan   (UNSPEC_SET_GOT		12)
68117404Skan   (UNSPEC_SSE_PROLOGUE_SAVE	13)
69117404Skan
70117404Skan   ; TLS support
71117404Skan   (UNSPEC_TP			15)
72117404Skan   (UNSPEC_TLS_GD		16)
73117404Skan   (UNSPEC_TLS_LD_BASE		17)
74117404Skan
75117404Skan   ; Other random patterns
76117404Skan   (UNSPEC_SCAS			20)
77117404Skan   (UNSPEC_SIN			21)
78117404Skan   (UNSPEC_COS			22)
79117404Skan   (UNSPEC_FNSTSW		24)
80117404Skan   (UNSPEC_SAHF			25)
81117404Skan   (UNSPEC_FSTCW		26)
82117404Skan   (UNSPEC_ADD_CARRY		27)
83117404Skan   (UNSPEC_FLDCW		28)
84117404Skan
85117404Skan   ; For SSE/MMX support:
86117404Skan   (UNSPEC_FIX			30)
87117404Skan   (UNSPEC_MASKMOV		32)
88117404Skan   (UNSPEC_MOVMSK		33)
89117404Skan   (UNSPEC_MOVNT		34)
90117404Skan   (UNSPEC_MOVA			38)
91117404Skan   (UNSPEC_MOVU			39)
92117404Skan   (UNSPEC_SHUFFLE		41)
93117404Skan   (UNSPEC_RCP			42)
94117404Skan   (UNSPEC_RSQRT		43)
95117404Skan   (UNSPEC_SFENCE		44)
96117404Skan   (UNSPEC_NOP			45)	; prevents combiner cleverness
97117404Skan   (UNSPEC_PAVGUSB		49)
98117404Skan   (UNSPEC_PFRCP		50)
99117404Skan   (UNSPEC_PFRCPIT1		51)
100117404Skan   (UNSPEC_PFRCPIT2		52)
101117404Skan   (UNSPEC_PFRSQRT		53)
102117404Skan   (UNSPEC_PFRSQIT1		54)
103117404Skan   (UNSPEC_PSHUFLW		55)
104117404Skan   (UNSPEC_PSHUFHW		56)
105117404Skan   (UNSPEC_MFENCE		59)
106117404Skan   (UNSPEC_LFENCE		60)
107117404Skan   (UNSPEC_PSADBW		61)
108122190Skan   (UNSPEC_ADDSUB		71)
109122190Skan   (UNSPEC_HADD			72)
110122190Skan   (UNSPEC_HSUB			73)
111122190Skan   (UNSPEC_MOVSHDUP		74)
112122190Skan   (UNSPEC_MOVSLDUP		75)
113122190Skan   (UNSPEC_LDQQU		76)
114122190Skan   (UNSPEC_MOVDDUP		77)
115132727Skan
116132727Skan   ; x87 Floating point
117132727Skan   (UNSPEC_FPATAN		65)
118132727Skan   (UNSPEC_FYL2X		66)
119132727Skan   (UNSPEC_FSCALE		67)
120132727Skan   (UNSPEC_FRNDINT		68)
121132727Skan   (UNSPEC_F2XM1		69)
122132727Skan
123132727Skan   ; REP instruction
124132727Skan   (UNSPEC_REP			75)
125117404Skan  ])
126117404Skan
127117404Skan(define_constants
128117404Skan  [(UNSPECV_BLOCKAGE		0)
129132727Skan   (UNSPECV_STACK_PROBE		10)
130117404Skan   (UNSPECV_EH_RETURN		13)
131117404Skan   (UNSPECV_EMMS		31)
132117404Skan   (UNSPECV_LDMXCSR		37)
133117404Skan   (UNSPECV_STMXCSR		40)
134117404Skan   (UNSPECV_FEMMS		46)
135117404Skan   (UNSPECV_CLFLUSH		57)
136132727Skan   (UNSPECV_ALIGN		68)
137122190Skan   (UNSPECV_MONITOR		69)
138122190Skan   (UNSPECV_MWAIT		70)
139117404Skan  ])
140117404Skan
14190286Sobrien;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
14290286Sobrien;; from i386.c.
14390286Sobrien
14490286Sobrien;; In C guard expressions, put expressions which may be compile-time
14590286Sobrien;; constants first.  This allows for better optimization.  For
14690286Sobrien;; example, write "TARGET_64BIT && reload_completed", not
14790286Sobrien;; "reload_completed && TARGET_64BIT".
14890286Sobrien
14918334Speter
15090286Sobrien;; Processor type.  This attribute must exactly match the processor_type
15190286Sobrien;; enumeration in i386.h.
152132727Skan(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153132727Skan  (const (symbol_ref "ix86_tune")))
15450650Sobrien
15590286Sobrien;; A basic instruction type.  Refinements due to arguments to be
15690286Sobrien;; provided in other attributes.
15752296Sobrien(define_attr "type"
158117404Skan  "other,multi,
159117404Skan   alu,alu1,negnot,imov,imovx,lea,
160117404Skan   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161117404Skan   icmp,test,ibr,setcc,icmov,
162132727Skan   push,pop,call,callv,leave,
163117404Skan   str,cld,
164117404Skan   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165117404Skan   sselog,sseiadd,sseishft,sseimul,
166132727Skan   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167117404Skan   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
16890286Sobrien  (const_string "other"))
16950650Sobrien
17090286Sobrien;; Main data type used by the insn
171117404Skan(define_attr "mode"
172132727Skan  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
17390286Sobrien  (const_string "unknown"))
17452296Sobrien
175117404Skan;; The CPU unit operations uses.
176117404Skan(define_attr "unit" "integer,i387,sse,mmx,unknown"
177117404Skan  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178117404Skan	   (const_string "i387")
179117404Skan	 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180132727Skan			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181117404Skan	   (const_string "sse")
182117404Skan	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183117404Skan	   (const_string "mmx")
184117404Skan	 (eq_attr "type" "other")
185117404Skan	   (const_string "unknown")]
186117404Skan	 (const_string "integer")))
18752296Sobrien
18890286Sobrien;; The (bounding maximum) length of an instruction immediate.
18990286Sobrien(define_attr "length_immediate" ""
190132727Skan  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
19190286Sobrien	   (const_int 0)
192117404Skan	 (eq_attr "unit" "i387,sse,mmx")
19390286Sobrien	   (const_int 0)
194117404Skan	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195117404Skan			  imul,icmp,push,pop")
19690286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
19790286Sobrien	 (eq_attr "type" "imov,test")
19890286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
19990286Sobrien	 (eq_attr "type" "call")
20090286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
20190286Sobrien	     (const_int 4)
20290286Sobrien	     (const_int 0))
20390286Sobrien	 (eq_attr "type" "callv")
20490286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
20590286Sobrien	     (const_int 4)
20690286Sobrien	     (const_int 0))
207117404Skan	 ;; We don't know the size before shorten_branches.  Expect
208117404Skan	 ;; the instruction to fit for better scheduling.
20990286Sobrien	 (eq_attr "type" "ibr")
210117404Skan	   (const_int 1)
21190286Sobrien	 ]
212117404Skan	 (symbol_ref "/* Update immediate_length and other attributes! */
213117404Skan		      abort(),1")))
21452296Sobrien
21590286Sobrien;; The (bounding maximum) length of an instruction address.
21690286Sobrien(define_attr "length_address" ""
21790286Sobrien  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
21890286Sobrien	   (const_int 0)
21990286Sobrien	 (and (eq_attr "type" "call")
220117404Skan	      (match_operand 0 "constant_call_address_operand" ""))
22190286Sobrien	     (const_int 0)
22290286Sobrien	 (and (eq_attr "type" "callv")
22390286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
22490286Sobrien	     (const_int 0)
22590286Sobrien	 ]
22690286Sobrien	 (symbol_ref "ix86_attr_length_address_default (insn)")))
22752296Sobrien
22890286Sobrien;; Set when length prefix is used.
22990286Sobrien(define_attr "prefix_data16" ""
230117404Skan  (if_then_else (ior (eq_attr "mode" "HI")
231117404Skan		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
23290286Sobrien    (const_int 1)
23390286Sobrien    (const_int 0)))
23452296Sobrien
23590286Sobrien;; Set when string REP prefix is used.
236117404Skan(define_attr "prefix_rep" "" 
237117404Skan  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238117404Skan    (const_int 1)
239117404Skan    (const_int 0)))
24052296Sobrien
24190286Sobrien;; Set when 0f opcode prefix is used.
24290286Sobrien(define_attr "prefix_0f" ""
243117404Skan  (if_then_else 
244132727Skan    (ior (eq_attr "type" "imovx,setcc,icmov")
245132727Skan	 (eq_attr "unit" "sse,mmx"))
24690286Sobrien    (const_int 1)
24790286Sobrien    (const_int 0)))
24852296Sobrien
249132727Skan;; Set when 0f opcode prefix is used.
250132727Skan(define_attr "prefix_rex" ""
251132727Skan  (cond [(and (eq_attr "mode" "DI")
252132727Skan  	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253132727Skan	   (const_int 1)
254132727Skan	 (and (eq_attr "mode" "QI")
255132727Skan	      (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256132727Skan		  (const_int 0)))
257132727Skan	   (const_int 1)
258132727Skan	 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259132727Skan	     (const_int 0))
260132727Skan	   (const_int 1)
261132727Skan	]
262132727Skan	(const_int 0)))
263132727Skan
26490286Sobrien;; Set when modrm byte is used.
26590286Sobrien(define_attr "modrm" ""
266132727Skan  (cond [(eq_attr "type" "str,cld,leave")
26790286Sobrien	   (const_int 0)
268117404Skan	 (eq_attr "unit" "i387")
26990286Sobrien	   (const_int 0)
27090286Sobrien         (and (eq_attr "type" "incdec")
27190286Sobrien	      (ior (match_operand:SI 1 "register_operand" "")
27290286Sobrien		   (match_operand:HI 1 "register_operand" "")))
27390286Sobrien	   (const_int 0)
27490286Sobrien	 (and (eq_attr "type" "push")
27590286Sobrien	      (not (match_operand 1 "memory_operand" "")))
27690286Sobrien	   (const_int 0)
27790286Sobrien	 (and (eq_attr "type" "pop")
27890286Sobrien	      (not (match_operand 0 "memory_operand" "")))
27990286Sobrien	   (const_int 0)
28090286Sobrien	 (and (eq_attr "type" "imov")
28190286Sobrien	      (and (match_operand 0 "register_operand" "")
28290286Sobrien	           (match_operand 1 "immediate_operand" "")))
28390286Sobrien	   (const_int 0)
284117404Skan	 (and (eq_attr "type" "call")
285117404Skan	      (match_operand 0 "constant_call_address_operand" ""))
286117404Skan	     (const_int 0)
287117404Skan	 (and (eq_attr "type" "callv")
288117404Skan	      (match_operand 1 "constant_call_address_operand" ""))
289117404Skan	     (const_int 0)
29090286Sobrien	 ]
29190286Sobrien	 (const_int 1)))
29290286Sobrien
29390286Sobrien;; The (bounding maximum) length of an instruction in bytes.
29490286Sobrien;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
29590286Sobrien;; to split it and compute proper length as for other insns.
29690286Sobrien(define_attr "length" ""
29790286Sobrien  (cond [(eq_attr "type" "other,multi,fistp")
29890286Sobrien	   (const_int 16)
299117404Skan	 (eq_attr "type" "fcmp")
300117404Skan	   (const_int 4)
301117404Skan	 (eq_attr "unit" "i387")
302117404Skan	   (plus (const_int 2)
303117404Skan		 (plus (attr "prefix_data16")
304117404Skan		       (attr "length_address")))]
30590286Sobrien	 (plus (plus (attr "modrm")
30690286Sobrien		     (plus (attr "prefix_0f")
307132727Skan			   (plus (attr "prefix_rex")
308132727Skan				 (const_int 1))))
30990286Sobrien	       (plus (attr "prefix_rep")
31090286Sobrien		     (plus (attr "prefix_data16")
31190286Sobrien			   (plus (attr "length_immediate")
31290286Sobrien				 (attr "length_address")))))))
31390286Sobrien
31490286Sobrien;; The `memory' attribute is `none' if no memory is referenced, `load' or
31590286Sobrien;; `store' if there is a simple memory reference therein, or `unknown'
31690286Sobrien;; if the instruction is complex.
31790286Sobrien
31890286Sobrien(define_attr "memory" "none,load,store,both,unknown"
31990286Sobrien  (cond [(eq_attr "type" "other,multi,str")
32090286Sobrien	   (const_string "unknown")
32190286Sobrien	 (eq_attr "type" "lea,fcmov,fpspc,cld")
32290286Sobrien	   (const_string "none")
323132727Skan	 (eq_attr "type" "fistp,leave")
32490286Sobrien	   (const_string "both")
32590286Sobrien	 (eq_attr "type" "push")
32690286Sobrien	   (if_then_else (match_operand 1 "memory_operand" "")
32790286Sobrien	     (const_string "both")
32890286Sobrien	     (const_string "store"))
329132727Skan	 (eq_attr "type" "pop")
33090286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
33190286Sobrien	     (const_string "both")
33290286Sobrien	     (const_string "load"))
333132727Skan	 (eq_attr "type" "setcc")
334132727Skan	   (if_then_else (match_operand 0 "memory_operand" "")
335132727Skan	     (const_string "store")
336132727Skan	     (const_string "none"))
337132727Skan	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
33890286Sobrien	   (if_then_else (ior (match_operand 0 "memory_operand" "")
33990286Sobrien			      (match_operand 1 "memory_operand" ""))
34090286Sobrien	     (const_string "load")
34190286Sobrien	     (const_string "none"))
34290286Sobrien	 (eq_attr "type" "ibr")
34390286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
34490286Sobrien	     (const_string "load")
34590286Sobrien	     (const_string "none"))
34690286Sobrien	 (eq_attr "type" "call")
34790286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
34890286Sobrien	     (const_string "none")
34990286Sobrien	     (const_string "load"))
35090286Sobrien	 (eq_attr "type" "callv")
35190286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
35290286Sobrien	     (const_string "none")
35390286Sobrien	     (const_string "load"))
354132727Skan	 (and (eq_attr "type" "alu1,negnot,ishift1")
35590286Sobrien	      (match_operand 1 "memory_operand" ""))
35690286Sobrien	   (const_string "both")
35790286Sobrien	 (and (match_operand 0 "memory_operand" "")
35890286Sobrien	      (match_operand 1 "memory_operand" ""))
35990286Sobrien	   (const_string "both")
36090286Sobrien	 (match_operand 0 "memory_operand" "")
36190286Sobrien	   (const_string "store")
36290286Sobrien	 (match_operand 1 "memory_operand" "")
36390286Sobrien	   (const_string "load")
364117404Skan	 (and (eq_attr "type"
365132727Skan		 "!alu1,negnot,ishift1,
366117404Skan		   imov,imovx,icmp,test,
367117404Skan		   fmov,fcmp,fsgn,
368132727Skan		   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369117404Skan		   mmx,mmxmov,mmxcmp,mmxcvt")
37090286Sobrien	      (match_operand 2 "memory_operand" ""))
37190286Sobrien	   (const_string "load")
37290286Sobrien	 (and (eq_attr "type" "icmov")
37390286Sobrien	      (match_operand 3 "memory_operand" ""))
37490286Sobrien	   (const_string "load")
37590286Sobrien	]
37652296Sobrien	(const_string "none")))
37752296Sobrien
37890286Sobrien;; Indicates if an instruction has both an immediate and a displacement.
37950650Sobrien
38090286Sobrien(define_attr "imm_disp" "false,true,unknown"
38190286Sobrien  (cond [(eq_attr "type" "other,multi")
38290286Sobrien	   (const_string "unknown")
383117404Skan	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
38490286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
38590286Sobrien		   (match_operand 1 "immediate_operand" "")))
38690286Sobrien	   (const_string "true")
387117404Skan	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
38890286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
38990286Sobrien		   (match_operand 2 "immediate_operand" "")))
39090286Sobrien	   (const_string "true")
39190286Sobrien	]
39290286Sobrien	(const_string "false")))
39350650Sobrien
39490286Sobrien;; Indicates if an FP operation has an integer source.
39550650Sobrien
39690286Sobrien(define_attr "fp_int_src" "false,true"
39790286Sobrien  (const_string "false"))
39850650Sobrien
39990286Sobrien;; Describe a user's asm statement.
40090286Sobrien(define_asm_attributes
40190286Sobrien  [(set_attr "length" "128")
40290286Sobrien   (set_attr "type" "multi")])
40390286Sobrien
404117404Skan(include "pentium.md")
405117404Skan(include "ppro.md")
406117404Skan(include "k6.md")
407117404Skan(include "athlon.md")
40890286Sobrien
40990286Sobrien;; Compare instructions.
41090286Sobrien
41190286Sobrien;; All compare insns have expanders that save the operands away without
41290286Sobrien;; actually generating RTL.  The bCOND or sCOND (emitted immediately
41390286Sobrien;; after the cmp) will actually emit the cmpM.
41490286Sobrien
41590286Sobrien(define_expand "cmpdi"
41690286Sobrien  [(set (reg:CC 17)
41790286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
41890286Sobrien		    (match_operand:DI 1 "x86_64_general_operand" "")))]
41990286Sobrien  ""
42018334Speter{
42190286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
42290286Sobrien    operands[0] = force_reg (DImode, operands[0]);
42390286Sobrien  ix86_compare_op0 = operands[0];
42490286Sobrien  ix86_compare_op1 = operands[1];
42518334Speter  DONE;
42690286Sobrien})
42718334Speter
42818334Speter(define_expand "cmpsi"
42990286Sobrien  [(set (reg:CC 17)
43090286Sobrien	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
43190286Sobrien		    (match_operand:SI 1 "general_operand" "")))]
43218334Speter  ""
43318334Speter{
43418334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
43518334Speter    operands[0] = force_reg (SImode, operands[0]);
43690286Sobrien  ix86_compare_op0 = operands[0];
43790286Sobrien  ix86_compare_op1 = operands[1];
43818334Speter  DONE;
43990286Sobrien})
44018334Speter
44118334Speter(define_expand "cmphi"
44290286Sobrien  [(set (reg:CC 17)
44390286Sobrien	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
44490286Sobrien		    (match_operand:HI 1 "general_operand" "")))]
44518334Speter  ""
44618334Speter{
44718334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
44818334Speter    operands[0] = force_reg (HImode, operands[0]);
44990286Sobrien  ix86_compare_op0 = operands[0];
45090286Sobrien  ix86_compare_op1 = operands[1];
45118334Speter  DONE;
45290286Sobrien})
45318334Speter
45418334Speter(define_expand "cmpqi"
45590286Sobrien  [(set (reg:CC 17)
45690286Sobrien	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
45790286Sobrien		    (match_operand:QI 1 "general_operand" "")))]
45890286Sobrien  "TARGET_QIMODE_MATH"
45918334Speter{
46018334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
46118334Speter    operands[0] = force_reg (QImode, operands[0]);
46290286Sobrien  ix86_compare_op0 = operands[0];
46390286Sobrien  ix86_compare_op1 = operands[1];
46418334Speter  DONE;
46590286Sobrien})
46618334Speter
46790286Sobrien(define_insn "cmpdi_ccno_1_rex64"
46890286Sobrien  [(set (reg 17)
46990286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
47090286Sobrien		 (match_operand:DI 1 "const0_operand" "n,n")))]
47190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
47290286Sobrien  "@
47390286Sobrien   test{q}\t{%0, %0|%0, %0}
47490286Sobrien   cmp{q}\t{%1, %0|%0, %1}"
47590286Sobrien  [(set_attr "type" "test,icmp")
47690286Sobrien   (set_attr "length_immediate" "0,1")
47790286Sobrien   (set_attr "mode" "DI")])
47818334Speter
47990286Sobrien(define_insn "*cmpdi_minus_1_rex64"
48090286Sobrien  [(set (reg 17)
48190286Sobrien	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
48290286Sobrien			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
48390286Sobrien		 (const_int 0)))]
48490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
48590286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
48690286Sobrien  [(set_attr "type" "icmp")
48790286Sobrien   (set_attr "mode" "DI")])
48818334Speter
48990286Sobrien(define_expand "cmpdi_1_rex64"
49090286Sobrien  [(set (reg:CC 17)
49190286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
49290286Sobrien		    (match_operand:DI 1 "general_operand" "")))]
49390286Sobrien  "TARGET_64BIT"
49490286Sobrien  "")
49518334Speter
49690286Sobrien(define_insn "cmpdi_1_insn_rex64"
49790286Sobrien  [(set (reg 17)
49890286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
49990286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
50090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
50190286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
50290286Sobrien  [(set_attr "type" "icmp")
50390286Sobrien   (set_attr "mode" "DI")])
50450650Sobrien
50518334Speter
50690286Sobrien(define_insn "*cmpsi_ccno_1"
50790286Sobrien  [(set (reg 17)
50890286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
50990286Sobrien		 (match_operand:SI 1 "const0_operand" "n,n")))]
51090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
51190286Sobrien  "@
51290286Sobrien   test{l}\t{%0, %0|%0, %0}
51390286Sobrien   cmp{l}\t{%1, %0|%0, %1}"
51490286Sobrien  [(set_attr "type" "test,icmp")
51590286Sobrien   (set_attr "length_immediate" "0,1")
51690286Sobrien   (set_attr "mode" "SI")])
51750650Sobrien
51890286Sobrien(define_insn "*cmpsi_minus_1"
51990286Sobrien  [(set (reg 17)
52090286Sobrien	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
52190286Sobrien			   (match_operand:SI 1 "general_operand" "ri,mr"))
52290286Sobrien		 (const_int 0)))]
52390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
52490286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
52590286Sobrien  [(set_attr "type" "icmp")
52690286Sobrien   (set_attr "mode" "SI")])
52718334Speter
52890286Sobrien(define_expand "cmpsi_1"
52990286Sobrien  [(set (reg:CC 17)
53090286Sobrien	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
53190286Sobrien		    (match_operand:SI 1 "general_operand" "ri,mr")))]
53290286Sobrien  ""
53390286Sobrien  "")
53418334Speter
53590286Sobrien(define_insn "*cmpsi_1_insn"
53690286Sobrien  [(set (reg 17)
53790286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
53890286Sobrien		 (match_operand:SI 1 "general_operand" "ri,mr")))]
53990286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
54090286Sobrien    && ix86_match_ccmode (insn, CCmode)"
54190286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
54290286Sobrien  [(set_attr "type" "icmp")
54390286Sobrien   (set_attr "mode" "SI")])
54418334Speter
54590286Sobrien(define_insn "*cmphi_ccno_1"
54690286Sobrien  [(set (reg 17)
54790286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
54890286Sobrien		 (match_operand:HI 1 "const0_operand" "n,n")))]
54990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
55090286Sobrien  "@
55190286Sobrien   test{w}\t{%0, %0|%0, %0}
55290286Sobrien   cmp{w}\t{%1, %0|%0, %1}"
55390286Sobrien  [(set_attr "type" "test,icmp")
55490286Sobrien   (set_attr "length_immediate" "0,1")
55590286Sobrien   (set_attr "mode" "HI")])
55618334Speter
55790286Sobrien(define_insn "*cmphi_minus_1"
55890286Sobrien  [(set (reg 17)
55990286Sobrien	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
56090286Sobrien			   (match_operand:HI 1 "general_operand" "ri,mr"))
56190286Sobrien		 (const_int 0)))]
56290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
56390286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
56490286Sobrien  [(set_attr "type" "icmp")
56590286Sobrien   (set_attr "mode" "HI")])
56650650Sobrien
56790286Sobrien(define_insn "*cmphi_1"
56890286Sobrien  [(set (reg 17)
56990286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
57090286Sobrien		 (match_operand:HI 1 "general_operand" "ri,mr")))]
57190286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
57290286Sobrien   && ix86_match_ccmode (insn, CCmode)"
57390286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
57490286Sobrien  [(set_attr "type" "icmp")
57590286Sobrien   (set_attr "mode" "HI")])
57618334Speter
57790286Sobrien(define_insn "*cmpqi_ccno_1"
57890286Sobrien  [(set (reg 17)
57990286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
58090286Sobrien		 (match_operand:QI 1 "const0_operand" "n,n")))]
58190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
58290286Sobrien  "@
58390286Sobrien   test{b}\t{%0, %0|%0, %0}
58490286Sobrien   cmp{b}\t{$0, %0|%0, 0}"
58590286Sobrien  [(set_attr "type" "test,icmp")
58690286Sobrien   (set_attr "length_immediate" "0,1")
58790286Sobrien   (set_attr "mode" "QI")])
58818334Speter
58990286Sobrien(define_insn "*cmpqi_1"
59090286Sobrien  [(set (reg 17)
59190286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
59290286Sobrien		 (match_operand:QI 1 "general_operand" "qi,mq")))]
59390286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
59490286Sobrien    && ix86_match_ccmode (insn, CCmode)"
59590286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
59690286Sobrien  [(set_attr "type" "icmp")
59790286Sobrien   (set_attr "mode" "QI")])
59818334Speter
59990286Sobrien(define_insn "*cmpqi_minus_1"
60090286Sobrien  [(set (reg 17)
60190286Sobrien	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
60290286Sobrien			   (match_operand:QI 1 "general_operand" "qi,mq"))
60390286Sobrien		 (const_int 0)))]
60490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
60590286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
60690286Sobrien  [(set_attr "type" "icmp")
60790286Sobrien   (set_attr "mode" "QI")])
60818334Speter
60990286Sobrien(define_insn "*cmpqi_ext_1"
61090286Sobrien  [(set (reg 17)
61190286Sobrien	(compare
61290286Sobrien	  (match_operand:QI 0 "general_operand" "Qm")
61390286Sobrien	  (subreg:QI
61490286Sobrien	    (zero_extract:SI
61590286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
61690286Sobrien	      (const_int 8)
61790286Sobrien	      (const_int 8)) 0)))]
61890286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
61990286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
62090286Sobrien  [(set_attr "type" "icmp")
62190286Sobrien   (set_attr "mode" "QI")])
62290286Sobrien
62390286Sobrien(define_insn "*cmpqi_ext_1_rex64"
62490286Sobrien  [(set (reg 17)
62590286Sobrien	(compare
62690286Sobrien	  (match_operand:QI 0 "register_operand" "Q")
62790286Sobrien	  (subreg:QI
62890286Sobrien	    (zero_extract:SI
62990286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
63090286Sobrien	      (const_int 8)
63190286Sobrien	      (const_int 8)) 0)))]
63290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
63390286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
63490286Sobrien  [(set_attr "type" "icmp")
63590286Sobrien   (set_attr "mode" "QI")])
63690286Sobrien
63790286Sobrien(define_insn "*cmpqi_ext_2"
63890286Sobrien  [(set (reg 17)
63990286Sobrien	(compare
64090286Sobrien	  (subreg:QI
64190286Sobrien	    (zero_extract:SI
64290286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
64390286Sobrien	      (const_int 8)
64490286Sobrien	      (const_int 8)) 0)
64590286Sobrien	  (match_operand:QI 1 "const0_operand" "n")))]
64690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
64790286Sobrien  "test{b}\t%h0, %h0"
64890286Sobrien  [(set_attr "type" "test")
64990286Sobrien   (set_attr "length_immediate" "0")
65090286Sobrien   (set_attr "mode" "QI")])
65190286Sobrien
65290286Sobrien(define_expand "cmpqi_ext_3"
65390286Sobrien  [(set (reg:CC 17)
65490286Sobrien	(compare:CC
65590286Sobrien	  (subreg:QI
65690286Sobrien	    (zero_extract:SI
65790286Sobrien	      (match_operand 0 "ext_register_operand" "")
65890286Sobrien	      (const_int 8)
65990286Sobrien	      (const_int 8)) 0)
66090286Sobrien	  (match_operand:QI 1 "general_operand" "")))]
66190286Sobrien  ""
66290286Sobrien  "")
66390286Sobrien
66490286Sobrien(define_insn "cmpqi_ext_3_insn"
66590286Sobrien  [(set (reg 17)
66690286Sobrien	(compare
66790286Sobrien	  (subreg:QI
66890286Sobrien	    (zero_extract:SI
66990286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
67090286Sobrien	      (const_int 8)
67190286Sobrien	      (const_int 8)) 0)
67290286Sobrien	  (match_operand:QI 1 "general_operand" "Qmn")))]
67390286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
67490286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
67590286Sobrien  [(set_attr "type" "icmp")
67690286Sobrien   (set_attr "mode" "QI")])
67790286Sobrien
67890286Sobrien(define_insn "cmpqi_ext_3_insn_rex64"
67990286Sobrien  [(set (reg 17)
68090286Sobrien	(compare
68190286Sobrien	  (subreg:QI
68290286Sobrien	    (zero_extract:SI
68390286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
68490286Sobrien	      (const_int 8)
68590286Sobrien	      (const_int 8)) 0)
68690286Sobrien	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
68790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
68890286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
68990286Sobrien  [(set_attr "type" "icmp")
69090286Sobrien   (set_attr "mode" "QI")])
69190286Sobrien
69290286Sobrien(define_insn "*cmpqi_ext_4"
69390286Sobrien  [(set (reg 17)
69490286Sobrien	(compare
69590286Sobrien	  (subreg:QI
69690286Sobrien	    (zero_extract:SI
69790286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
69890286Sobrien	      (const_int 8)
69990286Sobrien	      (const_int 8)) 0)
70090286Sobrien	  (subreg:QI
70190286Sobrien	    (zero_extract:SI
70290286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
70390286Sobrien	      (const_int 8)
70490286Sobrien	      (const_int 8)) 0)))]
70590286Sobrien  "ix86_match_ccmode (insn, CCmode)"
70690286Sobrien  "cmp{b}\t{%h1, %h0|%h0, %h1}"
70790286Sobrien  [(set_attr "type" "icmp")
70890286Sobrien   (set_attr "mode" "QI")])
70990286Sobrien
71090286Sobrien;; These implement float point compares.
71190286Sobrien;; %%% See if we can get away with VOIDmode operands on the actual insns,
71290286Sobrien;; which would allow mix and match FP modes on the compares.  Which is what
71390286Sobrien;; the old patterns did, but with many more of them.
71490286Sobrien
71518334Speter(define_expand "cmpxf"
71690286Sobrien  [(set (reg:CC 17)
71790286Sobrien	(compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
71890286Sobrien		    (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
71918334Speter  "TARGET_80387"
72018334Speter{
72190286Sobrien  ix86_compare_op0 = operands[0];
72290286Sobrien  ix86_compare_op1 = operands[1];
72318334Speter  DONE;
72490286Sobrien})
72518334Speter
72618334Speter(define_expand "cmpdf"
72790286Sobrien  [(set (reg:CC 17)
72890286Sobrien	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
72990286Sobrien		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
73090286Sobrien  "TARGET_80387 || TARGET_SSE2"
73118334Speter{
73290286Sobrien  ix86_compare_op0 = operands[0];
73390286Sobrien  ix86_compare_op1 = operands[1];
73418334Speter  DONE;
73590286Sobrien})
73618334Speter
73718334Speter(define_expand "cmpsf"
73890286Sobrien  [(set (reg:CC 17)
73990286Sobrien	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
74090286Sobrien		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
74190286Sobrien  "TARGET_80387 || TARGET_SSE"
74218334Speter{
74390286Sobrien  ix86_compare_op0 = operands[0];
74490286Sobrien  ix86_compare_op1 = operands[1];
74518334Speter  DONE;
74690286Sobrien})
74718334Speter
74890286Sobrien;; FP compares, step 1:
74990286Sobrien;; Set the FP condition codes.
75090286Sobrien;;
75190286Sobrien;; CCFPmode	compare with exceptions
75290286Sobrien;; CCFPUmode	compare with no exceptions
75318334Speter
75490286Sobrien;; %%% It is an unfortunate fact that ftst has no non-popping variant,
75590286Sobrien;; and that fp moves clobber the condition codes, and that there is
75690286Sobrien;; currently no way to describe this fact to reg-stack.  So there are
75790286Sobrien;; no splitters yet for this.
75818334Speter
75990286Sobrien;; %%% YIKES!  This scheme does not retain a strong connection between 
76090286Sobrien;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
76190286Sobrien;; work!  Only allow tos/mem with tos in op 0.
76290286Sobrien;;
76390286Sobrien;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
76490286Sobrien;; things aren't as bad as they sound...
76590286Sobrien
76690286Sobrien(define_insn "*cmpfp_0"
76790286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
76890286Sobrien	(unspec:HI
76990286Sobrien	  [(compare:CCFP (match_operand 1 "register_operand" "f")
770117404Skan		         (match_operand 2 "const0_operand" "X"))]
771117404Skan	  UNSPEC_FNSTSW))]
77290286Sobrien  "TARGET_80387
77390286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
77490286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
77590286Sobrien{
77690286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
77790286Sobrien    return "ftst\;fnstsw\t%0\;fstp\t%y0";
77890286Sobrien  else
77990286Sobrien    return "ftst\;fnstsw\t%0";
78090286Sobrien}
78190286Sobrien  [(set_attr "type" "multi")
782132727Skan   (set (attr "mode")
783132727Skan     (cond [(match_operand:SF 1 "" "")
784132727Skan	      (const_string "SF")
785132727Skan	    (match_operand:DF 1 "" "")
786132727Skan	      (const_string "DF")
787132727Skan	   ]
788132727Skan	   (const_string "XF")))])
78990286Sobrien
79090286Sobrien;; We may not use "#" to split and emit these, since the REG_DEAD notes
79190286Sobrien;; used to manage the reg stack popping would not be preserved.
79290286Sobrien
79390286Sobrien(define_insn "*cmpfp_2_sf"
79490286Sobrien  [(set (reg:CCFP 18)
79590286Sobrien	(compare:CCFP
79690286Sobrien	  (match_operand:SF 0 "register_operand" "f")
79790286Sobrien	  (match_operand:SF 1 "nonimmediate_operand" "fm")))]
79818334Speter  "TARGET_80387"
79990286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
80090286Sobrien  [(set_attr "type" "fcmp")
80190286Sobrien   (set_attr "mode" "SF")])
80218334Speter
80390286Sobrien(define_insn "*cmpfp_2_sf_1"
80490286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
80590286Sobrien	(unspec:HI
80690286Sobrien	  [(compare:CCFP
80790286Sobrien	     (match_operand:SF 1 "register_operand" "f")
808117404Skan	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809117404Skan	  UNSPEC_FNSTSW))]
81018334Speter  "TARGET_80387"
81190286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
81290286Sobrien  [(set_attr "type" "fcmp")
81390286Sobrien   (set_attr "mode" "SF")])
81418334Speter
81590286Sobrien(define_insn "*cmpfp_2_df"
81690286Sobrien  [(set (reg:CCFP 18)
81790286Sobrien	(compare:CCFP
81890286Sobrien	  (match_operand:DF 0 "register_operand" "f")
81990286Sobrien	  (match_operand:DF 1 "nonimmediate_operand" "fm")))]
82018334Speter  "TARGET_80387"
82190286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
82290286Sobrien  [(set_attr "type" "fcmp")
82390286Sobrien   (set_attr "mode" "DF")])
82418334Speter
82590286Sobrien(define_insn "*cmpfp_2_df_1"
82690286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
82790286Sobrien	(unspec:HI
82890286Sobrien	  [(compare:CCFP
82990286Sobrien	     (match_operand:DF 1 "register_operand" "f")
830117404Skan	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831117404Skan	  UNSPEC_FNSTSW))]
83218334Speter  "TARGET_80387"
83390286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
83490286Sobrien  [(set_attr "type" "multi")
83590286Sobrien   (set_attr "mode" "DF")])
83618334Speter
83790286Sobrien(define_insn "*cmpfp_2_xf"
83890286Sobrien  [(set (reg:CCFP 18)
83990286Sobrien	(compare:CCFP
84090286Sobrien	  (match_operand:XF 0 "register_operand" "f")
84190286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
84290286Sobrien  "TARGET_80387"
84390286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
84490286Sobrien  [(set_attr "type" "fcmp")
84590286Sobrien   (set_attr "mode" "XF")])
84618334Speter
84790286Sobrien(define_insn "*cmpfp_2_xf_1"
84890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
84990286Sobrien	(unspec:HI
85090286Sobrien	  [(compare:CCFP
85190286Sobrien	     (match_operand:XF 1 "register_operand" "f")
852117404Skan	     (match_operand:XF 2 "register_operand" "f"))]
853117404Skan	  UNSPEC_FNSTSW))]
85490286Sobrien  "TARGET_80387"
85590286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
85690286Sobrien  [(set_attr "type" "multi")
85790286Sobrien   (set_attr "mode" "XF")])
85818334Speter
85990286Sobrien(define_insn "*cmpfp_2u"
86090286Sobrien  [(set (reg:CCFPU 18)
86190286Sobrien	(compare:CCFPU
86290286Sobrien	  (match_operand 0 "register_operand" "f")
86390286Sobrien	  (match_operand 1 "register_operand" "f")))]
86490286Sobrien  "TARGET_80387
86590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
86690286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
86790286Sobrien  "* return output_fp_compare (insn, operands, 0, 1);"
86890286Sobrien  [(set_attr "type" "fcmp")
869132727Skan   (set (attr "mode")
870132727Skan     (cond [(match_operand:SF 1 "" "")
871132727Skan	      (const_string "SF")
872132727Skan	    (match_operand:DF 1 "" "")
873132727Skan	      (const_string "DF")
874132727Skan	   ]
875132727Skan	   (const_string "XF")))])
87618334Speter
87790286Sobrien(define_insn "*cmpfp_2u_1"
87890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
87990286Sobrien	(unspec:HI
88090286Sobrien	  [(compare:CCFPU
88190286Sobrien	     (match_operand 1 "register_operand" "f")
882117404Skan	     (match_operand 2 "register_operand" "f"))]
883117404Skan	  UNSPEC_FNSTSW))]
88490286Sobrien  "TARGET_80387
88590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
88690286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
88790286Sobrien  "* return output_fp_compare (insn, operands, 2, 1);"
88890286Sobrien  [(set_attr "type" "multi")
889132727Skan   (set (attr "mode")
890132727Skan     (cond [(match_operand:SF 1 "" "")
891132727Skan	      (const_string "SF")
892132727Skan	    (match_operand:DF 1 "" "")
893132727Skan	      (const_string "DF")
894132727Skan	   ]
895132727Skan	   (const_string "XF")))])
89618334Speter
89790286Sobrien;; Patterns to match the SImode-in-memory ficom instructions.
89890286Sobrien;;
89990286Sobrien;; %%% Play games with accepting gp registers, as otherwise we have to
90090286Sobrien;; force them to memory during rtl generation, which is no good.  We
90190286Sobrien;; can get rid of this once we teach reload to do memory input reloads 
90290286Sobrien;; via pushes.
90318334Speter
90490286Sobrien(define_insn "*ficom_1"
90590286Sobrien  [(set (reg:CCFP 18)
90690286Sobrien	(compare:CCFP
90790286Sobrien	  (match_operand 0 "register_operand" "f,f")
90890286Sobrien	  (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
90990286Sobrien  "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
91090286Sobrien   && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
91190286Sobrien  "#")
91218334Speter
91390286Sobrien;; Split the not-really-implemented gp register case into a
91490286Sobrien;; push-op-pop sequence.
91590286Sobrien;;
91690286Sobrien;; %%% This is most efficient, but am I gonna get in trouble
91790286Sobrien;; for separating cc0_setter and cc0_user?
91818334Speter
91990286Sobrien(define_split
92090286Sobrien  [(set (reg:CCFP 18)
92190286Sobrien	(compare:CCFP
92290286Sobrien	  (match_operand:SF 0 "register_operand" "")
92390286Sobrien	  (float (match_operand:SI 1 "register_operand" ""))))]
92490286Sobrien  "0 && TARGET_80387 && reload_completed"
92590286Sobrien  [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
92690286Sobrien   (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
92790286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
92890286Sobrien              (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
92990286Sobrien  "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
93090286Sobrien   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
93118334Speter
93290286Sobrien;; FP compares, step 2
93390286Sobrien;; Move the fpsw to ax.
93418334Speter
935132727Skan(define_insn "*x86_fnstsw_1"
93690286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
937117404Skan	(unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
93890286Sobrien  "TARGET_80387"
93990286Sobrien  "fnstsw\t%0"
94090286Sobrien  [(set_attr "length" "2")
94190286Sobrien   (set_attr "mode" "SI")
942117404Skan   (set_attr "unit" "i387")
94390286Sobrien   (set_attr "ppro_uops" "few")])
94418334Speter
94590286Sobrien;; FP compares, step 3
94690286Sobrien;; Get ax into flags, general case.
94750650Sobrien
94890286Sobrien(define_insn "x86_sahf_1"
94990286Sobrien  [(set (reg:CC 17)
950117404Skan	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
95190286Sobrien  "!TARGET_64BIT"
95290286Sobrien  "sahf"
95390286Sobrien  [(set_attr "length" "1")
95490286Sobrien   (set_attr "athlon_decode" "vector")
95590286Sobrien   (set_attr "mode" "SI")
95690286Sobrien   (set_attr "ppro_uops" "one")])
95718334Speter
95890286Sobrien;; Pentium Pro can do steps 1 through 3 in one go.
95918334Speter
96090286Sobrien(define_insn "*cmpfp_i"
96190286Sobrien  [(set (reg:CCFP 17)
96290286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f")
96390286Sobrien		      (match_operand 1 "register_operand" "f")))]
96490286Sobrien  "TARGET_80387 && TARGET_CMOVE
96590286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
96690286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
96790286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
96890286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
96990286Sobrien  [(set_attr "type" "fcmp")
970132727Skan   (set (attr "mode")
971132727Skan     (cond [(match_operand:SF 1 "" "")
972132727Skan	      (const_string "SF")
973132727Skan	    (match_operand:DF 1 "" "")
974132727Skan	      (const_string "DF")
975132727Skan	   ]
976132727Skan	   (const_string "XF")))
97790286Sobrien   (set_attr "athlon_decode" "vector")])
97818334Speter
97990286Sobrien(define_insn "*cmpfp_i_sse"
98090286Sobrien  [(set (reg:CCFP 17)
98190286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
98290286Sobrien		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
98390286Sobrien  "TARGET_80387
98490286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
98590286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
98690286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
987132727Skan  [(set_attr "type" "fcmp,ssecomi")
988132727Skan   (set (attr "mode")
989132727Skan     (if_then_else (match_operand:SF 1 "" "")
990132727Skan        (const_string "SF")
991132727Skan        (const_string "DF")))
99290286Sobrien   (set_attr "athlon_decode" "vector")])
99318334Speter
99490286Sobrien(define_insn "*cmpfp_i_sse_only"
99590286Sobrien  [(set (reg:CCFP 17)
99690286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "x")
99790286Sobrien		      (match_operand 1 "nonimmediate_operand" "xm")))]
99890286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
99990286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
100090286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
1001132727Skan  [(set_attr "type" "ssecomi")
1002132727Skan   (set (attr "mode")
1003132727Skan     (if_then_else (match_operand:SF 1 "" "")
1004132727Skan        (const_string "SF")
1005132727Skan        (const_string "DF")))
100690286Sobrien   (set_attr "athlon_decode" "vector")])
100718334Speter
100890286Sobrien(define_insn "*cmpfp_iu"
100990286Sobrien  [(set (reg:CCFPU 17)
101090286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f")
101190286Sobrien		       (match_operand 1 "register_operand" "f")))]
101290286Sobrien  "TARGET_80387 && TARGET_CMOVE
101390286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
101490286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
101590286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
101690286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
101790286Sobrien  [(set_attr "type" "fcmp")
1018132727Skan   (set (attr "mode")
1019132727Skan     (cond [(match_operand:SF 1 "" "")
1020132727Skan	      (const_string "SF")
1021132727Skan	    (match_operand:DF 1 "" "")
1022132727Skan	      (const_string "DF")
1023132727Skan	   ]
1024132727Skan	   (const_string "XF")))
102590286Sobrien   (set_attr "athlon_decode" "vector")])
102618334Speter
102790286Sobrien(define_insn "*cmpfp_iu_sse"
102890286Sobrien  [(set (reg:CCFPU 17)
102990286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
103090286Sobrien		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
103190286Sobrien  "TARGET_80387
103290286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
103390286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
103490286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
1035132727Skan  [(set_attr "type" "fcmp,ssecomi")
1036132727Skan   (set (attr "mode")
1037132727Skan     (if_then_else (match_operand:SF 1 "" "")
1038132727Skan        (const_string "SF")
1039132727Skan        (const_string "DF")))
104090286Sobrien   (set_attr "athlon_decode" "vector")])
104150650Sobrien
104290286Sobrien(define_insn "*cmpfp_iu_sse_only"
104390286Sobrien  [(set (reg:CCFPU 17)
104490286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "x")
104590286Sobrien		       (match_operand 1 "nonimmediate_operand" "xm")))]
104690286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
104790286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
104890286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
1049132727Skan  [(set_attr "type" "ssecomi")
1050132727Skan   (set (attr "mode")
1051132727Skan     (if_then_else (match_operand:SF 1 "" "")
1052132727Skan        (const_string "SF")
1053132727Skan        (const_string "DF")))
105490286Sobrien   (set_attr "athlon_decode" "vector")])
105590286Sobrien
105690286Sobrien;; Move instructions.
105718334Speter
105818334Speter;; General case of fullword move.
105918334Speter
106018334Speter(define_expand "movsi"
106190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
106218334Speter	(match_operand:SI 1 "general_operand" ""))]
106318334Speter  ""
106490286Sobrien  "ix86_expand_move (SImode, operands); DONE;")
106518334Speter
106690286Sobrien;; Push/pop instructions.  They are separate since autoinc/dec is not a
106790286Sobrien;; general_operand.
106890286Sobrien;;
106990286Sobrien;; %%% We don't use a post-inc memory reference because x86 is not a 
107090286Sobrien;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
107190286Sobrien;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
107290286Sobrien;; targets without our curiosities, and it is just as easy to represent
107390286Sobrien;; this differently.
107418334Speter
107590286Sobrien(define_insn "*pushsi2"
107690286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
107790286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
107890286Sobrien  "!TARGET_64BIT"
107990286Sobrien  "push{l}\t%1"
108090286Sobrien  [(set_attr "type" "push")
108190286Sobrien   (set_attr "mode" "SI")])
108218334Speter
108390286Sobrien;; For 64BIT abi we always round up to 8 bytes.
108490286Sobrien(define_insn "*pushsi2_rex64"
108590286Sobrien  [(set (match_operand:SI 0 "push_operand" "=X")
108690286Sobrien	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
108790286Sobrien  "TARGET_64BIT"
108890286Sobrien  "push{q}\t%q1"
108990286Sobrien  [(set_attr "type" "push")
109090286Sobrien   (set_attr "mode" "SI")])
109118334Speter
109290286Sobrien(define_insn "*pushsi2_prologue"
109390286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
109490286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
109590286Sobrien   (clobber (mem:BLK (scratch)))]
109690286Sobrien  "!TARGET_64BIT"
109790286Sobrien  "push{l}\t%1"
109890286Sobrien  [(set_attr "type" "push")
109990286Sobrien   (set_attr "mode" "SI")])
110052296Sobrien
110190286Sobrien(define_insn "*popsi1_epilogue"
110290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
110390286Sobrien	(mem:SI (reg:SI 7)))
110490286Sobrien   (set (reg:SI 7)
110590286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))
110690286Sobrien   (clobber (mem:BLK (scratch)))]
110790286Sobrien  "!TARGET_64BIT"
110890286Sobrien  "pop{l}\t%0"
110990286Sobrien  [(set_attr "type" "pop")
111090286Sobrien   (set_attr "mode" "SI")])
111118334Speter
111290286Sobrien(define_insn "popsi1"
111390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
111490286Sobrien	(mem:SI (reg:SI 7)))
111590286Sobrien   (set (reg:SI 7)
111690286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))]
111790286Sobrien  "!TARGET_64BIT"
111890286Sobrien  "pop{l}\t%0"
111990286Sobrien  [(set_attr "type" "pop")
112090286Sobrien   (set_attr "mode" "SI")])
112118334Speter
112290286Sobrien(define_insn "*movsi_xor"
112390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
112490286Sobrien	(match_operand:SI 1 "const0_operand" "i"))
112590286Sobrien   (clobber (reg:CC 17))]
112690286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
112790286Sobrien  "xor{l}\t{%0, %0|%0, %0}"
112890286Sobrien  [(set_attr "type" "alu1")
112990286Sobrien   (set_attr "mode" "SI")
113090286Sobrien   (set_attr "length_immediate" "0")])
1131132727Skan 
113290286Sobrien(define_insn "*movsi_or"
113390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
113490286Sobrien	(match_operand:SI 1 "immediate_operand" "i"))
113590286Sobrien   (clobber (reg:CC 17))]
1136132727Skan  "reload_completed
1137132727Skan   && operands[1] == constm1_rtx
113890286Sobrien   && (TARGET_PENTIUM || optimize_size)"
113990286Sobrien{
114090286Sobrien  operands[1] = constm1_rtx;
114190286Sobrien  return "or{l}\t{%1, %0|%0, %1}";
114290286Sobrien}
114390286Sobrien  [(set_attr "type" "alu1")
114490286Sobrien   (set_attr "mode" "SI")
114590286Sobrien   (set_attr "length_immediate" "1")])
114618334Speter
114790286Sobrien(define_insn "*movsi_1"
1148132727Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1149132727Skan	(match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1150132727Skan  "(TARGET_INTER_UNIT_MOVES || optimize_size)
1151132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
115250650Sobrien{
115390286Sobrien  switch (get_attr_type (insn))
115490286Sobrien    {
1155117404Skan    case TYPE_SSEMOV:
1156117404Skan      if (get_attr_mode (insn) == MODE_TI)
115790286Sobrien        return "movdqa\t{%1, %0|%0, %1}";
115890286Sobrien      return "movd\t{%1, %0|%0, %1}";
115952296Sobrien
1160117404Skan    case TYPE_MMXMOV:
1161117404Skan      if (get_attr_mode (insn) == MODE_DI)
116296294Sobrien	return "movq\t{%1, %0|%0, %1}";
116390286Sobrien      return "movd\t{%1, %0|%0, %1}";
116452296Sobrien
116590286Sobrien    case TYPE_LEA:
116690286Sobrien      return "lea{l}\t{%1, %0|%0, %1}";
116718334Speter
116890286Sobrien    default:
1169117404Skan      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
117090286Sobrien	abort();
117190286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
117290286Sobrien    }
117390286Sobrien}
117490286Sobrien  [(set (attr "type")
1175117404Skan     (cond [(eq_attr "alternative" "2,3,4")
1176117404Skan	      (const_string "mmxmov")
1177117404Skan	    (eq_attr "alternative" "5,6,7")
1178117404Skan	      (const_string "ssemov")
117990286Sobrien	    (and (ne (symbol_ref "flag_pic") (const_int 0))
118090286Sobrien		 (match_operand:SI 1 "symbolic_operand" ""))
118190286Sobrien	      (const_string "lea")
118290286Sobrien	   ]
118390286Sobrien	   (const_string "imov")))
1184132727Skan   (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
118550650Sobrien
1186132727Skan(define_insn "*movsi_1_nointernunit"
1187132727Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1188132727Skan	(match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1189132727Skan  "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1190132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1191132727Skan{
1192132727Skan  switch (get_attr_type (insn))
1193132727Skan    {
1194132727Skan    case TYPE_SSEMOV:
1195132727Skan      if (get_attr_mode (insn) == MODE_TI)
1196132727Skan        return "movdqa\t{%1, %0|%0, %1}";
1197132727Skan      return "movd\t{%1, %0|%0, %1}";
1198132727Skan
1199132727Skan    case TYPE_MMXMOV:
1200132727Skan      if (get_attr_mode (insn) == MODE_DI)
1201132727Skan	return "movq\t{%1, %0|%0, %1}";
1202132727Skan      return "movd\t{%1, %0|%0, %1}";
1203132727Skan
1204132727Skan    case TYPE_LEA:
1205132727Skan      return "lea{l}\t{%1, %0|%0, %1}";
1206132727Skan
1207132727Skan    default:
1208132727Skan      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1209132727Skan	abort();
1210132727Skan      return "mov{l}\t{%1, %0|%0, %1}";
1211132727Skan    }
1212132727Skan}
1213132727Skan  [(set (attr "type")
1214132727Skan     (cond [(eq_attr "alternative" "2,3,4")
1215132727Skan	      (const_string "mmxmov")
1216132727Skan	    (eq_attr "alternative" "5,6,7")
1217132727Skan	      (const_string "ssemov")
1218132727Skan	    (and (ne (symbol_ref "flag_pic") (const_int 0))
1219132727Skan		 (match_operand:SI 1 "symbolic_operand" ""))
1220132727Skan	      (const_string "lea")
1221132727Skan	   ]
1222132727Skan	   (const_string "imov")))
1223132727Skan   (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1224132727Skan
1225132727Skan;; Stores and loads of ax to arbitrary constant address.
122690286Sobrien;; We fake an second form of instruction to force reload to load address
122790286Sobrien;; into register when rax is not available
122890286Sobrien(define_insn "*movabssi_1_rex64"
1229117404Skan  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1230117404Skan	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1231117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
123290286Sobrien  "@
123390286Sobrien   movabs{l}\t{%1, %P0|%P0, %1}
1234117404Skan   mov{l}\t{%1, %a0|%a0, %1}"
123590286Sobrien  [(set_attr "type" "imov")
1236117404Skan   (set_attr "modrm" "0,*")
1237117404Skan   (set_attr "length_address" "8,0")
1238117404Skan   (set_attr "length_immediate" "0,*")
123990286Sobrien   (set_attr "memory" "store")
124090286Sobrien   (set_attr "mode" "SI")])
124150650Sobrien
124290286Sobrien(define_insn "*movabssi_2_rex64"
124390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a,r")
124490286Sobrien        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1245117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
124690286Sobrien  "@
124790286Sobrien   movabs{l}\t{%P1, %0|%0, %P1}
124890286Sobrien   mov{l}\t{%a1, %0|%0, %a1}"
124990286Sobrien  [(set_attr "type" "imov")
125090286Sobrien   (set_attr "modrm" "0,*")
125190286Sobrien   (set_attr "length_address" "8,0")
125290286Sobrien   (set_attr "length_immediate" "0")
125390286Sobrien   (set_attr "memory" "load")
125490286Sobrien   (set_attr "mode" "SI")])
125590286Sobrien
125690286Sobrien(define_insn "*swapsi"
125790286Sobrien  [(set (match_operand:SI 0 "register_operand" "+r")
125890286Sobrien	(match_operand:SI 1 "register_operand" "+r"))
125990286Sobrien   (set (match_dup 1)
126090286Sobrien	(match_dup 0))]
126150650Sobrien  ""
126290286Sobrien  "xchg{l}\t%1, %0"
126390286Sobrien  [(set_attr "type" "imov")
1264146906Skan   (set_attr "mode" "SI")
126590286Sobrien   (set_attr "pent_pair" "np")
126690286Sobrien   (set_attr "athlon_decode" "vector")
126790286Sobrien   (set_attr "ppro_uops" "few")])
126818334Speter
126990286Sobrien(define_expand "movhi"
127090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
127190286Sobrien        (match_operand:HI 1 "general_operand" ""))]
127290286Sobrien  ""
127390286Sobrien  "ix86_expand_move (HImode, operands); DONE;")
127418334Speter
127590286Sobrien(define_insn "*pushhi2"
127690286Sobrien  [(set (match_operand:HI 0 "push_operand" "=<,<")
127790286Sobrien	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
127890286Sobrien  "!TARGET_64BIT"
127990286Sobrien  "@
128090286Sobrien   push{w}\t{|WORD PTR }%1
128190286Sobrien   push{w}\t%1"
128290286Sobrien  [(set_attr "type" "push")
128390286Sobrien   (set_attr "mode" "HI")])
128418334Speter
128590286Sobrien;; For 64BIT abi we always round up to 8 bytes.
128690286Sobrien(define_insn "*pushhi2_rex64"
128790286Sobrien  [(set (match_operand:HI 0 "push_operand" "=X")
128890286Sobrien	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
128990286Sobrien  "TARGET_64BIT"
129090286Sobrien  "push{q}\t%q1"
129190286Sobrien  [(set_attr "type" "push")
129290286Sobrien   (set_attr "mode" "QI")])
129390286Sobrien
129490286Sobrien(define_insn "*movhi_1"
1295117404Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1296117404Skan	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
129790286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
129818334Speter{
129990286Sobrien  switch (get_attr_type (insn))
130018334Speter    {
130190286Sobrien    case TYPE_IMOVX:
130290286Sobrien      /* movzwl is faster than movw on p2 due to partial word stalls,
130390286Sobrien	 though not as fast as an aligned movl.  */
130490286Sobrien      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
130590286Sobrien    default:
130690286Sobrien      if (get_attr_mode (insn) == MODE_SI)
130790286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
130890286Sobrien      else
130990286Sobrien        return "mov{w}\t{%1, %0|%0, %1}";
131018334Speter    }
131190286Sobrien}
131290286Sobrien  [(set (attr "type")
1313117404Skan     (cond [(and (eq_attr "alternative" "0")
131490286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
131590286Sobrien			  (const_int 0))
131690286Sobrien		      (eq (symbol_ref "TARGET_HIMODE_MATH")
131790286Sobrien			  (const_int 0))))
131890286Sobrien	      (const_string "imov")
1319117404Skan	    (and (eq_attr "alternative" "1,2")
132090286Sobrien		 (match_operand:HI 1 "aligned_operand" ""))
132190286Sobrien	      (const_string "imov")
132290286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
132390286Sobrien		     (const_int 0))
1324117404Skan		 (eq_attr "alternative" "0,2"))
132590286Sobrien	      (const_string "imovx")
132690286Sobrien	   ]
132790286Sobrien	   (const_string "imov")))
132890286Sobrien    (set (attr "mode")
132990286Sobrien      (cond [(eq_attr "type" "imovx")
133090286Sobrien	       (const_string "SI")
1331117404Skan	     (and (eq_attr "alternative" "1,2")
133290286Sobrien		  (match_operand:HI 1 "aligned_operand" ""))
133390286Sobrien	       (const_string "SI")
1334117404Skan	     (and (eq_attr "alternative" "0")
133590286Sobrien		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
133690286Sobrien			   (const_int 0))
133790286Sobrien		       (eq (symbol_ref "TARGET_HIMODE_MATH")
133890286Sobrien			   (const_int 0))))
133990286Sobrien	       (const_string "SI")
134090286Sobrien	    ]
1341117404Skan	    (const_string "HI")))])
134218334Speter
1343132727Skan;; Stores and loads of ax to arbitrary constant address.
134490286Sobrien;; We fake an second form of instruction to force reload to load address
134590286Sobrien;; into register when rax is not available
134690286Sobrien(define_insn "*movabshi_1_rex64"
1347117404Skan  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1348117404Skan	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1349117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
135090286Sobrien  "@
135190286Sobrien   movabs{w}\t{%1, %P0|%P0, %1}
1352117404Skan   mov{w}\t{%1, %a0|%a0, %1}"
135390286Sobrien  [(set_attr "type" "imov")
1354117404Skan   (set_attr "modrm" "0,*")
1355117404Skan   (set_attr "length_address" "8,0")
1356117404Skan   (set_attr "length_immediate" "0,*")
135790286Sobrien   (set_attr "memory" "store")
135890286Sobrien   (set_attr "mode" "HI")])
135918334Speter
136090286Sobrien(define_insn "*movabshi_2_rex64"
136190286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a,r")
136290286Sobrien        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1363117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
136490286Sobrien  "@
136590286Sobrien   movabs{w}\t{%P1, %0|%0, %P1}
136690286Sobrien   mov{w}\t{%a1, %0|%0, %a1}"
136790286Sobrien  [(set_attr "type" "imov")
136890286Sobrien   (set_attr "modrm" "0,*")
136990286Sobrien   (set_attr "length_address" "8,0")
137090286Sobrien   (set_attr "length_immediate" "0")
137190286Sobrien   (set_attr "memory" "load")
137290286Sobrien   (set_attr "mode" "HI")])
137318334Speter
137490286Sobrien(define_insn "*swaphi_1"
137590286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
137690286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
137790286Sobrien   (set (match_dup 1)
137890286Sobrien	(match_dup 0))]
1379146906Skan  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1380146906Skan  "xchg{l}\t%k1, %k0"
138190286Sobrien  [(set_attr "type" "imov")
1382146906Skan   (set_attr "mode" "SI")
138390286Sobrien   (set_attr "pent_pair" "np")
1384146906Skan   (set_attr "athlon_decode" "vector")
138590286Sobrien   (set_attr "ppro_uops" "few")])
138618334Speter
138790286Sobrien(define_insn "*swaphi_2"
138890286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
138990286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
139090286Sobrien   (set (match_dup 1)
139190286Sobrien	(match_dup 0))]
1392146906Skan  "TARGET_PARTIAL_REG_STALL"
1393146906Skan  "xchg{w}\t%1, %0"
139490286Sobrien  [(set_attr "type" "imov")
1395146906Skan   (set_attr "mode" "HI")
139690286Sobrien   (set_attr "pent_pair" "np")
1397146906Skan   (set_attr "athlon_decode" "vector")
139890286Sobrien   (set_attr "ppro_uops" "few")])
139918334Speter
140018334Speter(define_expand "movstricthi"
140190286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
140218334Speter	(match_operand:HI 1 "general_operand" ""))]
140390286Sobrien  "! TARGET_PARTIAL_REG_STALL || optimize_size"
140418334Speter{
140518334Speter  /* Don't generate memory->memory moves, go through a register */
140690286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
140790286Sobrien    operands[1] = force_reg (HImode, operands[1]);
140890286Sobrien})
140918334Speter
141090286Sobrien(define_insn "*movstricthi_1"
141190286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
141290286Sobrien	(match_operand:HI 1 "general_operand" "rn,m"))]
141390286Sobrien  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
141490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
141590286Sobrien  "mov{w}\t{%1, %0|%0, %1}"
141690286Sobrien  [(set_attr "type" "imov")
141790286Sobrien   (set_attr "mode" "HI")])
141852296Sobrien
141990286Sobrien(define_insn "*movstricthi_xor"
142090286Sobrien  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
142190286Sobrien	(match_operand:HI 1 "const0_operand" "i"))
142290286Sobrien   (clobber (reg:CC 17))]
142390286Sobrien  "reload_completed
142490286Sobrien   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
142590286Sobrien  "xor{w}\t{%0, %0|%0, %0}"
142690286Sobrien  [(set_attr "type" "alu1")
142790286Sobrien   (set_attr "mode" "HI")
142890286Sobrien   (set_attr "length_immediate" "0")])
142952296Sobrien
143090286Sobrien(define_expand "movqi"
143190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
143290286Sobrien	(match_operand:QI 1 "general_operand" ""))]
143390286Sobrien  ""
143490286Sobrien  "ix86_expand_move (QImode, operands); DONE;")
143518334Speter
143690286Sobrien;; emit_push_insn when it calls move_by_pieces requires an insn to
143790286Sobrien;; "push a byte".  But actually we use pushw, which has the effect
143890286Sobrien;; of rounding the amount pushed up to a halfword.
143918334Speter
144090286Sobrien(define_insn "*pushqi2"
144190286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X,X")
144290286Sobrien	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
144390286Sobrien  "!TARGET_64BIT"
144490286Sobrien  "@
144590286Sobrien   push{w}\t{|word ptr }%1
144690286Sobrien   push{w}\t%w1"
144790286Sobrien  [(set_attr "type" "push")
144890286Sobrien   (set_attr "mode" "HI")])
144918334Speter
145090286Sobrien;; For 64BIT abi we always round up to 8 bytes.
145190286Sobrien(define_insn "*pushqi2_rex64"
145290286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X")
1453102802Skan	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
145490286Sobrien  "TARGET_64BIT"
145590286Sobrien  "push{q}\t%q1"
145690286Sobrien  [(set_attr "type" "push")
145790286Sobrien   (set_attr "mode" "QI")])
145890286Sobrien
145990286Sobrien;; Situation is quite tricky about when to choose full sized (SImode) move
146090286Sobrien;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
146190286Sobrien;; partial register dependency machines (such as AMD Athlon), where QImode
146290286Sobrien;; moves issue extra dependency and for partial register stalls machines
146390286Sobrien;; that don't use QImode patterns (and QImode move cause stall on the next
146490286Sobrien;; instruction).
146590286Sobrien;;
146690286Sobrien;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
146790286Sobrien;; register stall machines with, where we use QImode instructions, since
146890286Sobrien;; partial register stall can be caused there.  Then we use movzx.
146990286Sobrien(define_insn "*movqi_1"
147090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
147190286Sobrien	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
147290286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
147390286Sobrien{
147490286Sobrien  switch (get_attr_type (insn))
147590286Sobrien    {
147690286Sobrien    case TYPE_IMOVX:
147790286Sobrien      if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
147890286Sobrien	abort ();
147990286Sobrien      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
148090286Sobrien    default:
148190286Sobrien      if (get_attr_mode (insn) == MODE_SI)
148290286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
148390286Sobrien      else
148490286Sobrien        return "mov{b}\t{%1, %0|%0, %1}";
148590286Sobrien    }
148690286Sobrien}
148790286Sobrien  [(set (attr "type")
148890286Sobrien     (cond [(and (eq_attr "alternative" "3")
148990286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
149090286Sobrien			  (const_int 0))
149190286Sobrien		      (eq (symbol_ref "TARGET_QIMODE_MATH")
149290286Sobrien			  (const_int 0))))
149390286Sobrien	      (const_string "imov")
149490286Sobrien	    (eq_attr "alternative" "3,5")
149590286Sobrien	      (const_string "imovx")
149690286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
149790286Sobrien		     (const_int 0))
149890286Sobrien		 (eq_attr "alternative" "2"))
149990286Sobrien	      (const_string "imovx")
150090286Sobrien	   ]
150190286Sobrien	   (const_string "imov")))
150290286Sobrien   (set (attr "mode")
150390286Sobrien      (cond [(eq_attr "alternative" "3,4,5")
150490286Sobrien	       (const_string "SI")
150590286Sobrien	     (eq_attr "alternative" "6")
150690286Sobrien	       (const_string "QI")
150790286Sobrien	     (eq_attr "type" "imovx")
150890286Sobrien	       (const_string "SI")
150990286Sobrien	     (and (eq_attr "type" "imov")
151090286Sobrien		  (and (eq_attr "alternative" "0,1,2")
151190286Sobrien		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
151290286Sobrien			   (const_int 0))))
151390286Sobrien	       (const_string "SI")
151490286Sobrien	     ;; Avoid partial register stalls when not using QImode arithmetic
151590286Sobrien	     (and (eq_attr "type" "imov")
151690286Sobrien		  (and (eq_attr "alternative" "0,1,2")
151790286Sobrien		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
151890286Sobrien				(const_int 0))
151990286Sobrien			    (eq (symbol_ref "TARGET_QIMODE_MATH")
152090286Sobrien				(const_int 0)))))
152190286Sobrien	       (const_string "SI")
152290286Sobrien	   ]
152390286Sobrien	   (const_string "QI")))])
152490286Sobrien
152590286Sobrien(define_expand "reload_outqi"
152690286Sobrien  [(parallel [(match_operand:QI 0 "" "=m")
152790286Sobrien              (match_operand:QI 1 "register_operand" "r")
152890286Sobrien              (match_operand:QI 2 "register_operand" "=&q")])]
152918334Speter  ""
153090286Sobrien{
153190286Sobrien  rtx op0, op1, op2;
153290286Sobrien  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
153318334Speter
153490286Sobrien  if (reg_overlap_mentioned_p (op2, op0))
153590286Sobrien    abort ();
153690286Sobrien  if (! q_regs_operand (op1, QImode))
153790286Sobrien    {
153890286Sobrien      emit_insn (gen_movqi (op2, op1));
153990286Sobrien      op1 = op2;
154090286Sobrien    }
154190286Sobrien  emit_insn (gen_movqi (op0, op1));
154290286Sobrien  DONE;
154390286Sobrien})
154490286Sobrien
1545146906Skan(define_insn "*swapqi_1"
154690286Sobrien  [(set (match_operand:QI 0 "register_operand" "+r")
154790286Sobrien	(match_operand:QI 1 "register_operand" "+r"))
154890286Sobrien   (set (match_dup 1)
154990286Sobrien	(match_dup 0))]
1550146906Skan  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551146906Skan  "xchg{l}\t%k1, %k0"
1552146906Skan  [(set_attr "type" "imov")
1553146906Skan   (set_attr "mode" "SI")
1554146906Skan   (set_attr "pent_pair" "np")
1555146906Skan   (set_attr "athlon_decode" "vector")
1556146906Skan   (set_attr "ppro_uops" "few")])
1557146906Skan
1558146906Skan(define_insn "*swapqi_2"
1559146906Skan  [(set (match_operand:QI 0 "register_operand" "+q")
1560146906Skan	(match_operand:QI 1 "register_operand" "+q"))
1561146906Skan   (set (match_dup 1)
1562146906Skan	(match_dup 0))]
1563146906Skan  "TARGET_PARTIAL_REG_STALL"
156490286Sobrien  "xchg{b}\t%1, %0"
156590286Sobrien  [(set_attr "type" "imov")
1566146906Skan   (set_attr "mode" "QI")
156790286Sobrien   (set_attr "pent_pair" "np")
1568146906Skan   (set_attr "athlon_decode" "vector")
156990286Sobrien   (set_attr "ppro_uops" "few")])
157090286Sobrien
157190286Sobrien(define_expand "movstrictqi"
157290286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
157390286Sobrien	(match_operand:QI 1 "general_operand" ""))]
1574117404Skan  "! TARGET_PARTIAL_REG_STALL || optimize_size"
157518334Speter{
157690286Sobrien  /* Don't generate memory->memory moves, go through a register.  */
157790286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
157890286Sobrien    operands[1] = force_reg (QImode, operands[1]);
157990286Sobrien})
158018334Speter
158190286Sobrien(define_insn "*movstrictqi_1"
158290286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
158390286Sobrien	(match_operand:QI 1 "general_operand" "*qn,m"))]
1584117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
158590286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
158690286Sobrien  "mov{b}\t{%1, %0|%0, %1}"
158790286Sobrien  [(set_attr "type" "imov")
158890286Sobrien   (set_attr "mode" "QI")])
158918334Speter
159090286Sobrien(define_insn "*movstrictqi_xor"
159190286Sobrien  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
159290286Sobrien	(match_operand:QI 1 "const0_operand" "i"))
159390286Sobrien   (clobber (reg:CC 17))]
159490286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
159590286Sobrien  "xor{b}\t{%0, %0|%0, %0}"
159690286Sobrien  [(set_attr "type" "alu1")
159790286Sobrien   (set_attr "mode" "QI")
159890286Sobrien   (set_attr "length_immediate" "0")])
159918334Speter
160090286Sobrien(define_insn "*movsi_extv_1"
160190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
160290286Sobrien	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
160390286Sobrien			 (const_int 8)
160490286Sobrien			 (const_int 8)))]
160518334Speter  ""
160690286Sobrien  "movs{bl|x}\t{%h1, %0|%0, %h1}"
160790286Sobrien  [(set_attr "type" "imovx")
160890286Sobrien   (set_attr "mode" "SI")])
160990286Sobrien
161090286Sobrien(define_insn "*movhi_extv_1"
161190286Sobrien  [(set (match_operand:HI 0 "register_operand" "=R")
161290286Sobrien	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
161390286Sobrien			 (const_int 8)
161490286Sobrien			 (const_int 8)))]
161590286Sobrien  ""
161690286Sobrien  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
161790286Sobrien  [(set_attr "type" "imovx")
161890286Sobrien   (set_attr "mode" "SI")])
161990286Sobrien
162090286Sobrien(define_insn "*movqi_extv_1"
162190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
162290286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
162390286Sobrien                         (const_int 8)
162490286Sobrien                         (const_int 8)))]
162590286Sobrien  "!TARGET_64BIT"
162618334Speter{
162790286Sobrien  switch (get_attr_type (insn))
162818334Speter    {
162990286Sobrien    case TYPE_IMOVX:
163090286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
163190286Sobrien    default:
163290286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
163318334Speter    }
163490286Sobrien}
163590286Sobrien  [(set (attr "type")
163690286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
163790286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
163890286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
163990286Sobrien				 (const_int 0))))
164090286Sobrien	(const_string "imovx")
164190286Sobrien	(const_string "imov")))
164290286Sobrien   (set (attr "mode")
164390286Sobrien     (if_then_else (eq_attr "type" "imovx")
164490286Sobrien	(const_string "SI")
164590286Sobrien	(const_string "QI")))])
164618334Speter
164790286Sobrien(define_insn "*movqi_extv_1_rex64"
164890286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
164990286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
165090286Sobrien                         (const_int 8)
165190286Sobrien                         (const_int 8)))]
165290286Sobrien  "TARGET_64BIT"
165318334Speter{
165490286Sobrien  switch (get_attr_type (insn))
165550650Sobrien    {
165690286Sobrien    case TYPE_IMOVX:
165790286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
165890286Sobrien    default:
165990286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
166050650Sobrien    }
166190286Sobrien}
166290286Sobrien  [(set (attr "type")
166390286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
166490286Sobrien			(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
1674132727Skan;; Stores and loads of ax to arbitrary constant address.
167590286Sobrien;; We fake an second form of instruction to force reload to load address
167690286Sobrien;; into register when rax is not available
167790286Sobrien(define_insn "*movabsqi_1_rex64"
1678117404Skan  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1679117404Skan	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1680117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
168190286Sobrien  "@
168290286Sobrien   movabs{b}\t{%1, %P0|%P0, %1}
1683117404Skan   mov{b}\t{%1, %a0|%a0, %1}"
168490286Sobrien  [(set_attr "type" "imov")
1685117404Skan   (set_attr "modrm" "0,*")
1686117404Skan   (set_attr "length_address" "8,0")
1687117404Skan   (set_attr "length_immediate" "0,*")
168890286Sobrien   (set_attr "memory" "store")
168990286Sobrien   (set_attr "mode" "QI")])
169018334Speter
169190286Sobrien(define_insn "*movabsqi_2_rex64"
169290286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a,r")
169390286Sobrien        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1694117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
169590286Sobrien  "@
169690286Sobrien   movabs{b}\t{%P1, %0|%0, %P1}
169790286Sobrien   mov{b}\t{%a1, %0|%0, %a1}"
169890286Sobrien  [(set_attr "type" "imov")
169990286Sobrien   (set_attr "modrm" "0,*")
170090286Sobrien   (set_attr "length_address" "8,0")
170190286Sobrien   (set_attr "length_immediate" "0")
170290286Sobrien   (set_attr "memory" "load")
170390286Sobrien   (set_attr "mode" "QI")])
170418334Speter
170590286Sobrien(define_insn "*movsi_extzv_1"
170690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
170790286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
170890286Sobrien			 (const_int 8)
170990286Sobrien			 (const_int 8)))]
171090286Sobrien  ""
171190286Sobrien  "movz{bl|x}\t{%h1, %0|%0, %h1}"
171290286Sobrien  [(set_attr "type" "imovx")
171390286Sobrien   (set_attr "mode" "SI")])
171418334Speter
171590286Sobrien(define_insn "*movqi_extzv_2"
171690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
171790286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
171890286Sobrien				    (const_int 8)
171990286Sobrien				    (const_int 8)) 0))]
172090286Sobrien  "!TARGET_64BIT"
172118334Speter{
172290286Sobrien  switch (get_attr_type (insn))
172318334Speter    {
172490286Sobrien    case TYPE_IMOVX:
172590286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
172690286Sobrien    default:
172790286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
172818334Speter    }
172990286Sobrien}
173090286Sobrien  [(set (attr "type")
173190286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
173290286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
173390286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
173490286Sobrien				 (const_int 0))))
173590286Sobrien	(const_string "imovx")
173690286Sobrien	(const_string "imov")))
173790286Sobrien   (set (attr "mode")
173890286Sobrien     (if_then_else (eq_attr "type" "imovx")
173990286Sobrien	(const_string "SI")
174090286Sobrien	(const_string "QI")))])
174118334Speter
174290286Sobrien(define_insn "*movqi_extzv_2_rex64"
174390286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
174490286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
174590286Sobrien				    (const_int 8)
174690286Sobrien				    (const_int 8)) 0))]
174790286Sobrien  "TARGET_64BIT"
174818334Speter{
174990286Sobrien  switch (get_attr_type (insn))
175090286Sobrien    {
175190286Sobrien    case TYPE_IMOVX:
175290286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
175390286Sobrien    default:
175490286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
175590286Sobrien    }
175690286Sobrien}
175790286Sobrien  [(set (attr "type")
175890286Sobrien     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
175990286Sobrien			(ne (symbol_ref "TARGET_MOVX")
176090286Sobrien			    (const_int 0)))
176190286Sobrien	(const_string "imovx")
176290286Sobrien	(const_string "imov")))
176390286Sobrien   (set (attr "mode")
176490286Sobrien     (if_then_else (eq_attr "type" "imovx")
176590286Sobrien	(const_string "SI")
176690286Sobrien	(const_string "QI")))])
176718334Speter
176890286Sobrien(define_insn "movsi_insv_1"
176990286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
177090286Sobrien			 (const_int 8)
177190286Sobrien			 (const_int 8))
177290286Sobrien	(match_operand:SI 1 "general_operand" "Qmn"))]
177390286Sobrien  "!TARGET_64BIT"
177490286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
177590286Sobrien  [(set_attr "type" "imov")
177690286Sobrien   (set_attr "mode" "QI")])
177752296Sobrien
1778132727Skan(define_insn "movdi_insv_1_rex64"
1779132727Skan  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
178090286Sobrien			 (const_int 8)
178190286Sobrien			 (const_int 8))
1782132727Skan	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
178390286Sobrien  "TARGET_64BIT"
178490286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
178590286Sobrien  [(set_attr "type" "imov")
178690286Sobrien   (set_attr "mode" "QI")])
178718334Speter
178890286Sobrien(define_insn "*movqi_insv_2"
178990286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
179090286Sobrien			 (const_int 8)
179190286Sobrien			 (const_int 8))
1792132727Skan	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1793132727Skan		     (const_int 8)))]
179490286Sobrien  ""
179590286Sobrien  "mov{b}\t{%h1, %h0|%h0, %h1}"
179690286Sobrien  [(set_attr "type" "imov")
179790286Sobrien   (set_attr "mode" "QI")])
179818334Speter
179990286Sobrien(define_expand "movdi"
180090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
180190286Sobrien	(match_operand:DI 1 "general_operand" ""))]
180290286Sobrien  ""
180390286Sobrien  "ix86_expand_move (DImode, operands); DONE;")
180418334Speter
180590286Sobrien(define_insn "*pushdi"
180690286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
180790286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
180890286Sobrien  "!TARGET_64BIT"
180990286Sobrien  "#")
181090286Sobrien
181190286Sobrien(define_insn "pushdi2_rex64"
181290286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<,!<")
181390286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
181490286Sobrien  "TARGET_64BIT"
181590286Sobrien  "@
181690286Sobrien   push{q}\t%1
181790286Sobrien   #"
181890286Sobrien  [(set_attr "type" "push,multi")
181990286Sobrien   (set_attr "mode" "DI")])
182090286Sobrien
182190286Sobrien;; Convert impossible pushes of immediate to existing instructions.
182290286Sobrien;; First try to get scratch register and go through it.  In case this
182390286Sobrien;; fails, push sign extended lower part first and then overwrite
182490286Sobrien;; upper part by 32bit move.
182590286Sobrien(define_peephole2
182690286Sobrien  [(match_scratch:DI 2 "r")
182790286Sobrien   (set (match_operand:DI 0 "push_operand" "")
182890286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
182990286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
183090286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
183190286Sobrien  [(set (match_dup 2) (match_dup 1))
183290286Sobrien   (set (match_dup 0) (match_dup 2))]
183390286Sobrien  "")
183490286Sobrien
183590286Sobrien;; We need to define this as both peepholer and splitter for case
183690286Sobrien;; peephole2 pass is not run.
183790286Sobrien(define_peephole2
183890286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
183990286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
184090286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
184190286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
184290286Sobrien  [(set (match_dup 0) (match_dup 1))
184390286Sobrien   (set (match_dup 2) (match_dup 3))]
184490286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
184590286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
184690286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
184790286Sobrien						    GEN_INT (4)));
184890286Sobrien  ")
184990286Sobrien
185090286Sobrien(define_split
185190286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
185290286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
185390286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
185490286Sobrien   && !symbolic_operand (operands[1], DImode)
185590286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
185690286Sobrien  [(set (match_dup 0) (match_dup 1))
185790286Sobrien   (set (match_dup 2) (match_dup 3))]
185890286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
185990286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
186090286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
186190286Sobrien						    GEN_INT (4)));
186290286Sobrien  ")
186390286Sobrien
186490286Sobrien(define_insn "*pushdi2_prologue_rex64"
186590286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
186690286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
186790286Sobrien   (clobber (mem:BLK (scratch)))]
186890286Sobrien  "TARGET_64BIT"
186990286Sobrien  "push{q}\t%1"
187090286Sobrien  [(set_attr "type" "push")
187190286Sobrien   (set_attr "mode" "DI")])
187290286Sobrien
187390286Sobrien(define_insn "*popdi1_epilogue_rex64"
187490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
187590286Sobrien	(mem:DI (reg:DI 7)))
187690286Sobrien   (set (reg:DI 7)
187790286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))
187890286Sobrien   (clobber (mem:BLK (scratch)))]
187990286Sobrien  "TARGET_64BIT"
188090286Sobrien  "pop{q}\t%0"
188190286Sobrien  [(set_attr "type" "pop")
188290286Sobrien   (set_attr "mode" "DI")])
188390286Sobrien
188490286Sobrien(define_insn "popdi1"
188590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
188690286Sobrien	(mem:DI (reg:DI 7)))
188790286Sobrien   (set (reg:DI 7)
188890286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))]
188990286Sobrien  "TARGET_64BIT"
189090286Sobrien  "pop{q}\t%0"
189190286Sobrien  [(set_attr "type" "pop")
189290286Sobrien   (set_attr "mode" "DI")])
189390286Sobrien
189490286Sobrien(define_insn "*movdi_xor_rex64"
189590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
189690286Sobrien	(match_operand:DI 1 "const0_operand" "i"))
189790286Sobrien   (clobber (reg:CC 17))]
189890286Sobrien  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
189990286Sobrien   && reload_completed"
190090286Sobrien  "xor{l}\t{%k0, %k0|%k0, %k0}"
190190286Sobrien  [(set_attr "type" "alu1")
190290286Sobrien   (set_attr "mode" "SI")
190390286Sobrien   (set_attr "length_immediate" "0")])
190490286Sobrien
190590286Sobrien(define_insn "*movdi_or_rex64"
190690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
190790286Sobrien	(match_operand:DI 1 "const_int_operand" "i"))
190890286Sobrien   (clobber (reg:CC 17))]
190990286Sobrien  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
191090286Sobrien   && reload_completed
1911132727Skan   && operands[1] == constm1_rtx"
191218334Speter{
191390286Sobrien  operands[1] = constm1_rtx;
191490286Sobrien  return "or{q}\t{%1, %0|%0, %1}";
191590286Sobrien}
191690286Sobrien  [(set_attr "type" "alu1")
191790286Sobrien   (set_attr "mode" "DI")
191890286Sobrien   (set_attr "length_immediate" "1")])
191918334Speter
192090286Sobrien(define_insn "*movdi_2"
192196294Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
192290286Sobrien	(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
192390286Sobrien  "!TARGET_64BIT
192490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
192590286Sobrien  "@
192690286Sobrien   #
192790286Sobrien   #
192890286Sobrien   movq\t{%1, %0|%0, %1}
192990286Sobrien   movq\t{%1, %0|%0, %1}
193090286Sobrien   movq\t{%1, %0|%0, %1}
193190286Sobrien   movdqa\t{%1, %0|%0, %1}
193290286Sobrien   movq\t{%1, %0|%0, %1}"
1933117404Skan  [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
193490286Sobrien   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
193518334Speter
193690286Sobrien(define_split
193790286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
193890286Sobrien        (match_operand:DI 1 "general_operand" ""))]
193990286Sobrien  "!TARGET_64BIT && reload_completed
194090286Sobrien   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
194190286Sobrien  [(const_int 0)]
194290286Sobrien  "ix86_split_long_move (operands); DONE;")
194318334Speter
194490286Sobrien;; %%% This multiword shite has got to go.
194590286Sobrien(define_split
194690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
194790286Sobrien        (match_operand:DI 1 "general_operand" ""))]
194890286Sobrien  "!TARGET_64BIT && reload_completed
194990286Sobrien   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
195090286Sobrien   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
195190286Sobrien  [(const_int 0)]
195290286Sobrien  "ix86_split_long_move (operands); DONE;")
195318334Speter
195490286Sobrien(define_insn "*movdi_1_rex64"
1955132727Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1956132727Skan	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
195790286Sobrien  "TARGET_64BIT
1958132727Skan   && (TARGET_INTER_UNIT_MOVES || optimize_size)
195990286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
196090286Sobrien{
196190286Sobrien  switch (get_attr_type (insn))
196290286Sobrien    {
1963117404Skan    case TYPE_SSEMOV:
1964132727Skan      if (get_attr_mode (insn) == MODE_TI)
196590286Sobrien	  return "movdqa\t{%1, %0|%0, %1}";
196690286Sobrien      /* FALLTHRU */
1967117404Skan    case TYPE_MMXMOV:
1968132727Skan      /* Moves from and into integer register is done using movd opcode with
1969132727Skan 	 REX prefix.  */
1970132727Skan      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1971132727Skan	  return "movd\t{%1, %0|%0, %1}";
197290286Sobrien      return "movq\t{%1, %0|%0, %1}";
197390286Sobrien    case TYPE_MULTI:
197490286Sobrien      return "#";
197590286Sobrien    case TYPE_LEA:
197690286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
197790286Sobrien    default:
1978117404Skan      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
197990286Sobrien	abort ();
198090286Sobrien      if (get_attr_mode (insn) == MODE_SI)
198190286Sobrien	return "mov{l}\t{%k1, %k0|%k0, %k1}";
198290286Sobrien      else if (which_alternative == 2)
198390286Sobrien	return "movabs{q}\t{%1, %0|%0, %1}";
198418334Speter      else
198590286Sobrien	return "mov{q}\t{%1, %0|%0, %1}";
198618334Speter    }
198790286Sobrien}
198890286Sobrien  [(set (attr "type")
1989132727Skan     (cond [(eq_attr "alternative" "5,6,7")
1990117404Skan	      (const_string "mmxmov")
1991132727Skan	    (eq_attr "alternative" "8,9,10")
1992117404Skan	      (const_string "ssemov")
199390286Sobrien	    (eq_attr "alternative" "4")
199490286Sobrien	      (const_string "multi")
199590286Sobrien 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
199690286Sobrien		 (match_operand:DI 1 "symbolic_operand" ""))
199790286Sobrien	      (const_string "lea")
199890286Sobrien	   ]
199990286Sobrien	   (const_string "imov")))
2000132727Skan   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2001132727Skan   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2002132727Skan   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
200350650Sobrien
2004132727Skan(define_insn "*movdi_1_rex64_nointerunit"
2005132727Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2006132727Skan	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2007132727Skan  "TARGET_64BIT
2008132727Skan   && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2009132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2010132727Skan{
2011132727Skan  switch (get_attr_type (insn))
2012132727Skan    {
2013132727Skan    case TYPE_SSEMOV:
2014132727Skan      if (get_attr_mode (insn) == MODE_TI)
2015132727Skan	  return "movdqa\t{%1, %0|%0, %1}";
2016132727Skan      /* FALLTHRU */
2017132727Skan    case TYPE_MMXMOV:
2018132727Skan      return "movq\t{%1, %0|%0, %1}";
2019132727Skan    case TYPE_MULTI:
2020132727Skan      return "#";
2021132727Skan    case TYPE_LEA:
2022132727Skan      return "lea{q}\t{%a1, %0|%0, %a1}";
2023132727Skan    default:
2024132727Skan      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2025132727Skan	abort ();
2026132727Skan      if (get_attr_mode (insn) == MODE_SI)
2027132727Skan	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028132727Skan      else if (which_alternative == 2)
2029132727Skan	return "movabs{q}\t{%1, %0|%0, %1}";
2030132727Skan      else
2031132727Skan	return "mov{q}\t{%1, %0|%0, %1}";
2032132727Skan    }
2033132727Skan}
2034132727Skan  [(set (attr "type")
2035132727Skan     (cond [(eq_attr "alternative" "5,6,7")
2036132727Skan	      (const_string "mmxmov")
2037132727Skan	    (eq_attr "alternative" "8,9,10")
2038132727Skan	      (const_string "ssemov")
2039132727Skan	    (eq_attr "alternative" "4")
2040132727Skan	      (const_string "multi")
2041132727Skan 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
2042132727Skan		 (match_operand:DI 1 "symbolic_operand" ""))
2043132727Skan	      (const_string "lea")
2044132727Skan	   ]
2045132727Skan	   (const_string "imov")))
2046132727Skan   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2047132727Skan   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2048132727Skan   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2049132727Skan
2050132727Skan;; Stores and loads of ax to arbitrary constant address.
205190286Sobrien;; We fake an second form of instruction to force reload to load address
205290286Sobrien;; into register when rax is not available
205390286Sobrien(define_insn "*movabsdi_1_rex64"
2054102802Skan  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2055102802Skan	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2056117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
205790286Sobrien  "@
205890286Sobrien   movabs{q}\t{%1, %P0|%P0, %1}
2059102802Skan   mov{q}\t{%1, %a0|%a0, %1}"
206090286Sobrien  [(set_attr "type" "imov")
2061102802Skan   (set_attr "modrm" "0,*")
2062102802Skan   (set_attr "length_address" "8,0")
2063102802Skan   (set_attr "length_immediate" "0,*")
206490286Sobrien   (set_attr "memory" "store")
206590286Sobrien   (set_attr "mode" "DI")])
206618334Speter
206790286Sobrien(define_insn "*movabsdi_2_rex64"
206890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a,r")
206990286Sobrien        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2070117404Skan  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
207190286Sobrien  "@
207290286Sobrien   movabs{q}\t{%P1, %0|%0, %P1}
207390286Sobrien   mov{q}\t{%a1, %0|%0, %a1}"
207490286Sobrien  [(set_attr "type" "imov")
207590286Sobrien   (set_attr "modrm" "0,*")
207690286Sobrien   (set_attr "length_address" "8,0")
207790286Sobrien   (set_attr "length_immediate" "0")
207890286Sobrien   (set_attr "memory" "load")
207990286Sobrien   (set_attr "mode" "DI")])
208090286Sobrien
208190286Sobrien;; Convert impossible stores of immediate to existing instructions.
208290286Sobrien;; First try to get scratch register and go through it.  In case this
208390286Sobrien;; fails, move by 32bit parts.
208490286Sobrien(define_peephole2
208590286Sobrien  [(match_scratch:DI 2 "r")
208690286Sobrien   (set (match_operand:DI 0 "memory_operand" "")
208790286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
208890286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
208990286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
209090286Sobrien  [(set (match_dup 2) (match_dup 1))
209190286Sobrien   (set (match_dup 0) (match_dup 2))]
209252296Sobrien  "")
209350650Sobrien
209490286Sobrien;; We need to define this as both peepholer and splitter for case
209590286Sobrien;; peephole2 pass is not run.
209690286Sobrien(define_peephole2
209790286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
209890286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
209990286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
210090286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
210190286Sobrien  [(set (match_dup 2) (match_dup 3))
210290286Sobrien   (set (match_dup 4) (match_dup 5))]
210390286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
210490286Sobrien
210590286Sobrien(define_split
210690286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
210790286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
210890286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
210990286Sobrien   && !symbolic_operand (operands[1], DImode)
211090286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
211190286Sobrien  [(set (match_dup 2) (match_dup 3))
211290286Sobrien   (set (match_dup 4) (match_dup 5))]
211390286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
211490286Sobrien
211590286Sobrien(define_insn "*swapdi_rex64"
211690286Sobrien  [(set (match_operand:DI 0 "register_operand" "+r")
211790286Sobrien	(match_operand:DI 1 "register_operand" "+r"))
211890286Sobrien   (set (match_dup 1)
211990286Sobrien	(match_dup 0))]
212090286Sobrien  "TARGET_64BIT"
212190286Sobrien  "xchg{q}\t%1, %0"
212290286Sobrien  [(set_attr "type" "imov")
2123146906Skan   (set_attr "mode" "DI")
212490286Sobrien   (set_attr "pent_pair" "np")
212590286Sobrien   (set_attr "athlon_decode" "vector")
212690286Sobrien   (set_attr "ppro_uops" "few")])
212790286Sobrien
212850650Sobrien(define_expand "movsf"
212990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
213050650Sobrien	(match_operand:SF 1 "general_operand" ""))]
213118334Speter  ""
213290286Sobrien  "ix86_expand_move (SFmode, operands); DONE;")
213390286Sobrien
213490286Sobrien(define_insn "*pushsf"
213590286Sobrien  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
213690286Sobrien	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
213790286Sobrien  "!TARGET_64BIT"
213818334Speter{
213990286Sobrien  switch (which_alternative)
214018334Speter    {
214190286Sobrien    case 1:
214290286Sobrien      return "push{l}\t%1";
214390286Sobrien
214490286Sobrien    default:
2145132727Skan      /* This insn should be already split before reg-stack.  */
214690286Sobrien      abort ();
214718334Speter    }
214890286Sobrien}
214990286Sobrien  [(set_attr "type" "multi,push,multi")
215090286Sobrien   (set_attr "mode" "SF,SI,SF")])
215118334Speter
215290286Sobrien(define_insn "*pushsf_rex64"
215390286Sobrien  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
215490286Sobrien	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
215590286Sobrien  "TARGET_64BIT"
215618334Speter{
215790286Sobrien  switch (which_alternative)
215890286Sobrien    {
215990286Sobrien    case 1:
216090286Sobrien      return "push{q}\t%q1";
216118334Speter
216290286Sobrien    default:
2163132727Skan      /* This insn should be already split before reg-stack.  */
216490286Sobrien      abort ();
216518334Speter    }
216690286Sobrien}
216790286Sobrien  [(set_attr "type" "multi,push,multi")
216890286Sobrien   (set_attr "mode" "SF,DI,SF")])
216918334Speter
217090286Sobrien(define_split
217190286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
217290286Sobrien	(match_operand:SF 1 "memory_operand" ""))]
217390286Sobrien  "reload_completed
217490286Sobrien   && GET_CODE (operands[1]) == MEM
217590286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
217690286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
217790286Sobrien  [(set (match_dup 0)
217890286Sobrien	(match_dup 1))]
217990286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
218018334Speter
218190286Sobrien
218290286Sobrien;; %%% Kill this when call knows how to work this out.
218390286Sobrien(define_split
218490286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
2185117404Skan	(match_operand:SF 1 "any_fp_register_operand" ""))]
2186117404Skan  "!TARGET_64BIT"
218790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
218890286Sobrien   (set (mem:SF (reg:SI 7)) (match_dup 1))])
218990286Sobrien
219090286Sobrien(define_split
219190286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
2192117404Skan	(match_operand:SF 1 "any_fp_register_operand" ""))]
2193117404Skan  "TARGET_64BIT"
219490286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
219590286Sobrien   (set (mem:SF (reg:DI 7)) (match_dup 1))])
219690286Sobrien
219790286Sobrien(define_insn "*movsf_1"
219896294Sobrien  [(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")
2199117404Skan	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2200132727Skan  "(TARGET_INTER_UNIT_MOVES || optimize_size)
2201132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
220290286Sobrien   && (reload_in_progress || reload_completed
220390286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
220490286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
220590286Sobrien       || memory_operand (operands[0], SFmode))" 
220690286Sobrien{
220790286Sobrien  switch (which_alternative)
220818334Speter    {
220990286Sobrien    case 0:
221090286Sobrien      if (REG_P (operands[1])
221190286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
221290286Sobrien        return "fstp\t%y0";
221390286Sobrien      else if (STACK_TOP_P (operands[0]))
221490286Sobrien        return "fld%z1\t%y1";
221518334Speter      else
221690286Sobrien        return "fst\t%y0";
221718334Speter
221890286Sobrien    case 1:
221990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
222090286Sobrien        return "fstp%z0\t%y0";
222190286Sobrien      else
222290286Sobrien        return "fst%z0\t%y0";
222318334Speter
222490286Sobrien    case 2:
2225132727Skan      return standard_80387_constant_opcode (operands[1]);
2226132727Skan
2227132727Skan    case 3:
2228132727Skan    case 4:
2229132727Skan      return "mov{l}\t{%1, %0|%0, %1}";
2230132727Skan    case 5:
2231132727Skan      if (get_attr_mode (insn) == MODE_TI)
2232132727Skan	return "pxor\t%0, %0";
2233132727Skan      else
2234132727Skan	return "xorps\t%0, %0";
2235132727Skan    case 6:
2236132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
2237132727Skan	return "movaps\t{%1, %0|%0, %1}";
2238132727Skan      else
2239132727Skan	return "movss\t{%1, %0|%0, %1}";
2240132727Skan    case 7:
2241132727Skan    case 8:
2242132727Skan      return "movss\t{%1, %0|%0, %1}";
2243132727Skan
2244132727Skan    case 9:
2245132727Skan    case 10:
2246132727Skan      return "movd\t{%1, %0|%0, %1}";
2247132727Skan
2248132727Skan    case 11:
2249132727Skan      return "movq\t{%1, %0|%0, %1}";
2250132727Skan
2251132727Skan    default:
225290286Sobrien      abort();
2253132727Skan    }
2254132727Skan}
2255132727Skan  [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2256132727Skan   (set (attr "mode")
2257132727Skan        (cond [(eq_attr "alternative" "3,4,9,10")
2258132727Skan		 (const_string "SI")
2259132727Skan	       (eq_attr "alternative" "5")
2260132727Skan		 (if_then_else
2261132727Skan		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2262132727Skan			    	 (const_int 0))
2263132727Skan			     (ne (symbol_ref "TARGET_SSE2")
2264132727Skan				 (const_int 0)))
2265132727Skan			(eq (symbol_ref "optimize_size")
2266132727Skan			    (const_int 0)))
2267132727Skan		   (const_string "TI")
2268132727Skan		   (const_string "V4SF"))
2269132727Skan	       /* For architectures resolving dependencies on
2270132727Skan		  whole SSE registers use APS move to break dependency
2271132727Skan		  chains, otherwise use short move to avoid extra work. 
227218334Speter
2273132727Skan		  Do the same for architectures resolving dependencies on
2274132727Skan		  the parts.  While in DF mode it is better to always handle
2275132727Skan		  just register parts, the SF mode is different due to lack
2276132727Skan		  of instructions to load just part of the register.  It is
2277132727Skan		  better to maintain the whole registers in single format
2278132727Skan		  to avoid problems on using packed logical operations.  */
2279132727Skan	       (eq_attr "alternative" "6")
2280132727Skan		 (if_then_else
2281132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2282132727Skan			    (const_int 0))
2283132727Skan			(ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2284132727Skan			    (const_int 0)))
2285132727Skan		   (const_string "V4SF")
2286132727Skan		   (const_string "SF"))
2287132727Skan	       (eq_attr "alternative" "11")
2288132727Skan		 (const_string "DI")]
2289132727Skan	       (const_string "SF")))])
2290132727Skan
2291132727Skan(define_insn "*movsf_1_nointerunit"
2292132727Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2293132727Skan	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2294132727Skan  "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2295132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2296132727Skan   && (reload_in_progress || reload_completed
2297132727Skan       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2298132727Skan       || GET_CODE (operands[1]) != CONST_DOUBLE
2299132727Skan       || memory_operand (operands[0], SFmode))" 
2300132727Skan{
2301132727Skan  switch (which_alternative)
2302132727Skan    {
2303132727Skan    case 0:
2304132727Skan      if (REG_P (operands[1])
2305132727Skan          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2306132727Skan	{
2307132727Skan	  if (REGNO (operands[0]) == FIRST_STACK_REG
2308132727Skan	      && TARGET_USE_FFREEP)
2309132727Skan	    return "ffreep\t%y0";
2310132727Skan          return "fstp\t%y0";
2311132727Skan	}
2312132727Skan      else if (STACK_TOP_P (operands[0]))
2313132727Skan        return "fld%z1\t%y1";
2314132727Skan      else
2315132727Skan        return "fst\t%y0";
2316132727Skan
2317132727Skan    case 1:
2318132727Skan      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319132727Skan        return "fstp%z0\t%y0";
2320132727Skan      else
2321132727Skan        return "fst%z0\t%y0";
2322132727Skan
2323132727Skan    case 2:
2324132727Skan      return standard_80387_constant_opcode (operands[1]);
2325132727Skan
232690286Sobrien    case 3:
232790286Sobrien    case 4:
232890286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
232990286Sobrien    case 5:
2330132727Skan      if (get_attr_mode (insn) == MODE_TI)
233196294Sobrien	return "pxor\t%0, %0";
233296294Sobrien      else
233396294Sobrien	return "xorps\t%0, %0";
233490286Sobrien    case 6:
2335132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
233690286Sobrien	return "movaps\t{%1, %0|%0, %1}";
233790286Sobrien      else
233890286Sobrien	return "movss\t{%1, %0|%0, %1}";
233990286Sobrien    case 7:
234090286Sobrien    case 8:
234190286Sobrien      return "movss\t{%1, %0|%0, %1}";
234218334Speter
234396294Sobrien    case 9:
234496294Sobrien    case 10:
234596294Sobrien      return "movd\t{%1, %0|%0, %1}";
234696294Sobrien
234796294Sobrien    case 11:
234896294Sobrien      return "movq\t{%1, %0|%0, %1}";
234996294Sobrien
235090286Sobrien    default:
235190286Sobrien      abort();
235290286Sobrien    }
235390286Sobrien}
2354117404Skan  [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2355132727Skan   (set (attr "mode")
2356132727Skan        (cond [(eq_attr "alternative" "3,4,9,10")
2357132727Skan		 (const_string "SI")
2358132727Skan	       (eq_attr "alternative" "5")
2359132727Skan		 (if_then_else
2360132727Skan		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2361132727Skan			    	 (const_int 0))
2362132727Skan			     (ne (symbol_ref "TARGET_SSE2")
2363132727Skan				 (const_int 0)))
2364132727Skan			(eq (symbol_ref "optimize_size")
2365132727Skan			    (const_int 0)))
2366132727Skan		   (const_string "TI")
2367132727Skan		   (const_string "V4SF"))
2368132727Skan	       /* For architectures resolving dependencies on
2369132727Skan		  whole SSE registers use APS move to break dependency
2370132727Skan		  chains, otherwise use short move to avoid extra work. 
237118334Speter
2372132727Skan		  Do the same for architectures resolving dependencies on
2373132727Skan		  the parts.  While in DF mode it is better to always handle
2374132727Skan		  just register parts, the SF mode is different due to lack
2375132727Skan		  of instructions to load just part of the register.  It is
2376132727Skan		  better to maintain the whole registers in single format
2377132727Skan		  to avoid problems on using packed logical operations.  */
2378132727Skan	       (eq_attr "alternative" "6")
2379132727Skan		 (if_then_else
2380132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2381132727Skan			    (const_int 0))
2382132727Skan			(ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2383132727Skan			    (const_int 0)))
2384132727Skan		   (const_string "V4SF")
2385132727Skan		   (const_string "SF"))
2386132727Skan	       (eq_attr "alternative" "11")
2387132727Skan		 (const_string "DI")]
2388132727Skan	       (const_string "SF")))])
2389132727Skan
239090286Sobrien(define_insn "*swapsf"
239190286Sobrien  [(set (match_operand:SF 0 "register_operand" "+f")
239290286Sobrien	(match_operand:SF 1 "register_operand" "+f"))
239318334Speter   (set (match_dup 1)
239418334Speter	(match_dup 0))]
239590286Sobrien  "reload_completed || !TARGET_SSE"
239618334Speter{
239718334Speter  if (STACK_TOP_P (operands[0]))
239890286Sobrien    return "fxch\t%1";
239918334Speter  else
240090286Sobrien    return "fxch\t%0";
240190286Sobrien}
240290286Sobrien  [(set_attr "type" "fxch")
240390286Sobrien   (set_attr "mode" "SF")])
240418334Speter
240590286Sobrien(define_expand "movdf"
240690286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
240790286Sobrien	(match_operand:DF 1 "general_operand" ""))]
240890286Sobrien  ""
240990286Sobrien  "ix86_expand_move (DFmode, operands); DONE;")
241052296Sobrien
241190286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2412132727Skan;; Size of pushdf using integer instructions is 2+2*memory operand size
241390286Sobrien;; On the average, pushdf using integers can be still shorter.  Allow this
241490286Sobrien;; pattern for optimize_size too.
241590286Sobrien
241690286Sobrien(define_insn "*pushdf_nointeger"
241790286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
241890286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
241990286Sobrien  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
242018334Speter{
2421132727Skan  /* This insn should be already split before reg-stack.  */
2422132727Skan  abort ();
242390286Sobrien}
242490286Sobrien  [(set_attr "type" "multi")
242590286Sobrien   (set_attr "mode" "DF,SI,SI,DF")])
242618334Speter
242790286Sobrien(define_insn "*pushdf_integer"
242890286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
242990286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
243090286Sobrien  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
243190286Sobrien{
2432132727Skan  /* This insn should be already split before reg-stack.  */
2433132727Skan  abort ();
243490286Sobrien}
243590286Sobrien  [(set_attr "type" "multi")
243690286Sobrien   (set_attr "mode" "DF,SI,DF")])
243718334Speter
243890286Sobrien;; %%% Kill this when call knows how to work this out.
243952296Sobrien(define_split
244052296Sobrien  [(set (match_operand:DF 0 "push_operand" "")
2441117404Skan	(match_operand:DF 1 "any_fp_register_operand" ""))]
2442117404Skan  "!TARGET_64BIT && reload_completed"
244390286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
244490286Sobrien   (set (mem:DF (reg:SI 7)) (match_dup 1))]
244552296Sobrien  "")
244650650Sobrien
244790286Sobrien(define_split
244890286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
2449117404Skan	(match_operand:DF 1 "any_fp_register_operand" ""))]
2450117404Skan  "TARGET_64BIT && reload_completed"
245190286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
245290286Sobrien   (set (mem:DF (reg:DI 7)) (match_dup 1))]
245390286Sobrien  "")
245490286Sobrien
245590286Sobrien(define_split
245690286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
245750650Sobrien	(match_operand:DF 1 "general_operand" ""))]
245890286Sobrien  "reload_completed"
245990286Sobrien  [(const_int 0)]
246090286Sobrien  "ix86_split_long_move (operands); DONE;")
246190286Sobrien
246290286Sobrien;; Moving is usually shorter when only FP registers are used. This separate
246390286Sobrien;; movdf pattern avoids the use of integer registers for FP operations
246490286Sobrien;; when optimizing for size.
246590286Sobrien
246690286Sobrien(define_insn "*movdf_nointeger"
246790286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2468117404Skan	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
246990286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2470132727Skan   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
247190286Sobrien   && (reload_in_progress || reload_completed
247290286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
247390286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
247490286Sobrien       || memory_operand (operands[0], DFmode))" 
247518334Speter{
247690286Sobrien  switch (which_alternative)
247718334Speter    {
247890286Sobrien    case 0:
247990286Sobrien      if (REG_P (operands[1])
248090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2481132727Skan	{
2482132727Skan	  if (REGNO (operands[0]) == FIRST_STACK_REG
2483132727Skan	      && TARGET_USE_FFREEP)
2484132727Skan	    return "ffreep\t%y0";
2485132727Skan          return "fstp\t%y0";
2486132727Skan	}
248790286Sobrien      else if (STACK_TOP_P (operands[0]))
248890286Sobrien        return "fld%z1\t%y1";
248990286Sobrien      else
249090286Sobrien        return "fst\t%y0";
249118334Speter
249290286Sobrien    case 1:
249390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
249490286Sobrien        return "fstp%z0\t%y0";
249590286Sobrien      else
249690286Sobrien        return "fst%z0\t%y0";
249718334Speter
249890286Sobrien    case 2:
2499132727Skan      return standard_80387_constant_opcode (operands[1]);
250018334Speter
250190286Sobrien    case 3:
250290286Sobrien    case 4:
250390286Sobrien      return "#";
250490286Sobrien    case 5:
2505132727Skan      switch (get_attr_mode (insn))
2506132727Skan	{
2507132727Skan	case MODE_V4SF:
2508132727Skan	  return "xorps\t%0, %0";
2509132727Skan	case MODE_V2DF:
2510132727Skan	  return "xorpd\t%0, %0";
2511132727Skan	case MODE_TI:
2512132727Skan	  return "pxor\t%0, %0";
2513132727Skan	default:
2514132727Skan	  abort ();
2515132727Skan	}
251690286Sobrien    case 6:
2517132727Skan      switch (get_attr_mode (insn))
2518132727Skan	{
2519132727Skan	case MODE_V4SF:
2520132727Skan	  return "movaps\t{%1, %0|%0, %1}";
2521132727Skan	case MODE_V2DF:
2522132727Skan	  return "movapd\t{%1, %0|%0, %1}";
2523132727Skan	case MODE_DF:
2524132727Skan	  return "movsd\t{%1, %0|%0, %1}";
2525132727Skan	default:
2526132727Skan	  abort ();
2527132727Skan	}
2528132727Skan    case 7:
2529132727Skan      if (get_attr_mode (insn) == MODE_V2DF)
2530132727Skan	return "movlpd\t{%1, %0|%0, %1}";
253190286Sobrien      else
253290286Sobrien	return "movsd\t{%1, %0|%0, %1}";
253390286Sobrien    case 8:
2534132727Skan      return "movsd\t{%1, %0|%0, %1}";
253518334Speter
253690286Sobrien    default:
253790286Sobrien      abort();
253818334Speter    }
253990286Sobrien}
2540117404Skan  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2541132727Skan   (set (attr "mode")
2542132727Skan        (cond [(eq_attr "alternative" "3,4")
2543132727Skan		 (const_string "SI")
2544132727Skan	       /* xorps is one byte shorter.  */
2545132727Skan	       (eq_attr "alternative" "5")
2546132727Skan		 (cond [(ne (symbol_ref "optimize_size")
2547132727Skan			    (const_int 0))
2548132727Skan			  (const_string "V4SF")
2549132727Skan			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2550132727Skan			    (const_int 0))
2551132727Skan			  (const_string "TI")]
2552132727Skan		       (const_string "V2DF"))
2553132727Skan	       /* For architectures resolving dependencies on
2554132727Skan		  whole SSE registers use APD move to break dependency
2555132727Skan		  chains, otherwise use short move to avoid extra work.
255618334Speter
2557132727Skan		  movaps encodes one byte shorter.  */
2558132727Skan	       (eq_attr "alternative" "6")
2559132727Skan		 (cond
2560132727Skan		  [(ne (symbol_ref "optimize_size")
2561132727Skan		       (const_int 0))
2562132727Skan		     (const_string "V4SF")
2563132727Skan		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2564132727Skan		       (const_int 0))
2565132727Skan		     (const_string "V2DF")]
2566132727Skan		   (const_string "DF"))
2567132727Skan	       /* For architectures resolving dependencies on register
2568132727Skan		  parts we may avoid extra work to zero out upper part
2569132727Skan		  of register.  */
2570132727Skan	       (eq_attr "alternative" "7")
2571132727Skan		 (if_then_else
2572132727Skan		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2573132727Skan		       (const_int 0))
2574132727Skan		   (const_string "V2DF")
2575132727Skan		   (const_string "DF"))]
2576132727Skan	       (const_string "DF")))])
2577132727Skan
257890286Sobrien(define_insn "*movdf_integer"
257990286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2580117404Skan	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
258190286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2582132727Skan   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
258390286Sobrien   && (reload_in_progress || reload_completed
258490286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
258590286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
258690286Sobrien       || memory_operand (operands[0], DFmode))" 
258790286Sobrien{
258890286Sobrien  switch (which_alternative)
258918334Speter    {
259090286Sobrien    case 0:
259190286Sobrien      if (REG_P (operands[1])
259290286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2593132727Skan	{
2594132727Skan	  if (REGNO (operands[0]) == FIRST_STACK_REG
2595132727Skan	      && TARGET_USE_FFREEP)
2596132727Skan	    return "ffreep\t%y0";
2597132727Skan          return "fstp\t%y0";
2598132727Skan	}
259990286Sobrien      else if (STACK_TOP_P (operands[0]))
260090286Sobrien        return "fld%z1\t%y1";
260118334Speter      else
260290286Sobrien        return "fst\t%y0";
260318334Speter
260490286Sobrien    case 1:
260590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
260690286Sobrien        return "fstp%z0\t%y0";
260790286Sobrien      else
260890286Sobrien        return "fst%z0\t%y0";
260918334Speter
261090286Sobrien    case 2:
2611132727Skan      return standard_80387_constant_opcode (operands[1]);
261218334Speter
261390286Sobrien    case 3:
261490286Sobrien    case 4:
261590286Sobrien      return "#";
261618334Speter
261790286Sobrien    case 5:
2618132727Skan      switch (get_attr_mode (insn))
2619132727Skan	{
2620132727Skan	case MODE_V4SF:
2621132727Skan	  return "xorps\t%0, %0";
2622132727Skan	case MODE_V2DF:
2623132727Skan	  return "xorpd\t%0, %0";
2624132727Skan	case MODE_TI:
2625132727Skan	  return "pxor\t%0, %0";
2626132727Skan	default:
2627132727Skan	  abort ();
2628132727Skan	}
262990286Sobrien    case 6:
2630132727Skan      switch (get_attr_mode (insn))
2631132727Skan	{
2632132727Skan	case MODE_V4SF:
2633132727Skan	  return "movaps\t{%1, %0|%0, %1}";
2634132727Skan	case MODE_V2DF:
2635132727Skan	  return "movapd\t{%1, %0|%0, %1}";
2636132727Skan	case MODE_DF:
2637132727Skan	  return "movsd\t{%1, %0|%0, %1}";
2638132727Skan	default:
2639132727Skan	  abort ();
2640132727Skan	}
2641132727Skan    case 7:
2642132727Skan      if (get_attr_mode (insn) == MODE_V2DF)
2643132727Skan	return "movlpd\t{%1, %0|%0, %1}";
264490286Sobrien      else
264590286Sobrien	return "movsd\t{%1, %0|%0, %1}";
264690286Sobrien    case 8:
264790286Sobrien      return "movsd\t{%1, %0|%0, %1}";
264818334Speter
264990286Sobrien    default:
265090286Sobrien      abort();
265190286Sobrien    }
265290286Sobrien}
2653117404Skan  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2654132727Skan   (set (attr "mode")
2655132727Skan        (cond [(eq_attr "alternative" "3,4")
2656132727Skan		 (const_string "SI")
2657132727Skan	       /* xorps is one byte shorter.  */
2658132727Skan	       (eq_attr "alternative" "5")
2659132727Skan		 (cond [(ne (symbol_ref "optimize_size")
2660132727Skan			    (const_int 0))
2661132727Skan			  (const_string "V4SF")
2662132727Skan			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2663132727Skan			    (const_int 0))
2664132727Skan			  (const_string "TI")]
2665132727Skan		       (const_string "V2DF"))
2666132727Skan	       /* For architectures resolving dependencies on
2667132727Skan		  whole SSE registers use APD move to break dependency
2668132727Skan		  chains, otherwise use short move to avoid extra work.  
266918334Speter
2670132727Skan		  movaps encodes one byte shorter.  */
2671132727Skan	       (eq_attr "alternative" "6")
2672132727Skan		 (cond
2673132727Skan		  [(ne (symbol_ref "optimize_size")
2674132727Skan		       (const_int 0))
2675132727Skan		     (const_string "V4SF")
2676132727Skan		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2677132727Skan		       (const_int 0))
2678132727Skan		     (const_string "V2DF")]
2679132727Skan		   (const_string "DF"))
2680132727Skan	       /* For architectures resolving dependencies on register
2681132727Skan		  parts we may avoid extra work to zero out upper part
2682132727Skan		  of register.  */
2683132727Skan	       (eq_attr "alternative" "7")
2684132727Skan		 (if_then_else
2685132727Skan		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2686132727Skan		       (const_int 0))
2687132727Skan		   (const_string "V2DF")
2688132727Skan		   (const_string "DF"))]
2689132727Skan	       (const_string "DF")))])
2690132727Skan
269190286Sobrien(define_split
269290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
269390286Sobrien	(match_operand:DF 1 "general_operand" ""))]
269490286Sobrien  "reload_completed
269590286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
269690286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
269790286Sobrien	 (GET_CODE (operands[0]) == SUBREG
269890286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
269990286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
270090286Sobrien	 (GET_CODE (operands[1]) == SUBREG
270190286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
270290286Sobrien  [(const_int 0)]
270390286Sobrien  "ix86_split_long_move (operands); DONE;")
270450650Sobrien
270590286Sobrien(define_insn "*swapdf"
270690286Sobrien  [(set (match_operand:DF 0 "register_operand" "+f")
270790286Sobrien	(match_operand:DF 1 "register_operand" "+f"))
270818334Speter   (set (match_dup 1)
270918334Speter	(match_dup 0))]
271090286Sobrien  "reload_completed || !TARGET_SSE2"
271118334Speter{
271218334Speter  if (STACK_TOP_P (operands[0]))
271390286Sobrien    return "fxch\t%1";
271418334Speter  else
271590286Sobrien    return "fxch\t%0";
271690286Sobrien}
271790286Sobrien  [(set_attr "type" "fxch")
271890286Sobrien   (set_attr "mode" "DF")])
271918334Speter
272090286Sobrien(define_expand "movxf"
272190286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
272290286Sobrien	(match_operand:XF 1 "general_operand" ""))]
2723132727Skan  ""
272490286Sobrien  "ix86_expand_move (XFmode, operands); DONE;")
272590286Sobrien
272690286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727132727Skan;; Size of pushdf using integer instructions is 3+3*memory operand size
272890286Sobrien;; Pushing using integer instructions is longer except for constants
272990286Sobrien;; and direct memory references.
273090286Sobrien;; (assuming that any given constant is pushed only once, but this ought to be
273190286Sobrien;;  handled elsewhere).
273290286Sobrien
273390286Sobrien(define_insn "*pushxf_nointeger"
273490286Sobrien  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
273590286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
273690286Sobrien  "optimize_size"
273790286Sobrien{
2738132727Skan  /* This insn should be already split before reg-stack.  */
2739132727Skan  abort ();
274090286Sobrien}
274190286Sobrien  [(set_attr "type" "multi")
274290286Sobrien   (set_attr "mode" "XF,SI,SI")])
274350650Sobrien
274490286Sobrien(define_insn "*pushxf_integer"
274590286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<,<")
274690286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
274790286Sobrien  "!optimize_size"
274890286Sobrien{
2749132727Skan  /* This insn should be already split before reg-stack.  */
2750132727Skan  abort ();
275190286Sobrien}
275290286Sobrien  [(set_attr "type" "multi")
275390286Sobrien   (set_attr "mode" "XF,SI")])
275490286Sobrien
275552296Sobrien(define_split
275690286Sobrien  [(set (match_operand 0 "push_operand" "")
275790286Sobrien	(match_operand 1 "general_operand" ""))]
275890286Sobrien  "reload_completed
275990286Sobrien   && (GET_MODE (operands[0]) == XFmode
276090286Sobrien       || GET_MODE (operands[0]) == DFmode)
2761117404Skan   && !ANY_FP_REG_P (operands[1])"
276290286Sobrien  [(const_int 0)]
276390286Sobrien  "ix86_split_long_move (operands); DONE;")
276490286Sobrien
276590286Sobrien(define_split
276652296Sobrien  [(set (match_operand:XF 0 "push_operand" "")
2767117404Skan	(match_operand:XF 1 "any_fp_register_operand" ""))]
2768117404Skan  "!TARGET_64BIT"
2769132727Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2770132727Skan   (set (mem:XF (reg:SI 7)) (match_dup 1))]
2771132727Skan  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
277250650Sobrien
277390286Sobrien(define_split
2774132727Skan  [(set (match_operand:XF 0 "push_operand" "")
2775132727Skan	(match_operand:XF 1 "any_fp_register_operand" ""))]
2776117404Skan  "TARGET_64BIT"
2777132727Skan  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2778132727Skan   (set (mem:XF (reg:DI 7)) (match_dup 1))]
2779132727Skan  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
278090286Sobrien
278190286Sobrien;; Do not use integer registers when optimizing for size
278290286Sobrien(define_insn "*movxf_nointeger"
278390286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
278490286Sobrien	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785132727Skan  "optimize_size
278690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
278790286Sobrien   && (reload_in_progress || reload_completed
278890286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
278990286Sobrien       || memory_operand (operands[0], XFmode))" 
279018334Speter{
279190286Sobrien  switch (which_alternative)
279218334Speter    {
279390286Sobrien    case 0:
279490286Sobrien      if (REG_P (operands[1])
279590286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2796132727Skan	{
2797132727Skan	  if (REGNO (operands[0]) == FIRST_STACK_REG
2798132727Skan	      && TARGET_USE_FFREEP)
2799132727Skan	    return "ffreep\t%y0";
2800132727Skan          return "fstp\t%y0";
280190286Sobrien	}
280290286Sobrien      else if (STACK_TOP_P (operands[0]))
280390286Sobrien        return "fld%z1\t%y1";
280490286Sobrien      else
280590286Sobrien        return "fst\t%y0";
280618334Speter
280790286Sobrien    case 1:
280890286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
280990286Sobrien	 we need one, follow the store with a load.  */
281090286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
281190286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
281290286Sobrien      else
281390286Sobrien        return "fstp%z0\t%y0";
281418334Speter
281590286Sobrien    case 2:
2816132727Skan      return standard_80387_constant_opcode (operands[1]);
281718334Speter
281890286Sobrien    case 3: case 4:
281990286Sobrien      return "#";
282090286Sobrien    }
282190286Sobrien  abort();
282290286Sobrien}
282390286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
282490286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
282518334Speter
282690286Sobrien(define_insn "*movxf_integer"
282790286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
282890286Sobrien	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2829132727Skan  "!optimize_size
283090286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
283190286Sobrien   && (reload_in_progress || reload_completed
283290286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
283390286Sobrien       || memory_operand (operands[0], XFmode))" 
283490286Sobrien{
283590286Sobrien  switch (which_alternative)
283618334Speter    {
283790286Sobrien    case 0:
283890286Sobrien      if (REG_P (operands[1])
283990286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2840132727Skan	{
2841132727Skan	  if (REGNO (operands[0]) == FIRST_STACK_REG
2842132727Skan	      && TARGET_USE_FFREEP)
2843132727Skan	    return "ffreep\t%y0";
2844132727Skan          return "fstp\t%y0";
284590286Sobrien	}
284690286Sobrien      else if (STACK_TOP_P (operands[0]))
284790286Sobrien        return "fld%z1\t%y1";
284890286Sobrien      else
284990286Sobrien        return "fst\t%y0";
285018334Speter
285190286Sobrien    case 1:
285290286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
285390286Sobrien	 we need one, follow the store with a load.  */
285490286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
285590286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
285690286Sobrien      else
285790286Sobrien        return "fstp%z0\t%y0";
285818334Speter
285990286Sobrien    case 2:
2860132727Skan      return standard_80387_constant_opcode (operands[1]);
286118334Speter
286290286Sobrien    case 3: case 4:
286390286Sobrien      return "#";
286490286Sobrien    }
286590286Sobrien  abort();
286690286Sobrien}
286790286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
286890286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
286918334Speter
287090286Sobrien(define_split
287190286Sobrien  [(set (match_operand 0 "nonimmediate_operand" "")
287290286Sobrien	(match_operand 1 "general_operand" ""))]
287390286Sobrien  "reload_completed
287490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2875132727Skan   && GET_MODE (operands[0]) == XFmode
287690286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
287790286Sobrien	 (GET_CODE (operands[0]) == SUBREG
287890286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
287990286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
288090286Sobrien	 (GET_CODE (operands[1]) == SUBREG
288190286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
288290286Sobrien  [(const_int 0)]
288390286Sobrien  "ix86_split_long_move (operands); DONE;")
288418334Speter
288590286Sobrien(define_split
288690286Sobrien  [(set (match_operand 0 "register_operand" "")
288790286Sobrien	(match_operand 1 "memory_operand" ""))]
288890286Sobrien  "reload_completed
288990286Sobrien   && GET_CODE (operands[1]) == MEM
2890132727Skan   && (GET_MODE (operands[0]) == XFmode
289190286Sobrien       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
289290286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2893132727Skan   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2894132727Skan  [(set (match_dup 0) (match_dup 1))]
2895132727Skan{
2896132727Skan  rtx c = get_pool_constant (XEXP (operands[1], 0));
2897132727Skan  rtx r = operands[0];
289890286Sobrien
2899132727Skan  if (GET_CODE (r) == SUBREG)
2900132727Skan    r = SUBREG_REG (r);
2901132727Skan
2902132727Skan  if (SSE_REG_P (r))
2903132727Skan    {
2904132727Skan      if (!standard_sse_constant_p (c))
2905132727Skan	FAIL;
2906132727Skan    }
2907132727Skan  else if (FP_REG_P (r))
2908132727Skan    {
2909132727Skan      if (!standard_80387_constant_p (c))
2910132727Skan	FAIL;
2911132727Skan    }
2912132727Skan  else if (MMX_REG_P (r))
2913132727Skan    FAIL;
2914132727Skan
2915132727Skan  operands[1] = c;
2916132727Skan})
2917132727Skan
291890286Sobrien(define_insn "swapxf"
291990286Sobrien  [(set (match_operand:XF 0 "register_operand" "+f")
292090286Sobrien	(match_operand:XF 1 "register_operand" "+f"))
292118334Speter   (set (match_dup 1)
292218334Speter	(match_dup 0))]
292318334Speter  ""
292418334Speter{
292518334Speter  if (STACK_TOP_P (operands[0]))
292690286Sobrien    return "fxch\t%1";
292718334Speter  else
292890286Sobrien    return "fxch\t%0";
292990286Sobrien}
293090286Sobrien  [(set_attr "type" "fxch")
293190286Sobrien   (set_attr "mode" "XF")])
293218334Speter
293390286Sobrien;; Zero extension instructions
293418334Speter
293552296Sobrien(define_expand "zero_extendhisi2"
293652296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
293790286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
293852296Sobrien  ""
293990286Sobrien{
294090286Sobrien  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
294118334Speter    {
294290286Sobrien      operands[1] = force_reg (HImode, operands[1]);
294390286Sobrien      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
294490286Sobrien      DONE;
294518334Speter    }
294690286Sobrien})
294718334Speter
294890286Sobrien(define_insn "zero_extendhisi2_and"
294990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
295090286Sobrien     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
295190286Sobrien   (clobber (reg:CC 17))]
295290286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
295390286Sobrien  "#"
295490286Sobrien  [(set_attr "type" "alu1")
295590286Sobrien   (set_attr "mode" "SI")])
295650650Sobrien
295750650Sobrien(define_split
295850650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
295990286Sobrien	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
296090286Sobrien   (clobber (reg:CC 17))]
296190286Sobrien  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
296290286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
296390286Sobrien	      (clobber (reg:CC 17))])]
296490286Sobrien  "")
296550650Sobrien
296690286Sobrien(define_insn "*zero_extendhisi2_movzwl"
296790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
296890286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
296990286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
297090286Sobrien  "movz{wl|x}\t{%1, %0|%0, %1}"
297190286Sobrien  [(set_attr "type" "imovx")
297290286Sobrien   (set_attr "mode" "SI")])
297350650Sobrien
297452296Sobrien(define_expand "zero_extendqihi2"
297590286Sobrien  [(parallel
297690286Sobrien    [(set (match_operand:HI 0 "register_operand" "")
297790286Sobrien       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
297890286Sobrien     (clobber (reg:CC 17))])]
297952296Sobrien  ""
298052296Sobrien  "")
298152296Sobrien
298290286Sobrien(define_insn "*zero_extendqihi2_and"
298390286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
298490286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
298590286Sobrien   (clobber (reg:CC 17))]
298690286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
298790286Sobrien  "#"
298890286Sobrien  [(set_attr "type" "alu1")
298990286Sobrien   (set_attr "mode" "HI")])
299052296Sobrien
299190286Sobrien(define_insn "*zero_extendqihi2_movzbw_and"
299290286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
299390286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
299490286Sobrien   (clobber (reg:CC 17))]
299590286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
299690286Sobrien  "#"
299790286Sobrien  [(set_attr "type" "imovx,alu1")
299890286Sobrien   (set_attr "mode" "HI")])
299952296Sobrien
300090286Sobrien(define_insn "*zero_extendqihi2_movzbw"
300190286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r")
300290286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
300390286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
300490286Sobrien  "movz{bw|x}\t{%1, %0|%0, %1}"
300590286Sobrien  [(set_attr "type" "imovx")
300690286Sobrien   (set_attr "mode" "HI")])
300750650Sobrien
300890286Sobrien;; For the movzbw case strip only the clobber
300950650Sobrien(define_split
301050650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
301190286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
301290286Sobrien   (clobber (reg:CC 17))]
301390286Sobrien  "reload_completed 
301490286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
301590286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
301690286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
301790286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
301850650Sobrien
301990286Sobrien;; When source and destination does not overlap, clear destination
302090286Sobrien;; first and then do the movb
302150650Sobrien(define_split
302250650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
302390286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
302490286Sobrien   (clobber (reg:CC 17))]
302590286Sobrien  "reload_completed
302690286Sobrien   && ANY_QI_REG_P (operands[0])
302790286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
302890286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
302990286Sobrien  [(set (match_dup 0) (const_int 0))
303090286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
303190286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
303250650Sobrien
303390286Sobrien;; Rest is handled by single and.
303450650Sobrien(define_split
303550650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
303690286Sobrien	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
303790286Sobrien   (clobber (reg:CC 17))]
303890286Sobrien  "reload_completed
303990286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
304090286Sobrien  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
304190286Sobrien	      (clobber (reg:CC 17))])]
304290286Sobrien  "")
304350650Sobrien
304452296Sobrien(define_expand "zero_extendqisi2"
304590286Sobrien  [(parallel
304690286Sobrien    [(set (match_operand:SI 0 "register_operand" "")
304790286Sobrien       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
304890286Sobrien     (clobber (reg:CC 17))])]
304952296Sobrien  ""
305052296Sobrien  "")
305152296Sobrien
305290286Sobrien(define_insn "*zero_extendqisi2_and"
305390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
305490286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
305590286Sobrien   (clobber (reg:CC 17))]
305690286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
305790286Sobrien  "#"
305890286Sobrien  [(set_attr "type" "alu1")
305990286Sobrien   (set_attr "mode" "SI")])
306052296Sobrien
306190286Sobrien(define_insn "*zero_extendqisi2_movzbw_and"
306290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
306390286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
306490286Sobrien   (clobber (reg:CC 17))]
306590286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
306690286Sobrien  "#"
306790286Sobrien  [(set_attr "type" "imovx,alu1")
306890286Sobrien   (set_attr "mode" "SI")])
306950650Sobrien
307090286Sobrien(define_insn "*zero_extendqisi2_movzbw"
307190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
307290286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
307390286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
307490286Sobrien  "movz{bl|x}\t{%1, %0|%0, %1}"
307590286Sobrien  [(set_attr "type" "imovx")
307690286Sobrien   (set_attr "mode" "SI")])
307718334Speter
307890286Sobrien;; For the movzbl case strip only the clobber
307950650Sobrien(define_split
308050650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
308190286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
308290286Sobrien   (clobber (reg:CC 17))]
308390286Sobrien  "reload_completed 
308490286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
308590286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
308690286Sobrien  [(set (match_dup 0)
308790286Sobrien	(zero_extend:SI (match_dup 1)))])
308850650Sobrien
308990286Sobrien;; When source and destination does not overlap, clear destination
309090286Sobrien;; first and then do the movb
309150650Sobrien(define_split
309250650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
309390286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
309490286Sobrien   (clobber (reg:CC 17))]
309590286Sobrien  "reload_completed
309690286Sobrien   && ANY_QI_REG_P (operands[0])
309790286Sobrien   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
309890286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
309990286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
310090286Sobrien  [(set (match_dup 0) (const_int 0))
310190286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
310290286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
310350650Sobrien
310490286Sobrien;; Rest is handled by single and.
310550650Sobrien(define_split
310650650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
310790286Sobrien	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
310890286Sobrien   (clobber (reg:CC 17))]
310990286Sobrien  "reload_completed
311090286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
311190286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
311290286Sobrien	      (clobber (reg:CC 17))])]
311390286Sobrien  "")
311450650Sobrien
311590286Sobrien;; %%% Kill me once multi-word ops are sane.
311690286Sobrien(define_expand "zero_extendsidi2"
311790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
311890286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
311918334Speter  ""
312090286Sobrien  "if (!TARGET_64BIT)
312190286Sobrien     {
312290286Sobrien       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
312390286Sobrien       DONE;
312490286Sobrien     }
312590286Sobrien  ")
312650650Sobrien
312790286Sobrien(define_insn "zero_extendsidi2_32"
3128132727Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3129132727Skan	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
313090286Sobrien   (clobber (reg:CC 17))]
3131132727Skan  "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3132132727Skan  "@
3133132727Skan   #
3134132727Skan   #
3135132727Skan   #
3136132727Skan   movd\t{%1, %0|%0, %1}
3137132727Skan   movd\t{%1, %0|%0, %1}"
3138132727Skan  [(set_attr "mode" "SI,SI,SI,DI,TI")
3139132727Skan   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
314090286Sobrien
3141132727Skan(define_insn "*zero_extendsidi2_32_1"
3142132727Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3143132727Skan	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3144132727Skan   (clobber (reg:CC 17))]
3145132727Skan  "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3146132727Skan  "@
3147132727Skan   #
3148132727Skan   #
3149132727Skan   #
3150132727Skan   movd\t{%1, %0|%0, %1}
3151132727Skan   movd\t{%1, %0|%0, %1}"
3152132727Skan  [(set_attr "mode" "SI,SI,SI,DI,TI")
3153132727Skan   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3154132727Skan
315590286Sobrien(define_insn "zero_extendsidi2_rex64"
3156132727Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3157132727Skan     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3158132727Skan  "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
315990286Sobrien  "@
316090286Sobrien   mov\t{%k1, %k0|%k0, %k1}
3161132727Skan   #
3162132727Skan   movd\t{%1, %0|%0, %1}
3163132727Skan   movd\t{%1, %0|%0, %1}"
3164132727Skan  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3165132727Skan   (set_attr "mode" "SI,DI,DI,TI")])
316690286Sobrien
3167132727Skan(define_insn "*zero_extendsidi2_rex64_1"
3168132727Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3169132727Skan     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3170132727Skan  "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3171132727Skan  "@
3172132727Skan   mov\t{%k1, %k0|%k0, %k1}
3173132727Skan   #
3174132727Skan   movd\t{%1, %0|%0, %1}
3175132727Skan   movd\t{%1, %0|%0, %1}"
3176132727Skan  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3177132727Skan   (set_attr "mode" "SI,DI,SI,SI")])
3178132727Skan
317990286Sobrien(define_split
318090286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
318190286Sobrien     (zero_extend:DI (match_dup 0)))]
318290286Sobrien  "TARGET_64BIT"
318390286Sobrien  [(set (match_dup 4) (const_int 0))]
318490286Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
318590286Sobrien
318652296Sobrien(define_split 
318752296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
318890286Sobrien	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
318990286Sobrien   (clobber (reg:CC 17))]
319090286Sobrien  "!TARGET_64BIT && reload_completed
319190286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
319252296Sobrien  [(set (match_dup 4) (const_int 0))]
319352296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
319450650Sobrien
319552296Sobrien(define_split 
319652296Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
319790286Sobrien	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
319890286Sobrien   (clobber (reg:CC 17))]
3199132727Skan  "!TARGET_64BIT && reload_completed
3200132727Skan   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
320152296Sobrien  [(set (match_dup 3) (match_dup 1))
320252296Sobrien   (set (match_dup 4) (const_int 0))]
320352296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
320490286Sobrien
320590286Sobrien(define_insn "zero_extendhidi2"
320690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
320790286Sobrien     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
320890286Sobrien  "TARGET_64BIT"
320990286Sobrien  "@
321090286Sobrien   movz{wl|x}\t{%1, %k0|%k0, %1} 
321190286Sobrien   movz{wq|x}\t{%1, %0|%0, %1}"
321290286Sobrien  [(set_attr "type" "imovx")
321390286Sobrien   (set_attr "mode" "SI,DI")])
321490286Sobrien
321590286Sobrien(define_insn "zero_extendqidi2"
321690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
321790286Sobrien     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
321890286Sobrien  "TARGET_64BIT"
321990286Sobrien  "@
322090286Sobrien   movz{bl|x}\t{%1, %k0|%k0, %1} 
322190286Sobrien   movz{bq|x}\t{%1, %0|%0, %1}"
322290286Sobrien  [(set_attr "type" "imovx")
322390286Sobrien   (set_attr "mode" "SI,DI")])
322418334Speter
322590286Sobrien;; Sign extension instructions
322618334Speter
322790286Sobrien(define_expand "extendsidi2"
322890286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
322990286Sobrien		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
323090286Sobrien	      (clobber (reg:CC 17))
323190286Sobrien	      (clobber (match_scratch:SI 2 ""))])]
323290286Sobrien  ""
323390286Sobrien{
323490286Sobrien  if (TARGET_64BIT)
323590286Sobrien    {
323690286Sobrien      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
323790286Sobrien      DONE;
323890286Sobrien    }
323990286Sobrien})
324090286Sobrien
324190286Sobrien(define_insn "*extendsidi2_1"
324290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
324390286Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
324490286Sobrien   (clobber (reg:CC 17))
324552296Sobrien   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
324690286Sobrien  "!TARGET_64BIT"
324752296Sobrien  "#")
324852296Sobrien
324990286Sobrien(define_insn "extendsidi2_rex64"
325090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
325190286Sobrien	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
325290286Sobrien  "TARGET_64BIT"
325390286Sobrien  "@
325490286Sobrien   {cltq|cdqe}
325590286Sobrien   movs{lq|x}\t{%1,%0|%0, %1}"
325690286Sobrien  [(set_attr "type" "imovx")
325790286Sobrien   (set_attr "mode" "DI")
325890286Sobrien   (set_attr "prefix_0f" "0")
325990286Sobrien   (set_attr "modrm" "0,1")])
326090286Sobrien
326190286Sobrien(define_insn "extendhidi2"
326290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
326390286Sobrien	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
326490286Sobrien  "TARGET_64BIT"
326590286Sobrien  "movs{wq|x}\t{%1,%0|%0, %1}"
326690286Sobrien  [(set_attr "type" "imovx")
326790286Sobrien   (set_attr "mode" "DI")])
326890286Sobrien
326990286Sobrien(define_insn "extendqidi2"
327090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
327190286Sobrien	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
327290286Sobrien  "TARGET_64BIT"
327390286Sobrien  "movs{bq|x}\t{%1,%0|%0, %1}"
327490286Sobrien   [(set_attr "type" "imovx")
327590286Sobrien    (set_attr "mode" "DI")])
327690286Sobrien
327752296Sobrien;; Extend to memory case when source register does die.
327852296Sobrien(define_split 
327952296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
328052296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
328190286Sobrien   (clobber (reg:CC 17))
328252296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
328390286Sobrien  "(reload_completed
328452296Sobrien    && dead_or_set_p (insn, operands[1])
328552296Sobrien    && !reg_mentioned_p (operands[1], operands[0]))"
328652296Sobrien  [(set (match_dup 3) (match_dup 1))
328790286Sobrien   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
328890286Sobrien	      (clobber (reg:CC 17))])
328952296Sobrien   (set (match_dup 4) (match_dup 1))]
329052296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
329152296Sobrien
329252296Sobrien;; Extend to memory case when source register does not die.
329352296Sobrien(define_split 
329452296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
329552296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
329690286Sobrien   (clobber (reg:CC 17))
329752296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
329890286Sobrien  "reload_completed"
329952296Sobrien  [(const_int 0)]
330018334Speter{
330152296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
330252296Sobrien
330352296Sobrien  emit_move_insn (operands[3], operands[1]);
330452296Sobrien
330552296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
330652296Sobrien  if (true_regnum (operands[1]) == 0
330752296Sobrien      && true_regnum (operands[2]) == 1
330890286Sobrien      && (optimize_size || TARGET_USE_CLTD))
330918334Speter    {
331090286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
331118334Speter    }
331252296Sobrien  else
331352296Sobrien    {
331452296Sobrien      emit_move_insn (operands[2], operands[1]);
331590286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
331652296Sobrien    }
331752296Sobrien  emit_move_insn (operands[4], operands[2]);
331852296Sobrien  DONE;
331990286Sobrien})
332018334Speter
332152296Sobrien;; Extend to register case.  Optimize case where source and destination
332252296Sobrien;; registers match and cases where we can use cltd.
332352296Sobrien(define_split 
332452296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
332552296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
332690286Sobrien   (clobber (reg:CC 17))
332752296Sobrien   (clobber (match_scratch:SI 2 ""))]
332852296Sobrien  "reload_completed"
332952296Sobrien  [(const_int 0)]
333052296Sobrien{
333152296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
333218334Speter
333352296Sobrien  if (true_regnum (operands[3]) != true_regnum (operands[1]))
333452296Sobrien    emit_move_insn (operands[3], operands[1]);
333552296Sobrien
333652296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
333752296Sobrien  if (true_regnum (operands[3]) == 0
333890286Sobrien      && (optimize_size || TARGET_USE_CLTD))
333952296Sobrien    {
334090286Sobrien      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
334152296Sobrien      DONE;
334252296Sobrien    }
334352296Sobrien
334452296Sobrien  if (true_regnum (operands[4]) != true_regnum (operands[1]))
334552296Sobrien    emit_move_insn (operands[4], operands[1]);
334652296Sobrien
334790286Sobrien  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
334852296Sobrien  DONE;
334990286Sobrien})
335018334Speter
335118334Speter(define_insn "extendhisi2"
335290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=*a,r")
335390286Sobrien	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
335418334Speter  ""
335518334Speter{
335690286Sobrien  switch (get_attr_prefix_0f (insn))
335790286Sobrien    {
335890286Sobrien    case 0:
335990286Sobrien      return "{cwtl|cwde}";
336090286Sobrien    default:
336190286Sobrien      return "movs{wl|x}\t{%1,%0|%0, %1}";
336290286Sobrien    }
336390286Sobrien}
336490286Sobrien  [(set_attr "type" "imovx")
336590286Sobrien   (set_attr "mode" "SI")
336690286Sobrien   (set (attr "prefix_0f")
336790286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
336890286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
336990286Sobrien			(eq_attr "alternative" "0"))
337090286Sobrien	(const_string "0")
337190286Sobrien	(const_string "1")))
337290286Sobrien   (set (attr "modrm")
337390286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
337490286Sobrien	(const_string "0")
337590286Sobrien	(const_string "1")))])
337618334Speter
337790286Sobrien(define_insn "*extendhisi2_zext"
337890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
337990286Sobrien	(zero_extend:DI
338090286Sobrien	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
338190286Sobrien  "TARGET_64BIT"
338290286Sobrien{
338390286Sobrien  switch (get_attr_prefix_0f (insn))
338490286Sobrien    {
338590286Sobrien    case 0:
338690286Sobrien      return "{cwtl|cwde}";
338790286Sobrien    default:
338890286Sobrien      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
338990286Sobrien    }
339090286Sobrien}
339190286Sobrien  [(set_attr "type" "imovx")
339290286Sobrien   (set_attr "mode" "SI")
339390286Sobrien   (set (attr "prefix_0f")
339490286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
339590286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
339690286Sobrien			(eq_attr "alternative" "0"))
339790286Sobrien	(const_string "0")
339890286Sobrien	(const_string "1")))
339990286Sobrien   (set (attr "modrm")
340090286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
340190286Sobrien	(const_string "0")
340290286Sobrien	(const_string "1")))])
340318334Speter
340418334Speter(define_insn "extendqihi2"
340590286Sobrien  [(set (match_operand:HI 0 "register_operand" "=*a,r")
340690286Sobrien	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
340718334Speter  ""
340818334Speter{
340990286Sobrien  switch (get_attr_prefix_0f (insn))
341090286Sobrien    {
341190286Sobrien    case 0:
341290286Sobrien      return "{cbtw|cbw}";
341390286Sobrien    default:
341490286Sobrien      return "movs{bw|x}\t{%1,%0|%0, %1}";
341590286Sobrien    }
341690286Sobrien}
341790286Sobrien  [(set_attr "type" "imovx")
341890286Sobrien   (set_attr "mode" "HI")
341990286Sobrien   (set (attr "prefix_0f")
342090286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
342190286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
342290286Sobrien			(eq_attr "alternative" "0"))
342390286Sobrien	(const_string "0")
342490286Sobrien	(const_string "1")))
342590286Sobrien   (set (attr "modrm")
342690286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
342790286Sobrien	(const_string "0")
342890286Sobrien	(const_string "1")))])
342918334Speter
343018334Speter(define_insn "extendqisi2"
343150650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
343250650Sobrien	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
343318334Speter  ""
343490286Sobrien  "movs{bl|x}\t{%1,%0|%0, %1}"
343590286Sobrien   [(set_attr "type" "imovx")
343690286Sobrien    (set_attr "mode" "SI")])
343750650Sobrien
343890286Sobrien(define_insn "*extendqisi2_zext"
343990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
344090286Sobrien	(zero_extend:DI
344190286Sobrien	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
344290286Sobrien  "TARGET_64BIT"
344390286Sobrien  "movs{bl|x}\t{%1,%k0|%k0, %1}"
344490286Sobrien   [(set_attr "type" "imovx")
344590286Sobrien    (set_attr "mode" "SI")])
344618334Speter
344790286Sobrien;; Conversions between float and double.
344850650Sobrien
344990286Sobrien;; These are all no-ops in the model used for the 80387.  So just
345090286Sobrien;; emit moves.
345150650Sobrien
345290286Sobrien;; %%% Kill these when call knows how to work out a DFmode push earlier. 
345390286Sobrien(define_insn "*dummy_extendsfdf2"
345490286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<")
345590286Sobrien	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
345690286Sobrien  "0"
345790286Sobrien  "#")
345850650Sobrien
345990286Sobrien(define_split
346090286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
3461117404Skan	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3462117404Skan  "!TARGET_64BIT"
346390286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
346490286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
346550650Sobrien
346690286Sobrien(define_split
346790286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
3468117404Skan	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469117404Skan  "TARGET_64BIT"
347090286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
347190286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
347250650Sobrien
347390286Sobrien(define_insn "*dummy_extendsfxf2"
347490286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
347590286Sobrien	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
347690286Sobrien  "0"
347790286Sobrien  "#")
347850650Sobrien
347990286Sobrien(define_split
348090286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
3481117404Skan	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482132727Skan  ""
3483132727Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3484132727Skan   (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3485132727Skan  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
348650650Sobrien
348790286Sobrien(define_split
3488132727Skan  [(set (match_operand:XF 0 "push_operand" "")
3489132727Skan	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3490117404Skan  "TARGET_64BIT"
3491132727Skan  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3492132727Skan   (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3493132727Skan  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
349418334Speter
349590286Sobrien(define_split
349690286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
3497117404Skan	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498132727Skan  ""
3499132727Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3500132727Skan   (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3501132727Skan  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
350252296Sobrien
350352296Sobrien(define_split
3504132727Skan  [(set (match_operand:XF 0 "push_operand" "")
3505132727Skan	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3506117404Skan  "TARGET_64BIT"
3507132727Skan  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3508132727Skan   (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3509132727Skan  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
351018334Speter
351190286Sobrien(define_expand "extendsfdf2"
351252296Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3513117404Skan        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
351490286Sobrien  "TARGET_80387 || TARGET_SSE2"
351552296Sobrien{
3516117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3517117404Skan     are LEGITIMATE_CONSTANT_P.  */
3518117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3519117404Skan    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
352090286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
352190286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
352290286Sobrien})
352318334Speter
352490286Sobrien(define_insn "*extendsfdf2_1"
352590286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
352690286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
352790286Sobrien  "(TARGET_80387 || TARGET_SSE2)
352890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
352952296Sobrien{
353090286Sobrien  switch (which_alternative)
353190286Sobrien    {
353290286Sobrien    case 0:
353390286Sobrien      if (REG_P (operands[1])
353490286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
353590286Sobrien        return "fstp\t%y0";
353690286Sobrien      else if (STACK_TOP_P (operands[0]))
353790286Sobrien        return "fld%z1\t%y1";
353890286Sobrien      else
353990286Sobrien        return "fst\t%y0";
354052296Sobrien
354190286Sobrien    case 1:
354290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
354390286Sobrien        return "fstp%z0\t%y0";
354418334Speter
354590286Sobrien      else
354690286Sobrien        return "fst%z0\t%y0";
354790286Sobrien    case 2:
354890286Sobrien      return "cvtss2sd\t{%1, %0|%0, %1}";
354918334Speter
355090286Sobrien    default:
355190286Sobrien      abort ();
355290286Sobrien    }
355390286Sobrien}
3554117404Skan  [(set_attr "type" "fmov,fmov,ssecvt")
355590286Sobrien   (set_attr "mode" "SF,XF,DF")])
355618334Speter
355790286Sobrien(define_insn "*extendsfdf2_1_sse_only"
355890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
355990286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
356090286Sobrien  "!TARGET_80387 && TARGET_SSE2
356190286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
356290286Sobrien  "cvtss2sd\t{%1, %0|%0, %1}"
3563117404Skan  [(set_attr "type" "ssecvt")
356490286Sobrien   (set_attr "mode" "DF")])
356518334Speter
356690286Sobrien(define_expand "extendsfxf2"
356752296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3568117404Skan        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3569132727Skan  "TARGET_80387"
357090286Sobrien{
3571117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3572117404Skan     are LEGITIMATE_CONSTANT_P.  */
3573117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3574117404Skan    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
357590286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
357690286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
357790286Sobrien})
357818334Speter
357990286Sobrien(define_insn "*extendsfxf2_1"
358052296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
358190286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
358290286Sobrien  "TARGET_80387
358390286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
358418334Speter{
358590286Sobrien  switch (which_alternative)
358690286Sobrien    {
358790286Sobrien    case 0:
358890286Sobrien      if (REG_P (operands[1])
358990286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
359090286Sobrien        return "fstp\t%y0";
359190286Sobrien      else if (STACK_TOP_P (operands[0]))
359290286Sobrien        return "fld%z1\t%y1";
359390286Sobrien      else
359490286Sobrien        return "fst\t%y0";
359518334Speter
359690286Sobrien    case 1:
359790286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
359890286Sobrien	 we need one, follow the store with a load.  */
359990286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
360090286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
360190286Sobrien      else
360290286Sobrien        return "fstp%z0\t%y0";
360318334Speter
360490286Sobrien    default:
360590286Sobrien      abort ();
360690286Sobrien    }
360790286Sobrien}
360890286Sobrien  [(set_attr "type" "fmov")
360990286Sobrien   (set_attr "mode" "SF,XF")])
361018334Speter
361190286Sobrien(define_expand "extenddfxf2"
361252296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3613117404Skan        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3614132727Skan  "TARGET_80387"
361590286Sobrien{
3616117404Skan  /* ??? Needed for compress_float_constant since all fp constants
3617117404Skan     are LEGITIMATE_CONSTANT_P.  */
3618117404Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3619117404Skan    operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
362090286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
362190286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
362290286Sobrien})
362318334Speter
362490286Sobrien(define_insn "*extenddfxf2_1"
362552296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
362690286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
362790286Sobrien  "TARGET_80387
362890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
362990286Sobrien{
363090286Sobrien  switch (which_alternative)
363190286Sobrien    {
363290286Sobrien    case 0:
363390286Sobrien      if (REG_P (operands[1])
363490286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
363590286Sobrien        return "fstp\t%y0";
363690286Sobrien      else if (STACK_TOP_P (operands[0]))
363790286Sobrien        return "fld%z1\t%y1";
363890286Sobrien      else
363990286Sobrien        return "fst\t%y0";
364090286Sobrien
364190286Sobrien    case 1:
364290286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
364390286Sobrien	 we need one, follow the store with a load.  */
364490286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
364590286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
364690286Sobrien      else
364790286Sobrien        return "fstp%z0\t%y0";
364890286Sobrien
364990286Sobrien    default:
365090286Sobrien      abort ();
365190286Sobrien    }
365290286Sobrien}
365390286Sobrien  [(set_attr "type" "fmov")
365490286Sobrien   (set_attr "mode" "DF,XF")])
365590286Sobrien
365690286Sobrien;; %%% This seems bad bad news.
365790286Sobrien;; This cannot output into an f-reg because there is no way to be sure
365890286Sobrien;; of truncating in that case.  Otherwise this is just like a simple move
365990286Sobrien;; insn.  So we pretend we can output to a reg in order to get better
366090286Sobrien;; register preferencing, but we really use a stack slot.
366190286Sobrien
366218334Speter(define_expand "truncdfsf2"
366318334Speter  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
366418334Speter		   (float_truncate:SF
366518334Speter		    (match_operand:DF 1 "register_operand" "")))
366618334Speter	      (clobber (match_dup 2))])]
366790286Sobrien  "TARGET_80387 || TARGET_SSE2"
366818334Speter  "
366990286Sobrien   if (TARGET_80387)
367090286Sobrien     operands[2] = assign_386_stack_local (SFmode, 0);
367190286Sobrien   else
367290286Sobrien     {
367390286Sobrien	emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
367490286Sobrien	DONE;
367590286Sobrien     }
367690286Sobrien")
367790286Sobrien
367890286Sobrien(define_insn "*truncdfsf2_1"
367990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
368090286Sobrien	(float_truncate:SF
368190286Sobrien	 (match_operand:DF 1 "register_operand" "f,f,f,f")))
368290286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
368390286Sobrien  "TARGET_80387 && !TARGET_SSE2"
368418334Speter{
368590286Sobrien  switch (which_alternative)
368690286Sobrien    {
368790286Sobrien    case 0:
368890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
368990286Sobrien	return "fstp%z0\t%y0";
369090286Sobrien      else
369190286Sobrien	return "fst%z0\t%y0";
369290286Sobrien    default:
369390286Sobrien      abort ();
369490286Sobrien    }
369590286Sobrien}
369690286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
369790286Sobrien   (set_attr "mode" "SF,SF,SF,SF")])
369818334Speter
369990286Sobrien(define_insn "*truncdfsf2_1_sse"
3700132727Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
370118334Speter	(float_truncate:SF
3702132727Skan	 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
370390286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3704132727Skan  "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
370518334Speter{
370690286Sobrien  switch (which_alternative)
370790286Sobrien    {
370890286Sobrien    case 0:
370990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
371090286Sobrien	return "fstp%z0\t%y0";
371190286Sobrien      else
371290286Sobrien	return "fst%z0\t%y0";
371390286Sobrien    case 4:
3714132727Skan      return "#";
371590286Sobrien    default:
371690286Sobrien      abort ();
371790286Sobrien    }
371890286Sobrien}
3719117404Skan  [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
372090286Sobrien   (set_attr "mode" "SF,SF,SF,SF,DF")])
372118334Speter
3722132727Skan(define_insn "*truncdfsf2_1_sse_nooverlap"
3723132727Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3724132727Skan	(float_truncate:SF
3725132727Skan	 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3726132727Skan   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3727132727Skan  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3728132727Skan{
3729132727Skan  switch (which_alternative)
3730132727Skan    {
3731132727Skan    case 0:
3732132727Skan      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3733132727Skan	return "fstp%z0\t%y0";
3734132727Skan      else
3735132727Skan	return "fst%z0\t%y0";
3736132727Skan    case 4:
3737132727Skan      return "#";
3738132727Skan    default:
3739132727Skan      abort ();
3740132727Skan    }
3741132727Skan}
3742132727Skan  [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3743132727Skan   (set_attr "mode" "SF,SF,SF,SF,DF")])
3744132727Skan
374590286Sobrien(define_insn "*truncdfsf2_2"
3746132727Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
374790286Sobrien	(float_truncate:SF
3748132727Skan	 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3749132727Skan  "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3750132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3751132727Skan{
3752132727Skan  switch (which_alternative)
3753132727Skan    {
3754132727Skan    case 0:
3755132727Skan    case 1:
3756132727Skan      return "cvtsd2ss\t{%1, %0|%0, %1}";
3757132727Skan    case 2:
3758132727Skan      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759132727Skan	return "fstp%z0\t%y0";
3760132727Skan      else
3761132727Skan	return "fst%z0\t%y0";
3762132727Skan    default:
3763132727Skan      abort ();
3764132727Skan    }
3765132727Skan}
3766132727Skan  [(set_attr "type" "ssecvt,ssecvt,fmov")
3767132727Skan   (set_attr "athlon_decode" "vector,double,*")
3768132727Skan   (set_attr "mode" "SF,SF,SF")])
3769132727Skan
3770132727Skan(define_insn "*truncdfsf2_2_nooverlap"
3771132727Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3772132727Skan	(float_truncate:SF
377390286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3774132727Skan  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
377590286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
377690286Sobrien{
377790286Sobrien  switch (which_alternative)
377890286Sobrien    {
377990286Sobrien    case 0:
3780132727Skan      return "#";
378190286Sobrien    case 1:
378290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
378390286Sobrien	return "fstp%z0\t%y0";
378490286Sobrien      else
378590286Sobrien	return "fst%z0\t%y0";
378690286Sobrien    default:
378790286Sobrien      abort ();
378890286Sobrien    }
378990286Sobrien}
3790117404Skan  [(set_attr "type" "ssecvt,fmov")
379190286Sobrien   (set_attr "mode" "DF,SF")])
379252296Sobrien
3793132727Skan(define_insn "*truncdfsf2_3"
379490286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
379590286Sobrien	(float_truncate:SF
379690286Sobrien	 (match_operand:DF 1 "register_operand" "f")))]
379790286Sobrien  "TARGET_80387"
379890286Sobrien{
379990286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
380090286Sobrien    return "fstp%z0\t%y0";
380118334Speter  else
380290286Sobrien    return "fst%z0\t%y0";
380390286Sobrien}
380490286Sobrien  [(set_attr "type" "fmov")
380590286Sobrien   (set_attr "mode" "SF")])
380618334Speter
380790286Sobrien(define_insn "truncdfsf2_sse_only"
3808132727Skan  [(set (match_operand:SF 0 "register_operand" "=Y,Y")
380990286Sobrien	(float_truncate:SF
3810132727Skan	 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3811132727Skan  "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
381290286Sobrien  "cvtsd2ss\t{%1, %0|%0, %1}"
3813117404Skan  [(set_attr "type" "ssecvt")
3814132727Skan   (set_attr "athlon_decode" "vector,double")
3815132727Skan   (set_attr "mode" "SF")])
3816132727Skan
3817132727Skan(define_insn "*truncdfsf2_sse_only_nooverlap"
3818132727Skan  [(set (match_operand:SF 0 "register_operand" "=&Y")
3819132727Skan	(float_truncate:SF
3820132727Skan	 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3821132727Skan  "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3822132727Skan  "#"
3823132727Skan  [(set_attr "type" "ssecvt")
382490286Sobrien   (set_attr "mode" "DF")])
382552296Sobrien
382652296Sobrien(define_split
382790286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
382890286Sobrien	(float_truncate:SF
382990286Sobrien	 (match_operand:DF 1 "register_operand" "")))
383052296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
383190286Sobrien  "TARGET_80387"
383290286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
383352296Sobrien  "")
383452296Sobrien
3835132727Skan; Avoid possible reformatting penalty on the destination by first
3836132727Skan; zeroing it out
383752296Sobrien(define_split
3838132727Skan  [(set (match_operand:SF 0 "register_operand" "")
383990286Sobrien	(float_truncate:SF
384090286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "")))
384190286Sobrien   (clobber (match_operand 2 "" ""))]
384290286Sobrien  "TARGET_80387 && reload_completed
3843132727Skan   && SSE_REG_P (operands[0])
3844132727Skan   && !STACK_REG_P (operands[1])"
3845132727Skan  [(const_int 0)]
3846132727Skan{
3847132727Skan  rtx src, dest;
3848132727Skan  if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3849132727Skan    emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3850132727Skan  else
3851132727Skan    {
3852132727Skan      dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3853132727Skan      src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3854132727Skan      /* simplify_gen_subreg refuses to widen memory references.  */
3855132727Skan      if (GET_CODE (src) == SUBREG)
3856132727Skan	alter_subreg (&src);
3857132727Skan      if (reg_overlap_mentioned_p (operands[0], operands[1]))
3858132727Skan	abort ();
3859132727Skan      emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3860132727Skan      emit_insn (gen_cvtsd2ss (dest, dest, src));
3861132727Skan    }
3862132727Skan  DONE;
3863132727Skan})
386490286Sobrien
386590286Sobrien(define_split
386690286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
386790286Sobrien	(float_truncate:SF
3868132727Skan	 (match_operand:DF 1 "nonimmediate_operand" "")))]
3869132727Skan  "TARGET_80387 && reload_completed
3870132727Skan   && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3871132727Skan  [(const_int 0)]
3872132727Skan{
3873132727Skan  rtx src, dest;
3874132727Skan  dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3875132727Skan  src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3876132727Skan  /* simplify_gen_subreg refuses to widen memory references.  */
3877132727Skan  if (GET_CODE (src) == SUBREG)
3878132727Skan    alter_subreg (&src);
3879132727Skan  if (reg_overlap_mentioned_p (operands[0], operands[1]))
3880132727Skan    abort ();
3881132727Skan  emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3882132727Skan  emit_insn (gen_cvtsd2ss (dest, dest, src));
3883132727Skan  DONE;
3884132727Skan})
3885132727Skan
3886132727Skan(define_split
3887132727Skan  [(set (match_operand:SF 0 "register_operand" "")
3888132727Skan	(float_truncate:SF
3889117404Skan	 (match_operand:DF 1 "fp_register_operand" "")))
389052296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
3891117404Skan  "TARGET_80387 && reload_completed"
389290286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
389390286Sobrien   (set (match_dup 0) (match_dup 2))]
389452296Sobrien  "")
389552296Sobrien
389690286Sobrien(define_expand "truncxfsf2"
389790286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
389890286Sobrien		   (float_truncate:SF
389990286Sobrien		    (match_operand:XF 1 "register_operand" "")))
390090286Sobrien	      (clobber (match_dup 2))])]
3901132727Skan  "TARGET_80387"
390290286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
390352296Sobrien
390490286Sobrien(define_insn "*truncxfsf2_1"
390590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
390690286Sobrien	(float_truncate:SF
390790286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
390890286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3909132727Skan  "TARGET_80387"
391090286Sobrien{
391190286Sobrien  switch (which_alternative)
391290286Sobrien    {
391390286Sobrien    case 0:
391490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
391590286Sobrien	return "fstp%z0\t%y0";
391690286Sobrien      else
391790286Sobrien	return "fst%z0\t%y0";
391890286Sobrien    default:
391990286Sobrien      abort();
392090286Sobrien    }
392190286Sobrien}
392290286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
392390286Sobrien   (set_attr "mode" "SF")])
392490286Sobrien
392590286Sobrien(define_insn "*truncxfsf2_2"
392652296Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
392790286Sobrien	(float_truncate:SF
392890286Sobrien	 (match_operand:XF 1 "register_operand" "f")))]
3929132727Skan  "TARGET_80387"
393018334Speter{
393190286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
393290286Sobrien    return "fstp%z0\t%y0";
393318334Speter  else
393490286Sobrien    return "fst%z0\t%y0";
393590286Sobrien}
393690286Sobrien  [(set_attr "type" "fmov")
393790286Sobrien   (set_attr "mode" "SF")])
393852296Sobrien
393990286Sobrien(define_split
394090286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
394190286Sobrien	(float_truncate:SF
394290286Sobrien	 (match_operand:XF 1 "register_operand" "")))
394390286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
394490286Sobrien  "TARGET_80387"
394590286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
394690286Sobrien  "")
394790286Sobrien
394890286Sobrien(define_split
394990286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
395090286Sobrien	(float_truncate:SF
395190286Sobrien	 (match_operand:XF 1 "register_operand" "")))
395290286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
395390286Sobrien  "TARGET_80387 && reload_completed"
395490286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
395590286Sobrien   (set (match_dup 0) (match_dup 2))]
395690286Sobrien  "")
395790286Sobrien
395852296Sobrien(define_expand "truncxfdf2"
395952296Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
396052296Sobrien		   (float_truncate:DF
396152296Sobrien		    (match_operand:XF 1 "register_operand" "")))
396252296Sobrien	      (clobber (match_dup 2))])]
3963132727Skan  "TARGET_80387"
396490286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
396518334Speter
396690286Sobrien(define_insn "*truncxfdf2_1"
396790286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
396852296Sobrien	(float_truncate:DF
396990286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
397090286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971132727Skan  "TARGET_80387"
397218334Speter{
397390286Sobrien  switch (which_alternative)
397452296Sobrien    {
397590286Sobrien    case 0:
397690286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
397790286Sobrien	return "fstp%z0\t%y0";
397890286Sobrien      else
397990286Sobrien	return "fst%z0\t%y0";
398090286Sobrien    default:
398190286Sobrien      abort();
398252296Sobrien    }
398390286Sobrien  abort ();
398490286Sobrien}
398590286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
398690286Sobrien   (set_attr "mode" "DF")])
398752296Sobrien
398890286Sobrien(define_insn "*truncxfdf2_2"
398990286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
399090286Sobrien	(float_truncate:DF
399190286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
3992132727Skan  "TARGET_80387"
399390286Sobrien{
399490286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
399590286Sobrien    return "fstp%z0\t%y0";
399690286Sobrien  else
399790286Sobrien    return "fst%z0\t%y0";
399890286Sobrien}
399990286Sobrien  [(set_attr "type" "fmov")
400090286Sobrien   (set_attr "mode" "DF")])
400152296Sobrien
400252296Sobrien(define_split
400390286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
400490286Sobrien	(float_truncate:DF
400590286Sobrien	 (match_operand:XF 1 "register_operand" "")))
400652296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
400790286Sobrien  "TARGET_80387"
400890286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
400952296Sobrien  "")
401052296Sobrien
401152296Sobrien(define_split
401290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
401390286Sobrien	(float_truncate:DF
401490286Sobrien	 (match_operand:XF 1 "register_operand" "")))
401552296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
401652296Sobrien  "TARGET_80387 && reload_completed"
401790286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
401890286Sobrien   (set (match_dup 0) (match_dup 2))]
401952296Sobrien  "")
402052296Sobrien
402190286Sobrien
402290286Sobrien;; %%% Break up all these bad boys.
402390286Sobrien
402490286Sobrien;; Signed conversion to DImode.
402590286Sobrien
402690286Sobrien(define_expand "fix_truncxfdi2"
402790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
402890286Sobrien        (fix:DI (match_operand:XF 1 "register_operand" "")))]
402918334Speter  "TARGET_80387"
403090286Sobrien  "")
403118334Speter
403252296Sobrien(define_expand "fix_truncdfdi2"
403390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
403490286Sobrien        (fix:DI (match_operand:DF 1 "register_operand" "")))]
403590286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
403618334Speter{
403790286Sobrien  if (TARGET_64BIT && TARGET_SSE2)
403890286Sobrien   {
403990286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
404090286Sobrien     emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
404190286Sobrien     if (out != operands[0])
404290286Sobrien	emit_move_insn (operands[0], out);
404390286Sobrien     DONE;
404490286Sobrien   }
404590286Sobrien})
404618334Speter
404790286Sobrien(define_expand "fix_truncsfdi2"
404890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
404990286Sobrien	(fix:DI (match_operand:SF 1 "register_operand" "")))]
405090286Sobrien  "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
405190286Sobrien{
405290286Sobrien  if (TARGET_SSE && TARGET_64BIT)
405390286Sobrien   {
405490286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
405590286Sobrien     emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
405690286Sobrien     if (out != operands[0])
405790286Sobrien	emit_move_insn (operands[0], out);
405890286Sobrien     DONE;
405990286Sobrien   }
406090286Sobrien})
406152296Sobrien
406290286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
406390286Sobrien;; of the machinery.
406490286Sobrien(define_insn_and_split "*fix_truncdi_1"
406590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
406690286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))]
406790286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
406890286Sobrien   && !reload_completed && !reload_in_progress
406990286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
407090286Sobrien  "#"
407190286Sobrien  "&& 1"
407290286Sobrien  [(const_int 0)]
407390286Sobrien{
4074132727Skan  ix86_optimize_mode_switching = 1;
407590286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
407690286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
407790286Sobrien  if (memory_operand (operands[0], VOIDmode))
407890286Sobrien    emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
407990286Sobrien				       operands[2], operands[3]));
408090286Sobrien  else
408190286Sobrien    {
408290286Sobrien      operands[4] = assign_386_stack_local (DImode, 0);
408390286Sobrien      emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
408490286Sobrien					   operands[2], operands[3],
408590286Sobrien					   operands[4]));
408690286Sobrien    }
408790286Sobrien  DONE;
408890286Sobrien}
4089132727Skan  [(set_attr "type" "fistp")
4090132727Skan   (set_attr "mode" "DI")])
409190286Sobrien
409290286Sobrien(define_insn "fix_truncdi_nomemory"
409390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
409490286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))
409590286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
409690286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
409790286Sobrien   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
409890286Sobrien   (clobber (match_scratch:DF 5 "=&1f,&1f"))]
409990286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
410090286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
410190286Sobrien  "#"
4102132727Skan  [(set_attr "type" "fistp")
4103132727Skan   (set_attr "mode" "DI")])
410490286Sobrien
410590286Sobrien(define_insn "fix_truncdi_memory"
410690286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
410790286Sobrien	(fix:DI (match_operand 1 "register_operand" "f")))
410890286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
410990286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))
411090286Sobrien   (clobber (match_scratch:DF 4 "=&1f"))]
411190286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
411290286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
411390286Sobrien  "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4114132727Skan  [(set_attr "type" "fistp")
4115132727Skan   (set_attr "mode" "DI")])
411690286Sobrien
411790286Sobrien(define_split 
411890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
411990286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
412090286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
412190286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
412290286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
412390286Sobrien   (clobber (match_scratch 5 ""))]
412490286Sobrien  "reload_completed"
412590286Sobrien  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
412690286Sobrien	      (use (match_dup 2))
412790286Sobrien	      (use (match_dup 3))
412890286Sobrien	      (clobber (match_dup 5))])
412990286Sobrien   (set (match_dup 0) (match_dup 4))]
413090286Sobrien  "")
413190286Sobrien
413290286Sobrien(define_split 
413390286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
413490286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
413590286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
413690286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
413790286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
413890286Sobrien   (clobber (match_scratch 5 ""))]
413990286Sobrien  "reload_completed"
414090286Sobrien  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
414190286Sobrien	      (use (match_dup 2))
414290286Sobrien	      (use (match_dup 3))
414390286Sobrien	      (clobber (match_dup 5))])]
414490286Sobrien  "")
414590286Sobrien
414690286Sobrien;; When SSE available, it is always faster to use it!
414790286Sobrien(define_insn "fix_truncsfdi_sse"
4148132727Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
4149132727Skan	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
415090286Sobrien  "TARGET_64BIT && TARGET_SSE"
415190286Sobrien  "cvttss2si{q}\t{%1, %0|%0, %1}"
4152132727Skan  [(set_attr "type" "sseicvt")
4153132727Skan   (set_attr "mode" "SF")
4154132727Skan   (set_attr "athlon_decode" "double,vector")])
415590286Sobrien
4156132727Skan;; Avoid vector decoded form of the instruction.
4157132727Skan(define_peephole2
4158132727Skan  [(match_scratch:SF 2 "x")
4159132727Skan   (set (match_operand:DI 0 "register_operand" "")
4160132727Skan	(fix:DI (match_operand:SF 1 "memory_operand" "")))]
4161132727Skan  "TARGET_K8 && !optimize_size"
4162132727Skan  [(set (match_dup 2) (match_dup 1))
4163132727Skan   (set (match_dup 0) (fix:DI (match_dup 2)))]
4164132727Skan  "")
4165132727Skan
416690286Sobrien(define_insn "fix_truncdfdi_sse"
4167132727Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
4168132727Skan	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
416990286Sobrien  "TARGET_64BIT && TARGET_SSE2"
417090286Sobrien  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4171132727Skan  [(set_attr "type" "sseicvt,sseicvt")
4172132727Skan   (set_attr "mode" "DF")
4173132727Skan   (set_attr "athlon_decode" "double,vector")])
417490286Sobrien
4175132727Skan;; Avoid vector decoded form of the instruction.
4176132727Skan(define_peephole2
4177132727Skan  [(match_scratch:DF 2 "Y")
4178132727Skan   (set (match_operand:DI 0 "register_operand" "")
4179132727Skan	(fix:DI (match_operand:DF 1 "memory_operand" "")))]
4180132727Skan  "TARGET_K8 && !optimize_size"
4181132727Skan  [(set (match_dup 2) (match_dup 1))
4182132727Skan   (set (match_dup 0) (fix:DI (match_dup 2)))]
4183132727Skan  "")
4184132727Skan
418590286Sobrien;; Signed conversion to SImode.
418690286Sobrien
418752296Sobrien(define_expand "fix_truncxfsi2"
418890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
418990286Sobrien	(fix:SI (match_operand:XF 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{
4235132727Skan  ix86_optimize_mode_switching = 1;
423690286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
423790286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
423890286Sobrien  if (memory_operand (operands[0], VOIDmode))
423990286Sobrien    emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
424090286Sobrien				       operands[2], operands[3]));
424190286Sobrien  else
424290286Sobrien    {
424390286Sobrien      operands[4] = assign_386_stack_local (SImode, 0);
424490286Sobrien      emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
424590286Sobrien					   operands[2], operands[3],
424690286Sobrien					   operands[4]));
424790286Sobrien    }
424890286Sobrien  DONE;
424990286Sobrien}
4250132727Skan  [(set_attr "type" "fistp")
4251132727Skan   (set_attr "mode" "SI")])
425218334Speter
425390286Sobrien(define_insn "fix_truncsi_nomemory"
425490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
425590286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))
425690286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
425790286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
425890286Sobrien   (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
425990286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
426090286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
426190286Sobrien  "#"
4262132727Skan  [(set_attr "type" "fistp")
4263132727Skan   (set_attr "mode" "SI")])
426490286Sobrien
426590286Sobrien(define_insn "fix_truncsi_memory"
426690286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
426790286Sobrien	(fix:SI (match_operand 1 "register_operand" "f")))
426890286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
426990286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
427090286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
427190286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
427252296Sobrien  "* return output_fix_trunc (insn, operands);"
4273132727Skan  [(set_attr "type" "fistp")
4274132727Skan   (set_attr "mode" "SI")])
427518334Speter
427690286Sobrien;; When SSE available, it is always faster to use it!
427790286Sobrien(define_insn "fix_truncsfsi_sse"
4278132727Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
4279132727Skan	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
428090286Sobrien  "TARGET_SSE"
428190286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
4282132727Skan  [(set_attr "type" "sseicvt")
4283132727Skan   (set_attr "mode" "DF")
4284132727Skan   (set_attr "athlon_decode" "double,vector")])
428552296Sobrien
4286132727Skan;; Avoid vector decoded form of the instruction.
4287132727Skan(define_peephole2
4288132727Skan  [(match_scratch:SF 2 "x")
4289132727Skan   (set (match_operand:SI 0 "register_operand" "")
4290132727Skan	(fix:SI (match_operand:SF 1 "memory_operand" "")))]
4291132727Skan  "TARGET_K8 && !optimize_size"
4292132727Skan  [(set (match_dup 2) (match_dup 1))
4293132727Skan   (set (match_dup 0) (fix:SI (match_dup 2)))]
4294132727Skan  "")
4295132727Skan
429690286Sobrien(define_insn "fix_truncdfsi_sse"
4297132727Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
4298132727Skan	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
429990286Sobrien  "TARGET_SSE2"
430090286Sobrien  "cvttsd2si\t{%1, %0|%0, %1}"
4301132727Skan  [(set_attr "type" "sseicvt")
4302132727Skan   (set_attr "mode" "DF")
4303132727Skan   (set_attr "athlon_decode" "double,vector")])
430452296Sobrien
4305132727Skan;; Avoid vector decoded form of the instruction.
4306132727Skan(define_peephole2
4307132727Skan  [(match_scratch:DF 2 "Y")
4308132727Skan   (set (match_operand:SI 0 "register_operand" "")
4309132727Skan	(fix:SI (match_operand:DF 1 "memory_operand" "")))]
4310132727Skan  "TARGET_K8 && !optimize_size"
4311132727Skan  [(set (match_dup 2) (match_dup 1))
4312132727Skan   (set (match_dup 0) (fix:SI (match_dup 2)))]
4313132727Skan  "")
4314132727Skan
431590286Sobrien(define_split 
431690286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
431790286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
431890286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
431990286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
432090286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
432190286Sobrien  "reload_completed"
432290286Sobrien  [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
432390286Sobrien	      (use (match_dup 2))
432490286Sobrien	      (use (match_dup 3))])
432590286Sobrien   (set (match_dup 0) (match_dup 4))]
432690286Sobrien  "")
432718334Speter
432890286Sobrien(define_split 
432990286Sobrien  [(set (match_operand:SI 0 "memory_operand" "")
433090286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
433190286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
433290286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
433390286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
433490286Sobrien  "reload_completed"
433590286Sobrien  [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
433690286Sobrien	      (use (match_dup 2))
433790286Sobrien	      (use (match_dup 3))])]
433852296Sobrien  "")
433952296Sobrien
434090286Sobrien;; Signed conversion to HImode.
434190286Sobrien
434290286Sobrien(define_expand "fix_truncxfhi2"
434390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
434490286Sobrien        (fix:HI (match_operand:XF 1 "register_operand" "")))]
434518334Speter  "TARGET_80387"
434690286Sobrien  "")
434718334Speter
434890286Sobrien(define_expand "fix_truncdfhi2"
434990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
435090286Sobrien	(fix:HI (match_operand:DF 1 "register_operand" "")))]
435190286Sobrien  "TARGET_80387 && !TARGET_SSE2"
435290286Sobrien  "")
435318334Speter
435490286Sobrien(define_expand "fix_truncsfhi2"
435590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
435690286Sobrien	(fix:HI (match_operand:SF 1 "register_operand" "")))]
435790286Sobrien  "TARGET_80387 && !TARGET_SSE"
435890286Sobrien  "")
435952296Sobrien
436090286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
436190286Sobrien;; of the machinery.
436290286Sobrien(define_insn_and_split "*fix_trunchi_1"
436390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
436490286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))]
436590286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
436690286Sobrien   && !reload_completed && !reload_in_progress
436790286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
436890286Sobrien  "#"
436990286Sobrien  ""
437090286Sobrien  [(const_int 0)]
437190286Sobrien{
4372132727Skan  ix86_optimize_mode_switching = 1;
437390286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
437490286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
437590286Sobrien  if (memory_operand (operands[0], VOIDmode))
437690286Sobrien    emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
437790286Sobrien				       operands[2], operands[3]));
437890286Sobrien  else
437990286Sobrien    {
438090286Sobrien      operands[4] = assign_386_stack_local (HImode, 0);
438190286Sobrien      emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
438290286Sobrien					   operands[2], operands[3],
438390286Sobrien					   operands[4]));
438490286Sobrien    }
438590286Sobrien  DONE;
438690286Sobrien}
4387132727Skan  [(set_attr "type" "fistp")
4388132727Skan   (set_attr "mode" "HI")])
438990286Sobrien
439090286Sobrien(define_insn "fix_trunchi_nomemory"
439190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
439290286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))
439390286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
439490286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
439590286Sobrien   (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
439690286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
439790286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
439890286Sobrien  "#"
4399132727Skan  [(set_attr "type" "fistp")
4400132727Skan   (set_attr "mode" "HI")])
440190286Sobrien
440290286Sobrien(define_insn "fix_trunchi_memory"
440390286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
440490286Sobrien	(fix:HI (match_operand 1 "register_operand" "f")))
440590286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
440690286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
440790286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
440890286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
440990286Sobrien  "* return output_fix_trunc (insn, operands);"
4410132727Skan  [(set_attr "type" "fistp")
4411132727Skan   (set_attr "mode" "HI")])
441290286Sobrien
441390286Sobrien(define_split 
441490286Sobrien  [(set (match_operand:HI 0 "memory_operand" "")
441590286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
441690286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
441790286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
441890286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
441990286Sobrien  "reload_completed"
442090286Sobrien  [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
442190286Sobrien	      (use (match_dup 2))
442290286Sobrien	      (use (match_dup 3))])]
442318334Speter  "")
442418334Speter
442590286Sobrien(define_split 
442690286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
442790286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
442890286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
442990286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
443090286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
443190286Sobrien  "reload_completed"
443290286Sobrien  [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
443390286Sobrien	      (use (match_dup 2))
443490286Sobrien	      (use (match_dup 3))
443590286Sobrien	      (clobber (match_dup 4))])
443690286Sobrien   (set (match_dup 0) (match_dup 4))]
443752296Sobrien  "")
443852296Sobrien
443990286Sobrien;; %% Not used yet.
444090286Sobrien(define_insn "x86_fnstcw_1"
444190286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
4442117404Skan	(unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
444352296Sobrien  "TARGET_80387"
444490286Sobrien  "fnstcw\t%0"
444590286Sobrien  [(set_attr "length" "2")
444690286Sobrien   (set_attr "mode" "HI")
4447117404Skan   (set_attr "unit" "i387")
444890286Sobrien   (set_attr "ppro_uops" "few")])
444952296Sobrien
445090286Sobrien(define_insn "x86_fldcw_1"
445190286Sobrien  [(set (reg:HI 18)
4452117404Skan	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
445352296Sobrien  "TARGET_80387"
445490286Sobrien  "fldcw\t%0"
445590286Sobrien  [(set_attr "length" "2")
445690286Sobrien   (set_attr "mode" "HI")
4457117404Skan   (set_attr "unit" "i387")
445890286Sobrien   (set_attr "athlon_decode" "vector")
445990286Sobrien   (set_attr "ppro_uops" "few")])
446090286Sobrien
446190286Sobrien;; Conversion between fixed point and floating point.
446252296Sobrien
446390286Sobrien;; Even though we only accept memory inputs, the backend _really_
446490286Sobrien;; wants to be able to do this between registers.
446590286Sobrien
4466132727Skan(define_expand "floathisf2"
4467132727Skan  [(set (match_operand:SF 0 "register_operand" "")
4468132727Skan	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4469132727Skan  "TARGET_SSE || TARGET_80387"
4470132727Skan{
4471132727Skan  if (TARGET_SSE && TARGET_SSE_MATH)
4472132727Skan    {
4473132727Skan      emit_insn (gen_floatsisf2 (operands[0],
4474132727Skan				 convert_to_mode (SImode, operands[1], 0)));
4475132727Skan      DONE;
4476132727Skan    }
4477132727Skan})
4478132727Skan
4479132727Skan(define_insn "*floathisf2_1"
448052296Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
448190286Sobrien	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4482132727Skan  "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
448390286Sobrien  "@
448490286Sobrien   fild%z1\t%1
448590286Sobrien   #"
448690286Sobrien  [(set_attr "type" "fmov,multi")
448790286Sobrien   (set_attr "mode" "SF")
448890286Sobrien   (set_attr "fp_int_src" "true")])
448952296Sobrien
449090286Sobrien(define_expand "floatsisf2"
449118334Speter  [(set (match_operand:SF 0 "register_operand" "")
449290286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
449390286Sobrien  "TARGET_SSE || TARGET_80387"
449418334Speter  "")
449518334Speter
449690286Sobrien(define_insn "*floatsisf2_i387"
4497132727Skan  [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4498132727Skan	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
449990286Sobrien  "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
450090286Sobrien  "@
450190286Sobrien   fild%z1\t%1
450290286Sobrien   #
4503132727Skan   cvtsi2ss\t{%1, %0|%0, %1}
450490286Sobrien   cvtsi2ss\t{%1, %0|%0, %1}"
4505132727Skan  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
450690286Sobrien   (set_attr "mode" "SF")
4507132727Skan   (set_attr "athlon_decode" "*,*,vector,double")
450890286Sobrien   (set_attr "fp_int_src" "true")])
450990286Sobrien
451090286Sobrien(define_insn "*floatsisf2_sse"
4511132727Skan  [(set (match_operand:SF 0 "register_operand" "=x,x")
4512132727Skan	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
451390286Sobrien  "TARGET_SSE"
451490286Sobrien  "cvtsi2ss\t{%1, %0|%0, %1}"
4515132727Skan  [(set_attr "type" "sseicvt")
451690286Sobrien   (set_attr "mode" "SF")
4517132727Skan   (set_attr "athlon_decode" "vector,double")
451890286Sobrien   (set_attr "fp_int_src" "true")])
451990286Sobrien
4520132727Skan; Avoid possible reformatting penalty on the destination by first
4521132727Skan; zeroing it out
4522132727Skan(define_split
4523132727Skan  [(set (match_operand:SF 0 "register_operand" "")
4524132727Skan	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525132727Skan  "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4526132727Skan   && SSE_REG_P (operands[0])"
4527132727Skan  [(const_int 0)]
4528132727Skan{
4529132727Skan  rtx dest;
4530132727Skan  dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4531132727Skan  emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4532132727Skan  emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4533132727Skan  DONE;
4534132727Skan})
4535132727Skan
453690286Sobrien(define_expand "floatdisf2"
453752296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
453890286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
453990286Sobrien  "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
454052296Sobrien  "")
454152296Sobrien
454290286Sobrien(define_insn "*floatdisf2_i387_only"
454390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f")
454490286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
454590286Sobrien  "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
454690286Sobrien  "@
454790286Sobrien   fild%z1\t%1
454890286Sobrien   #"
454990286Sobrien  [(set_attr "type" "fmov,multi")
455090286Sobrien   (set_attr "mode" "SF")
455190286Sobrien   (set_attr "fp_int_src" "true")])
455252296Sobrien
455390286Sobrien(define_insn "*floatdisf2_i387"
4554132727Skan  [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4555132727Skan	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
455690286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
455790286Sobrien  "@
455890286Sobrien   fild%z1\t%1
455990286Sobrien   #
4560132727Skan   cvtsi2ss{q}\t{%1, %0|%0, %1}
456190286Sobrien   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562132727Skan  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
456390286Sobrien   (set_attr "mode" "SF")
4564132727Skan   (set_attr "athlon_decode" "*,*,vector,double")
456590286Sobrien   (set_attr "fp_int_src" "true")])
456652296Sobrien
456790286Sobrien(define_insn "*floatdisf2_sse"
4568132727Skan  [(set (match_operand:SF 0 "register_operand" "=x,x")
4569132727Skan	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
457090286Sobrien  "TARGET_64BIT && TARGET_SSE"
457190286Sobrien  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4572132727Skan  [(set_attr "type" "sseicvt")
457390286Sobrien   (set_attr "mode" "SF")
4574132727Skan   (set_attr "athlon_decode" "vector,double")
457590286Sobrien   (set_attr "fp_int_src" "true")])
457690286Sobrien
4577132727Skan; Avoid possible reformatting penalty on the destination by first
4578132727Skan; zeroing it out
4579132727Skan(define_split
4580132727Skan  [(set (match_operand:SF 0 "register_operand" "")
4581132727Skan	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4582132727Skan  "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4583132727Skan   && SSE_REG_P (operands[0])"
4584132727Skan  [(const_int 0)]
4585132727Skan{
4586132727Skan  rtx dest;
4587132727Skan  dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4588132727Skan  emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4589132727Skan  emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4590132727Skan  DONE;
4591132727Skan})
4592132727Skan
4593132727Skan(define_expand "floathidf2"
4594132727Skan  [(set (match_operand:DF 0 "register_operand" "")
4595132727Skan	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4596132727Skan  "TARGET_SSE2 || TARGET_80387"
4597132727Skan{
4598132727Skan  if (TARGET_SSE && TARGET_SSE_MATH)
4599132727Skan    {
4600132727Skan      emit_insn (gen_floatsidf2 (operands[0],
4601132727Skan				 convert_to_mode (SImode, operands[1], 0)));
4602132727Skan      DONE;
4603132727Skan    }
4604132727Skan})
4605132727Skan
4606132727Skan(define_insn "*floathidf2_1"
460752296Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
460890286Sobrien	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4609132727Skan  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
461090286Sobrien  "@
461190286Sobrien   fild%z1\t%1
461290286Sobrien   #"
461390286Sobrien  [(set_attr "type" "fmov,multi")
461490286Sobrien   (set_attr "mode" "DF")
461590286Sobrien   (set_attr "fp_int_src" "true")])
461652296Sobrien
461790286Sobrien(define_expand "floatsidf2"
461818334Speter  [(set (match_operand:DF 0 "register_operand" "")
461990286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
462096294Sobrien  "TARGET_80387 || TARGET_SSE2"
462152296Sobrien  "")
462252296Sobrien
462390286Sobrien(define_insn "*floatsidf2_i387"
4624132727Skan  [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4625132727Skan	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
462690286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
462790286Sobrien  "@
462890286Sobrien   fild%z1\t%1
462990286Sobrien   #
4630132727Skan   cvtsi2sd\t{%1, %0|%0, %1}
463190286Sobrien   cvtsi2sd\t{%1, %0|%0, %1}"
4632132727Skan  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
463390286Sobrien   (set_attr "mode" "DF")
4634132727Skan   (set_attr "athlon_decode" "*,*,double,direct")
463590286Sobrien   (set_attr "fp_int_src" "true")])
463690286Sobrien
463790286Sobrien(define_insn "*floatsidf2_sse"
4638132727Skan  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4639132727Skan	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
464090286Sobrien  "TARGET_SSE2"
464190286Sobrien  "cvtsi2sd\t{%1, %0|%0, %1}"
4642132727Skan  [(set_attr "type" "sseicvt")
464390286Sobrien   (set_attr "mode" "DF")
4644132727Skan   (set_attr "athlon_decode" "double,direct")
464590286Sobrien   (set_attr "fp_int_src" "true")])
464690286Sobrien
464790286Sobrien(define_expand "floatdidf2"
464852296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
464990286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
465090286Sobrien  "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
465152296Sobrien  "")
465252296Sobrien
465390286Sobrien(define_insn "*floatdidf2_i387_only"
465490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f")
465590286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
465690286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
465790286Sobrien  "@
465890286Sobrien   fild%z1\t%1
465990286Sobrien   #"
466090286Sobrien  [(set_attr "type" "fmov,multi")
466190286Sobrien   (set_attr "mode" "DF")
466290286Sobrien   (set_attr "fp_int_src" "true")])
466390286Sobrien
466490286Sobrien(define_insn "*floatdidf2_i387"
4665132727Skan  [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4666132727Skan	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
466790286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
466890286Sobrien  "@
466990286Sobrien   fild%z1\t%1
467090286Sobrien   #
4671132727Skan   cvtsi2sd{q}\t{%1, %0|%0, %1}
467290286Sobrien   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673132727Skan  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
467490286Sobrien   (set_attr "mode" "DF")
4675132727Skan   (set_attr "athlon_decode" "*,*,double,direct")
467690286Sobrien   (set_attr "fp_int_src" "true")])
467790286Sobrien
467890286Sobrien(define_insn "*floatdidf2_sse"
4679132727Skan  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4680132727Skan	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
468190286Sobrien  "TARGET_SSE2"
468290286Sobrien  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4683132727Skan  [(set_attr "type" "sseicvt")
468490286Sobrien   (set_attr "mode" "DF")
4685132727Skan   (set_attr "athlon_decode" "double,direct")
468690286Sobrien   (set_attr "fp_int_src" "true")])
468790286Sobrien
468890286Sobrien(define_insn "floathixf2"
468990286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
469090286Sobrien	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
469118334Speter  "TARGET_80387"
469290286Sobrien  "@
469390286Sobrien   fild%z1\t%1
469490286Sobrien   #"
469590286Sobrien  [(set_attr "type" "fmov,multi")
469690286Sobrien   (set_attr "mode" "XF")
469790286Sobrien   (set_attr "fp_int_src" "true")])
469852296Sobrien
469990286Sobrien(define_insn "floatsixf2"
470090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
470190286Sobrien	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
470252296Sobrien  "TARGET_80387"
470390286Sobrien  "@
470490286Sobrien   fild%z1\t%1
470590286Sobrien   #"
470690286Sobrien  [(set_attr "type" "fmov,multi")
470790286Sobrien   (set_attr "mode" "XF")
470890286Sobrien   (set_attr "fp_int_src" "true")])
470952296Sobrien
471090286Sobrien(define_insn "floatdixf2"
471190286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
471290286Sobrien	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
471352296Sobrien  "TARGET_80387"
471490286Sobrien  "@
471590286Sobrien   fild%z1\t%1
471690286Sobrien   #"
471790286Sobrien  [(set_attr "type" "fmov,multi")
471890286Sobrien   (set_attr "mode" "XF")
471990286Sobrien   (set_attr "fp_int_src" "true")])
472052296Sobrien
472190286Sobrien;; %%% Kill these when reload knows how to do it.
472252296Sobrien(define_split
4723117404Skan  [(set (match_operand 0 "fp_register_operand" "")
472490286Sobrien	(float (match_operand 1 "register_operand" "")))]
4725117404Skan  "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
472690286Sobrien  [(const_int 0)]
472790286Sobrien{
472890286Sobrien  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
472990286Sobrien  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
473090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
473190286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
473290286Sobrien  DONE;
473390286Sobrien})
4734132727Skan
4735132727Skan(define_expand "floatunssisf2"
4736132727Skan  [(use (match_operand:SF 0 "register_operand" ""))
4737132727Skan   (use (match_operand:SI 1 "register_operand" ""))]
4738132727Skan  "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4739132727Skan  "x86_emit_floatuns (operands); DONE;")
4740132727Skan
4741132727Skan(define_expand "floatunsdisf2"
4742132727Skan  [(use (match_operand:SF 0 "register_operand" ""))
4743132727Skan   (use (match_operand:DI 1 "register_operand" ""))]
4744132727Skan  "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4745132727Skan  "x86_emit_floatuns (operands); DONE;")
4746132727Skan
4747132727Skan(define_expand "floatunsdidf2"
4748132727Skan  [(use (match_operand:DF 0 "register_operand" ""))
4749132727Skan   (use (match_operand:DI 1 "register_operand" ""))]
4750132727Skan  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4751132727Skan  "x86_emit_floatuns (operands); DONE;")
475290286Sobrien
4753132727Skan;; SSE extract/set expanders
4754132727Skan
4755132727Skan(define_expand "vec_setv2df"
4756132727Skan  [(match_operand:V2DF 0 "register_operand" "")
4757132727Skan   (match_operand:DF 1 "register_operand" "")
4758132727Skan   (match_operand 2 "const_int_operand" "")]
4759132727Skan  "TARGET_SSE2"
4760132727Skan{
4761132727Skan  switch (INTVAL (operands[2]))
4762132727Skan    {
4763132727Skan    case 0:
4764132727Skan      emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765132727Skan				 simplify_gen_subreg (V2DFmode, operands[1],
4766132727Skan						      DFmode, 0)));
4767132727Skan      break;
4768132727Skan    case 1:
4769132727Skan      {
4770132727Skan	rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771132727Skan
4772132727Skan	emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773132727Skan      }
4774132727Skan      break;
4775132727Skan    default:
4776132727Skan      abort ();
4777132727Skan    }
4778132727Skan  DONE;
4779132727Skan})
4780132727Skan
4781132727Skan(define_expand "vec_extractv2df"
4782132727Skan  [(match_operand:DF 0 "register_operand" "")
4783132727Skan   (match_operand:V2DF 1 "register_operand" "")
4784132727Skan   (match_operand 2 "const_int_operand" "")]
4785132727Skan  "TARGET_SSE2"
4786132727Skan{
4787132727Skan  switch (INTVAL (operands[2]))
4788132727Skan    {
4789132727Skan    case 0:
4790132727Skan      emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791132727Skan      break;
4792132727Skan    case 1:
4793132727Skan      {
4794132727Skan	rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795132727Skan
4796132727Skan	emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797132727Skan      }
4798132727Skan      break;
4799132727Skan    default:
4800132727Skan      abort ();
4801132727Skan    }
4802132727Skan  DONE;
4803132727Skan})
4804132727Skan
4805132727Skan(define_expand "vec_initv2df"
4806132727Skan  [(match_operand:V2DF 0 "register_operand" "")
4807132727Skan   (match_operand 1 "" "")]
4808132727Skan  "TARGET_SSE2"
4809132727Skan{
4810132727Skan  ix86_expand_vector_init (operands[0], operands[1]);
4811132727Skan  DONE;
4812132727Skan})
4813132727Skan
4814132727Skan(define_expand "vec_setv4sf"
4815132727Skan  [(match_operand:V4SF 0 "register_operand" "")
4816132727Skan   (match_operand:SF 1 "register_operand" "")
4817132727Skan   (match_operand 2 "const_int_operand" "")]
4818132727Skan  "TARGET_SSE"
4819132727Skan{
4820132727Skan  switch (INTVAL (operands[2]))
4821132727Skan    {
4822132727Skan    case 0:
4823132727Skan      emit_insn (gen_sse_movss (operands[0], operands[0],
4824132727Skan				simplify_gen_subreg (V4SFmode, operands[1],
4825132727Skan						     SFmode, 0)));
4826132727Skan      break;
4827132727Skan    case 1:
4828132727Skan      {
4829132727Skan	rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830132727Skan	rtx tmp = gen_reg_rtx (V4SFmode);
4831132727Skan 
4832132727Skan        emit_move_insn (tmp, operands[0]);
4833132727Skan	emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834132727Skan	emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835132727Skan        emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836132727Skan                                   GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837132727Skan      }
4838132727Skan    case 2:
4839132727Skan      {
4840132727Skan        rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4841132727Skan        rtx tmp = gen_reg_rtx (V4SFmode);
4842132727Skan
4843132727Skan        emit_move_insn (tmp, operands[0]);
4844132727Skan        emit_insn (gen_sse_movss (tmp, tmp, op1));
4845132727Skan        emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4846132727Skan                                   GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4847132727Skan      }
4848132727Skan      break;
4849132727Skan    case 3:
4850132727Skan      {
4851132727Skan        rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4852132727Skan        rtx tmp = gen_reg_rtx (V4SFmode);
4853132727Skan
4854132727Skan        emit_move_insn (tmp, operands[0]);
4855132727Skan        emit_insn (gen_sse_movss (tmp, tmp, op1));
4856132727Skan        emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4857132727Skan                                   GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4858132727Skan      }
4859132727Skan      break;
4860132727Skan    default:
4861132727Skan      abort ();
4862132727Skan    }
4863132727Skan  DONE;
4864132727Skan})
4865132727Skan
4866132727Skan(define_expand "vec_extractv4sf"
4867132727Skan  [(match_operand:SF 0 "register_operand" "")
4868132727Skan   (match_operand:V4SF 1 "register_operand" "")
4869132727Skan   (match_operand 2 "const_int_operand" "")]
4870132727Skan  "TARGET_SSE"
4871132727Skan{
4872132727Skan  switch (INTVAL (operands[2]))
4873132727Skan    {
4874132727Skan    case 0:
4875132727Skan      emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4876132727Skan      break;
4877132727Skan    case 1:
4878132727Skan      {
4879132727Skan	rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4880132727Skan	rtx tmp = gen_reg_rtx (V4SFmode);
4881132727Skan 
4882132727Skan        emit_move_insn (tmp, operands[1]);
4883132727Skan        emit_insn (gen_sse_shufps (op0, tmp, tmp,
4884132727Skan                                   GEN_INT (1)));
4885132727Skan      }
4886132727Skan    case 2:
4887132727Skan      {
4888132727Skan	rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4889132727Skan	rtx tmp = gen_reg_rtx (V4SFmode);
4890132727Skan 
4891132727Skan        emit_move_insn (tmp, operands[1]);
4892132727Skan        emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4893132727Skan      }
4894132727Skan    case 3:
4895132727Skan      {
4896132727Skan	rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4897132727Skan	rtx tmp = gen_reg_rtx (V4SFmode);
4898132727Skan 
4899132727Skan        emit_move_insn (tmp, operands[1]);
4900132727Skan        emit_insn (gen_sse_shufps (op0, tmp, tmp,
4901132727Skan                                   GEN_INT (3)));
4902132727Skan      }
4903132727Skan    default:
4904132727Skan      abort ();
4905132727Skan    }
4906132727Skan  DONE;
4907132727Skan})
4908132727Skan
4909132727Skan(define_expand "vec_initv4sf"
4910132727Skan  [(match_operand:V4SF 0 "register_operand" "")
4911132727Skan   (match_operand 1 "" "")]
4912132727Skan  "TARGET_SSE"
4913132727Skan{
4914132727Skan  ix86_expand_vector_init (operands[0], operands[1]);
4915132727Skan  DONE;
4916132727Skan})
4917132727Skan
491890286Sobrien;; Add instructions
491918334Speter
492090286Sobrien;; %%% splits for addsidi3
492190286Sobrien;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
492290286Sobrien;	(plus:DI (match_operand:DI 1 "general_operand" "")
492390286Sobrien;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
492452296Sobrien
492590286Sobrien(define_expand "adddi3"
492690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
492790286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
492890286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "")))
492990286Sobrien   (clobber (reg:CC 17))]
493090286Sobrien  ""
493190286Sobrien  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
493252296Sobrien
493390286Sobrien(define_insn "*adddi3_1"
493490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
493590286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
493690286Sobrien		 (match_operand:DI 2 "general_operand" "roiF,riF")))
493790286Sobrien   (clobber (reg:CC 17))]
4938107605Sobrien  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
493952296Sobrien  "#")
494052296Sobrien
494152296Sobrien(define_split
494290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
494390286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
494490286Sobrien		 (match_operand:DI 2 "general_operand" "")))
494590286Sobrien   (clobber (reg:CC 17))]
494690286Sobrien  "!TARGET_64BIT && reload_completed"
4947117404Skan  [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4948117404Skan					  UNSPEC_ADD_CARRY))
494990286Sobrien	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
495090286Sobrien   (parallel [(set (match_dup 3)
495190286Sobrien		   (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
495290286Sobrien				     (match_dup 4))
495390286Sobrien			    (match_dup 5)))
495490286Sobrien	      (clobber (reg:CC 17))])]
495590286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
495690286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
495790286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
495818334Speter
4959132727Skan(define_insn "adddi3_carry_rex64"
496090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4961132727Skan	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
496290286Sobrien			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
496390286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
496490286Sobrien   (clobber (reg:CC 17))]
496590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
496690286Sobrien  "adc{q}\t{%2, %0|%0, %2}"
496790286Sobrien  [(set_attr "type" "alu")
496890286Sobrien   (set_attr "pent_pair" "pu")
496990286Sobrien   (set_attr "mode" "DI")
497090286Sobrien   (set_attr "ppro_uops" "few")])
497152296Sobrien
497290286Sobrien(define_insn "*adddi3_cc_rex64"
4973117404Skan  [(set (reg:CC 17)
4974117404Skan	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4975117404Skan		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4976117404Skan		   UNSPEC_ADD_CARRY))
497790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
497890286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
497990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
498090286Sobrien  "add{q}\t{%2, %0|%0, %2}"
498190286Sobrien  [(set_attr "type" "alu")
498290286Sobrien   (set_attr "mode" "DI")])
498352296Sobrien
4984132727Skan(define_insn "addqi3_carry"
4985132727Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4986132727Skan	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4987132727Skan			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4988132727Skan		   (match_operand:QI 2 "general_operand" "qi,qm")))
4989132727Skan   (clobber (reg:CC 17))]
4990132727Skan  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4991132727Skan  "adc{b}\t{%2, %0|%0, %2}"
4992132727Skan  [(set_attr "type" "alu")
4993132727Skan   (set_attr "pent_pair" "pu")
4994132727Skan   (set_attr "mode" "QI")
4995132727Skan   (set_attr "ppro_uops" "few")])
4996132727Skan
4997132727Skan(define_insn "addhi3_carry"
4998132727Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4999132727Skan	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5000132727Skan			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5001132727Skan		   (match_operand:HI 2 "general_operand" "ri,rm")))
5002132727Skan   (clobber (reg:CC 17))]
5003132727Skan  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5004132727Skan  "adc{w}\t{%2, %0|%0, %2}"
5005132727Skan  [(set_attr "type" "alu")
5006132727Skan   (set_attr "pent_pair" "pu")
5007132727Skan   (set_attr "mode" "HI")
5008132727Skan   (set_attr "ppro_uops" "few")])
5009132727Skan
5010132727Skan(define_insn "addsi3_carry"
501190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5012132727Skan	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
501390286Sobrien			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
501490286Sobrien		   (match_operand:SI 2 "general_operand" "ri,rm")))
501590286Sobrien   (clobber (reg:CC 17))]
501690286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
501790286Sobrien  "adc{l}\t{%2, %0|%0, %2}"
501890286Sobrien  [(set_attr "type" "alu")
501990286Sobrien   (set_attr "pent_pair" "pu")
502090286Sobrien   (set_attr "mode" "SI")
502190286Sobrien   (set_attr "ppro_uops" "few")])
502252296Sobrien
502390286Sobrien(define_insn "*addsi3_carry_zext"
502490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
502590286Sobrien	  (zero_extend:DI 
5026132727Skan	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
502790286Sobrien			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
502890286Sobrien		     (match_operand:SI 2 "general_operand" "rim"))))
502990286Sobrien   (clobber (reg:CC 17))]
503090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
503190286Sobrien  "adc{l}\t{%2, %k0|%k0, %2}"
503290286Sobrien  [(set_attr "type" "alu")
503390286Sobrien   (set_attr "pent_pair" "pu")
503490286Sobrien   (set_attr "mode" "SI")
503590286Sobrien   (set_attr "ppro_uops" "few")])
503652296Sobrien
503790286Sobrien(define_insn "*addsi3_cc"
5038117404Skan  [(set (reg:CC 17)
5039117404Skan	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5040117404Skan		    (match_operand:SI 2 "general_operand" "ri,rm")]
5041117404Skan		   UNSPEC_ADD_CARRY))
504290286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
504390286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
504490286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
504590286Sobrien  "add{l}\t{%2, %0|%0, %2}"
504690286Sobrien  [(set_attr "type" "alu")
504790286Sobrien   (set_attr "mode" "SI")])
504818334Speter
504990286Sobrien(define_insn "addqi3_cc"
5050117404Skan  [(set (reg:CC 17)
5051117404Skan	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5052117404Skan		    (match_operand:QI 2 "general_operand" "qi,qm")]
5053117404Skan		   UNSPEC_ADD_CARRY))
505490286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
505590286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
505690286Sobrien  "ix86_binary_operator_ok (PLUS, QImode, operands)"
505790286Sobrien  "add{b}\t{%2, %0|%0, %2}"
505890286Sobrien  [(set_attr "type" "alu")
505990286Sobrien   (set_attr "mode" "QI")])
506018334Speter
506190286Sobrien(define_expand "addsi3"
506290286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
506390286Sobrien		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
506490286Sobrien			    (match_operand:SI 2 "general_operand" "")))
506590286Sobrien	      (clobber (reg:CC 17))])]
506690286Sobrien  ""
506790286Sobrien  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
506818334Speter
506990286Sobrien(define_insn "*lea_1"
507090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
5071132727Skan	(match_operand:SI 1 "no_seg_address_operand" "p"))]
507290286Sobrien  "!TARGET_64BIT"
507390286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
507490286Sobrien  [(set_attr "type" "lea")
507590286Sobrien   (set_attr "mode" "SI")])
507618334Speter
507790286Sobrien(define_insn "*lea_1_rex64"
507890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
5079132727Skan	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
508090286Sobrien  "TARGET_64BIT"
508190286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
508290286Sobrien  [(set_attr "type" "lea")
508390286Sobrien   (set_attr "mode" "SI")])
508418334Speter
508590286Sobrien(define_insn "*lea_1_zext"
508690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
5087132727Skan	(zero_extend:DI
5088132727Skan	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
508990286Sobrien  "TARGET_64BIT"
509090286Sobrien  "lea{l}\t{%a1, %k0|%k0, %a1}"
509190286Sobrien  [(set_attr "type" "lea")
509290286Sobrien   (set_attr "mode" "SI")])
509390286Sobrien
509490286Sobrien(define_insn "*lea_2_rex64"
509590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
5096132727Skan	(match_operand:DI 1 "no_seg_address_operand" "p"))]
509790286Sobrien  "TARGET_64BIT"
509890286Sobrien  "lea{q}\t{%a1, %0|%0, %a1}"
509990286Sobrien  [(set_attr "type" "lea")
510090286Sobrien   (set_attr "mode" "DI")])
510190286Sobrien
510290286Sobrien;; The lea patterns for non-Pmodes needs to be matched by several
510390286Sobrien;; insns converted to real lea by splitters.
510490286Sobrien
510590286Sobrien(define_insn_and_split "*lea_general_1"
510690286Sobrien  [(set (match_operand 0 "register_operand" "=r")
5107117404Skan	(plus (plus (match_operand 1 "index_register_operand" "r")
510890286Sobrien		    (match_operand 2 "register_operand" "r"))
510990286Sobrien	      (match_operand 3 "immediate_operand" "i")))]
511090286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
511190286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
511290286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
511390286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
511490286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[2])
511590286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
511690286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
511790286Sobrien  "#"
511890286Sobrien  "&& reload_completed"
511990286Sobrien  [(const_int 0)]
512090286Sobrien{
512190286Sobrien  rtx pat;
512290286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
512390286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
512490286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
512590286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
512690286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
512790286Sobrien  		      operands[3]);
512890286Sobrien  if (Pmode != SImode)
512990286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
513090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
513190286Sobrien  DONE;
513290286Sobrien}
513390286Sobrien  [(set_attr "type" "lea")
513490286Sobrien   (set_attr "mode" "SI")])
513590286Sobrien
513690286Sobrien(define_insn_and_split "*lea_general_1_zext"
513790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
513890286Sobrien	(zero_extend:DI
5139117404Skan	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
514090286Sobrien			    (match_operand:SI 2 "register_operand" "r"))
514190286Sobrien		   (match_operand:SI 3 "immediate_operand" "i"))))]
514290286Sobrien  "TARGET_64BIT"
514390286Sobrien  "#"
514490286Sobrien  "&& reload_completed"
514552296Sobrien  [(set (match_dup 0)
514690286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
514790286Sobrien						     (match_dup 2))
514890286Sobrien					    (match_dup 3)) 0)))]
514990286Sobrien{
515090286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
515190286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
515290286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
515390286Sobrien}
515490286Sobrien  [(set_attr "type" "lea")
515590286Sobrien   (set_attr "mode" "SI")])
515652296Sobrien
515790286Sobrien(define_insn_and_split "*lea_general_2"
515890286Sobrien  [(set (match_operand 0 "register_operand" "=r")
5159117404Skan	(plus (mult (match_operand 1 "index_register_operand" "r")
516090286Sobrien		    (match_operand 2 "const248_operand" "i"))
516190286Sobrien	      (match_operand 3 "nonmemory_operand" "ri")))]
516290286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
516390286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
516490286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
516590286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
516690286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
516790286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
516890286Sobrien  "#"
516990286Sobrien  "&& reload_completed"
517090286Sobrien  [(const_int 0)]
517190286Sobrien{
517290286Sobrien  rtx pat;
517390286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
517490286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
517590286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
517690286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
517790286Sobrien  		      operands[3]);
517890286Sobrien  if (Pmode != SImode)
517990286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
518090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
518190286Sobrien  DONE;
518290286Sobrien}
518390286Sobrien  [(set_attr "type" "lea")
518490286Sobrien   (set_attr "mode" "SI")])
518552296Sobrien
518690286Sobrien(define_insn_and_split "*lea_general_2_zext"
518790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
518890286Sobrien	(zero_extend:DI
5189117404Skan	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
519090286Sobrien			    (match_operand:SI 2 "const248_operand" "n"))
519190286Sobrien		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
519290286Sobrien  "TARGET_64BIT"
519390286Sobrien  "#"
519490286Sobrien  "&& reload_completed"
519590286Sobrien  [(set (match_dup 0)
519690286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
519790286Sobrien						     (match_dup 2))
519890286Sobrien					    (match_dup 3)) 0)))]
519990286Sobrien{
520090286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
520190286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
520290286Sobrien}
520390286Sobrien  [(set_attr "type" "lea")
520490286Sobrien   (set_attr "mode" "SI")])
520518334Speter
520690286Sobrien(define_insn_and_split "*lea_general_3"
520790286Sobrien  [(set (match_operand 0 "register_operand" "=r")
5208117404Skan	(plus (plus (mult (match_operand 1 "index_register_operand" "r")
520990286Sobrien			  (match_operand 2 "const248_operand" "i"))
521090286Sobrien		    (match_operand 3 "register_operand" "r"))
521190286Sobrien	      (match_operand 4 "immediate_operand" "i")))]
521290286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
521390286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
521490286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
521590286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
521690286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
521790286Sobrien  "#"
521890286Sobrien  "&& reload_completed"
521990286Sobrien  [(const_int 0)]
522090286Sobrien{
522190286Sobrien  rtx pat;
522290286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
522390286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
522490286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
522590286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
522690286Sobrien  pat = gen_rtx_PLUS (Pmode,
522790286Sobrien  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
522890286Sobrien		      					 operands[2]),
522990286Sobrien				    operands[3]),
523090286Sobrien  		      operands[4]);
523190286Sobrien  if (Pmode != SImode)
523290286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
523390286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
523490286Sobrien  DONE;
523590286Sobrien}
523690286Sobrien  [(set_attr "type" "lea")
523790286Sobrien   (set_attr "mode" "SI")])
523852296Sobrien
523990286Sobrien(define_insn_and_split "*lea_general_3_zext"
524090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
524190286Sobrien	(zero_extend:DI
5242117404Skan	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
524390286Sobrien				     (match_operand:SI 2 "const248_operand" "n"))
524490286Sobrien			    (match_operand:SI 3 "register_operand" "r"))
524590286Sobrien		   (match_operand:SI 4 "immediate_operand" "i"))))]
524690286Sobrien  "TARGET_64BIT"
524790286Sobrien  "#"
524890286Sobrien  "&& reload_completed"
524990286Sobrien  [(set (match_dup 0)
525090286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
525190286Sobrien							      (match_dup 2))
525290286Sobrien						     (match_dup 3))
525390286Sobrien					    (match_dup 4)) 0)))]
525490286Sobrien{
525590286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
525690286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
525790286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
525890286Sobrien}
525990286Sobrien  [(set_attr "type" "lea")
526090286Sobrien   (set_attr "mode" "SI")])
526118334Speter
526290286Sobrien(define_insn "*adddi_1_rex64"
526390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
526490286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
526590286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
526690286Sobrien   (clobber (reg:CC 17))]
526790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
526890286Sobrien{
526990286Sobrien  switch (get_attr_type (insn))
527090286Sobrien    {
527190286Sobrien    case TYPE_LEA:
527290286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
527390286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
527490286Sobrien
527590286Sobrien    case TYPE_INCDEC:
527690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
527790286Sobrien	abort ();
527890286Sobrien      if (operands[2] == const1_rtx)
527990286Sobrien        return "inc{q}\t%0";
528090286Sobrien      else if (operands[2] == constm1_rtx)
528190286Sobrien        return "dec{q}\t%0";
528290286Sobrien      else
528390286Sobrien	abort ();
528490286Sobrien
528590286Sobrien    default:
528690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
528790286Sobrien	abort ();
528890286Sobrien
528990286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
529090286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
529190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
529290286Sobrien	  /* Avoid overflows.  */
529390286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
529490286Sobrien          && (INTVAL (operands[2]) == 128
529590286Sobrien	      || (INTVAL (operands[2]) < 0
529690286Sobrien		  && INTVAL (operands[2]) != -128)))
529790286Sobrien        {
529890286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
529990286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
530090286Sobrien        }
530190286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
530290286Sobrien    }
530390286Sobrien}
530490286Sobrien  [(set (attr "type")
530590286Sobrien     (cond [(eq_attr "alternative" "2")
530690286Sobrien	      (const_string "lea")
530790286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
530890286Sobrien	    ; ought but a memory context.
530990286Sobrien	    (match_operand:DI 2 "pic_symbolic_operand" "")
531090286Sobrien	      (const_string "lea")
531190286Sobrien	    (match_operand:DI 2 "incdec_operand" "")
531290286Sobrien	      (const_string "incdec")
531390286Sobrien	   ]
531490286Sobrien	   (const_string "alu")))
531590286Sobrien   (set_attr "mode" "DI")])
531690286Sobrien
531790286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
531852296Sobrien(define_split
531990286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
532090286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "")
532190286Sobrien		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
532290286Sobrien   (clobber (reg:CC 17))]
532390286Sobrien  "TARGET_64BIT && reload_completed
532490286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
532552296Sobrien  [(set (match_dup 0)
532690286Sobrien	(plus:DI (match_dup 1)
532790286Sobrien		 (match_dup 2)))]
532852296Sobrien  "")
532952296Sobrien
533090286Sobrien(define_insn "*adddi_2_rex64"
533190286Sobrien  [(set (reg 17)
533290286Sobrien	(compare
533390286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
533490286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
533590286Sobrien	  (const_int 0)))			
533690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
533790286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
533890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
533990286Sobrien   && ix86_binary_operator_ok (PLUS, DImode, operands)
534090286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
534190286Sobrien      ought but a memory context.  */
534290286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
534390286Sobrien{
534490286Sobrien  switch (get_attr_type (insn))
534590286Sobrien    {
534690286Sobrien    case TYPE_INCDEC:
534790286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
534890286Sobrien	abort ();
534990286Sobrien      if (operands[2] == const1_rtx)
535090286Sobrien        return "inc{q}\t%0";
535190286Sobrien      else if (operands[2] == constm1_rtx)
535290286Sobrien        return "dec{q}\t%0";
535390286Sobrien      else
535490286Sobrien	abort ();
535552296Sobrien
535690286Sobrien    default:
535790286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
535890286Sobrien	abort ();
535990286Sobrien      /* ???? We ought to handle there the 32bit case too
5360132727Skan	 - do we need new constraint?  */
536190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
536290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
536390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
536490286Sobrien	  /* Avoid overflows.  */
536590286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
536690286Sobrien          && (INTVAL (operands[2]) == 128
536790286Sobrien	      || (INTVAL (operands[2]) < 0
536890286Sobrien		  && INTVAL (operands[2]) != -128)))
536990286Sobrien        {
537090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
537190286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
537290286Sobrien        }
537390286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
537490286Sobrien    }
537590286Sobrien}
537690286Sobrien  [(set (attr "type")
537790286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
537890286Sobrien	(const_string "incdec")
537990286Sobrien	(const_string "alu")))
538090286Sobrien   (set_attr "mode" "DI")])
538118334Speter
538290286Sobrien(define_insn "*adddi_3_rex64"
538390286Sobrien  [(set (reg 17)
538490286Sobrien	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
538590286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
538690286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
538790286Sobrien  "TARGET_64BIT
538890286Sobrien   && ix86_match_ccmode (insn, CCZmode)
538990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
539090286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
539190286Sobrien      ought but a memory context.  */
539290286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
539350650Sobrien{
539490286Sobrien  switch (get_attr_type (insn))
539590286Sobrien    {
539690286Sobrien    case TYPE_INCDEC:
539790286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
539890286Sobrien	abort ();
539990286Sobrien      if (operands[2] == const1_rtx)
540090286Sobrien        return "inc{q}\t%0";
540190286Sobrien      else if (operands[2] == constm1_rtx)
540290286Sobrien        return "dec{q}\t%0";
540390286Sobrien      else
540490286Sobrien	abort ();
540550650Sobrien
540690286Sobrien    default:
540790286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
540890286Sobrien	abort ();
540990286Sobrien      /* ???? We ought to handle there the 32bit case too
5410132727Skan	 - do we need new constraint?  */
541190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
541290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
541390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
541490286Sobrien	  /* Avoid overflows.  */
541590286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
541690286Sobrien          && (INTVAL (operands[2]) == 128
541790286Sobrien	      || (INTVAL (operands[2]) < 0
541890286Sobrien		  && INTVAL (operands[2]) != -128)))
541990286Sobrien        {
542090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
542190286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
542290286Sobrien        }
542390286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
542490286Sobrien    }
542590286Sobrien}
542690286Sobrien  [(set (attr "type")
542790286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
542890286Sobrien	(const_string "incdec")
542990286Sobrien	(const_string "alu")))
543090286Sobrien   (set_attr "mode" "DI")])
543150650Sobrien
543290286Sobrien; For comparisons against 1, -1 and 128, we may generate better code
543390286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
543490286Sobrien; is matched then.  We can't accept general immediate, because for
543590286Sobrien; case of overflows,  the result is messed up.
543690286Sobrien; This pattern also don't hold of 0x8000000000000000, since the value overflows
543790286Sobrien; when negated.
543890286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
543990286Sobrien; only for comparisons not depending on it.
544090286Sobrien(define_insn "*adddi_4_rex64"
544190286Sobrien  [(set (reg 17)
544290286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
544390286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
544490286Sobrien   (clobber (match_scratch:DI 0 "=rm"))]
544590286Sobrien  "TARGET_64BIT
544690286Sobrien   &&  ix86_match_ccmode (insn, CCGCmode)"
544790286Sobrien{
544890286Sobrien  switch (get_attr_type (insn))
544990286Sobrien    {
545090286Sobrien    case TYPE_INCDEC:
545190286Sobrien      if (operands[2] == constm1_rtx)
545290286Sobrien        return "inc{q}\t%0";
545390286Sobrien      else if (operands[2] == const1_rtx)
545490286Sobrien        return "dec{q}\t%0";
545590286Sobrien      else
545690286Sobrien	abort();
545750650Sobrien
545890286Sobrien    default:
545990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
546090286Sobrien	abort ();
546190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
546290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
546390286Sobrien      if ((INTVAL (operands[2]) == -128
546490286Sobrien	   || (INTVAL (operands[2]) > 0
546590286Sobrien	       && INTVAL (operands[2]) != 128))
546690286Sobrien	  /* Avoid overflows.  */
546790286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
546890286Sobrien	return "sub{q}\t{%2, %0|%0, %2}";
546990286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
547090286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
547190286Sobrien    }
547290286Sobrien}
547390286Sobrien  [(set (attr "type")
547490286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
547590286Sobrien	(const_string "incdec")
547690286Sobrien	(const_string "alu")))
547790286Sobrien   (set_attr "mode" "DI")])
547890286Sobrien
547990286Sobrien(define_insn "*adddi_5_rex64"
548090286Sobrien  [(set (reg 17)
548190286Sobrien	(compare
548290286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
548390286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
548490286Sobrien	  (const_int 0)))			
548590286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
548690286Sobrien  "TARGET_64BIT
548790286Sobrien   && ix86_match_ccmode (insn, CCGOCmode)
548890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
548990286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
549090286Sobrien      ought but a memory context.  */
549190286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
549290286Sobrien{
549390286Sobrien  switch (get_attr_type (insn))
549450650Sobrien    {
549590286Sobrien    case TYPE_INCDEC:
549690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
549790286Sobrien	abort ();
549890286Sobrien      if (operands[2] == const1_rtx)
549990286Sobrien        return "inc{q}\t%0";
550090286Sobrien      else if (operands[2] == constm1_rtx)
550190286Sobrien        return "dec{q}\t%0";
550290286Sobrien      else
550390286Sobrien	abort();
550450650Sobrien
550590286Sobrien    default:
550690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
550790286Sobrien	abort ();
550890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
550990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
551090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
551190286Sobrien	  /* Avoid overflows.  */
551290286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
551390286Sobrien          && (INTVAL (operands[2]) == 128
551490286Sobrien	      || (INTVAL (operands[2]) < 0
551590286Sobrien		  && INTVAL (operands[2]) != -128)))
551690286Sobrien        {
551790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
551890286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
551990286Sobrien        }
552090286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
552150650Sobrien    }
552290286Sobrien}
552390286Sobrien  [(set (attr "type")
552490286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
552590286Sobrien	(const_string "incdec")
552690286Sobrien	(const_string "alu")))
552790286Sobrien   (set_attr "mode" "DI")])
552850650Sobrien
552950650Sobrien
553090286Sobrien(define_insn "*addsi_1"
553190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
553290286Sobrien	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
553390286Sobrien		 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
553490286Sobrien   (clobber (reg:CC 17))]
553590286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
553650650Sobrien{
553790286Sobrien  switch (get_attr_type (insn))
553890286Sobrien    {
553990286Sobrien    case TYPE_LEA:
554090286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
554190286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
554250650Sobrien
554390286Sobrien    case TYPE_INCDEC:
554490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
554590286Sobrien	abort ();
554690286Sobrien      if (operands[2] == const1_rtx)
554790286Sobrien        return "inc{l}\t%0";
554890286Sobrien      else if (operands[2] == constm1_rtx)
554990286Sobrien        return "dec{l}\t%0";
555090286Sobrien      else
555190286Sobrien	abort();
555250650Sobrien
555390286Sobrien    default:
555490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
555590286Sobrien	abort ();
555650650Sobrien
555790286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
555890286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
555990286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
556090286Sobrien          && (INTVAL (operands[2]) == 128
556190286Sobrien	      || (INTVAL (operands[2]) < 0
556290286Sobrien		  && INTVAL (operands[2]) != -128)))
556390286Sobrien        {
556490286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
556590286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
556690286Sobrien        }
556790286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
556890286Sobrien    }
556990286Sobrien}
557090286Sobrien  [(set (attr "type")
557190286Sobrien     (cond [(eq_attr "alternative" "2")
557290286Sobrien	      (const_string "lea")
557390286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
557490286Sobrien	    ; ought but a memory context.
557590286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
557690286Sobrien	      (const_string "lea")
557790286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
557890286Sobrien	      (const_string "incdec")
557990286Sobrien	   ]
558090286Sobrien	   (const_string "alu")))
558190286Sobrien   (set_attr "mode" "SI")])
558290286Sobrien
558390286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
558490286Sobrien(define_split
558590286Sobrien  [(set (match_operand 0 "register_operand" "")
558690286Sobrien	(plus (match_operand 1 "register_operand" "")
558790286Sobrien              (match_operand 2 "nonmemory_operand" "")))
558890286Sobrien   (clobber (reg:CC 17))]
558990286Sobrien  "reload_completed
559090286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
559190286Sobrien  [(const_int 0)]
559290286Sobrien{
559390286Sobrien  rtx pat;
559490286Sobrien  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
559590286Sobrien     may confuse gen_lowpart.  */
559690286Sobrien  if (GET_MODE (operands[0]) != Pmode)
559750650Sobrien    {
559890286Sobrien      operands[1] = gen_lowpart (Pmode, operands[1]);
559990286Sobrien      operands[2] = gen_lowpart (Pmode, operands[2]);
560090286Sobrien    }
560190286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
560290286Sobrien  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
560390286Sobrien  if (Pmode != SImode)
560490286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
560590286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
560690286Sobrien  DONE;
560790286Sobrien})
560850650Sobrien
560990286Sobrien;; It may seem that nonimmediate operand is proper one for operand 1.
561090286Sobrien;; The addsi_1 pattern allows nonimmediate operand at that place and
561190286Sobrien;; we take care in ix86_binary_operator_ok to not allow two memory
561290286Sobrien;; operands so proper swapping will be done in reload.  This allow
561390286Sobrien;; patterns constructed from addsi_1 to match.
561490286Sobrien(define_insn "addsi_1_zext"
561590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
561690286Sobrien	(zero_extend:DI
561790286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
561890286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))))
561990286Sobrien   (clobber (reg:CC 17))]
562090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
562190286Sobrien{
562290286Sobrien  switch (get_attr_type (insn))
562390286Sobrien    {
562490286Sobrien    case TYPE_LEA:
562590286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
562690286Sobrien      return "lea{l}\t{%a2, %k0|%k0, %a2}";
562790286Sobrien
562890286Sobrien    case TYPE_INCDEC:
562990286Sobrien      if (operands[2] == const1_rtx)
563090286Sobrien        return "inc{l}\t%k0";
563190286Sobrien      else if (operands[2] == constm1_rtx)
563290286Sobrien        return "dec{l}\t%k0";
563350650Sobrien      else
563490286Sobrien	abort();
563590286Sobrien
563690286Sobrien    default:
563790286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
563890286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
563990286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
564090286Sobrien          && (INTVAL (operands[2]) == 128
564190286Sobrien	      || (INTVAL (operands[2]) < 0
564290286Sobrien		  && INTVAL (operands[2]) != -128)))
564390286Sobrien        {
564490286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
564590286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
564690286Sobrien        }
564790286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
564850650Sobrien    }
564990286Sobrien}
565090286Sobrien  [(set (attr "type")
565190286Sobrien     (cond [(eq_attr "alternative" "1")
565290286Sobrien	      (const_string "lea")
565390286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
565490286Sobrien	    ; ought but a memory context.
565590286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
565690286Sobrien	      (const_string "lea")
565790286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
565890286Sobrien	      (const_string "incdec")
565990286Sobrien	   ]
566090286Sobrien	   (const_string "alu")))
566190286Sobrien   (set_attr "mode" "SI")])
566250650Sobrien
566390286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
566490286Sobrien(define_split
566590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
566690286Sobrien	(zero_extend:DI
566790286Sobrien	  (plus:SI (match_operand:SI 1 "register_operand" "")
566890286Sobrien		   (match_operand:SI 2 "nonmemory_operand" ""))))
566990286Sobrien   (clobber (reg:CC 17))]
5670132727Skan  "TARGET_64BIT && reload_completed
567190286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
567290286Sobrien  [(set (match_dup 0)
567390286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
567490286Sobrien{
567590286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
567690286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
567790286Sobrien})
567850650Sobrien
567990286Sobrien(define_insn "*addsi_2"
568090286Sobrien  [(set (reg 17)
568190286Sobrien	(compare
568290286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
568390286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))
568490286Sobrien	  (const_int 0)))			
568590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
568690286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
568790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
568890286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
568990286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
569090286Sobrien      ought but a memory context.  */
569190286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
569218334Speter{
569390286Sobrien  switch (get_attr_type (insn))
569490286Sobrien    {
569590286Sobrien    case TYPE_INCDEC:
569690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
569790286Sobrien	abort ();
569890286Sobrien      if (operands[2] == const1_rtx)
569990286Sobrien        return "inc{l}\t%0";
570090286Sobrien      else if (operands[2] == constm1_rtx)
570190286Sobrien        return "dec{l}\t%0";
570290286Sobrien      else
570390286Sobrien	abort();
570418334Speter
570590286Sobrien    default:
570690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
570790286Sobrien	abort ();
570890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
570990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
571090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
571190286Sobrien          && (INTVAL (operands[2]) == 128
571290286Sobrien	      || (INTVAL (operands[2]) < 0
571390286Sobrien		  && INTVAL (operands[2]) != -128)))
571490286Sobrien        {
571590286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
571690286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
571790286Sobrien        }
571890286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
571990286Sobrien    }
572090286Sobrien}
572190286Sobrien  [(set (attr "type")
572290286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
572390286Sobrien	(const_string "incdec")
572490286Sobrien	(const_string "alu")))
572590286Sobrien   (set_attr "mode" "SI")])
572618334Speter
572790286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
572890286Sobrien(define_insn "*addsi_2_zext"
572990286Sobrien  [(set (reg 17)
573090286Sobrien	(compare
573190286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
573290286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
573390286Sobrien	  (const_int 0)))			
573490286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
573590286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
573690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
573790286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
573890286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
573990286Sobrien      ought but a memory context.  */
574090286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
574190286Sobrien{
574290286Sobrien  switch (get_attr_type (insn))
574318334Speter    {
574490286Sobrien    case TYPE_INCDEC:
574590286Sobrien      if (operands[2] == const1_rtx)
574690286Sobrien        return "inc{l}\t%k0";
574790286Sobrien      else if (operands[2] == constm1_rtx)
574890286Sobrien        return "dec{l}\t%k0";
574990286Sobrien      else
575090286Sobrien	abort();
575190286Sobrien
575290286Sobrien    default:
575390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
575490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
575590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
575690286Sobrien          && (INTVAL (operands[2]) == 128
575790286Sobrien	      || (INTVAL (operands[2]) < 0
575890286Sobrien		  && INTVAL (operands[2]) != -128)))
575990286Sobrien        {
576090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
576190286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
576290286Sobrien        }
576390286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
576418334Speter    }
576590286Sobrien}
576690286Sobrien  [(set (attr "type")
576790286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
576890286Sobrien	(const_string "incdec")
576990286Sobrien	(const_string "alu")))
577090286Sobrien   (set_attr "mode" "SI")])
577118334Speter
577290286Sobrien(define_insn "*addsi_3"
577390286Sobrien  [(set (reg 17)
577490286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
577590286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
577690286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
577790286Sobrien  "ix86_match_ccmode (insn, CCZmode)
577890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
577990286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
578090286Sobrien      ought but a memory context.  */
578190286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
578290286Sobrien{
578390286Sobrien  switch (get_attr_type (insn))
578418334Speter    {
578590286Sobrien    case TYPE_INCDEC:
578690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
578790286Sobrien	abort ();
578890286Sobrien      if (operands[2] == const1_rtx)
578990286Sobrien        return "inc{l}\t%0";
579090286Sobrien      else if (operands[2] == constm1_rtx)
579190286Sobrien        return "dec{l}\t%0";
579290286Sobrien      else
579390286Sobrien	abort();
579418334Speter
579590286Sobrien    default:
579690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
579790286Sobrien	abort ();
579890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
579990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
580090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
580190286Sobrien          && (INTVAL (operands[2]) == 128
580290286Sobrien	      || (INTVAL (operands[2]) < 0
580390286Sobrien		  && INTVAL (operands[2]) != -128)))
580490286Sobrien        {
580590286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
580690286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
580790286Sobrien        }
580890286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
580990286Sobrien    }
581090286Sobrien}
581190286Sobrien  [(set (attr "type")
581290286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
581390286Sobrien	(const_string "incdec")
581490286Sobrien	(const_string "alu")))
581590286Sobrien   (set_attr "mode" "SI")])
581690286Sobrien
581790286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
581890286Sobrien(define_insn "*addsi_3_zext"
581990286Sobrien  [(set (reg 17)
582090286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
582190286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
582290286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
582390286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
582490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
582590286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
582690286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
582790286Sobrien      ought but a memory context.  */
582890286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
582990286Sobrien{
583090286Sobrien  switch (get_attr_type (insn))
583190286Sobrien    {
583290286Sobrien    case TYPE_INCDEC:
583390286Sobrien      if (operands[2] == const1_rtx)
583490286Sobrien        return "inc{l}\t%k0";
583590286Sobrien      else if (operands[2] == constm1_rtx)
583690286Sobrien        return "dec{l}\t%k0";
583718334Speter      else
583890286Sobrien	abort();
583990286Sobrien
584090286Sobrien    default:
584190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
584290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
584390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
584490286Sobrien          && (INTVAL (operands[2]) == 128
584590286Sobrien	      || (INTVAL (operands[2]) < 0
584690286Sobrien		  && INTVAL (operands[2]) != -128)))
584790286Sobrien        {
584890286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
584990286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
585090286Sobrien        }
585190286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
585218334Speter    }
585390286Sobrien}
585490286Sobrien  [(set (attr "type")
585590286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
585690286Sobrien	(const_string "incdec")
585790286Sobrien	(const_string "alu")))
585890286Sobrien   (set_attr "mode" "SI")])
585918334Speter
5860132727Skan; For comparisons against 1, -1 and 128, we may generate better code
586190286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
586290286Sobrien; is matched then.  We can't accept general immediate, because for
586390286Sobrien; case of overflows,  the result is messed up.
586490286Sobrien; This pattern also don't hold of 0x80000000, since the value overflows
586590286Sobrien; when negated.
586690286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
586790286Sobrien; only for comparisons not depending on it.
586890286Sobrien(define_insn "*addsi_4"
586990286Sobrien  [(set (reg 17)
587090286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
587190286Sobrien		 (match_operand:SI 2 "const_int_operand" "n")))
587290286Sobrien   (clobber (match_scratch:SI 0 "=rm"))]
587390286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
587490286Sobrien   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
587590286Sobrien{
587690286Sobrien  switch (get_attr_type (insn))
587718334Speter    {
587890286Sobrien    case TYPE_INCDEC:
587990286Sobrien      if (operands[2] == constm1_rtx)
588090286Sobrien        return "inc{l}\t%0";
588190286Sobrien      else if (operands[2] == const1_rtx)
588290286Sobrien        return "dec{l}\t%0";
588390286Sobrien      else
588490286Sobrien	abort();
588518334Speter
588690286Sobrien    default:
588790286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
588890286Sobrien	abort ();
588990286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
589090286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
589190286Sobrien      if ((INTVAL (operands[2]) == -128
589290286Sobrien	   || (INTVAL (operands[2]) > 0
589390286Sobrien	       && INTVAL (operands[2]) != 128)))
589490286Sobrien	return "sub{l}\t{%2, %0|%0, %2}";
589590286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
589690286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
589718334Speter    }
589890286Sobrien}
589990286Sobrien  [(set (attr "type")
590090286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
590190286Sobrien	(const_string "incdec")
590290286Sobrien	(const_string "alu")))
590390286Sobrien   (set_attr "mode" "SI")])
590418334Speter
590590286Sobrien(define_insn "*addsi_5"
590690286Sobrien  [(set (reg 17)
590790286Sobrien	(compare
590890286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
590990286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
591090286Sobrien	  (const_int 0)))			
591190286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
591290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
591390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
591490286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
591590286Sobrien      ought but a memory context.  */
591690286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
591790286Sobrien{
591890286Sobrien  switch (get_attr_type (insn))
591918334Speter    {
592090286Sobrien    case TYPE_INCDEC:
592190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
592290286Sobrien	abort ();
592390286Sobrien      if (operands[2] == const1_rtx)
592490286Sobrien        return "inc{l}\t%0";
592590286Sobrien      else if (operands[2] == constm1_rtx)
592690286Sobrien        return "dec{l}\t%0";
592790286Sobrien      else
592890286Sobrien	abort();
592990286Sobrien
593090286Sobrien    default:
593190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
593290286Sobrien	abort ();
593390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
593490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
593590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
593690286Sobrien          && (INTVAL (operands[2]) == 128
593790286Sobrien	      || (INTVAL (operands[2]) < 0
593890286Sobrien		  && INTVAL (operands[2]) != -128)))
593990286Sobrien        {
594090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
594190286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
594290286Sobrien        }
594390286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
594418334Speter    }
594590286Sobrien}
594690286Sobrien  [(set (attr "type")
594790286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
594890286Sobrien	(const_string "incdec")
594990286Sobrien	(const_string "alu")))
595090286Sobrien   (set_attr "mode" "SI")])
595118334Speter
595290286Sobrien(define_expand "addhi3"
595390286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
595490286Sobrien		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
595590286Sobrien			    (match_operand:HI 2 "general_operand" "")))
595690286Sobrien	      (clobber (reg:CC 17))])]
595790286Sobrien  "TARGET_HIMODE_MATH"
595890286Sobrien  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
595918334Speter
596090286Sobrien;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
596190286Sobrien;; type optimizations enabled by define-splits.  This is not important
596290286Sobrien;; for PII, and in fact harmful because of partial register stalls.
596318334Speter
596490286Sobrien(define_insn "*addhi_1_lea"
596590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
596690286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
596790286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
596890286Sobrien   (clobber (reg:CC 17))]
596990286Sobrien  "!TARGET_PARTIAL_REG_STALL
597090286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
597190286Sobrien{
597290286Sobrien  switch (get_attr_type (insn))
597390286Sobrien    {
597490286Sobrien    case TYPE_LEA:
597590286Sobrien      return "#";
597690286Sobrien    case TYPE_INCDEC:
597790286Sobrien      if (operands[2] == const1_rtx)
597890286Sobrien	return "inc{w}\t%0";
5979117404Skan      else if (operands[2] == constm1_rtx)
598090286Sobrien	return "dec{w}\t%0";
598190286Sobrien      abort();
598218334Speter
598390286Sobrien    default:
598490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
598590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
598690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
598790286Sobrien          && (INTVAL (operands[2]) == 128
598890286Sobrien	      || (INTVAL (operands[2]) < 0
598990286Sobrien		  && INTVAL (operands[2]) != -128)))
599090286Sobrien	{
599190286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
599290286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
599390286Sobrien	}
599490286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
599590286Sobrien    }
599690286Sobrien}
599790286Sobrien  [(set (attr "type")
599890286Sobrien     (if_then_else (eq_attr "alternative" "2")
599990286Sobrien	(const_string "lea")
600090286Sobrien	(if_then_else (match_operand:HI 2 "incdec_operand" "")
600190286Sobrien	   (const_string "incdec")
600290286Sobrien	   (const_string "alu"))))
600390286Sobrien   (set_attr "mode" "HI,HI,SI")])
600450650Sobrien
600590286Sobrien(define_insn "*addhi_1"
600690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
600790286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
600890286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
600990286Sobrien   (clobber (reg:CC 17))]
601090286Sobrien  "TARGET_PARTIAL_REG_STALL
601190286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
601218334Speter{
601390286Sobrien  switch (get_attr_type (insn))
601418334Speter    {
601590286Sobrien    case TYPE_INCDEC:
601690286Sobrien      if (operands[2] == const1_rtx)
601790286Sobrien	return "inc{w}\t%0";
6018117404Skan      else if (operands[2] == constm1_rtx)
601990286Sobrien	return "dec{w}\t%0";
602090286Sobrien      abort();
602118334Speter
602290286Sobrien    default:
602390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
602490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
602590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
602690286Sobrien          && (INTVAL (operands[2]) == 128
602790286Sobrien	      || (INTVAL (operands[2]) < 0
602890286Sobrien		  && INTVAL (operands[2]) != -128)))
602918334Speter	{
603090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
603190286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
603218334Speter	}
603390286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
603490286Sobrien    }
603590286Sobrien}
603690286Sobrien  [(set (attr "type")
603790286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
603890286Sobrien	(const_string "incdec")
603990286Sobrien	(const_string "alu")))
604090286Sobrien   (set_attr "mode" "HI")])
604118334Speter
604290286Sobrien(define_insn "*addhi_2"
604390286Sobrien  [(set (reg 17)
604490286Sobrien	(compare
604590286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
604690286Sobrien		   (match_operand:HI 2 "general_operand" "rmni,rni"))
604790286Sobrien	  (const_int 0)))			
604890286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
604990286Sobrien	(plus:HI (match_dup 1) (match_dup 2)))]
605090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
605190286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
605290286Sobrien{
605390286Sobrien  switch (get_attr_type (insn))
605490286Sobrien    {
605590286Sobrien    case TYPE_INCDEC:
605690286Sobrien      if (operands[2] == const1_rtx)
605790286Sobrien	return "inc{w}\t%0";
6058117404Skan      else if (operands[2] == constm1_rtx)
605990286Sobrien	return "dec{w}\t%0";
606090286Sobrien      abort();
606190286Sobrien
606290286Sobrien    default:
606390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
606490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
606590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
606690286Sobrien          && (INTVAL (operands[2]) == 128
606790286Sobrien	      || (INTVAL (operands[2]) < 0
606890286Sobrien		  && INTVAL (operands[2]) != -128)))
606918334Speter	{
607090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
607190286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
607218334Speter	}
607390286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
607418334Speter    }
607590286Sobrien}
607690286Sobrien  [(set (attr "type")
607790286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
607890286Sobrien	(const_string "incdec")
607990286Sobrien	(const_string "alu")))
608090286Sobrien   (set_attr "mode" "HI")])
608118334Speter
608290286Sobrien(define_insn "*addhi_3"
608390286Sobrien  [(set (reg 17)
608490286Sobrien	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
608590286Sobrien		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
608690286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
608790286Sobrien  "ix86_match_ccmode (insn, CCZmode)
608890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
608990286Sobrien{
609090286Sobrien  switch (get_attr_type (insn))
609190286Sobrien    {
609290286Sobrien    case TYPE_INCDEC:
609390286Sobrien      if (operands[2] == const1_rtx)
609490286Sobrien	return "inc{w}\t%0";
6095117404Skan      else if (operands[2] == constm1_rtx)
609690286Sobrien	return "dec{w}\t%0";
609790286Sobrien      abort();
609850650Sobrien
609990286Sobrien    default:
610090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
610190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
610290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
610390286Sobrien          && (INTVAL (operands[2]) == 128
610490286Sobrien	      || (INTVAL (operands[2]) < 0
610590286Sobrien		  && INTVAL (operands[2]) != -128)))
610690286Sobrien	{
610790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
610890286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
610990286Sobrien	}
611090286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
611190286Sobrien    }
611290286Sobrien}
611390286Sobrien  [(set (attr "type")
611490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
611590286Sobrien	(const_string "incdec")
611690286Sobrien	(const_string "alu")))
611790286Sobrien   (set_attr "mode" "HI")])
611818334Speter
611990286Sobrien; See comments above addsi_3_imm for details.
612090286Sobrien(define_insn "*addhi_4"
612190286Sobrien  [(set (reg 17)
612290286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
612390286Sobrien		 (match_operand:HI 2 "const_int_operand" "n")))
612490286Sobrien   (clobber (match_scratch:HI 0 "=rm"))]
612590286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
612690286Sobrien   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
612790286Sobrien{
612890286Sobrien  switch (get_attr_type (insn))
612990286Sobrien    {
613090286Sobrien    case TYPE_INCDEC:
6131117404Skan      if (operands[2] == constm1_rtx)
613290286Sobrien        return "inc{w}\t%0";
613390286Sobrien      else if (operands[2] == const1_rtx)
613490286Sobrien        return "dec{w}\t%0";
613590286Sobrien      else
613690286Sobrien	abort();
613718334Speter
613890286Sobrien    default:
613990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
614090286Sobrien	abort ();
614190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
614290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
614390286Sobrien      if ((INTVAL (operands[2]) == -128
614490286Sobrien	   || (INTVAL (operands[2]) > 0
614590286Sobrien	       && INTVAL (operands[2]) != 128)))
614690286Sobrien	return "sub{w}\t{%2, %0|%0, %2}";
614790286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
614890286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
614950650Sobrien    }
615090286Sobrien}
615190286Sobrien  [(set (attr "type")
615290286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
615390286Sobrien	(const_string "incdec")
615490286Sobrien	(const_string "alu")))
615590286Sobrien   (set_attr "mode" "SI")])
615650650Sobrien
615718334Speter
615890286Sobrien(define_insn "*addhi_5"
615990286Sobrien  [(set (reg 17)
616090286Sobrien	(compare
616190286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
616290286Sobrien		   (match_operand:HI 2 "general_operand" "rmni"))
616390286Sobrien	  (const_int 0)))			
616490286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
616590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
616690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
616750650Sobrien{
616890286Sobrien  switch (get_attr_type (insn))
616950650Sobrien    {
617090286Sobrien    case TYPE_INCDEC:
617190286Sobrien      if (operands[2] == const1_rtx)
617290286Sobrien	return "inc{w}\t%0";
6173117404Skan      else if (operands[2] == constm1_rtx)
617490286Sobrien	return "dec{w}\t%0";
617590286Sobrien      abort();
617650650Sobrien
617790286Sobrien    default:
617890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
617990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
618090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
618190286Sobrien          && (INTVAL (operands[2]) == 128
618290286Sobrien	      || (INTVAL (operands[2]) < 0
618390286Sobrien		  && INTVAL (operands[2]) != -128)))
618490286Sobrien	{
618590286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
618690286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
618790286Sobrien	}
618890286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
618950650Sobrien    }
619090286Sobrien}
619190286Sobrien  [(set (attr "type")
619290286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
619390286Sobrien	(const_string "incdec")
619490286Sobrien	(const_string "alu")))
619590286Sobrien   (set_attr "mode" "HI")])
619650650Sobrien
619790286Sobrien(define_expand "addqi3"
619890286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
619990286Sobrien		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
620090286Sobrien			    (match_operand:QI 2 "general_operand" "")))
620190286Sobrien	      (clobber (reg:CC 17))])]
620290286Sobrien  "TARGET_QIMODE_MATH"
620390286Sobrien  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
620450650Sobrien
620590286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
620690286Sobrien(define_insn "*addqi_1_lea"
620790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
620890286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
620990286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
621090286Sobrien   (clobber (reg:CC 17))]
621190286Sobrien  "!TARGET_PARTIAL_REG_STALL
621290286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
621390286Sobrien{
621490286Sobrien  int widen = (which_alternative == 2);
621590286Sobrien  switch (get_attr_type (insn))
621690286Sobrien    {
621790286Sobrien    case TYPE_LEA:
621890286Sobrien      return "#";
621990286Sobrien    case TYPE_INCDEC:
622090286Sobrien      if (operands[2] == const1_rtx)
622190286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222117404Skan      else if (operands[2] == constm1_rtx)
622390286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
622490286Sobrien      abort();
622518334Speter
622690286Sobrien    default:
622790286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
622890286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
622990286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
623090286Sobrien          && (INTVAL (operands[2]) == 128
623190286Sobrien	      || (INTVAL (operands[2]) < 0
623290286Sobrien		  && INTVAL (operands[2]) != -128)))
623390286Sobrien	{
623490286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
623590286Sobrien	  if (widen)
623690286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
623790286Sobrien	  else
623890286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
623990286Sobrien	}
624090286Sobrien      if (widen)
624190286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
624290286Sobrien      else
624390286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
624490286Sobrien    }
624590286Sobrien}
624690286Sobrien  [(set (attr "type")
624790286Sobrien     (if_then_else (eq_attr "alternative" "3")
624890286Sobrien	(const_string "lea")
624990286Sobrien	(if_then_else (match_operand:QI 2 "incdec_operand" "")
625090286Sobrien	   (const_string "incdec")
625190286Sobrien	   (const_string "alu"))))
625290286Sobrien   (set_attr "mode" "QI,QI,SI,SI")])
625350650Sobrien
625490286Sobrien(define_insn "*addqi_1"
625590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
625690286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
625790286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
625890286Sobrien   (clobber (reg:CC 17))]
625990286Sobrien  "TARGET_PARTIAL_REG_STALL
626090286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
626118334Speter{
626290286Sobrien  int widen = (which_alternative == 2);
626390286Sobrien  switch (get_attr_type (insn))
626452296Sobrien    {
626590286Sobrien    case TYPE_INCDEC:
626690286Sobrien      if (operands[2] == const1_rtx)
626790286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268117404Skan      else if (operands[2] == constm1_rtx)
626990286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
627090286Sobrien      abort();
627152296Sobrien
627290286Sobrien    default:
627390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
627490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
627590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
627690286Sobrien          && (INTVAL (operands[2]) == 128
627790286Sobrien	      || (INTVAL (operands[2]) < 0
627890286Sobrien		  && INTVAL (operands[2]) != -128)))
627990286Sobrien	{
628090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
628190286Sobrien	  if (widen)
628290286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
628390286Sobrien	  else
628490286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
628590286Sobrien	}
628690286Sobrien      if (widen)
628790286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
628890286Sobrien      else
628990286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
629052296Sobrien    }
629190286Sobrien}
629290286Sobrien  [(set (attr "type")
629390286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
629490286Sobrien	(const_string "incdec")
629590286Sobrien	(const_string "alu")))
629690286Sobrien   (set_attr "mode" "QI,QI,SI")])
629752296Sobrien
6298117404Skan(define_insn "*addqi_1_slp"
6299117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6300117404Skan	(plus:QI (match_dup 0)
6301117404Skan		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6302117404Skan   (clobber (reg:CC 17))]
6303117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6304117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6305117404Skan{
6306117404Skan  switch (get_attr_type (insn))
6307117404Skan    {
6308117404Skan    case TYPE_INCDEC:
6309117404Skan      if (operands[1] == const1_rtx)
6310117404Skan	return "inc{b}\t%0";
6311117404Skan      else if (operands[1] == constm1_rtx)
6312117404Skan	return "dec{b}\t%0";
6313117404Skan      abort();
6314117404Skan
6315117404Skan    default:
6316117404Skan      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6317117404Skan      if (GET_CODE (operands[1]) == CONST_INT
6318117404Skan	  && INTVAL (operands[1]) < 0)
6319117404Skan	{
6320132727Skan	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6321117404Skan	  return "sub{b}\t{%1, %0|%0, %1}";
6322117404Skan	}
6323117404Skan      return "add{b}\t{%1, %0|%0, %1}";
6324117404Skan    }
6325117404Skan}
6326117404Skan  [(set (attr "type")
6327146906Skan     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6328117404Skan	(const_string "incdec")
6329117404Skan	(const_string "alu1")))
6330146906Skan   (set (attr "memory")
6331146906Skan     (if_then_else (match_operand 1 "memory_operand" "")
6332146906Skan        (const_string "load")
6333146906Skan        (const_string "none")))
6334117404Skan   (set_attr "mode" "QI")])
6335117404Skan
633690286Sobrien(define_insn "*addqi_2"
633790286Sobrien  [(set (reg 17)
633890286Sobrien	(compare
633990286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
634090286Sobrien		   (match_operand:QI 2 "general_operand" "qmni,qni"))
634190286Sobrien	  (const_int 0)))
634290286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
634390286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
634490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
634590286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
634690286Sobrien{
634790286Sobrien  switch (get_attr_type (insn))
634818334Speter    {
634990286Sobrien    case TYPE_INCDEC:
635090286Sobrien      if (operands[2] == const1_rtx)
635190286Sobrien	return "inc{b}\t%0";
635290286Sobrien      else if (operands[2] == constm1_rtx
635390286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
635490286Sobrien		   && INTVAL (operands[2]) == 255))
635590286Sobrien	return "dec{b}\t%0";
635690286Sobrien      abort();
635718334Speter
635890286Sobrien    default:
635990286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
636090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
636190286Sobrien          && INTVAL (operands[2]) < 0)
636290286Sobrien	{
636390286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
636490286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
636590286Sobrien	}
636690286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
636718334Speter    }
636890286Sobrien}
636990286Sobrien  [(set (attr "type")
637090286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
637190286Sobrien	(const_string "incdec")
637290286Sobrien	(const_string "alu")))
637390286Sobrien   (set_attr "mode" "QI")])
637418334Speter
637590286Sobrien(define_insn "*addqi_3"
637690286Sobrien  [(set (reg 17)
637790286Sobrien	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
637890286Sobrien		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
637990286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
638090286Sobrien  "ix86_match_ccmode (insn, CCZmode)
638190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
638290286Sobrien{
638390286Sobrien  switch (get_attr_type (insn))
638450650Sobrien    {
638590286Sobrien    case TYPE_INCDEC:
638690286Sobrien      if (operands[2] == const1_rtx)
638790286Sobrien	return "inc{b}\t%0";
638890286Sobrien      else if (operands[2] == constm1_rtx
638990286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
639090286Sobrien		   && INTVAL (operands[2]) == 255))
639190286Sobrien	return "dec{b}\t%0";
639290286Sobrien      abort();
639350650Sobrien
639490286Sobrien    default:
639590286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
639690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
639790286Sobrien          && INTVAL (operands[2]) < 0)
639850650Sobrien	{
639990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
640090286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
640190286Sobrien	}
640290286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
640390286Sobrien    }
640490286Sobrien}
640590286Sobrien  [(set (attr "type")
640690286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
640790286Sobrien	(const_string "incdec")
640890286Sobrien	(const_string "alu")))
640990286Sobrien   (set_attr "mode" "QI")])
641050650Sobrien
641190286Sobrien; See comments above addsi_3_imm for details.
641290286Sobrien(define_insn "*addqi_4"
641390286Sobrien  [(set (reg 17)
641490286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
641590286Sobrien		 (match_operand:QI 2 "const_int_operand" "n")))
641690286Sobrien   (clobber (match_scratch:QI 0 "=qm"))]
641790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
641890286Sobrien   && (INTVAL (operands[2]) & 0xff) != 0x80"
641990286Sobrien{
642090286Sobrien  switch (get_attr_type (insn))
642190286Sobrien    {
642290286Sobrien    case TYPE_INCDEC:
642390286Sobrien      if (operands[2] == constm1_rtx
642490286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
642590286Sobrien	      && INTVAL (operands[2]) == 255))
642690286Sobrien        return "inc{b}\t%0";
642790286Sobrien      else if (operands[2] == const1_rtx)
642890286Sobrien        return "dec{b}\t%0";
642990286Sobrien      else
643090286Sobrien	abort();
643150650Sobrien
643290286Sobrien    default:
643390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
643490286Sobrien	abort ();
643590286Sobrien      if (INTVAL (operands[2]) < 0)
643690286Sobrien        {
643790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
643890286Sobrien          return "add{b}\t{%2, %0|%0, %2}";
643990286Sobrien        }
644090286Sobrien      return "sub{b}\t{%2, %0|%0, %2}";
644150650Sobrien    }
644290286Sobrien}
644390286Sobrien  [(set (attr "type")
644490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
644590286Sobrien	(const_string "incdec")
644690286Sobrien	(const_string "alu")))
644790286Sobrien   (set_attr "mode" "QI")])
644850650Sobrien
644918334Speter
645090286Sobrien(define_insn "*addqi_5"
645190286Sobrien  [(set (reg 17)
645290286Sobrien	(compare
645390286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
645490286Sobrien		   (match_operand:QI 2 "general_operand" "qmni"))
645590286Sobrien	  (const_int 0)))
645690286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
645790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
645890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
645990286Sobrien{
646090286Sobrien  switch (get_attr_type (insn))
646190286Sobrien    {
646290286Sobrien    case TYPE_INCDEC:
646390286Sobrien      if (operands[2] == const1_rtx)
646490286Sobrien	return "inc{b}\t%0";
646590286Sobrien      else if (operands[2] == constm1_rtx
646690286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
646790286Sobrien		   && INTVAL (operands[2]) == 255))
646890286Sobrien	return "dec{b}\t%0";
646990286Sobrien      abort();
647018334Speter
647190286Sobrien    default:
647290286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
647390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
647490286Sobrien          && INTVAL (operands[2]) < 0)
647590286Sobrien	{
647690286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
647790286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
647890286Sobrien	}
647990286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
648090286Sobrien    }
648190286Sobrien}
648290286Sobrien  [(set (attr "type")
648390286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
648490286Sobrien	(const_string "incdec")
648590286Sobrien	(const_string "alu")))
648690286Sobrien   (set_attr "mode" "QI")])
648718334Speter
648850650Sobrien
648990286Sobrien(define_insn "addqi_ext_1"
649090286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
649190286Sobrien			 (const_int 8)
649290286Sobrien			 (const_int 8))
649390286Sobrien	(plus:SI
649490286Sobrien	  (zero_extract:SI
649590286Sobrien	    (match_operand 1 "ext_register_operand" "0")
649690286Sobrien	    (const_int 8)
649790286Sobrien	    (const_int 8))
649890286Sobrien	  (match_operand:QI 2 "general_operand" "Qmn")))
649990286Sobrien   (clobber (reg:CC 17))]
650090286Sobrien  "!TARGET_64BIT"
650118334Speter{
650290286Sobrien  switch (get_attr_type (insn))
650352296Sobrien    {
650490286Sobrien    case TYPE_INCDEC:
650590286Sobrien      if (operands[2] == const1_rtx)
650690286Sobrien	return "inc{b}\t%h0";
650790286Sobrien      else if (operands[2] == constm1_rtx
650890286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
650990286Sobrien		   && INTVAL (operands[2]) == 255))
651090286Sobrien	return "dec{b}\t%h0";
651190286Sobrien      abort();
651252296Sobrien
651390286Sobrien    default:
651490286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
651552296Sobrien    }
651690286Sobrien}
651790286Sobrien  [(set (attr "type")
651890286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
651990286Sobrien	(const_string "incdec")
652090286Sobrien	(const_string "alu")))
652190286Sobrien   (set_attr "mode" "QI")])
652218334Speter
652390286Sobrien(define_insn "*addqi_ext_1_rex64"
652490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
652590286Sobrien			 (const_int 8)
652690286Sobrien			 (const_int 8))
652790286Sobrien	(plus:SI
652890286Sobrien	  (zero_extract:SI
652990286Sobrien	    (match_operand 1 "ext_register_operand" "0")
653090286Sobrien	    (const_int 8)
653190286Sobrien	    (const_int 8))
653290286Sobrien	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
653390286Sobrien   (clobber (reg:CC 17))]
653490286Sobrien  "TARGET_64BIT"
653590286Sobrien{
653690286Sobrien  switch (get_attr_type (insn))
653790286Sobrien    {
653890286Sobrien    case TYPE_INCDEC:
653990286Sobrien      if (operands[2] == const1_rtx)
654090286Sobrien	return "inc{b}\t%h0";
654190286Sobrien      else if (operands[2] == constm1_rtx
654290286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
654390286Sobrien		   && INTVAL (operands[2]) == 255))
654490286Sobrien	return "dec{b}\t%h0";
654590286Sobrien      abort();
654618334Speter
654790286Sobrien    default:
654890286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
654990286Sobrien    }
655090286Sobrien}
655190286Sobrien  [(set (attr "type")
655290286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
655390286Sobrien	(const_string "incdec")
655490286Sobrien	(const_string "alu")))
655590286Sobrien   (set_attr "mode" "QI")])
655618334Speter
655790286Sobrien(define_insn "*addqi_ext_2"
655890286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
655990286Sobrien			 (const_int 8)
656090286Sobrien			 (const_int 8))
656190286Sobrien	(plus:SI
656290286Sobrien	  (zero_extract:SI
656390286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
656490286Sobrien	    (const_int 8)
656590286Sobrien	    (const_int 8))
656690286Sobrien	  (zero_extract:SI
656790286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
656890286Sobrien	    (const_int 8)
656990286Sobrien	    (const_int 8))))
657090286Sobrien   (clobber (reg:CC 17))]
657190286Sobrien  ""
657290286Sobrien  "add{b}\t{%h2, %h0|%h0, %h2}"
657390286Sobrien  [(set_attr "type" "alu")
657490286Sobrien   (set_attr "mode" "QI")])
657518334Speter
657618334Speter;; The patterns that match these are at the end of this file.
657718334Speter
657818334Speter(define_expand "addxf3"
657918334Speter  [(set (match_operand:XF 0 "register_operand" "")
658050650Sobrien	(plus:XF (match_operand:XF 1 "register_operand" "")
658150650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
658218334Speter  "TARGET_80387"
658318334Speter  "")
658418334Speter
658518334Speter(define_expand "adddf3"
658618334Speter  [(set (match_operand:DF 0 "register_operand" "")
658790286Sobrien	(plus:DF (match_operand:DF 1 "register_operand" "")
658818334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
658990286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
659018334Speter  "")
659118334Speter
659218334Speter(define_expand "addsf3"
659318334Speter  [(set (match_operand:SF 0 "register_operand" "")
659490286Sobrien	(plus:SF (match_operand:SF 1 "register_operand" "")
659518334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
659690286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
659718334Speter  "")
659818334Speter
659990286Sobrien;; Subtract instructions
660018334Speter
660190286Sobrien;; %%% splits for subsidi3
660250650Sobrien
660390286Sobrien(define_expand "subdi3"
660490286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
660590286Sobrien		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
660690286Sobrien			     (match_operand:DI 2 "x86_64_general_operand" "")))
660790286Sobrien	      (clobber (reg:CC 17))])]
660818334Speter  ""
660990286Sobrien  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
661018334Speter
661190286Sobrien(define_insn "*subdi3_1"
661290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
661390286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
661490286Sobrien		  (match_operand:DI 2 "general_operand" "roiF,riF")))
661590286Sobrien   (clobber (reg:CC 17))]
6616107605Sobrien  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
661790286Sobrien  "#")
661818334Speter
661990286Sobrien(define_split
662090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
662190286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
662290286Sobrien		  (match_operand:DI 2 "general_operand" "")))
662390286Sobrien   (clobber (reg:CC 17))]
662490286Sobrien  "!TARGET_64BIT && reload_completed"
662590286Sobrien  [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
662690286Sobrien	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
662790286Sobrien   (parallel [(set (match_dup 3)
662890286Sobrien		   (minus:SI (match_dup 4)
662990286Sobrien			     (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
663090286Sobrien				      (match_dup 5))))
663190286Sobrien	      (clobber (reg:CC 17))])]
663290286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
663390286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
663490286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
663518334Speter
663690286Sobrien(define_insn "subdi3_carry_rex64"
663790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
663890286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6639132727Skan	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
664090286Sobrien	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
664190286Sobrien   (clobber (reg:CC 17))]
664290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
664390286Sobrien  "sbb{q}\t{%2, %0|%0, %2}"
664490286Sobrien  [(set_attr "type" "alu")
664590286Sobrien   (set_attr "pent_pair" "pu")
664690286Sobrien   (set_attr "ppro_uops" "few")
664790286Sobrien   (set_attr "mode" "DI")])
664818334Speter
664990286Sobrien(define_insn "*subdi_1_rex64"
665090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
665190286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
665290286Sobrien		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
665390286Sobrien   (clobber (reg:CC 17))]
665490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
665590286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
665690286Sobrien  [(set_attr "type" "alu")
665790286Sobrien   (set_attr "mode" "DI")])
665818334Speter
665990286Sobrien(define_insn "*subdi_2_rex64"
666090286Sobrien  [(set (reg 17)
666190286Sobrien	(compare
666290286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
666390286Sobrien		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
666490286Sobrien	  (const_int 0)))
666590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
666690286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
666790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
666890286Sobrien   && ix86_binary_operator_ok (MINUS, DImode, operands)"
666990286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
667090286Sobrien  [(set_attr "type" "alu")
667190286Sobrien   (set_attr "mode" "DI")])
667252296Sobrien
667390286Sobrien(define_insn "*subdi_3_rex63"
667490286Sobrien  [(set (reg 17)
667590286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
667690286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
667790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
667890286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
667990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
668090286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
668190286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
668290286Sobrien  [(set_attr "type" "alu")
668390286Sobrien   (set_attr "mode" "DI")])
668418334Speter
6685132727Skan(define_insn "subqi3_carry"
6686132727Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6687132727Skan	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6688132727Skan	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6689132727Skan	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6690132727Skan   (clobber (reg:CC 17))]
6691132727Skan  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6692132727Skan  "sbb{b}\t{%2, %0|%0, %2}"
6693132727Skan  [(set_attr "type" "alu")
6694132727Skan   (set_attr "pent_pair" "pu")
6695132727Skan   (set_attr "ppro_uops" "few")
6696132727Skan   (set_attr "mode" "QI")])
669718334Speter
6698132727Skan(define_insn "subhi3_carry"
6699132727Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6700132727Skan	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6701132727Skan	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6702132727Skan	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6703132727Skan   (clobber (reg:CC 17))]
6704132727Skan  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6705132727Skan  "sbb{w}\t{%2, %0|%0, %2}"
6706132727Skan  [(set_attr "type" "alu")
6707132727Skan   (set_attr "pent_pair" "pu")
6708132727Skan   (set_attr "ppro_uops" "few")
6709132727Skan   (set_attr "mode" "HI")])
6710132727Skan
671190286Sobrien(define_insn "subsi3_carry"
671290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
671390286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714132727Skan	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
671590286Sobrien	       (match_operand:SI 2 "general_operand" "ri,rm"))))
671690286Sobrien   (clobber (reg:CC 17))]
671790286Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
671890286Sobrien  "sbb{l}\t{%2, %0|%0, %2}"
671990286Sobrien  [(set_attr "type" "alu")
672090286Sobrien   (set_attr "pent_pair" "pu")
672190286Sobrien   (set_attr "ppro_uops" "few")
672290286Sobrien   (set_attr "mode" "SI")])
672318334Speter
672490286Sobrien(define_insn "subsi3_carry_zext"
672590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm,r")
672690286Sobrien	  (zero_extend:DI
672790286Sobrien	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6728132727Skan	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
672990286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))))
673090286Sobrien   (clobber (reg:CC 17))]
673190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
673290286Sobrien  "sbb{l}\t{%2, %k0|%k0, %2}"
673390286Sobrien  [(set_attr "type" "alu")
673490286Sobrien   (set_attr "pent_pair" "pu")
673590286Sobrien   (set_attr "ppro_uops" "few")
673690286Sobrien   (set_attr "mode" "SI")])
673718334Speter
673850650Sobrien(define_expand "subsi3"
673990286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
674090286Sobrien		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
674190286Sobrien			     (match_operand:SI 2 "general_operand" "")))
674290286Sobrien	      (clobber (reg:CC 17))])]
674350650Sobrien  ""
674490286Sobrien  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
674550650Sobrien
674690286Sobrien(define_insn "*subsi_1"
674750650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
674850650Sobrien	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
674990286Sobrien		  (match_operand:SI 2 "general_operand" "ri,rm")))
675090286Sobrien   (clobber (reg:CC 17))]
675150650Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
675290286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
675390286Sobrien  [(set_attr "type" "alu")
675490286Sobrien   (set_attr "mode" "SI")])
675518334Speter
675690286Sobrien(define_insn "*subsi_1_zext"
675790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
675890286Sobrien	(zero_extend:DI
675990286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
676090286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))))
676190286Sobrien   (clobber (reg:CC 17))]
676290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
676390286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
676490286Sobrien  [(set_attr "type" "alu")
676590286Sobrien   (set_attr "mode" "SI")])
676690286Sobrien
676790286Sobrien(define_insn "*subsi_2"
676890286Sobrien  [(set (reg 17)
676990286Sobrien	(compare
677090286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
677190286Sobrien		    (match_operand:SI 2 "general_operand" "ri,rm"))
677290286Sobrien	  (const_int 0)))
677390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
677490286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
677590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
677690286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
677790286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
677890286Sobrien  [(set_attr "type" "alu")
677990286Sobrien   (set_attr "mode" "SI")])
678090286Sobrien
678190286Sobrien(define_insn "*subsi_2_zext"
678290286Sobrien  [(set (reg 17)
678390286Sobrien	(compare
678490286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
678590286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))
678690286Sobrien	  (const_int 0)))
678790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
678890286Sobrien	(zero_extend:DI
678990286Sobrien	  (minus:SI (match_dup 1)
679090286Sobrien		    (match_dup 2))))]
679190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
679290286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
679390286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
679490286Sobrien  [(set_attr "type" "alu")
679590286Sobrien   (set_attr "mode" "SI")])
679690286Sobrien
679790286Sobrien(define_insn "*subsi_3"
679890286Sobrien  [(set (reg 17)
679990286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
680090286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))
680190286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
680290286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
680390286Sobrien  "ix86_match_ccmode (insn, CCmode)
680490286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
680590286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
680690286Sobrien  [(set_attr "type" "alu")
680790286Sobrien   (set_attr "mode" "SI")])
680890286Sobrien
680990286Sobrien(define_insn "*subsi_3_zext"
681090286Sobrien  [(set (reg 17)
6811132727Skan	(compare (match_operand:SI 1 "register_operand" "0")
681290286Sobrien		 (match_operand:SI 2 "general_operand" "rim")))
681390286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
681490286Sobrien	(zero_extend:DI
681590286Sobrien	  (minus:SI (match_dup 1)
681690286Sobrien		    (match_dup 2))))]
681790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
681890286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
681990286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
682090286Sobrien  [(set_attr "type" "alu")
682190286Sobrien   (set_attr "mode" "DI")])
682290286Sobrien
682350650Sobrien(define_expand "subhi3"
682490286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
682590286Sobrien		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
682690286Sobrien			     (match_operand:HI 2 "general_operand" "")))
682790286Sobrien	      (clobber (reg:CC 17))])]
682890286Sobrien  "TARGET_HIMODE_MATH"
682990286Sobrien  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
683050650Sobrien
683190286Sobrien(define_insn "*subhi_1"
683250650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
683350650Sobrien	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
683490286Sobrien		  (match_operand:HI 2 "general_operand" "ri,rm")))
683590286Sobrien   (clobber (reg:CC 17))]
683650650Sobrien  "ix86_binary_operator_ok (MINUS, HImode, operands)"
683790286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
683890286Sobrien  [(set_attr "type" "alu")
683990286Sobrien   (set_attr "mode" "HI")])
684050650Sobrien
684190286Sobrien(define_insn "*subhi_2"
684290286Sobrien  [(set (reg 17)
684390286Sobrien	(compare
684490286Sobrien	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
684590286Sobrien		    (match_operand:HI 2 "general_operand" "ri,rm"))
684690286Sobrien	  (const_int 0)))
684790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
684890286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
684990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
685090286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
685190286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
685290286Sobrien  [(set_attr "type" "alu")
685390286Sobrien   (set_attr "mode" "HI")])
685490286Sobrien
685590286Sobrien(define_insn "*subhi_3"
685690286Sobrien  [(set (reg 17)
685790286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
685890286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
685990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
686090286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
686190286Sobrien  "ix86_match_ccmode (insn, CCmode)
686290286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
686390286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
686490286Sobrien  [(set_attr "type" "alu")
686590286Sobrien   (set_attr "mode" "HI")])
686690286Sobrien
686750650Sobrien(define_expand "subqi3"
686890286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
686990286Sobrien		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
687090286Sobrien			     (match_operand:QI 2 "general_operand" "")))
687190286Sobrien	      (clobber (reg:CC 17))])]
687290286Sobrien  "TARGET_QIMODE_MATH"
687390286Sobrien  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
687418334Speter
687590286Sobrien(define_insn "*subqi_1"
687650650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
687750650Sobrien	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
687890286Sobrien		  (match_operand:QI 2 "general_operand" "qn,qmn")))
687990286Sobrien   (clobber (reg:CC 17))]
688050650Sobrien  "ix86_binary_operator_ok (MINUS, QImode, operands)"
688190286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
688290286Sobrien  [(set_attr "type" "alu")
688390286Sobrien   (set_attr "mode" "QI")])
688418334Speter
6885117404Skan(define_insn "*subqi_1_slp"
6886117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6887117404Skan	(minus:QI (match_dup 0)
6888117404Skan		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6889117404Skan   (clobber (reg:CC 17))]
6890117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6891117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6892117404Skan  "sub{b}\t{%1, %0|%0, %1}"
6893117404Skan  [(set_attr "type" "alu1")
6894117404Skan   (set_attr "mode" "QI")])
6895117404Skan
689690286Sobrien(define_insn "*subqi_2"
689790286Sobrien  [(set (reg 17)
689890286Sobrien	(compare
689990286Sobrien	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
690090286Sobrien		    (match_operand:QI 2 "general_operand" "qi,qm"))
690190286Sobrien	  (const_int 0)))
690290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
690390286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
690490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
690590286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
690690286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
690790286Sobrien  [(set_attr "type" "alu")
690890286Sobrien   (set_attr "mode" "QI")])
690990286Sobrien
691090286Sobrien(define_insn "*subqi_3"
691190286Sobrien  [(set (reg 17)
691290286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
691390286Sobrien		 (match_operand:QI 2 "general_operand" "qi,qm")))
691490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
691590286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
691690286Sobrien  "ix86_match_ccmode (insn, CCmode)
691790286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
691890286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
691990286Sobrien  [(set_attr "type" "alu")
692090286Sobrien   (set_attr "mode" "QI")])
692190286Sobrien
692218334Speter;; The patterns that match these are at the end of this file.
692318334Speter
692418334Speter(define_expand "subxf3"
692518334Speter  [(set (match_operand:XF 0 "register_operand" "")
692650650Sobrien	(minus:XF (match_operand:XF 1 "register_operand" "")
692750650Sobrien		  (match_operand:XF 2 "register_operand" "")))]
692818334Speter  "TARGET_80387"
692918334Speter  "")
693018334Speter
693118334Speter(define_expand "subdf3"
693218334Speter  [(set (match_operand:DF 0 "register_operand" "")
693390286Sobrien	(minus:DF (match_operand:DF 1 "register_operand" "")
693418334Speter		  (match_operand:DF 2 "nonimmediate_operand" "")))]
693590286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
693618334Speter  "")
693718334Speter
693818334Speter(define_expand "subsf3"
693918334Speter  [(set (match_operand:SF 0 "register_operand" "")
694090286Sobrien	(minus:SF (match_operand:SF 1 "register_operand" "")
694118334Speter		  (match_operand:SF 2 "nonimmediate_operand" "")))]
694290286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
694318334Speter  "")
694418334Speter
694590286Sobrien;; Multiply instructions
694618334Speter
694790286Sobrien(define_expand "muldi3"
694890286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
694990286Sobrien		   (mult:DI (match_operand:DI 1 "register_operand" "")
695090286Sobrien			    (match_operand:DI 2 "x86_64_general_operand" "")))
695190286Sobrien	      (clobber (reg:CC 17))])]
695290286Sobrien  "TARGET_64BIT"
695390286Sobrien  "")
695418334Speter
695590286Sobrien(define_insn "*muldi3_1_rex64"
695690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957132727Skan	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
695890286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
695990286Sobrien   (clobber (reg:CC 17))]
696090286Sobrien  "TARGET_64BIT
696190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
696290286Sobrien  "@
696390286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
696490286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
696590286Sobrien   imul{q}\t{%2, %0|%0, %2}"
696690286Sobrien  [(set_attr "type" "imul")
696790286Sobrien   (set_attr "prefix_0f" "0,0,1")
6968132727Skan   (set (attr "athlon_decode")
6969132727Skan	(cond [(eq_attr "cpu" "athlon")
6970132727Skan		  (const_string "vector")
6971132727Skan	       (eq_attr "alternative" "1")
6972132727Skan		  (const_string "vector")
6973132727Skan	       (and (eq_attr "alternative" "2")
6974132727Skan		    (match_operand 1 "memory_operand" ""))
6975132727Skan		  (const_string "vector")]
6976132727Skan	      (const_string "direct")))
697790286Sobrien   (set_attr "mode" "DI")])
697818334Speter
697990286Sobrien(define_expand "mulsi3"
698090286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
698190286Sobrien		   (mult:SI (match_operand:SI 1 "register_operand" "")
698290286Sobrien			    (match_operand:SI 2 "general_operand" "")))
698390286Sobrien	      (clobber (reg:CC 17))])]
698418334Speter  ""
698590286Sobrien  "")
698618334Speter
698790286Sobrien(define_insn "*mulsi3_1"
698890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6989132727Skan	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
699090286Sobrien		 (match_operand:SI 2 "general_operand" "K,i,mr")))
699190286Sobrien   (clobber (reg:CC 17))]
699290286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
699390286Sobrien  "@
699490286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
699590286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
699690286Sobrien   imul{l}\t{%2, %0|%0, %2}"
699790286Sobrien  [(set_attr "type" "imul")
699890286Sobrien   (set_attr "prefix_0f" "0,0,1")
6999132727Skan   (set (attr "athlon_decode")
7000132727Skan	(cond [(eq_attr "cpu" "athlon")
7001132727Skan		  (const_string "vector")
7002132727Skan	       (eq_attr "alternative" "1")
7003132727Skan		  (const_string "vector")
7004132727Skan	       (and (eq_attr "alternative" "2")
7005132727Skan		    (match_operand 1 "memory_operand" ""))
7006132727Skan		  (const_string "vector")]
7007132727Skan	      (const_string "direct")))
700890286Sobrien   (set_attr "mode" "SI")])
700990286Sobrien
701090286Sobrien(define_insn "*mulsi3_1_zext"
701190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
701290286Sobrien	(zero_extend:DI
7013132727Skan	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
701490286Sobrien		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
701590286Sobrien   (clobber (reg:CC 17))]
701690286Sobrien  "TARGET_64BIT
701790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
701890286Sobrien  "@
701990286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
702090286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
702190286Sobrien   imul{l}\t{%2, %k0|%k0, %2}"
702290286Sobrien  [(set_attr "type" "imul")
702390286Sobrien   (set_attr "prefix_0f" "0,0,1")
7024132727Skan   (set (attr "athlon_decode")
7025132727Skan	(cond [(eq_attr "cpu" "athlon")
7026132727Skan		  (const_string "vector")
7027132727Skan	       (eq_attr "alternative" "1")
7028132727Skan		  (const_string "vector")
7029132727Skan	       (and (eq_attr "alternative" "2")
7030132727Skan		    (match_operand 1 "memory_operand" ""))
7031132727Skan		  (const_string "vector")]
7032132727Skan	      (const_string "direct")))
703390286Sobrien   (set_attr "mode" "SI")])
703490286Sobrien
703590286Sobrien(define_expand "mulhi3"
703690286Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
703790286Sobrien		   (mult:HI (match_operand:HI 1 "register_operand" "")
703890286Sobrien			    (match_operand:HI 2 "general_operand" "")))
703990286Sobrien	      (clobber (reg:CC 17))])]
704090286Sobrien  "TARGET_HIMODE_MATH"
704190286Sobrien  "")
704290286Sobrien
704390286Sobrien(define_insn "*mulhi3_1"
704490286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7045132727Skan	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
704690286Sobrien		 (match_operand:HI 2 "general_operand" "K,i,mr")))
704790286Sobrien   (clobber (reg:CC 17))]
704890286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
704990286Sobrien  "@
705090286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
705190286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
705290286Sobrien   imul{w}\t{%2, %0|%0, %2}"
705390286Sobrien  [(set_attr "type" "imul")
705490286Sobrien   (set_attr "prefix_0f" "0,0,1")
7055132727Skan   (set (attr "athlon_decode")
7056132727Skan	(cond [(eq_attr "cpu" "athlon")
7057132727Skan		  (const_string "vector")
7058132727Skan	       (eq_attr "alternative" "1,2")
7059132727Skan		  (const_string "vector")]
7060132727Skan	      (const_string "direct")))
706190286Sobrien   (set_attr "mode" "HI")])
706290286Sobrien
706396294Sobrien(define_expand "mulqi3"
706496294Sobrien  [(parallel [(set (match_operand:QI 0 "register_operand" "")
706596294Sobrien		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
706696294Sobrien			    (match_operand:QI 2 "register_operand" "")))
706796294Sobrien	      (clobber (reg:CC 17))])]
706896294Sobrien  "TARGET_QIMODE_MATH"
706996294Sobrien  "")
707096294Sobrien
707196294Sobrien(define_insn "*mulqi3_1"
707290286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
707396294Sobrien	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
707490286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
707590286Sobrien   (clobber (reg:CC 17))]
707696294Sobrien  "TARGET_QIMODE_MATH
707796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
707890286Sobrien  "mul{b}\t%2"
707990286Sobrien  [(set_attr "type" "imul")
708090286Sobrien   (set_attr "length_immediate" "0")
7081132727Skan   (set (attr "athlon_decode")
7082132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7083132727Skan        (const_string "vector")
7084132727Skan        (const_string "direct")))
708590286Sobrien   (set_attr "mode" "QI")])
708690286Sobrien
708796294Sobrien(define_expand "umulqihi3"
708896294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
708996294Sobrien		   (mult:HI (zero_extend:HI
709096294Sobrien			      (match_operand:QI 1 "nonimmediate_operand" ""))
709196294Sobrien			    (zero_extend:HI
709296294Sobrien			      (match_operand:QI 2 "register_operand" ""))))
709396294Sobrien	      (clobber (reg:CC 17))])]
709496294Sobrien  "TARGET_QIMODE_MATH"
709596294Sobrien  "")
709696294Sobrien
709796294Sobrien(define_insn "*umulqihi3_1"
709850650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
709996294Sobrien	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
710090286Sobrien		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
710190286Sobrien   (clobber (reg:CC 17))]
710296294Sobrien  "TARGET_QIMODE_MATH
710396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
710490286Sobrien  "mul{b}\t%2"
710590286Sobrien  [(set_attr "type" "imul")
710690286Sobrien   (set_attr "length_immediate" "0")
7107132727Skan   (set (attr "athlon_decode")
7108132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7109132727Skan        (const_string "vector")
7110132727Skan        (const_string "direct")))
711190286Sobrien   (set_attr "mode" "QI")])
711218334Speter
711396294Sobrien(define_expand "mulqihi3"
711496294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
711596294Sobrien		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
711696294Sobrien			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
711796294Sobrien	      (clobber (reg:CC 17))])]
711896294Sobrien  "TARGET_QIMODE_MATH"
711996294Sobrien  "")
712096294Sobrien
712196294Sobrien(define_insn "*mulqihi3_insn"
712250650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
712396294Sobrien	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
712490286Sobrien		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
712590286Sobrien   (clobber (reg:CC 17))]
712696294Sobrien  "TARGET_QIMODE_MATH
712796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
712890286Sobrien  "imul{b}\t%2"
712990286Sobrien  [(set_attr "type" "imul")
713090286Sobrien   (set_attr "length_immediate" "0")
7131132727Skan   (set (attr "athlon_decode")
7132132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7133132727Skan        (const_string "vector")
7134132727Skan        (const_string "direct")))
713590286Sobrien   (set_attr "mode" "QI")])
713618334Speter
713796294Sobrien(define_expand "umulditi3"
713896294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
713996294Sobrien		   (mult:TI (zero_extend:TI
714096294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
714196294Sobrien			    (zero_extend:TI
714296294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
714396294Sobrien	      (clobber (reg:CC 17))])]
714496294Sobrien  "TARGET_64BIT"
714596294Sobrien  "")
714696294Sobrien
714796294Sobrien(define_insn "*umulditi3_insn"
714890286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
714996294Sobrien	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
715090286Sobrien		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
715190286Sobrien   (clobber (reg:CC 17))]
715296294Sobrien  "TARGET_64BIT
715396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
715490286Sobrien  "mul{q}\t%2"
715590286Sobrien  [(set_attr "type" "imul")
715690286Sobrien   (set_attr "ppro_uops" "few")
715790286Sobrien   (set_attr "length_immediate" "0")
7158132727Skan   (set (attr "athlon_decode")
7159132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7160132727Skan        (const_string "vector")
7161132727Skan        (const_string "double")))
716290286Sobrien   (set_attr "mode" "DI")])
716390286Sobrien
716490286Sobrien;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
716596294Sobrien(define_expand "umulsidi3"
716696294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
716796294Sobrien		   (mult:DI (zero_extend:DI
716896294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
716996294Sobrien			    (zero_extend:DI
717096294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
717196294Sobrien	      (clobber (reg:CC 17))])]
717296294Sobrien  "!TARGET_64BIT"
717396294Sobrien  "")
717496294Sobrien
717596294Sobrien(define_insn "*umulsidi3_insn"
717618334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
717796294Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
717890286Sobrien		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
717990286Sobrien   (clobber (reg:CC 17))]
718096294Sobrien  "!TARGET_64BIT
718196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
718290286Sobrien  "mul{l}\t%2"
718390286Sobrien  [(set_attr "type" "imul")
718490286Sobrien   (set_attr "ppro_uops" "few")
718590286Sobrien   (set_attr "length_immediate" "0")
7186132727Skan   (set (attr "athlon_decode")
7187132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7188132727Skan        (const_string "vector")
7189132727Skan        (const_string "double")))
719090286Sobrien   (set_attr "mode" "SI")])
719118334Speter
719296294Sobrien(define_expand "mulditi3"
719396294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
719496294Sobrien		   (mult:TI (sign_extend:TI
719596294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
719696294Sobrien			    (sign_extend:TI
719796294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
719896294Sobrien	      (clobber (reg:CC 17))])]
719996294Sobrien  "TARGET_64BIT"
720096294Sobrien  "")
720196294Sobrien
720296294Sobrien(define_insn "*mulditi3_insn"
720390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
720496294Sobrien	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
720590286Sobrien		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
720690286Sobrien   (clobber (reg:CC 17))]
720796294Sobrien  "TARGET_64BIT
720896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
720990286Sobrien  "imul{q}\t%2"
721090286Sobrien  [(set_attr "type" "imul")
721190286Sobrien   (set_attr "length_immediate" "0")
7212132727Skan   (set (attr "athlon_decode")
7213132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7214132727Skan        (const_string "vector")
7215132727Skan        (const_string "double")))
721690286Sobrien   (set_attr "mode" "DI")])
721790286Sobrien
721896294Sobrien(define_expand "mulsidi3"
721996294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
722096294Sobrien		   (mult:DI (sign_extend:DI
722196294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
722296294Sobrien			    (sign_extend:DI
722396294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
722496294Sobrien	      (clobber (reg:CC 17))])]
722596294Sobrien  "!TARGET_64BIT"
722696294Sobrien  "")
722796294Sobrien
722896294Sobrien(define_insn "*mulsidi3_insn"
722918334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
723096294Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
723190286Sobrien		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
723290286Sobrien   (clobber (reg:CC 17))]
723396294Sobrien  "!TARGET_64BIT
723496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
723590286Sobrien  "imul{l}\t%2"
723690286Sobrien  [(set_attr "type" "imul")
723790286Sobrien   (set_attr "length_immediate" "0")
7238132727Skan   (set (attr "athlon_decode")
7239132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7240132727Skan        (const_string "vector")
7241132727Skan        (const_string "double")))
724290286Sobrien   (set_attr "mode" "SI")])
724318334Speter
724496294Sobrien(define_expand "umuldi3_highpart"
724596294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
724696294Sobrien		   (truncate:DI
724796294Sobrien		     (lshiftrt:TI
724896294Sobrien		       (mult:TI (zero_extend:TI
724996294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
725096294Sobrien				(zero_extend:TI
725196294Sobrien				  (match_operand:DI 2 "register_operand" "")))
725296294Sobrien		       (const_int 64))))
725396294Sobrien	      (clobber (match_scratch:DI 3 ""))
725496294Sobrien	      (clobber (reg:CC 17))])]
725596294Sobrien  "TARGET_64BIT"
725696294Sobrien  "")
725796294Sobrien
725890286Sobrien(define_insn "*umuldi3_highpart_rex64"
725990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
726090286Sobrien	(truncate:DI
726190286Sobrien	  (lshiftrt:TI
726290286Sobrien	    (mult:TI (zero_extend:TI
726396294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
726490286Sobrien		     (zero_extend:TI
726590286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
726690286Sobrien	    (const_int 64))))
726796294Sobrien   (clobber (match_scratch:DI 3 "=1"))
726890286Sobrien   (clobber (reg:CC 17))]
726996294Sobrien  "TARGET_64BIT
727096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
727190286Sobrien  "mul{q}\t%2"
727290286Sobrien  [(set_attr "type" "imul")
727390286Sobrien   (set_attr "ppro_uops" "few")
727490286Sobrien   (set_attr "length_immediate" "0")
7275132727Skan   (set (attr "athlon_decode")
7276132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7277132727Skan        (const_string "vector")
7278132727Skan        (const_string "double")))
727990286Sobrien   (set_attr "mode" "DI")])
728090286Sobrien
728196294Sobrien(define_expand "umulsi3_highpart"
728296294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
728396294Sobrien		   (truncate:SI
728496294Sobrien		     (lshiftrt:DI
728596294Sobrien		       (mult:DI (zero_extend:DI
728696294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
728796294Sobrien				(zero_extend:DI
728896294Sobrien				  (match_operand:SI 2 "register_operand" "")))
728996294Sobrien		       (const_int 32))))
729096294Sobrien	      (clobber (match_scratch:SI 3 ""))
729196294Sobrien	      (clobber (reg:CC 17))])]
729296294Sobrien  ""
729396294Sobrien  "")
729496294Sobrien
729596294Sobrien(define_insn "*umulsi3_highpart_insn"
729618334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
729790286Sobrien	(truncate:SI
729890286Sobrien	  (lshiftrt:DI
729990286Sobrien	    (mult:DI (zero_extend:DI
730096294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
730190286Sobrien		     (zero_extend:DI
730290286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
730390286Sobrien	    (const_int 32))))
730496294Sobrien   (clobber (match_scratch:SI 3 "=1"))
730590286Sobrien   (clobber (reg:CC 17))]
730696294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
730790286Sobrien  "mul{l}\t%2"
730890286Sobrien  [(set_attr "type" "imul")
730990286Sobrien   (set_attr "ppro_uops" "few")
731090286Sobrien   (set_attr "length_immediate" "0")
7311132727Skan   (set (attr "athlon_decode")
7312132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7313132727Skan        (const_string "vector")
7314132727Skan        (const_string "double")))
731590286Sobrien   (set_attr "mode" "SI")])
731618334Speter
731790286Sobrien(define_insn "*umulsi3_highpart_zext"
731890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
731990286Sobrien	(zero_extend:DI (truncate:SI
732090286Sobrien	  (lshiftrt:DI
732190286Sobrien	    (mult:DI (zero_extend:DI
732296294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
732390286Sobrien		     (zero_extend:DI
732490286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
732590286Sobrien	    (const_int 32)))))
732696294Sobrien   (clobber (match_scratch:SI 3 "=1"))
732790286Sobrien   (clobber (reg:CC 17))]
732896294Sobrien  "TARGET_64BIT
732996294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
733090286Sobrien  "mul{l}\t%2"
733190286Sobrien  [(set_attr "type" "imul")
733290286Sobrien   (set_attr "ppro_uops" "few")
733390286Sobrien   (set_attr "length_immediate" "0")
7334132727Skan   (set (attr "athlon_decode")
7335132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7336132727Skan        (const_string "vector")
7337132727Skan        (const_string "double")))
733890286Sobrien   (set_attr "mode" "SI")])
733990286Sobrien
734096294Sobrien(define_expand "smuldi3_highpart"
734196294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
734296294Sobrien		   (truncate:DI
734396294Sobrien		     (lshiftrt:TI
734496294Sobrien		       (mult:TI (sign_extend:TI
734596294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
734696294Sobrien				(sign_extend:TI
734796294Sobrien				  (match_operand:DI 2 "register_operand" "")))
734896294Sobrien		       (const_int 64))))
734996294Sobrien	      (clobber (match_scratch:DI 3 ""))
735096294Sobrien	      (clobber (reg:CC 17))])]
735196294Sobrien  "TARGET_64BIT"
735296294Sobrien  "")
735396294Sobrien
735490286Sobrien(define_insn "*smuldi3_highpart_rex64"
735590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
735690286Sobrien	(truncate:DI
735790286Sobrien	  (lshiftrt:TI
735890286Sobrien	    (mult:TI (sign_extend:TI
735996294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
736090286Sobrien		     (sign_extend:TI
736190286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
736290286Sobrien	    (const_int 64))))
736396294Sobrien   (clobber (match_scratch:DI 3 "=1"))
736490286Sobrien   (clobber (reg:CC 17))]
736596294Sobrien  "TARGET_64BIT
736696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
736790286Sobrien  "imul{q}\t%2"
736890286Sobrien  [(set_attr "type" "imul")
736990286Sobrien   (set_attr "ppro_uops" "few")
7370132727Skan   (set (attr "athlon_decode")
7371132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7372132727Skan        (const_string "vector")
7373132727Skan        (const_string "double")))
737490286Sobrien   (set_attr "mode" "DI")])
737590286Sobrien
737696294Sobrien(define_expand "smulsi3_highpart"
737796294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
737896294Sobrien		   (truncate:SI
737996294Sobrien		     (lshiftrt:DI
738096294Sobrien		       (mult:DI (sign_extend:DI
738196294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
738296294Sobrien				(sign_extend:DI
738396294Sobrien				  (match_operand:SI 2 "register_operand" "")))
738496294Sobrien		       (const_int 32))))
738596294Sobrien	      (clobber (match_scratch:SI 3 ""))
738696294Sobrien	      (clobber (reg:CC 17))])]
738796294Sobrien  ""
738896294Sobrien  "")
738996294Sobrien
739096294Sobrien(define_insn "*smulsi3_highpart_insn"
739118334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
739290286Sobrien	(truncate:SI
739390286Sobrien	  (lshiftrt:DI
739490286Sobrien	    (mult:DI (sign_extend:DI
739596294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
739690286Sobrien		     (sign_extend:DI
739790286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
739890286Sobrien	    (const_int 32))))
739996294Sobrien   (clobber (match_scratch:SI 3 "=1"))
740090286Sobrien   (clobber (reg:CC 17))]
740196294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
740290286Sobrien  "imul{l}\t%2"
740390286Sobrien  [(set_attr "type" "imul")
740490286Sobrien   (set_attr "ppro_uops" "few")
7405132727Skan   (set (attr "athlon_decode")
7406132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7407132727Skan        (const_string "vector")
7408132727Skan        (const_string "double")))
740990286Sobrien   (set_attr "mode" "SI")])
741018334Speter
741190286Sobrien(define_insn "*smulsi3_highpart_zext"
741290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
741390286Sobrien	(zero_extend:DI (truncate:SI
741490286Sobrien	  (lshiftrt:DI
741590286Sobrien	    (mult:DI (sign_extend:DI
741696294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
741790286Sobrien		     (sign_extend:DI
741890286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
741990286Sobrien	    (const_int 32)))))
742096294Sobrien   (clobber (match_scratch:SI 3 "=1"))
742190286Sobrien   (clobber (reg:CC 17))]
742296294Sobrien  "TARGET_64BIT
742396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
742490286Sobrien  "imul{l}\t%2"
742590286Sobrien  [(set_attr "type" "imul")
742690286Sobrien   (set_attr "ppro_uops" "few")
7427132727Skan   (set (attr "athlon_decode")
7428132727Skan     (if_then_else (eq_attr "cpu" "athlon")
7429132727Skan        (const_string "vector")
7430132727Skan        (const_string "double")))
743190286Sobrien   (set_attr "mode" "SI")])
743290286Sobrien
743318334Speter;; The patterns that match these are at the end of this file.
743418334Speter
743518334Speter(define_expand "mulxf3"
743618334Speter  [(set (match_operand:XF 0 "register_operand" "")
743750650Sobrien	(mult:XF (match_operand:XF 1 "register_operand" "")
743850650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
743918334Speter  "TARGET_80387"
744018334Speter  "")
744118334Speter
744218334Speter(define_expand "muldf3"
744318334Speter  [(set (match_operand:DF 0 "register_operand" "")
744450650Sobrien	(mult:DF (match_operand:DF 1 "register_operand" "")
744518334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
744690286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
744718334Speter  "")
744818334Speter
744918334Speter(define_expand "mulsf3"
745018334Speter  [(set (match_operand:SF 0 "register_operand" "")
745150650Sobrien	(mult:SF (match_operand:SF 1 "register_operand" "")
745218334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
745390286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
745418334Speter  "")
745518334Speter
745690286Sobrien;; Divide instructions
745718334Speter
745818334Speter(define_insn "divqi3"
745950650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
746050650Sobrien	(div:QI (match_operand:HI 1 "register_operand" "0")
746190286Sobrien		(match_operand:QI 2 "nonimmediate_operand" "qm")))
746290286Sobrien   (clobber (reg:CC 17))]
746390286Sobrien  "TARGET_QIMODE_MATH"
746490286Sobrien  "idiv{b}\t%2"
746590286Sobrien  [(set_attr "type" "idiv")
746690286Sobrien   (set_attr "mode" "QI")
746790286Sobrien   (set_attr "ppro_uops" "few")])
746818334Speter
746918334Speter(define_insn "udivqi3"
747050650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
747150650Sobrien	(udiv:QI (match_operand:HI 1 "register_operand" "0")
747290286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
747390286Sobrien   (clobber (reg:CC 17))]
747490286Sobrien  "TARGET_QIMODE_MATH"
747590286Sobrien  "div{b}\t%2"
747690286Sobrien  [(set_attr "type" "idiv")
747790286Sobrien   (set_attr "mode" "QI")
747890286Sobrien   (set_attr "ppro_uops" "few")])
747918334Speter
748018334Speter;; The patterns that match these are at the end of this file.
748118334Speter
748218334Speter(define_expand "divxf3"
748318334Speter  [(set (match_operand:XF 0 "register_operand" "")
748450650Sobrien	(div:XF (match_operand:XF 1 "register_operand" "")
748550650Sobrien		(match_operand:XF 2 "register_operand" "")))]
748618334Speter  "TARGET_80387"
748718334Speter  "")
748818334Speter
748918334Speter(define_expand "divdf3"
749018334Speter  [(set (match_operand:DF 0 "register_operand" "")
749150650Sobrien 	(div:DF (match_operand:DF 1 "register_operand" "")
749250650Sobrien 		(match_operand:DF 2 "nonimmediate_operand" "")))]
749390286Sobrien   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
749450650Sobrien   "")
749550650Sobrien 
749618334Speter(define_expand "divsf3"
749718334Speter  [(set (match_operand:SF 0 "register_operand" "")
749850650Sobrien	(div:SF (match_operand:SF 1 "register_operand" "")
749918334Speter		(match_operand:SF 2 "nonimmediate_operand" "")))]
750090286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
750118334Speter  "")
750218334Speter
750318334Speter;; Remainder instructions.
750418334Speter
750590286Sobrien(define_expand "divmoddi4"
750690286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
750790286Sobrien		   (div:DI (match_operand:DI 1 "register_operand" "")
750890286Sobrien			   (match_operand:DI 2 "nonimmediate_operand" "")))
750990286Sobrien	      (set (match_operand:DI 3 "register_operand" "")
751090286Sobrien		   (mod:DI (match_dup 1) (match_dup 2)))
751190286Sobrien	      (clobber (reg:CC 17))])]
751290286Sobrien  "TARGET_64BIT"
751390286Sobrien  "")
751490286Sobrien
751590286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
7516132727Skan;; Penalize eax case slightly because it results in worse scheduling
751790286Sobrien;; of code.
751890286Sobrien(define_insn "*divmoddi4_nocltd_rex64"
751990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
752090286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "1,0")
752190286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
752290286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d,&d")
752390286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
752490286Sobrien   (clobber (reg:CC 17))]
752590286Sobrien  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
752690286Sobrien  "#"
752790286Sobrien  [(set_attr "type" "multi")])
752890286Sobrien
752990286Sobrien(define_insn "*divmoddi4_cltd_rex64"
753090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
753190286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "a")
753290286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm")))
753390286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d")
753490286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
753590286Sobrien   (clobber (reg:CC 17))]
753690286Sobrien  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
753790286Sobrien  "#"
753890286Sobrien  [(set_attr "type" "multi")])
753990286Sobrien
754090286Sobrien(define_insn "*divmoddi_noext_rex64"
754190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
754290286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "0")
754390286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "rm")))
754490286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
754590286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
754690286Sobrien   (use (match_operand:DI 4 "register_operand" "3"))
754790286Sobrien   (clobber (reg:CC 17))]
754890286Sobrien  "TARGET_64BIT"
754990286Sobrien  "idiv{q}\t%2"
755090286Sobrien  [(set_attr "type" "idiv")
755190286Sobrien   (set_attr "mode" "DI")
755290286Sobrien   (set_attr "ppro_uops" "few")])
755390286Sobrien
755490286Sobrien(define_split
755590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
755690286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "")
755790286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "")))
755890286Sobrien   (set (match_operand:DI 3 "register_operand" "")
755990286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
756090286Sobrien   (clobber (reg:CC 17))]
756190286Sobrien  "TARGET_64BIT && reload_completed"
756290286Sobrien  [(parallel [(set (match_dup 3)
756390286Sobrien		   (ashiftrt:DI (match_dup 4) (const_int 63)))
756490286Sobrien	      (clobber (reg:CC 17))])
756590286Sobrien   (parallel [(set (match_dup 0)
756690286Sobrien	           (div:DI (reg:DI 0) (match_dup 2)))
756790286Sobrien	      (set (match_dup 3)
756890286Sobrien		   (mod:DI (reg:DI 0) (match_dup 2)))
756990286Sobrien	      (use (match_dup 3))
757090286Sobrien	      (clobber (reg:CC 17))])]
757190286Sobrien{
7572117404Skan  /* Avoid use of cltd in favor of a mov+shift.  */
757390286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
757490286Sobrien    {
757590286Sobrien      if (true_regnum (operands[1]))
757690286Sobrien        emit_move_insn (operands[0], operands[1]);
757790286Sobrien      else
757890286Sobrien	emit_move_insn (operands[3], operands[1]);
757990286Sobrien      operands[4] = operands[3];
758090286Sobrien    }
758190286Sobrien  else
758290286Sobrien    {
758390286Sobrien      if (true_regnum (operands[1]))
758490286Sobrien	abort();
758590286Sobrien      operands[4] = operands[1];
758690286Sobrien    }
758790286Sobrien})
758890286Sobrien
758990286Sobrien
759090286Sobrien(define_expand "divmodsi4"
759190286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
759290286Sobrien		   (div:SI (match_operand:SI 1 "register_operand" "")
759390286Sobrien			   (match_operand:SI 2 "nonimmediate_operand" "")))
759490286Sobrien	      (set (match_operand:SI 3 "register_operand" "")
759590286Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))
759690286Sobrien	      (clobber (reg:CC 17))])]
759790286Sobrien  ""
759890286Sobrien  "")
759990286Sobrien
760090286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
7601132727Skan;; Penalize eax case slightly because it results in worse scheduling
760290286Sobrien;; of code.
760390286Sobrien(define_insn "*divmodsi4_nocltd"
760490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
760590286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "1,0")
760690286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
760790286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d,&d")
760890286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
760990286Sobrien   (clobber (reg:CC 17))]
761090286Sobrien  "!optimize_size && !TARGET_USE_CLTD"
761190286Sobrien  "#"
761290286Sobrien  [(set_attr "type" "multi")])
761390286Sobrien
761490286Sobrien(define_insn "*divmodsi4_cltd"
761518334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
761690286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "a")
761790286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm")))
761890286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d")
761990286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
762090286Sobrien   (clobber (reg:CC 17))]
762190286Sobrien  "optimize_size || TARGET_USE_CLTD"
762290286Sobrien  "#"
762390286Sobrien  [(set_attr "type" "multi")])
762490286Sobrien
762590286Sobrien(define_insn "*divmodsi_noext"
762690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
762718334Speter	(div:SI (match_operand:SI 1 "register_operand" "0")
762850650Sobrien		(match_operand:SI 2 "nonimmediate_operand" "rm")))
762990286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
763090286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
763190286Sobrien   (use (match_operand:SI 4 "register_operand" "3"))
763290286Sobrien   (clobber (reg:CC 17))]
763318334Speter  ""
763490286Sobrien  "idiv{l}\t%2"
763590286Sobrien  [(set_attr "type" "idiv")
763690286Sobrien   (set_attr "mode" "SI")
763790286Sobrien   (set_attr "ppro_uops" "few")])
763890286Sobrien
763990286Sobrien(define_split
764090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
764190286Sobrien	(div:SI (match_operand:SI 1 "register_operand" "")
764290286Sobrien		(match_operand:SI 2 "nonimmediate_operand" "")))
764390286Sobrien   (set (match_operand:SI 3 "register_operand" "")
764490286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
764590286Sobrien   (clobber (reg:CC 17))]
764690286Sobrien  "reload_completed"
764790286Sobrien  [(parallel [(set (match_dup 3)
764890286Sobrien		   (ashiftrt:SI (match_dup 4) (const_int 31)))
764990286Sobrien	      (clobber (reg:CC 17))])
765090286Sobrien   (parallel [(set (match_dup 0)
765190286Sobrien	           (div:SI (reg:SI 0) (match_dup 2)))
765290286Sobrien	      (set (match_dup 3)
765390286Sobrien		   (mod:SI (reg:SI 0) (match_dup 2)))
765490286Sobrien	      (use (match_dup 3))
765590286Sobrien	      (clobber (reg:CC 17))])]
765618334Speter{
7657117404Skan  /* Avoid use of cltd in favor of a mov+shift.  */
765890286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
765990286Sobrien    {
766090286Sobrien      if (true_regnum (operands[1]))
766190286Sobrien        emit_move_insn (operands[0], operands[1]);
766290286Sobrien      else
766390286Sobrien	emit_move_insn (operands[3], operands[1]);
766490286Sobrien      operands[4] = operands[3];
766590286Sobrien    }
766690286Sobrien  else
766790286Sobrien    {
766890286Sobrien      if (true_regnum (operands[1]))
766990286Sobrien	abort();
767090286Sobrien      operands[4] = operands[1];
767190286Sobrien    }
767290286Sobrien})
767390286Sobrien;; %%% Split me.
767418334Speter(define_insn "divmodhi4"
767518334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
767618334Speter	(div:HI (match_operand:HI 1 "register_operand" "0")
767750650Sobrien		(match_operand:HI 2 "nonimmediate_operand" "rm")))
767818334Speter   (set (match_operand:HI 3 "register_operand" "=&d")
767990286Sobrien	(mod:HI (match_dup 1) (match_dup 2)))
768090286Sobrien   (clobber (reg:CC 17))]
768190286Sobrien  "TARGET_HIMODE_MATH"
768290286Sobrien  "cwtd\;idiv{w}\t%2"
768390286Sobrien  [(set_attr "type" "multi")
768490286Sobrien   (set_attr "length_immediate" "0")
768590286Sobrien   (set_attr "mode" "SI")])
768618334Speter
768790286Sobrien(define_insn "udivmoddi4"
768890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
768990286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
769090286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
769190286Sobrien   (set (match_operand:DI 3 "register_operand" "=&d")
769290286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
769390286Sobrien   (clobber (reg:CC 17))]
769490286Sobrien  "TARGET_64BIT"
769590286Sobrien  "xor{q}\t%3, %3\;div{q}\t%2"
769690286Sobrien  [(set_attr "type" "multi")
769790286Sobrien   (set_attr "length_immediate" "0")
769890286Sobrien   (set_attr "mode" "DI")])
769990286Sobrien
770090286Sobrien(define_insn "*udivmoddi4_noext"
770190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
770290286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
770390286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
770490286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
770590286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
770690286Sobrien   (use (match_dup 3))
770790286Sobrien   (clobber (reg:CC 17))]
770890286Sobrien  "TARGET_64BIT"
770990286Sobrien  "div{q}\t%2"
771090286Sobrien  [(set_attr "type" "idiv")
771190286Sobrien   (set_attr "ppro_uops" "few")
771290286Sobrien   (set_attr "mode" "DI")])
771390286Sobrien
771490286Sobrien(define_split
771590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
771690286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "")
771790286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "")))
771890286Sobrien   (set (match_operand:DI 3 "register_operand" "")
771990286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
772090286Sobrien   (clobber (reg:CC 17))]
772190286Sobrien  "TARGET_64BIT && reload_completed"
772290286Sobrien  [(set (match_dup 3) (const_int 0))
772390286Sobrien   (parallel [(set (match_dup 0)
772490286Sobrien		   (udiv:DI (match_dup 1) (match_dup 2)))
772590286Sobrien	      (set (match_dup 3)
772690286Sobrien		   (umod:DI (match_dup 1) (match_dup 2)))
772790286Sobrien	      (use (match_dup 3))
772890286Sobrien	      (clobber (reg:CC 17))])]
772990286Sobrien  "")
773090286Sobrien
773118334Speter(define_insn "udivmodsi4"
773218334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
773318334Speter	(udiv:SI (match_operand:SI 1 "register_operand" "0")
773450650Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
773518334Speter   (set (match_operand:SI 3 "register_operand" "=&d")
773690286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
773790286Sobrien   (clobber (reg:CC 17))]
773818334Speter  ""
773990286Sobrien  "xor{l}\t%3, %3\;div{l}\t%2"
774090286Sobrien  [(set_attr "type" "multi")
774190286Sobrien   (set_attr "length_immediate" "0")
774290286Sobrien   (set_attr "mode" "SI")])
774318334Speter
774490286Sobrien(define_insn "*udivmodsi4_noext"
774590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
774690286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "0")
774790286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
774890286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
774990286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
775090286Sobrien   (use (match_dup 3))
775190286Sobrien   (clobber (reg:CC 17))]
775290286Sobrien  ""
775390286Sobrien  "div{l}\t%2"
775490286Sobrien  [(set_attr "type" "idiv")
775590286Sobrien   (set_attr "ppro_uops" "few")
775690286Sobrien   (set_attr "mode" "SI")])
775790286Sobrien
775890286Sobrien(define_split
775990286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
776090286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "")
776190286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "")))
776290286Sobrien   (set (match_operand:SI 3 "register_operand" "")
776390286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
776490286Sobrien   (clobber (reg:CC 17))]
776590286Sobrien  "reload_completed"
776690286Sobrien  [(set (match_dup 3) (const_int 0))
776790286Sobrien   (parallel [(set (match_dup 0)
776890286Sobrien		   (udiv:SI (match_dup 1) (match_dup 2)))
776990286Sobrien	      (set (match_dup 3)
777090286Sobrien		   (umod:SI (match_dup 1) (match_dup 2)))
777190286Sobrien	      (use (match_dup 3))
777290286Sobrien	      (clobber (reg:CC 17))])]
777390286Sobrien  "")
777490286Sobrien
777590286Sobrien(define_expand "udivmodhi4"
777690286Sobrien  [(set (match_dup 4) (const_int 0))
777790286Sobrien   (parallel [(set (match_operand:HI 0 "register_operand" "")
777890286Sobrien		   (udiv:HI (match_operand:HI 1 "register_operand" "")
777990286Sobrien		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
778090286Sobrien	      (set (match_operand:HI 3 "register_operand" "")
778190286Sobrien	   	   (umod:HI (match_dup 1) (match_dup 2)))
778290286Sobrien	      (use (match_dup 4))
778390286Sobrien	      (clobber (reg:CC 17))])]
778490286Sobrien  "TARGET_HIMODE_MATH"
778590286Sobrien  "operands[4] = gen_reg_rtx (HImode);")
778690286Sobrien
778790286Sobrien(define_insn "*udivmodhi_noext"
778818334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
778918334Speter	(udiv:HI (match_operand:HI 1 "register_operand" "0")
779050650Sobrien		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
779190286Sobrien   (set (match_operand:HI 3 "register_operand" "=d")
779290286Sobrien	(umod:HI (match_dup 1) (match_dup 2)))
779390286Sobrien   (use (match_operand:HI 4 "register_operand" "3"))
779490286Sobrien   (clobber (reg:CC 17))]
779518334Speter  ""
779690286Sobrien  "div{w}\t%2"
779790286Sobrien  [(set_attr "type" "idiv")
779890286Sobrien   (set_attr "mode" "HI")
779990286Sobrien   (set_attr "ppro_uops" "few")])
780018334Speter
780190286Sobrien;; We can not use div/idiv for double division, because it causes
780290286Sobrien;; "division by zero" on the overflow and that's not what we expect
780390286Sobrien;; from truncate.  Because true (non truncating) double division is
780490286Sobrien;; never generated, we can't create this insn anyway.
780590286Sobrien;
780690286Sobrien;(define_insn ""
780790286Sobrien;  [(set (match_operand:SI 0 "register_operand" "=a")
780890286Sobrien;	(truncate:SI
780990286Sobrien;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
781090286Sobrien;		   (zero_extend:DI
781190286Sobrien;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
781290286Sobrien;   (set (match_operand:SI 3 "register_operand" "=d")
781390286Sobrien;	(truncate:SI
781490286Sobrien;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
781590286Sobrien;   (clobber (reg:CC 17))]
781690286Sobrien;  ""
781790286Sobrien;  "div{l}\t{%2, %0|%0, %2}"
781890286Sobrien;  [(set_attr "type" "idiv")
781990286Sobrien;   (set_attr "ppro_uops" "few")])
782090286Sobrien
782190286Sobrien;;- Logical AND instructions
782218334Speter
782390286Sobrien;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
782490286Sobrien;; Note that this excludes ah.
782590286Sobrien
782690286Sobrien(define_insn "*testdi_1_rex64"
782790286Sobrien  [(set (reg 17)
782890286Sobrien	(compare
7829132727Skan	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7830132727Skan		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
783190286Sobrien	  (const_int 0)))]
7832132727Skan  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7833132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
783490286Sobrien  "@
783590286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
783690286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
783790286Sobrien   test{q}\t{%1, %0|%0, %1} 
783890286Sobrien   test{q}\t{%1, %0|%0, %1} 
783990286Sobrien   test{q}\t{%1, %0|%0, %1}"
784090286Sobrien  [(set_attr "type" "test")
784190286Sobrien   (set_attr "modrm" "0,1,0,1,1")
784290286Sobrien   (set_attr "mode" "SI,SI,DI,DI,DI")
784390286Sobrien   (set_attr "pent_pair" "uv,np,uv,np,uv")])
784490286Sobrien
784590286Sobrien(define_insn "testsi_1"
784690286Sobrien  [(set (reg 17)
784790286Sobrien	(compare
7848132727Skan	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7849132727Skan		  (match_operand:SI 1 "general_operand" "in,in,rin"))
785090286Sobrien	  (const_int 0)))]
7851132727Skan  "ix86_match_ccmode (insn, CCNOmode)
7852132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
785390286Sobrien  "test{l}\t{%1, %0|%0, %1}"
785490286Sobrien  [(set_attr "type" "test")
785590286Sobrien   (set_attr "modrm" "0,1,1")
785690286Sobrien   (set_attr "mode" "SI")
785790286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
785890286Sobrien
785990286Sobrien(define_expand "testsi_ccno_1"
786090286Sobrien  [(set (reg:CCNO 17)
786190286Sobrien	(compare:CCNO
786290286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
786390286Sobrien		  (match_operand:SI 1 "nonmemory_operand" ""))
786490286Sobrien	  (const_int 0)))]
786518334Speter  ""
786690286Sobrien  "")
786718334Speter
786890286Sobrien(define_insn "*testhi_1"
786990286Sobrien  [(set (reg 17)
7870132727Skan        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7871132727Skan			 (match_operand:HI 1 "general_operand" "n,n,rn"))
787290286Sobrien		 (const_int 0)))]
7873132727Skan  "ix86_match_ccmode (insn, CCNOmode)
7874132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
787590286Sobrien  "test{w}\t{%1, %0|%0, %1}"
787690286Sobrien  [(set_attr "type" "test")
787790286Sobrien   (set_attr "modrm" "0,1,1")
787890286Sobrien   (set_attr "mode" "HI")
787990286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
788018334Speter
788190286Sobrien(define_expand "testqi_ccz_1"
788290286Sobrien  [(set (reg:CCZ 17)
788390286Sobrien        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
788490286Sobrien			     (match_operand:QI 1 "nonmemory_operand" ""))
788590286Sobrien		 (const_int 0)))]
788690286Sobrien  ""
788790286Sobrien  "")
788818334Speter
7889146906Skan(define_insn "*testqi_1_maybe_si"
789090286Sobrien  [(set (reg 17)
7891146906Skan        (compare
7892146906Skan	  (and:QI
7893146906Skan	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7894146906Skan	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7895146906Skan	  (const_int 0)))]
7896146906Skan  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897146906Skan   && ix86_match_ccmode (insn,
7898146906Skan			 GET_CODE (operands[1]) == CONST_INT
7899146906Skan			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
790018334Speter{
790190286Sobrien  if (which_alternative == 3)
790218334Speter    {
7903146906Skan      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
790490286Sobrien	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
790590286Sobrien      return "test{l}\t{%1, %k0|%k0, %1}";
790650650Sobrien    }
790790286Sobrien  return "test{b}\t{%1, %0|%0, %1}";
790890286Sobrien}
790990286Sobrien  [(set_attr "type" "test")
791090286Sobrien   (set_attr "modrm" "0,1,1,1")
791190286Sobrien   (set_attr "mode" "QI,QI,QI,SI")
791290286Sobrien   (set_attr "pent_pair" "uv,np,uv,np")])
791318334Speter
7914146906Skan(define_insn "*testqi_1"
7915146906Skan  [(set (reg 17)
7916146906Skan        (compare
7917146906Skan	  (and:QI
7918146906Skan	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7919146906Skan	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7920146906Skan	  (const_int 0)))]
7921146906Skan  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7922146906Skan   && ix86_match_ccmode (insn, CCNOmode)"
7923146906Skan  "test{b}\t{%1, %0|%0, %1}"
7924146906Skan  [(set_attr "type" "test")
7925146906Skan   (set_attr "modrm" "0,1,1")
7926146906Skan   (set_attr "mode" "QI")
7927146906Skan   (set_attr "pent_pair" "uv,np,uv")])
7928146906Skan
792990286Sobrien(define_expand "testqi_ext_ccno_0"
793090286Sobrien  [(set (reg:CCNO 17)
793190286Sobrien	(compare:CCNO
793290286Sobrien	  (and:SI
793390286Sobrien	    (zero_extract:SI
793490286Sobrien	      (match_operand 0 "ext_register_operand" "")
793590286Sobrien	      (const_int 8)
793690286Sobrien	      (const_int 8))
793790286Sobrien	    (match_operand 1 "const_int_operand" ""))
793890286Sobrien	  (const_int 0)))]
793990286Sobrien  ""
794090286Sobrien  "")
794118334Speter
794290286Sobrien(define_insn "*testqi_ext_0"
794390286Sobrien  [(set (reg 17)
794490286Sobrien	(compare
794590286Sobrien	  (and:SI
794690286Sobrien	    (zero_extract:SI
794790286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
794890286Sobrien	      (const_int 8)
794990286Sobrien	      (const_int 8))
795090286Sobrien	    (match_operand 1 "const_int_operand" "n"))
795190286Sobrien	  (const_int 0)))]
7952117404Skan  "ix86_match_ccmode (insn, CCNOmode)"
795390286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
795490286Sobrien  [(set_attr "type" "test")
795590286Sobrien   (set_attr "mode" "QI")
795690286Sobrien   (set_attr "length_immediate" "1")
795790286Sobrien   (set_attr "pent_pair" "np")])
795850650Sobrien
795990286Sobrien(define_insn "*testqi_ext_1"
796090286Sobrien  [(set (reg 17)
796190286Sobrien	(compare
796290286Sobrien	  (and:SI
796390286Sobrien	    (zero_extract:SI
796490286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
796590286Sobrien	      (const_int 8)
796690286Sobrien	      (const_int 8))
796790286Sobrien	    (zero_extend:SI
7968132727Skan	      (match_operand:QI 1 "general_operand" "Qm")))
796990286Sobrien	  (const_int 0)))]
7970132727Skan  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7971132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
797290286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
797390286Sobrien  [(set_attr "type" "test")
797490286Sobrien   (set_attr "mode" "QI")])
797518334Speter
797690286Sobrien(define_insn "*testqi_ext_1_rex64"
797790286Sobrien  [(set (reg 17)
797890286Sobrien	(compare
797990286Sobrien	  (and:SI
798090286Sobrien	    (zero_extract:SI
798190286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
798290286Sobrien	      (const_int 8)
798390286Sobrien	      (const_int 8))
798490286Sobrien	    (zero_extend:SI
798590286Sobrien	      (match_operand:QI 1 "register_operand" "Q")))
798690286Sobrien	  (const_int 0)))]
798790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
798890286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
798990286Sobrien  [(set_attr "type" "test")
799090286Sobrien   (set_attr "mode" "QI")])
799118334Speter
799290286Sobrien(define_insn "*testqi_ext_2"
799390286Sobrien  [(set (reg 17)
799490286Sobrien	(compare
799590286Sobrien	  (and:SI
799690286Sobrien	    (zero_extract:SI
799790286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
799890286Sobrien	      (const_int 8)
799990286Sobrien	      (const_int 8))
800090286Sobrien	    (zero_extract:SI
800190286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
800290286Sobrien	      (const_int 8)
800390286Sobrien	      (const_int 8)))
800490286Sobrien	  (const_int 0)))]
800590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
800690286Sobrien  "test{b}\t{%h1, %h0|%h0, %h1}"
800790286Sobrien  [(set_attr "type" "test")
800890286Sobrien   (set_attr "mode" "QI")])
800950650Sobrien
801090286Sobrien;; Combine likes to form bit extractions for some tests.  Humor it.
801190286Sobrien(define_insn "*testqi_ext_3"
801290286Sobrien  [(set (reg 17)
801390286Sobrien        (compare (zero_extract:SI
801490286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
801590286Sobrien		   (match_operand:SI 1 "const_int_operand" "")
801690286Sobrien		   (match_operand:SI 2 "const_int_operand" ""))
801790286Sobrien		 (const_int 0)))]
801890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
801990286Sobrien   && (GET_MODE (operands[0]) == SImode
802090286Sobrien       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
802190286Sobrien       || GET_MODE (operands[0]) == HImode
802290286Sobrien       || GET_MODE (operands[0]) == QImode)"
802390286Sobrien  "#")
802450650Sobrien
802590286Sobrien(define_insn "*testqi_ext_3_rex64"
802690286Sobrien  [(set (reg 17)
802790286Sobrien        (compare (zero_extract:DI
802890286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
802990286Sobrien		   (match_operand:DI 1 "const_int_operand" "")
803090286Sobrien		   (match_operand:DI 2 "const_int_operand" ""))
803190286Sobrien		 (const_int 0)))]
803290286Sobrien  "TARGET_64BIT
803390286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
803490286Sobrien   /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
803590286Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
803690286Sobrien   /* Ensure that resulting mask is zero or sign extended operand.  */
803790286Sobrien   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
803890286Sobrien       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
803990286Sobrien	   && INTVAL (operands[1]) > 32))
804090286Sobrien   && (GET_MODE (operands[0]) == SImode
804190286Sobrien       || GET_MODE (operands[0]) == DImode
804290286Sobrien       || GET_MODE (operands[0]) == HImode
804390286Sobrien       || GET_MODE (operands[0]) == QImode)"
804490286Sobrien  "#")
804550650Sobrien
804690286Sobrien(define_split
8047146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
8048146906Skan        (match_operator 1 "compare_operator"
8049146906Skan	  [(zero_extract
8050146906Skan	     (match_operand 2 "nonimmediate_operand" "")
8051146906Skan	     (match_operand 3 "const_int_operand" "")
8052146906Skan	     (match_operand 4 "const_int_operand" ""))
8053146906Skan	   (const_int 0)]))]
805490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
8055146906Skan  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
805690286Sobrien{
8057146906Skan  rtx val = operands[2];
8058146906Skan  HOST_WIDE_INT len = INTVAL (operands[3]);
8059146906Skan  HOST_WIDE_INT pos = INTVAL (operands[4]);
806090286Sobrien  HOST_WIDE_INT mask;
806190286Sobrien  enum machine_mode mode, submode;
806218334Speter
8063146906Skan  mode = GET_MODE (val);
8064146906Skan  if (GET_CODE (val) == MEM)
806590286Sobrien    {
806690286Sobrien      /* ??? Combine likes to put non-volatile mem extractions in QImode
806790286Sobrien	 no matter the size of the test.  So find a mode that works.  */
8068146906Skan      if (! MEM_VOLATILE_P (val))
806918334Speter	{
807090286Sobrien	  mode = smallest_mode_for_size (pos + len, MODE_INT);
8071146906Skan	  val = adjust_address (val, mode, 0);
807290286Sobrien	}
807390286Sobrien    }
8074146906Skan  else if (GET_CODE (val) == SUBREG
8075146906Skan	   && (submode = GET_MODE (SUBREG_REG (val)),
807690286Sobrien	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
807790286Sobrien	   && pos + len <= GET_MODE_BITSIZE (submode))
807890286Sobrien    {
807990286Sobrien      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
808090286Sobrien      mode = submode;
8081146906Skan      val = SUBREG_REG (val);
808290286Sobrien    }
808390286Sobrien  else if (mode == HImode && pos + len <= 8)
808490286Sobrien    {
808590286Sobrien      /* Small HImode tests can be converted to QImode.  */
808690286Sobrien      mode = QImode;
8087146906Skan      val = gen_lowpart (QImode, val);
808890286Sobrien    }
808918334Speter
809090286Sobrien  mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
809190286Sobrien  mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
809218334Speter
8093146906Skan  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
809490286Sobrien})
809550650Sobrien
8096117404Skan;; Convert HImode/SImode test instructions with immediate to QImode ones.
8097117404Skan;; i386 does not allow to encode test with 8bit sign extended immediate, so
8098117404Skan;; this is relatively important trick.
8099132727Skan;; Do the conversion only post-reload to avoid limiting of the register class
8100117404Skan;; to QI regs.
8101117404Skan(define_split
8102146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
8103146906Skan	(match_operator 1 "compare_operator"
8104146906Skan	  [(and (match_operand 2 "register_operand" "")
8105146906Skan	        (match_operand 3 "const_int_operand" ""))
8106146906Skan	   (const_int 0)]))]
8107117404Skan   "reload_completed
8108146906Skan    && QI_REG_P (operands[2])
8109146906Skan    && GET_MODE (operands[2]) != QImode
8110117404Skan    && ((ix86_match_ccmode (insn, CCZmode)
8111146906Skan    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8112117404Skan	|| (ix86_match_ccmode (insn, CCNOmode)
8113146906Skan	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8114146906Skan  [(set (match_dup 0)
8115146906Skan	(match_op_dup 1
8116146906Skan	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8117146906Skan		   (match_dup 3))
8118146906Skan	   (const_int 0)]))]
8119146906Skan  "operands[2] = gen_lowpart (SImode, operands[2]);
8120146906Skan   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8121117404Skan
8122117404Skan(define_split
8123146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
8124146906Skan	(match_operator 1 "compare_operator"
8125146906Skan	  [(and (match_operand 2 "nonimmediate_operand" "")
8126146906Skan	        (match_operand 3 "const_int_operand" ""))
8127146906Skan	   (const_int 0)]))]
8128117404Skan   "reload_completed
8129146906Skan    && GET_MODE (operands[2]) != QImode
8130146906Skan    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8131117404Skan    && ((ix86_match_ccmode (insn, CCZmode)
8132146906Skan	 && !(INTVAL (operands[3]) & ~255))
8133117404Skan	|| (ix86_match_ccmode (insn, CCNOmode)
8134146906Skan	    && !(INTVAL (operands[3]) & ~127)))"
8135146906Skan  [(set (match_dup 0)
8136146906Skan	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8137146906Skan			 (const_int 0)]))]
8138146906Skan  "operands[2] = gen_lowpart (QImode, operands[2]);
8139146906Skan   operands[3] = gen_lowpart (QImode, operands[3]);")
8140117404Skan
8141117404Skan
814290286Sobrien;; %%% This used to optimize known byte-wide and operations to memory,
814390286Sobrien;; and sometimes to QImode registers.  If this is considered useful,
814490286Sobrien;; it should be done with splitters.
814518334Speter
814690286Sobrien(define_expand "anddi3"
814790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
814890286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
814990286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
815090286Sobrien   (clobber (reg:CC 17))]
815190286Sobrien  "TARGET_64BIT"
815290286Sobrien  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
815350650Sobrien
815490286Sobrien(define_insn "*anddi_1_rex64"
815590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
815690286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
815790286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
815890286Sobrien   (clobber (reg:CC 17))]
815990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
816090286Sobrien{
816190286Sobrien  switch (get_attr_type (insn))
816290286Sobrien    {
816390286Sobrien    case TYPE_IMOVX:
816490286Sobrien      {
816590286Sobrien	enum machine_mode mode;
816650650Sobrien
816790286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
816890286Sobrien	  abort ();
816990286Sobrien        if (INTVAL (operands[2]) == 0xff)
817090286Sobrien	  mode = QImode;
817190286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
817290286Sobrien	  mode = HImode;
817390286Sobrien	else
817490286Sobrien	  abort ();
817590286Sobrien	
817690286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
817790286Sobrien	if (mode == QImode)
817890286Sobrien	  return "movz{bq|x}\t{%1,%0|%0, %1}";
817990286Sobrien	else
818090286Sobrien	  return "movz{wq|x}\t{%1,%0|%0, %1}";
818190286Sobrien      }
818250650Sobrien
818350650Sobrien    default:
818490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
818590286Sobrien	abort ();
818690286Sobrien      if (get_attr_mode (insn) == MODE_SI)
818790286Sobrien	return "and{l}\t{%k2, %k0|%k0, %k2}";
818890286Sobrien      else
818990286Sobrien	return "and{q}\t{%2, %0|%0, %2}";
819018334Speter    }
819190286Sobrien}
819290286Sobrien  [(set_attr "type" "alu,alu,alu,imovx")
819390286Sobrien   (set_attr "length_immediate" "*,*,*,0")
819490286Sobrien   (set_attr "mode" "SI,DI,DI,DI")])
819518334Speter
819690286Sobrien(define_insn "*anddi_2"
819790286Sobrien  [(set (reg 17)
819890286Sobrien	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
819990286Sobrien			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
820090286Sobrien		 (const_int 0)))
820190286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
820290286Sobrien	(and:DI (match_dup 1) (match_dup 2)))]
820390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
820490286Sobrien   && ix86_binary_operator_ok (AND, DImode, operands)"
820590286Sobrien  "@
820690286Sobrien   and{l}\t{%k2, %k0|%k0, %k2} 
820790286Sobrien   and{q}\t{%2, %0|%0, %2} 
820890286Sobrien   and{q}\t{%2, %0|%0, %2}"
820990286Sobrien  [(set_attr "type" "alu")
821090286Sobrien   (set_attr "mode" "SI,DI,DI")])
821118334Speter
821290286Sobrien(define_expand "andsi3"
821390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
821490286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
821590286Sobrien		(match_operand:SI 2 "general_operand" "")))
821690286Sobrien   (clobber (reg:CC 17))]
821718334Speter  ""
821890286Sobrien  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
821990286Sobrien
822090286Sobrien(define_insn "*andsi_1"
822190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
822290286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
822390286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm,L")))
822490286Sobrien   (clobber (reg:CC 17))]
822590286Sobrien  "ix86_binary_operator_ok (AND, SImode, operands)"
822618334Speter{
822790286Sobrien  switch (get_attr_type (insn))
822818334Speter    {
822990286Sobrien    case TYPE_IMOVX:
823090286Sobrien      {
823190286Sobrien	enum machine_mode mode;
823218334Speter
823390286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
823490286Sobrien	  abort ();
823590286Sobrien        if (INTVAL (operands[2]) == 0xff)
823690286Sobrien	  mode = QImode;
823790286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
823890286Sobrien	  mode = HImode;
823990286Sobrien	else
824090286Sobrien	  abort ();
824190286Sobrien	
824290286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
824390286Sobrien	if (mode == QImode)
824490286Sobrien	  return "movz{bl|x}\t{%1,%0|%0, %1}";
824590286Sobrien	else
824690286Sobrien	  return "movz{wl|x}\t{%1,%0|%0, %1}";
824790286Sobrien      }
824818334Speter
824990286Sobrien    default:
825090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
825190286Sobrien	abort ();
825290286Sobrien      return "and{l}\t{%2, %0|%0, %2}";
825390286Sobrien    }
825490286Sobrien}
825590286Sobrien  [(set_attr "type" "alu,alu,imovx")
825690286Sobrien   (set_attr "length_immediate" "*,*,0")
825790286Sobrien   (set_attr "mode" "SI")])
825818334Speter
825990286Sobrien(define_split
826090286Sobrien  [(set (match_operand 0 "register_operand" "")
826190286Sobrien	(and (match_dup 0)
826290286Sobrien	     (const_int -65536)))
826390286Sobrien   (clobber (reg:CC 17))]
8264117404Skan  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
826590286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
826690286Sobrien  "operands[1] = gen_lowpart (HImode, operands[0]);")
826718334Speter
826890286Sobrien(define_split
826990286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
827090286Sobrien	(and (match_dup 0)
827190286Sobrien	     (const_int -256)))
827290286Sobrien   (clobber (reg:CC 17))]
827390286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
827490286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
827590286Sobrien  "operands[1] = gen_lowpart (QImode, operands[0]);")
827618334Speter
827790286Sobrien(define_split
827890286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
827990286Sobrien	(and (match_dup 0)
828090286Sobrien	     (const_int -65281)))
828190286Sobrien   (clobber (reg:CC 17))]
828290286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
828390286Sobrien  [(parallel [(set (zero_extract:SI (match_dup 0)
828490286Sobrien				    (const_int 8)
828590286Sobrien				    (const_int 8))
828690286Sobrien		   (xor:SI 
828790286Sobrien		     (zero_extract:SI (match_dup 0)
828890286Sobrien				      (const_int 8)
828990286Sobrien				      (const_int 8))
829090286Sobrien		     (zero_extract:SI (match_dup 0)
829190286Sobrien				      (const_int 8)
829290286Sobrien				      (const_int 8))))
829390286Sobrien	      (clobber (reg:CC 17))])]
829490286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);")
829550650Sobrien
829690286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
829790286Sobrien(define_insn "*andsi_1_zext"
829890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
829990286Sobrien	(zero_extend:DI
830090286Sobrien	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
830190286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
830290286Sobrien   (clobber (reg:CC 17))]
830390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
830490286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
830590286Sobrien  [(set_attr "type" "alu")
830690286Sobrien   (set_attr "mode" "SI")])
830718334Speter
830890286Sobrien(define_insn "*andsi_2"
830990286Sobrien  [(set (reg 17)
831090286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
831190286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
831290286Sobrien		 (const_int 0)))
831390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
831490286Sobrien	(and:SI (match_dup 1) (match_dup 2)))]
831590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
831690286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
831790286Sobrien  "and{l}\t{%2, %0|%0, %2}"
831890286Sobrien  [(set_attr "type" "alu")
831990286Sobrien   (set_attr "mode" "SI")])
832090286Sobrien
832190286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
832290286Sobrien(define_insn "*andsi_2_zext"
832390286Sobrien  [(set (reg 17)
832490286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
832590286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
832690286Sobrien		 (const_int 0)))
832790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
832890286Sobrien	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
832990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
833090286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
833190286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
833290286Sobrien  [(set_attr "type" "alu")
833390286Sobrien   (set_attr "mode" "SI")])
833490286Sobrien
833590286Sobrien(define_expand "andhi3"
833690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
833790286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
833890286Sobrien		(match_operand:HI 2 "general_operand" "")))
833990286Sobrien   (clobber (reg:CC 17))]
834090286Sobrien  "TARGET_HIMODE_MATH"
834190286Sobrien  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
834290286Sobrien
834390286Sobrien(define_insn "*andhi_1"
834490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
834590286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
834690286Sobrien		(match_operand:HI 2 "general_operand" "ri,rm,L")))
834790286Sobrien   (clobber (reg:CC 17))]
834890286Sobrien  "ix86_binary_operator_ok (AND, HImode, operands)"
834990286Sobrien{
835090286Sobrien  switch (get_attr_type (insn))
835150650Sobrien    {
835290286Sobrien    case TYPE_IMOVX:
835390286Sobrien      if (GET_CODE (operands[2]) != CONST_INT)
835490286Sobrien	abort ();
835590286Sobrien      if (INTVAL (operands[2]) == 0xff)
835690286Sobrien	return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
835790286Sobrien      abort ();
835890286Sobrien
835990286Sobrien    default:
836090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
836190286Sobrien	abort ();
836290286Sobrien
836390286Sobrien      return "and{w}\t{%2, %0|%0, %2}";
836450650Sobrien    }
836590286Sobrien}
836690286Sobrien  [(set_attr "type" "alu,alu,imovx")
836790286Sobrien   (set_attr "length_immediate" "*,*,0")
836890286Sobrien   (set_attr "mode" "HI,HI,SI")])
836950650Sobrien
837090286Sobrien(define_insn "*andhi_2"
837190286Sobrien  [(set (reg 17)
837290286Sobrien	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
837390286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
837490286Sobrien		 (const_int 0)))
837590286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
837690286Sobrien	(and:HI (match_dup 1) (match_dup 2)))]
837790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
837890286Sobrien   && ix86_binary_operator_ok (AND, HImode, operands)"
837990286Sobrien  "and{w}\t{%2, %0|%0, %2}"
838090286Sobrien  [(set_attr "type" "alu")
838190286Sobrien   (set_attr "mode" "HI")])
838290286Sobrien
838390286Sobrien(define_expand "andqi3"
838490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
838590286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
838690286Sobrien		(match_operand:QI 2 "general_operand" "")))
838790286Sobrien   (clobber (reg:CC 17))]
838890286Sobrien  "TARGET_QIMODE_MATH"
838990286Sobrien  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
839090286Sobrien
839190286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
839290286Sobrien(define_insn "*andqi_1"
839390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
839490286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
839590286Sobrien		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
839690286Sobrien   (clobber (reg:CC 17))]
839790286Sobrien  "ix86_binary_operator_ok (AND, QImode, operands)"
839890286Sobrien  "@
839990286Sobrien   and{b}\t{%2, %0|%0, %2}
840090286Sobrien   and{b}\t{%2, %0|%0, %2}
840190286Sobrien   and{l}\t{%k2, %k0|%k0, %k2}"
840290286Sobrien  [(set_attr "type" "alu")
840390286Sobrien   (set_attr "mode" "QI,QI,SI")])
840490286Sobrien
840590286Sobrien(define_insn "*andqi_1_slp"
840690286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
840790286Sobrien	(and:QI (match_dup 0)
840890286Sobrien		(match_operand:QI 1 "general_operand" "qi,qmi")))
840990286Sobrien   (clobber (reg:CC 17))]
8410117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8411117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
841290286Sobrien  "and{b}\t{%1, %0|%0, %1}"
841390286Sobrien  [(set_attr "type" "alu1")
841490286Sobrien   (set_attr "mode" "QI")])
841590286Sobrien
8416146906Skan(define_insn "*andqi_2_maybe_si"
841790286Sobrien  [(set (reg 17)
841890286Sobrien	(compare (and:QI
8419146906Skan		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8420146906Skan		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
842190286Sobrien		 (const_int 0)))
842290286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
842390286Sobrien	(and:QI (match_dup 1) (match_dup 2)))]
8424146906Skan  "ix86_binary_operator_ok (AND, QImode, operands)
8425146906Skan   && ix86_match_ccmode (insn,
8426146906Skan			 GET_CODE (operands[2]) == CONST_INT
8427146906Skan			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
842890286Sobrien{
842990286Sobrien  if (which_alternative == 2)
843050650Sobrien    {
8431146906Skan      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
843290286Sobrien        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
843390286Sobrien      return "and{l}\t{%2, %k0|%k0, %2}";
843450650Sobrien    }
843590286Sobrien  return "and{b}\t{%2, %0|%0, %2}";
843690286Sobrien}
843790286Sobrien  [(set_attr "type" "alu")
843890286Sobrien   (set_attr "mode" "QI,QI,SI")])
843950650Sobrien
8440146906Skan(define_insn "*andqi_2"
8441146906Skan  [(set (reg 17)
8442146906Skan	(compare (and:QI
8443146906Skan		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8444146906Skan		   (match_operand:QI 2 "general_operand" "qim,qi"))
8445146906Skan		 (const_int 0)))
8446146906Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8447146906Skan	(and:QI (match_dup 1) (match_dup 2)))]
8448146906Skan  "ix86_match_ccmode (insn, CCNOmode)
8449146906Skan   && ix86_binary_operator_ok (AND, QImode, operands)"
8450146906Skan  "and{b}\t{%2, %0|%0, %2}"
8451146906Skan  [(set_attr "type" "alu")
8452146906Skan   (set_attr "mode" "QI")])
8453146906Skan
845490286Sobrien(define_insn "*andqi_2_slp"
845590286Sobrien  [(set (reg 17)
845690286Sobrien	(compare (and:QI
845790286Sobrien		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
845890286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
845990286Sobrien		 (const_int 0)))
846090286Sobrien   (set (strict_low_part (match_dup 0))
846190286Sobrien	(and:QI (match_dup 0) (match_dup 1)))]
8462117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8463117404Skan   && ix86_match_ccmode (insn, CCNOmode)
8464117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
846590286Sobrien  "and{b}\t{%1, %0|%0, %1}"
846690286Sobrien  [(set_attr "type" "alu1")
846790286Sobrien   (set_attr "mode" "QI")])
846818334Speter
846990286Sobrien;; ??? A bug in recog prevents it from recognizing a const_int as an
847090286Sobrien;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
847190286Sobrien;; for a QImode operand, which of course failed.
847218334Speter
847390286Sobrien(define_insn "andqi_ext_0"
847490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
847590286Sobrien			 (const_int 8)
847690286Sobrien			 (const_int 8))
847790286Sobrien	(and:SI 
847890286Sobrien	  (zero_extract:SI
847990286Sobrien	    (match_operand 1 "ext_register_operand" "0")
848090286Sobrien	    (const_int 8)
848190286Sobrien	    (const_int 8))
848290286Sobrien	  (match_operand 2 "const_int_operand" "n")))
848390286Sobrien   (clobber (reg:CC 17))]
8484117404Skan  ""
848590286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
848690286Sobrien  [(set_attr "type" "alu")
848790286Sobrien   (set_attr "length_immediate" "1")
848890286Sobrien   (set_attr "mode" "QI")])
848918334Speter
849090286Sobrien;; Generated by peephole translating test to and.  This shows up
849190286Sobrien;; often in fp comparisons.
849290286Sobrien
849390286Sobrien(define_insn "*andqi_ext_0_cc"
849490286Sobrien  [(set (reg 17)
849590286Sobrien	(compare
849690286Sobrien	  (and:SI
849790286Sobrien	    (zero_extract:SI
849890286Sobrien	      (match_operand 1 "ext_register_operand" "0")
849990286Sobrien	      (const_int 8)
850090286Sobrien	      (const_int 8))
850190286Sobrien	    (match_operand 2 "const_int_operand" "n"))
850290286Sobrien	  (const_int 0)))
850390286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
850490286Sobrien			 (const_int 8)
850590286Sobrien			 (const_int 8))
850690286Sobrien	(and:SI 
850790286Sobrien	  (zero_extract:SI
850890286Sobrien	    (match_dup 1)
850990286Sobrien	    (const_int 8)
851090286Sobrien	    (const_int 8))
851190286Sobrien	  (match_dup 2)))]
8512117404Skan  "ix86_match_ccmode (insn, CCNOmode)"
851390286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
851490286Sobrien  [(set_attr "type" "alu")
851590286Sobrien   (set_attr "length_immediate" "1")
851690286Sobrien   (set_attr "mode" "QI")])
851790286Sobrien
851890286Sobrien(define_insn "*andqi_ext_1"
851990286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
852090286Sobrien			 (const_int 8)
852190286Sobrien			 (const_int 8))
852290286Sobrien	(and:SI 
852390286Sobrien	  (zero_extract:SI
852490286Sobrien	    (match_operand 1 "ext_register_operand" "0")
852590286Sobrien	    (const_int 8)
852690286Sobrien	    (const_int 8))
852790286Sobrien	  (zero_extend:SI
852890286Sobrien	    (match_operand:QI 2 "general_operand" "Qm"))))
852990286Sobrien   (clobber (reg:CC 17))]
853090286Sobrien  "!TARGET_64BIT"
853190286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
853290286Sobrien  [(set_attr "type" "alu")
853390286Sobrien   (set_attr "length_immediate" "0")
853490286Sobrien   (set_attr "mode" "QI")])
853590286Sobrien
853690286Sobrien(define_insn "*andqi_ext_1_rex64"
853790286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
853890286Sobrien			 (const_int 8)
853990286Sobrien			 (const_int 8))
854090286Sobrien	(and:SI 
854190286Sobrien	  (zero_extract:SI
854290286Sobrien	    (match_operand 1 "ext_register_operand" "0")
854390286Sobrien	    (const_int 8)
854490286Sobrien	    (const_int 8))
854590286Sobrien	  (zero_extend:SI
854690286Sobrien	    (match_operand 2 "ext_register_operand" "Q"))))
854790286Sobrien   (clobber (reg:CC 17))]
854890286Sobrien  "TARGET_64BIT"
854990286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
855090286Sobrien  [(set_attr "type" "alu")
855190286Sobrien   (set_attr "length_immediate" "0")
855290286Sobrien   (set_attr "mode" "QI")])
855390286Sobrien
855490286Sobrien(define_insn "*andqi_ext_2"
855590286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
855690286Sobrien			 (const_int 8)
855790286Sobrien			 (const_int 8))
855818334Speter	(and:SI
855990286Sobrien	  (zero_extract:SI
856090286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
856190286Sobrien	    (const_int 8)
856290286Sobrien	    (const_int 8))
856390286Sobrien	  (zero_extract:SI
856490286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
856590286Sobrien	    (const_int 8)
856690286Sobrien	    (const_int 8))))
856790286Sobrien   (clobber (reg:CC 17))]
856890286Sobrien  ""
856990286Sobrien  "and{b}\t{%h2, %h0|%h0, %h2}"
857090286Sobrien  [(set_attr "type" "alu")
857190286Sobrien   (set_attr "length_immediate" "0")
857290286Sobrien   (set_attr "mode" "QI")])
8573117404Skan
8574117404Skan;; Convert wide AND instructions with immediate operand to shorter QImode
8575117404Skan;; equivalents when possible.
8576132727Skan;; Don't do the splitting with memory operands, since it introduces risk
8577117404Skan;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8578117404Skan;; for size, but that can (should?) be handled by generic code instead.
8579117404Skan(define_split
8580117404Skan  [(set (match_operand 0 "register_operand" "")
8581117404Skan	(and (match_operand 1 "register_operand" "")
8582117404Skan	     (match_operand 2 "const_int_operand" "")))
8583117404Skan   (clobber (reg:CC 17))]
8584117404Skan   "reload_completed
8585117404Skan    && QI_REG_P (operands[0])
8586117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8587117404Skan    && !(~INTVAL (operands[2]) & ~(255 << 8))
8588117404Skan    && GET_MODE (operands[0]) != QImode"
8589117404Skan  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8590117404Skan		   (and:SI (zero_extract:SI (match_dup 1)
8591117404Skan					    (const_int 8) (const_int 8))
8592117404Skan			   (match_dup 2)))
8593117404Skan	      (clobber (reg:CC 17))])]
8594117404Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
8595117404Skan   operands[1] = gen_lowpart (SImode, operands[1]);
8596117404Skan   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8597117404Skan
8598117404Skan;; Since AND can be encoded with sign extended immediate, this is only
8599117404Skan;; profitable when 7th bit is not set.
8600117404Skan(define_split
8601117404Skan  [(set (match_operand 0 "register_operand" "")
8602117404Skan	(and (match_operand 1 "general_operand" "")
8603117404Skan	     (match_operand 2 "const_int_operand" "")))
8604117404Skan   (clobber (reg:CC 17))]
8605117404Skan   "reload_completed
8606117404Skan    && ANY_QI_REG_P (operands[0])
8607117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8608117404Skan    && !(~INTVAL (operands[2]) & ~255)
8609117404Skan    && !(INTVAL (operands[2]) & 128)
8610117404Skan    && GET_MODE (operands[0]) != QImode"
8611117404Skan  [(parallel [(set (strict_low_part (match_dup 0))
8612117404Skan		   (and:QI (match_dup 1)
8613117404Skan			   (match_dup 2)))
8614117404Skan	      (clobber (reg:CC 17))])]
8615117404Skan  "operands[0] = gen_lowpart (QImode, operands[0]);
8616117404Skan   operands[1] = gen_lowpart (QImode, operands[1]);
8617117404Skan   operands[2] = gen_lowpart (QImode, operands[2]);")
861818334Speter
861990286Sobrien;; Logical inclusive OR instructions
862018334Speter
862190286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
862290286Sobrien;; If this is considered useful, it should be done with splitters.
862390286Sobrien
862490286Sobrien(define_expand "iordi3"
862590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
862690286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
862790286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
862890286Sobrien   (clobber (reg:CC 17))]
862990286Sobrien  "TARGET_64BIT"
863090286Sobrien  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
863190286Sobrien
863290286Sobrien(define_insn "*iordi_1_rex64"
863390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
863490286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
863590286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
863690286Sobrien   (clobber (reg:CC 17))]
863790286Sobrien  "TARGET_64BIT
863890286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
863990286Sobrien  "or{q}\t{%2, %0|%0, %2}"
864090286Sobrien  [(set_attr "type" "alu")
864190286Sobrien   (set_attr "mode" "DI")])
864290286Sobrien
864390286Sobrien(define_insn "*iordi_2_rex64"
864490286Sobrien  [(set (reg 17)
864590286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
864690286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
864790286Sobrien		 (const_int 0)))
864890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
864990286Sobrien	(ior:DI (match_dup 1) (match_dup 2)))]
865090286Sobrien  "TARGET_64BIT
865190286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
865290286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
865390286Sobrien  "or{q}\t{%2, %0|%0, %2}"
865490286Sobrien  [(set_attr "type" "alu")
865590286Sobrien   (set_attr "mode" "DI")])
865690286Sobrien
865790286Sobrien(define_insn "*iordi_3_rex64"
865890286Sobrien  [(set (reg 17)
865990286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
866090286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
866190286Sobrien		 (const_int 0)))
866290286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
866390286Sobrien  "TARGET_64BIT
866490286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
866590286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
866690286Sobrien  "or{q}\t{%2, %0|%0, %2}"
866790286Sobrien  [(set_attr "type" "alu")
866890286Sobrien   (set_attr "mode" "DI")])
866990286Sobrien
867090286Sobrien
867190286Sobrien(define_expand "iorsi3"
867290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
867390286Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
867490286Sobrien		(match_operand:SI 2 "general_operand" "")))
867590286Sobrien   (clobber (reg:CC 17))]
867690286Sobrien  ""
867790286Sobrien  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
867890286Sobrien
867990286Sobrien(define_insn "*iorsi_1"
868050650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
868150650Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
868290286Sobrien		(match_operand:SI 2 "general_operand" "ri,rmi")))
868390286Sobrien   (clobber (reg:CC 17))]
868490286Sobrien  "ix86_binary_operator_ok (IOR, SImode, operands)"
868590286Sobrien  "or{l}\t{%2, %0|%0, %2}"
868690286Sobrien  [(set_attr "type" "alu")
868790286Sobrien   (set_attr "mode" "SI")])
868850650Sobrien
868990286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
869090286Sobrien(define_insn "*iorsi_1_zext"
869190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
869290286Sobrien	(zero_extend:DI
869390286Sobrien	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
869490286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
869590286Sobrien   (clobber (reg:CC 17))]
869690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
869790286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
869890286Sobrien  [(set_attr "type" "alu")
869990286Sobrien   (set_attr "mode" "SI")])
870050650Sobrien
870190286Sobrien(define_insn "*iorsi_1_zext_imm"
870290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
870390286Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
870490286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
870590286Sobrien   (clobber (reg:CC 17))]
870690286Sobrien  "TARGET_64BIT"
870790286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
870890286Sobrien  [(set_attr "type" "alu")
870990286Sobrien   (set_attr "mode" "SI")])
871050650Sobrien
871190286Sobrien(define_insn "*iorsi_2"
871290286Sobrien  [(set (reg 17)
871390286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
871490286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
871590286Sobrien		 (const_int 0)))
871690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
871790286Sobrien	(ior:SI (match_dup 1) (match_dup 2)))]
871890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
871990286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
872090286Sobrien  "or{l}\t{%2, %0|%0, %2}"
872190286Sobrien  [(set_attr "type" "alu")
872290286Sobrien   (set_attr "mode" "SI")])
872350650Sobrien
872490286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
872590286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
872690286Sobrien(define_insn "*iorsi_2_zext"
872790286Sobrien  [(set (reg 17)
872890286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
872990286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
873090286Sobrien		 (const_int 0)))
873190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
873290286Sobrien	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
873390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
873490286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
873590286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
873690286Sobrien  [(set_attr "type" "alu")
873790286Sobrien   (set_attr "mode" "SI")])
873850650Sobrien
873990286Sobrien(define_insn "*iorsi_2_zext_imm"
874090286Sobrien  [(set (reg 17)
874190286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
874290286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
874390286Sobrien		 (const_int 0)))
874490286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
874590286Sobrien	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
874690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
874790286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
874890286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
874990286Sobrien  [(set_attr "type" "alu")
875090286Sobrien   (set_attr "mode" "SI")])
875150650Sobrien
875290286Sobrien(define_insn "*iorsi_3"
875390286Sobrien  [(set (reg 17)
875490286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
875590286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
875690286Sobrien		 (const_int 0)))
875790286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
875890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
875990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
876090286Sobrien  "or{l}\t{%2, %0|%0, %2}"
876190286Sobrien  [(set_attr "type" "alu")
876290286Sobrien   (set_attr "mode" "SI")])
876350650Sobrien
876490286Sobrien(define_expand "iorhi3"
876590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
876690286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
876790286Sobrien		(match_operand:HI 2 "general_operand" "")))
876890286Sobrien   (clobber (reg:CC 17))]
876990286Sobrien  "TARGET_HIMODE_MATH"
877090286Sobrien  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
877150650Sobrien
877290286Sobrien(define_insn "*iorhi_1"
877390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
877490286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
877590286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
877690286Sobrien   (clobber (reg:CC 17))]
877790286Sobrien  "ix86_binary_operator_ok (IOR, HImode, operands)"
877890286Sobrien  "or{w}\t{%2, %0|%0, %2}"
877990286Sobrien  [(set_attr "type" "alu")
878090286Sobrien   (set_attr "mode" "HI")])
878118334Speter
878290286Sobrien(define_insn "*iorhi_2"
878390286Sobrien  [(set (reg 17)
878490286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
878590286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
878690286Sobrien		 (const_int 0)))
878790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
878890286Sobrien	(ior:HI (match_dup 1) (match_dup 2)))]
878990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
879090286Sobrien   && ix86_binary_operator_ok (IOR, HImode, operands)"
879190286Sobrien  "or{w}\t{%2, %0|%0, %2}"
879290286Sobrien  [(set_attr "type" "alu")
879390286Sobrien   (set_attr "mode" "HI")])
879418334Speter
879590286Sobrien(define_insn "*iorhi_3"
879690286Sobrien  [(set (reg 17)
879790286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
879890286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
879990286Sobrien		 (const_int 0)))
880090286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
880190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
880290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
880390286Sobrien  "or{w}\t{%2, %0|%0, %2}"
880490286Sobrien  [(set_attr "type" "alu")
880590286Sobrien   (set_attr "mode" "HI")])
880650650Sobrien
880790286Sobrien(define_expand "iorqi3"
880890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
880990286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
881090286Sobrien		(match_operand:QI 2 "general_operand" "")))
881190286Sobrien   (clobber (reg:CC 17))]
881290286Sobrien  "TARGET_QIMODE_MATH"
881390286Sobrien  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
881418334Speter
881590286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
881690286Sobrien(define_insn "*iorqi_1"
881790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
881890286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
881990286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
882090286Sobrien   (clobber (reg:CC 17))]
882190286Sobrien  "ix86_binary_operator_ok (IOR, QImode, operands)"
882290286Sobrien  "@
882390286Sobrien   or{b}\t{%2, %0|%0, %2}
882490286Sobrien   or{b}\t{%2, %0|%0, %2}
882590286Sobrien   or{l}\t{%k2, %k0|%k0, %k2}"
882690286Sobrien  [(set_attr "type" "alu")
882790286Sobrien   (set_attr "mode" "QI,QI,SI")])
882850650Sobrien
882990286Sobrien(define_insn "*iorqi_1_slp"
883090286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
883190286Sobrien	(ior:QI (match_dup 0)
883290286Sobrien		(match_operand:QI 1 "general_operand" "qmi,qi")))
883390286Sobrien   (clobber (reg:CC 17))]
8834117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8835117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
883690286Sobrien  "or{b}\t{%1, %0|%0, %1}"
883790286Sobrien  [(set_attr "type" "alu1")
883890286Sobrien   (set_attr "mode" "QI")])
883918334Speter
884090286Sobrien(define_insn "*iorqi_2"
884190286Sobrien  [(set (reg 17)
884290286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
884390286Sobrien			 (match_operand:QI 2 "general_operand" "qim,qi"))
884490286Sobrien		 (const_int 0)))
884590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
884690286Sobrien	(ior:QI (match_dup 1) (match_dup 2)))]
884790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
884890286Sobrien   && ix86_binary_operator_ok (IOR, QImode, operands)"
884990286Sobrien  "or{b}\t{%2, %0|%0, %2}"
885090286Sobrien  [(set_attr "type" "alu")
885190286Sobrien   (set_attr "mode" "QI")])
885218334Speter
885390286Sobrien(define_insn "*iorqi_2_slp"
885490286Sobrien  [(set (reg 17)
885590286Sobrien	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
885690286Sobrien			 (match_operand:QI 1 "general_operand" "qim,qi"))
885790286Sobrien		 (const_int 0)))
885890286Sobrien   (set (strict_low_part (match_dup 0))
885990286Sobrien	(ior:QI (match_dup 0) (match_dup 1)))]
8860117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8861117404Skan   && ix86_match_ccmode (insn, CCNOmode)
8862117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
886390286Sobrien  "or{b}\t{%1, %0|%0, %1}"
886490286Sobrien  [(set_attr "type" "alu1")
886590286Sobrien   (set_attr "mode" "QI")])
886618334Speter
886790286Sobrien(define_insn "*iorqi_3"
886890286Sobrien  [(set (reg 17)
886990286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
887090286Sobrien			 (match_operand:QI 2 "general_operand" "qim"))
887190286Sobrien		 (const_int 0)))
887290286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
887390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
887490286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
887590286Sobrien  "or{b}\t{%2, %0|%0, %2}"
887690286Sobrien  [(set_attr "type" "alu")
887790286Sobrien   (set_attr "mode" "QI")])
887818334Speter
8879117404Skan(define_insn "iorqi_ext_0"
8880117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8881117404Skan			 (const_int 8)
8882117404Skan			 (const_int 8))
8883117404Skan	(ior:SI 
8884117404Skan	  (zero_extract:SI
8885117404Skan	    (match_operand 1 "ext_register_operand" "0")
8886117404Skan	    (const_int 8)
8887117404Skan	    (const_int 8))
8888117404Skan	  (match_operand 2 "const_int_operand" "n")))
8889117404Skan   (clobber (reg:CC 17))]
8890117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8891117404Skan  "or{b}\t{%2, %h0|%h0, %2}"
8892117404Skan  [(set_attr "type" "alu")
8893117404Skan   (set_attr "length_immediate" "1")
8894117404Skan   (set_attr "mode" "QI")])
8895117404Skan
8896117404Skan(define_insn "*iorqi_ext_1"
8897117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8898117404Skan			 (const_int 8)
8899117404Skan			 (const_int 8))
8900117404Skan	(ior:SI 
8901117404Skan	  (zero_extract:SI
8902117404Skan	    (match_operand 1 "ext_register_operand" "0")
8903117404Skan	    (const_int 8)
8904117404Skan	    (const_int 8))
8905117404Skan	  (zero_extend:SI
8906117404Skan	    (match_operand:QI 2 "general_operand" "Qm"))))
8907117404Skan   (clobber (reg:CC 17))]
8908117404Skan  "!TARGET_64BIT
8909117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910117404Skan  "or{b}\t{%2, %h0|%h0, %2}"
8911117404Skan  [(set_attr "type" "alu")
8912117404Skan   (set_attr "length_immediate" "0")
8913117404Skan   (set_attr "mode" "QI")])
8914117404Skan
8915117404Skan(define_insn "*iorqi_ext_1_rex64"
8916117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8917117404Skan			 (const_int 8)
8918117404Skan			 (const_int 8))
8919117404Skan	(ior:SI 
8920117404Skan	  (zero_extract:SI
8921117404Skan	    (match_operand 1 "ext_register_operand" "0")
8922117404Skan	    (const_int 8)
8923117404Skan	    (const_int 8))
8924117404Skan	  (zero_extend:SI
8925117404Skan	    (match_operand 2 "ext_register_operand" "Q"))))
8926117404Skan   (clobber (reg:CC 17))]
8927117404Skan  "TARGET_64BIT
8928117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8929117404Skan  "or{b}\t{%2, %h0|%h0, %2}"
8930117404Skan  [(set_attr "type" "alu")
8931117404Skan   (set_attr "length_immediate" "0")
8932117404Skan   (set_attr "mode" "QI")])
8933117404Skan
8934117404Skan(define_insn "*iorqi_ext_2"
8935117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8936117404Skan			 (const_int 8)
8937117404Skan			 (const_int 8))
8938117404Skan	(ior:SI 
8939117404Skan	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8940117404Skan	  		   (const_int 8)
8941117404Skan			   (const_int 8))
8942117404Skan	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8943117404Skan	  		   (const_int 8)
8944117404Skan			   (const_int 8))))
8945117404Skan   (clobber (reg:CC 17))]
8946117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8947117404Skan  "ior{b}\t{%h2, %h0|%h0, %h2}"
8948117404Skan  [(set_attr "type" "alu")
8949117404Skan   (set_attr "length_immediate" "0")
8950117404Skan   (set_attr "mode" "QI")])
8951117404Skan
8952117404Skan(define_split
8953117404Skan  [(set (match_operand 0 "register_operand" "")
8954117404Skan	(ior (match_operand 1 "register_operand" "")
8955117404Skan	     (match_operand 2 "const_int_operand" "")))
8956117404Skan   (clobber (reg:CC 17))]
8957117404Skan   "reload_completed
8958117404Skan    && QI_REG_P (operands[0])
8959117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8960117404Skan    && !(INTVAL (operands[2]) & ~(255 << 8))
8961117404Skan    && GET_MODE (operands[0]) != QImode"
8962117404Skan  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8963117404Skan		   (ior:SI (zero_extract:SI (match_dup 1)
8964117404Skan					    (const_int 8) (const_int 8))
8965117404Skan			   (match_dup 2)))
8966117404Skan	      (clobber (reg:CC 17))])]
8967117404Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
8968117404Skan   operands[1] = gen_lowpart (SImode, operands[1]);
8969117404Skan   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8970117404Skan
8971117404Skan;; Since OR can be encoded with sign extended immediate, this is only
8972117404Skan;; profitable when 7th bit is set.
8973117404Skan(define_split
8974117404Skan  [(set (match_operand 0 "register_operand" "")
8975117404Skan	(ior (match_operand 1 "general_operand" "")
8976117404Skan	     (match_operand 2 "const_int_operand" "")))
8977117404Skan   (clobber (reg:CC 17))]
8978117404Skan   "reload_completed
8979117404Skan    && ANY_QI_REG_P (operands[0])
8980117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8981117404Skan    && !(INTVAL (operands[2]) & ~255)
8982117404Skan    && (INTVAL (operands[2]) & 128)
8983117404Skan    && GET_MODE (operands[0]) != QImode"
8984117404Skan  [(parallel [(set (strict_low_part (match_dup 0))
8985117404Skan		   (ior:QI (match_dup 1)
8986117404Skan			   (match_dup 2)))
8987117404Skan	      (clobber (reg:CC 17))])]
8988117404Skan  "operands[0] = gen_lowpart (QImode, operands[0]);
8989117404Skan   operands[1] = gen_lowpart (QImode, operands[1]);
8990117404Skan   operands[2] = gen_lowpart (QImode, operands[2]);")
899190286Sobrien
899290286Sobrien;; Logical XOR instructions
899390286Sobrien
899490286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
899590286Sobrien;; If this is considered useful, it should be done with splitters.
899690286Sobrien
899790286Sobrien(define_expand "xordi3"
899890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
899990286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
900090286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
900190286Sobrien   (clobber (reg:CC 17))]
900290286Sobrien  "TARGET_64BIT"
900390286Sobrien  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
900490286Sobrien
900590286Sobrien(define_insn "*xordi_1_rex64"
900690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
900790286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
900890286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
900990286Sobrien   (clobber (reg:CC 17))]
901090286Sobrien  "TARGET_64BIT
901190286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
901290286Sobrien  "@
901390286Sobrien   xor{q}\t{%2, %0|%0, %2} 
901490286Sobrien   xor{q}\t{%2, %0|%0, %2}"
901590286Sobrien  [(set_attr "type" "alu")
901690286Sobrien   (set_attr "mode" "DI,DI")])
901790286Sobrien
901890286Sobrien(define_insn "*xordi_2_rex64"
901990286Sobrien  [(set (reg 17)
902090286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
902190286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
902290286Sobrien		 (const_int 0)))
902390286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
902490286Sobrien	(xor:DI (match_dup 1) (match_dup 2)))]
902590286Sobrien  "TARGET_64BIT
902690286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
902790286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
902890286Sobrien  "@
902990286Sobrien   xor{q}\t{%2, %0|%0, %2} 
903090286Sobrien   xor{q}\t{%2, %0|%0, %2}"
903190286Sobrien  [(set_attr "type" "alu")
903290286Sobrien   (set_attr "mode" "DI,DI")])
903390286Sobrien
903490286Sobrien(define_insn "*xordi_3_rex64"
903590286Sobrien  [(set (reg 17)
903690286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
903790286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
903890286Sobrien		 (const_int 0)))
903990286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
904090286Sobrien  "TARGET_64BIT
904190286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
904290286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
904390286Sobrien  "xor{q}\t{%2, %0|%0, %2}"
904490286Sobrien  [(set_attr "type" "alu")
904590286Sobrien   (set_attr "mode" "DI")])
904690286Sobrien
904790286Sobrien(define_expand "xorsi3"
904890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
904990286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
905090286Sobrien		(match_operand:SI 2 "general_operand" "")))
905190286Sobrien   (clobber (reg:CC 17))]
905218334Speter  ""
905390286Sobrien  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
905418334Speter
905590286Sobrien(define_insn "*xorsi_1"
905690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
905790286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
905890286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm")))
905990286Sobrien   (clobber (reg:CC 17))]
906090286Sobrien  "ix86_binary_operator_ok (XOR, SImode, operands)"
906190286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
906290286Sobrien  [(set_attr "type" "alu")
906390286Sobrien   (set_attr "mode" "SI")])
906418334Speter
906590286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
906690286Sobrien;; Add speccase for immediates
906790286Sobrien(define_insn "*xorsi_1_zext"
906890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
906990286Sobrien	(zero_extend:DI
907090286Sobrien	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
907190286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
907290286Sobrien   (clobber (reg:CC 17))]
907390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
907490286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
907590286Sobrien  [(set_attr "type" "alu")
907690286Sobrien   (set_attr "mode" "SI")])
907750650Sobrien
907890286Sobrien(define_insn "*xorsi_1_zext_imm"
907990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
908090286Sobrien	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
908190286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
908290286Sobrien   (clobber (reg:CC 17))]
908390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
908490286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
908590286Sobrien  [(set_attr "type" "alu")
908690286Sobrien   (set_attr "mode" "SI")])
908750650Sobrien
908890286Sobrien(define_insn "*xorsi_2"
908990286Sobrien  [(set (reg 17)
909090286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
909190286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
909290286Sobrien		 (const_int 0)))
909390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
909490286Sobrien	(xor:SI (match_dup 1) (match_dup 2)))]
909590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
909690286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
909790286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
909890286Sobrien  [(set_attr "type" "alu")
909990286Sobrien   (set_attr "mode" "SI")])
910050650Sobrien
910190286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
910290286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
910390286Sobrien(define_insn "*xorsi_2_zext"
910490286Sobrien  [(set (reg 17)
910590286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
910690286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
910790286Sobrien		 (const_int 0)))
910890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
910990286Sobrien	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
911090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
911190286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
911290286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
911390286Sobrien  [(set_attr "type" "alu")
911490286Sobrien   (set_attr "mode" "SI")])
911550650Sobrien
911690286Sobrien(define_insn "*xorsi_2_zext_imm"
911790286Sobrien  [(set (reg 17)
911890286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
911990286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
912090286Sobrien		 (const_int 0)))
912190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
912290286Sobrien	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
912390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
912490286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
912590286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
912690286Sobrien  [(set_attr "type" "alu")
912790286Sobrien   (set_attr "mode" "SI")])
912850650Sobrien
912990286Sobrien(define_insn "*xorsi_3"
913090286Sobrien  [(set (reg 17)
913190286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
913290286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
913390286Sobrien		 (const_int 0)))
913490286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
913590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
913690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
913790286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
913890286Sobrien  [(set_attr "type" "alu")
913990286Sobrien   (set_attr "mode" "SI")])
914018334Speter
914190286Sobrien(define_expand "xorhi3"
914290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
914390286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
914490286Sobrien		(match_operand:HI 2 "general_operand" "")))
914590286Sobrien   (clobber (reg:CC 17))]
914690286Sobrien  "TARGET_HIMODE_MATH"
914790286Sobrien  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
914818334Speter
914990286Sobrien(define_insn "*xorhi_1"
915090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
915190286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
915290286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
915390286Sobrien   (clobber (reg:CC 17))]
915490286Sobrien  "ix86_binary_operator_ok (XOR, HImode, operands)"
915590286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
915690286Sobrien  [(set_attr "type" "alu")
915790286Sobrien   (set_attr "mode" "HI")])
915818334Speter
915990286Sobrien(define_insn "*xorhi_2"
916090286Sobrien  [(set (reg 17)
916190286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
916290286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
916390286Sobrien		 (const_int 0)))
916490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
916590286Sobrien	(xor:HI (match_dup 1) (match_dup 2)))]
916690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
916790286Sobrien   && ix86_binary_operator_ok (XOR, HImode, operands)"
916890286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
916990286Sobrien  [(set_attr "type" "alu")
917090286Sobrien   (set_attr "mode" "HI")])
917150650Sobrien
917290286Sobrien(define_insn "*xorhi_3"
917390286Sobrien  [(set (reg 17)
917490286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
917590286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
917690286Sobrien		 (const_int 0)))
917790286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
917890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
917990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
918090286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
918190286Sobrien  [(set_attr "type" "alu")
918290286Sobrien   (set_attr "mode" "HI")])
918350650Sobrien
918490286Sobrien(define_expand "xorqi3"
918590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
918690286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
918790286Sobrien		(match_operand:QI 2 "general_operand" "")))
918890286Sobrien   (clobber (reg:CC 17))]
918990286Sobrien  "TARGET_QIMODE_MATH"
919090286Sobrien  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
919150650Sobrien
919290286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
919390286Sobrien(define_insn "*xorqi_1"
919490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
919590286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
919690286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
919790286Sobrien   (clobber (reg:CC 17))]
919890286Sobrien  "ix86_binary_operator_ok (XOR, QImode, operands)"
919990286Sobrien  "@
920090286Sobrien   xor{b}\t{%2, %0|%0, %2}
920190286Sobrien   xor{b}\t{%2, %0|%0, %2}
920290286Sobrien   xor{l}\t{%k2, %k0|%k0, %k2}"
920390286Sobrien  [(set_attr "type" "alu")
920490286Sobrien   (set_attr "mode" "QI,QI,SI")])
920518334Speter
9206117404Skan(define_insn "*xorqi_1_slp"
9207117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9208117404Skan	(xor:QI (match_dup 0)
9209117404Skan		(match_operand:QI 1 "general_operand" "qi,qmi")))
9210117404Skan   (clobber (reg:CC 17))]
9211117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9213117404Skan  "xor{b}\t{%1, %0|%0, %1}"
9214117404Skan  [(set_attr "type" "alu1")
9215117404Skan   (set_attr "mode" "QI")])
9216117404Skan
9217117404Skan(define_insn "xorqi_ext_0"
9218117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9219117404Skan			 (const_int 8)
9220117404Skan			 (const_int 8))
9221117404Skan	(xor:SI 
9222117404Skan	  (zero_extract:SI
9223117404Skan	    (match_operand 1 "ext_register_operand" "0")
9224117404Skan	    (const_int 8)
9225117404Skan	    (const_int 8))
9226117404Skan	  (match_operand 2 "const_int_operand" "n")))
9227117404Skan   (clobber (reg:CC 17))]
9228117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9229117404Skan  "xor{b}\t{%2, %h0|%h0, %2}"
9230117404Skan  [(set_attr "type" "alu")
9231117404Skan   (set_attr "length_immediate" "1")
9232117404Skan   (set_attr "mode" "QI")])
9233117404Skan
923490286Sobrien(define_insn "*xorqi_ext_1"
923590286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
923690286Sobrien			 (const_int 8)
923790286Sobrien			 (const_int 8))
923890286Sobrien	(xor:SI 
9239117404Skan	  (zero_extract:SI
9240117404Skan	    (match_operand 1 "ext_register_operand" "0")
9241117404Skan	    (const_int 8)
9242117404Skan	    (const_int 8))
9243117404Skan	  (zero_extend:SI
9244117404Skan	    (match_operand:QI 2 "general_operand" "Qm"))))
9245117404Skan   (clobber (reg:CC 17))]
9246117404Skan  "!TARGET_64BIT
9247117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248117404Skan  "xor{b}\t{%2, %h0|%h0, %2}"
9249117404Skan  [(set_attr "type" "alu")
9250117404Skan   (set_attr "length_immediate" "0")
9251117404Skan   (set_attr "mode" "QI")])
9252117404Skan
9253117404Skan(define_insn "*xorqi_ext_1_rex64"
9254117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9255117404Skan			 (const_int 8)
9256117404Skan			 (const_int 8))
9257117404Skan	(xor:SI 
9258117404Skan	  (zero_extract:SI
9259117404Skan	    (match_operand 1 "ext_register_operand" "0")
9260117404Skan	    (const_int 8)
9261117404Skan	    (const_int 8))
9262117404Skan	  (zero_extend:SI
9263117404Skan	    (match_operand 2 "ext_register_operand" "Q"))))
9264117404Skan   (clobber (reg:CC 17))]
9265117404Skan  "TARGET_64BIT
9266117404Skan   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9267117404Skan  "xor{b}\t{%2, %h0|%h0, %2}"
9268117404Skan  [(set_attr "type" "alu")
9269117404Skan   (set_attr "length_immediate" "0")
9270117404Skan   (set_attr "mode" "QI")])
9271117404Skan
9272117404Skan(define_insn "*xorqi_ext_2"
9273117404Skan  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274117404Skan			 (const_int 8)
9275117404Skan			 (const_int 8))
9276117404Skan	(xor:SI 
927790286Sobrien	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
927890286Sobrien	  		   (const_int 8)
927990286Sobrien			   (const_int 8))
928090286Sobrien	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
928190286Sobrien	  		   (const_int 8)
928290286Sobrien			   (const_int 8))))
928390286Sobrien   (clobber (reg:CC 17))]
9284117404Skan  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
928590286Sobrien  "xor{b}\t{%h2, %h0|%h0, %h2}"
928690286Sobrien  [(set_attr "type" "alu")
928790286Sobrien   (set_attr "length_immediate" "0")
928890286Sobrien   (set_attr "mode" "QI")])
928950650Sobrien
929090286Sobrien(define_insn "*xorqi_cc_1"
929190286Sobrien  [(set (reg 17)
929290286Sobrien	(compare
929390286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
929490286Sobrien		  (match_operand:QI 2 "general_operand" "qim,qi"))
929590286Sobrien	  (const_int 0)))
929690286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
929790286Sobrien	(xor:QI (match_dup 1) (match_dup 2)))]
929890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
929990286Sobrien   && ix86_binary_operator_ok (XOR, QImode, operands)"
930090286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
930190286Sobrien  [(set_attr "type" "alu")
930290286Sobrien   (set_attr "mode" "QI")])
930350650Sobrien
9304117404Skan(define_insn "*xorqi_2_slp"
9305117404Skan  [(set (reg 17)
9306117404Skan	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9307117404Skan			 (match_operand:QI 1 "general_operand" "qim,qi"))
9308117404Skan		 (const_int 0)))
9309117404Skan   (set (strict_low_part (match_dup 0))
9310117404Skan	(xor:QI (match_dup 0) (match_dup 1)))]
9311117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9312117404Skan   && ix86_match_ccmode (insn, CCNOmode)
9313117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9314117404Skan  "xor{b}\t{%1, %0|%0, %1}"
9315117404Skan  [(set_attr "type" "alu1")
9316117404Skan   (set_attr "mode" "QI")])
9317117404Skan
931890286Sobrien(define_insn "*xorqi_cc_2"
931990286Sobrien  [(set (reg 17)
932090286Sobrien	(compare
932190286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
932290286Sobrien		  (match_operand:QI 2 "general_operand" "qim"))
932390286Sobrien	  (const_int 0)))
932490286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
932590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
932690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
932790286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
932890286Sobrien  [(set_attr "type" "alu")
932990286Sobrien   (set_attr "mode" "QI")])
933018334Speter
933190286Sobrien(define_insn "*xorqi_cc_ext_1"
933290286Sobrien  [(set (reg 17)
933390286Sobrien	(compare
933490286Sobrien	  (xor:SI
933590286Sobrien	    (zero_extract:SI
933690286Sobrien	      (match_operand 1 "ext_register_operand" "0")
933790286Sobrien	      (const_int 8)
933890286Sobrien	      (const_int 8))
933990286Sobrien	    (match_operand:QI 2 "general_operand" "qmn"))
934090286Sobrien	  (const_int 0)))
934190286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
934290286Sobrien			 (const_int 8)
934390286Sobrien			 (const_int 8))
934490286Sobrien	(xor:SI 
934590286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
934690286Sobrien	  (match_dup 2)))]
934790286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
934890286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
934990286Sobrien  [(set_attr "type" "alu")
935090286Sobrien   (set_attr "mode" "QI")])
935190286Sobrien
935290286Sobrien(define_insn "*xorqi_cc_ext_1_rex64"
935390286Sobrien  [(set (reg 17)
935490286Sobrien	(compare
935590286Sobrien	  (xor:SI
935690286Sobrien	    (zero_extract:SI
935790286Sobrien	      (match_operand 1 "ext_register_operand" "0")
935890286Sobrien	      (const_int 8)
935990286Sobrien	      (const_int 8))
936090286Sobrien	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
936190286Sobrien	  (const_int 0)))
936290286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
936390286Sobrien			 (const_int 8)
936490286Sobrien			 (const_int 8))
936590286Sobrien	(xor:SI 
936690286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
936790286Sobrien	  (match_dup 2)))]
936890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
936990286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
937090286Sobrien  [(set_attr "type" "alu")
937190286Sobrien   (set_attr "mode" "QI")])
937290286Sobrien
937390286Sobrien(define_expand "xorqi_cc_ext_1"
937490286Sobrien  [(parallel [
937590286Sobrien     (set (reg:CCNO 17)
937690286Sobrien	  (compare:CCNO
937790286Sobrien	    (xor:SI
937890286Sobrien	      (zero_extract:SI
937990286Sobrien		(match_operand 1 "ext_register_operand" "")
938090286Sobrien		(const_int 8)
938190286Sobrien		(const_int 8))
938290286Sobrien	      (match_operand:QI 2 "general_operand" ""))
938390286Sobrien	    (const_int 0)))
938490286Sobrien     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
938590286Sobrien			   (const_int 8)
938690286Sobrien			   (const_int 8))
938790286Sobrien	  (xor:SI 
938890286Sobrien	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
938990286Sobrien	    (match_dup 2)))])]
939018334Speter  ""
939190286Sobrien  "")
9392117404Skan
9393117404Skan(define_split
9394117404Skan  [(set (match_operand 0 "register_operand" "")
9395117404Skan	(xor (match_operand 1 "register_operand" "")
9396117404Skan	     (match_operand 2 "const_int_operand" "")))
9397117404Skan   (clobber (reg:CC 17))]
9398117404Skan   "reload_completed
9399117404Skan    && QI_REG_P (operands[0])
9400117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9401117404Skan    && !(INTVAL (operands[2]) & ~(255 << 8))
9402117404Skan    && GET_MODE (operands[0]) != QImode"
9403117404Skan  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9404117404Skan		   (xor:SI (zero_extract:SI (match_dup 1)
9405117404Skan					    (const_int 8) (const_int 8))
9406117404Skan			   (match_dup 2)))
9407117404Skan	      (clobber (reg:CC 17))])]
9408117404Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
9409117404Skan   operands[1] = gen_lowpart (SImode, operands[1]);
9410117404Skan   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9411117404Skan
9412117404Skan;; Since XOR can be encoded with sign extended immediate, this is only
9413117404Skan;; profitable when 7th bit is set.
9414117404Skan(define_split
9415117404Skan  [(set (match_operand 0 "register_operand" "")
9416117404Skan	(xor (match_operand 1 "general_operand" "")
9417117404Skan	     (match_operand 2 "const_int_operand" "")))
9418117404Skan   (clobber (reg:CC 17))]
9419117404Skan   "reload_completed
9420117404Skan    && ANY_QI_REG_P (operands[0])
9421117404Skan    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9422117404Skan    && !(INTVAL (operands[2]) & ~255)
9423117404Skan    && (INTVAL (operands[2]) & 128)
9424117404Skan    && GET_MODE (operands[0]) != QImode"
9425117404Skan  [(parallel [(set (strict_low_part (match_dup 0))
9426117404Skan		   (xor:QI (match_dup 1)
9427117404Skan			   (match_dup 2)))
9428117404Skan	      (clobber (reg:CC 17))])]
9429117404Skan  "operands[0] = gen_lowpart (QImode, operands[0]);
9430117404Skan   operands[1] = gen_lowpart (QImode, operands[1]);
9431117404Skan   operands[2] = gen_lowpart (QImode, operands[2]);")
943218334Speter
943390286Sobrien;; Negation instructions
943418334Speter
943590286Sobrien(define_expand "negdi2"
943690286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
943790286Sobrien		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
943890286Sobrien	      (clobber (reg:CC 17))])]
943918334Speter  ""
944090286Sobrien  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
944150650Sobrien
944290286Sobrien(define_insn "*negdi2_1"
944390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
944490286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "0")))
944590286Sobrien   (clobber (reg:CC 17))]
944690286Sobrien  "!TARGET_64BIT
944790286Sobrien   && ix86_unary_operator_ok (NEG, DImode, operands)"
944890286Sobrien  "#")
944950650Sobrien
945090286Sobrien(define_split
945190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
945290286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "")))
945390286Sobrien   (clobber (reg:CC 17))]
945490286Sobrien  "!TARGET_64BIT && reload_completed"
945590286Sobrien  [(parallel
945690286Sobrien    [(set (reg:CCZ 17)
945790286Sobrien	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
945890286Sobrien     (set (match_dup 0) (neg:SI (match_dup 2)))])
945990286Sobrien   (parallel
946090286Sobrien    [(set (match_dup 1)
946190286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
946290286Sobrien			    (match_dup 3))
946390286Sobrien		   (const_int 0)))
946490286Sobrien     (clobber (reg:CC 17))])
946590286Sobrien   (parallel
946690286Sobrien    [(set (match_dup 1)
946790286Sobrien	  (neg:SI (match_dup 1)))
946890286Sobrien     (clobber (reg:CC 17))])]
946990286Sobrien  "split_di (operands+1, 1, operands+2, operands+3);
947090286Sobrien   split_di (operands+0, 1, operands+0, operands+1);")
947150650Sobrien
947290286Sobrien(define_insn "*negdi2_1_rex64"
947390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
947490286Sobrien	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
947590286Sobrien   (clobber (reg:CC 17))]
947690286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
947790286Sobrien  "neg{q}\t%0"
947890286Sobrien  [(set_attr "type" "negnot")
947990286Sobrien   (set_attr "mode" "DI")])
948050650Sobrien
948190286Sobrien;; The problem with neg is that it does not perform (compare x 0),
948290286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
948390286Sobrien;; flag being the only useful item.
948450650Sobrien
948590286Sobrien(define_insn "*negdi2_cmpz_rex64"
948690286Sobrien  [(set (reg:CCZ 17)
948790286Sobrien	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
948890286Sobrien		     (const_int 0)))
948990286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
949090286Sobrien	(neg:DI (match_dup 1)))]
949190286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
949290286Sobrien  "neg{q}\t%0"
949390286Sobrien  [(set_attr "type" "negnot")
949490286Sobrien   (set_attr "mode" "DI")])
949550650Sobrien
949618334Speter
949790286Sobrien(define_expand "negsi2"
949890286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
949990286Sobrien		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
950090286Sobrien	      (clobber (reg:CC 17))])]
950190286Sobrien  ""
950290286Sobrien  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
950318334Speter
950490286Sobrien(define_insn "*negsi2_1"
950590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
950690286Sobrien	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
950790286Sobrien   (clobber (reg:CC 17))]
950890286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
950990286Sobrien  "neg{l}\t%0"
951090286Sobrien  [(set_attr "type" "negnot")
951190286Sobrien   (set_attr "mode" "SI")])
951250650Sobrien
951390286Sobrien;; Combine is quite creative about this pattern.
951490286Sobrien(define_insn "*negsi2_1_zext"
951590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
951690286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
951790286Sobrien					(const_int 32)))
951890286Sobrien		     (const_int 32)))
951990286Sobrien   (clobber (reg:CC 17))]
952090286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
952190286Sobrien  "neg{l}\t%k0"
952290286Sobrien  [(set_attr "type" "negnot")
952390286Sobrien   (set_attr "mode" "SI")])
952450650Sobrien
952590286Sobrien;; The problem with neg is that it does not perform (compare x 0),
952690286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
952790286Sobrien;; flag being the only useful item.
952818334Speter
952990286Sobrien(define_insn "*negsi2_cmpz"
953090286Sobrien  [(set (reg:CCZ 17)
953190286Sobrien	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
953290286Sobrien		     (const_int 0)))
953390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
953490286Sobrien	(neg:SI (match_dup 1)))]
953590286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
953690286Sobrien  "neg{l}\t%0"
953790286Sobrien  [(set_attr "type" "negnot")
953890286Sobrien   (set_attr "mode" "SI")])
953950650Sobrien
954090286Sobrien(define_insn "*negsi2_cmpz_zext"
954190286Sobrien  [(set (reg:CCZ 17)
954290286Sobrien	(compare:CCZ (lshiftrt:DI
954390286Sobrien		       (neg:DI (ashift:DI
954490286Sobrien				 (match_operand:DI 1 "register_operand" "0")
954590286Sobrien				 (const_int 32)))
954690286Sobrien		       (const_int 32))
954790286Sobrien		     (const_int 0)))
954890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
954990286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
955090286Sobrien					(const_int 32)))
955190286Sobrien		     (const_int 32)))]
955290286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
955390286Sobrien  "neg{l}\t%k0"
955490286Sobrien  [(set_attr "type" "negnot")
955590286Sobrien   (set_attr "mode" "SI")])
955690286Sobrien
955790286Sobrien(define_expand "neghi2"
955890286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
955990286Sobrien		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
956090286Sobrien	      (clobber (reg:CC 17))])]
956190286Sobrien  "TARGET_HIMODE_MATH"
956290286Sobrien  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
956390286Sobrien
956490286Sobrien(define_insn "*neghi2_1"
956590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
956690286Sobrien	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
956790286Sobrien   (clobber (reg:CC 17))]
956890286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
956990286Sobrien  "neg{w}\t%0"
957090286Sobrien  [(set_attr "type" "negnot")
957190286Sobrien   (set_attr "mode" "HI")])
957290286Sobrien
957390286Sobrien(define_insn "*neghi2_cmpz"
957490286Sobrien  [(set (reg:CCZ 17)
957590286Sobrien	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
957690286Sobrien		     (const_int 0)))
957790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
957890286Sobrien	(neg:HI (match_dup 1)))]
957990286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
958090286Sobrien  "neg{w}\t%0"
958190286Sobrien  [(set_attr "type" "negnot")
958290286Sobrien   (set_attr "mode" "HI")])
958390286Sobrien
958490286Sobrien(define_expand "negqi2"
958590286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
958690286Sobrien		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
958790286Sobrien	      (clobber (reg:CC 17))])]
958890286Sobrien  "TARGET_QIMODE_MATH"
958990286Sobrien  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
959090286Sobrien
959190286Sobrien(define_insn "*negqi2_1"
959290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
959390286Sobrien	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
959490286Sobrien   (clobber (reg:CC 17))]
959590286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
959690286Sobrien  "neg{b}\t%0"
959790286Sobrien  [(set_attr "type" "negnot")
959890286Sobrien   (set_attr "mode" "QI")])
959990286Sobrien
960090286Sobrien(define_insn "*negqi2_cmpz"
960190286Sobrien  [(set (reg:CCZ 17)
960290286Sobrien	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
960390286Sobrien		     (const_int 0)))
960490286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
960590286Sobrien	(neg:QI (match_dup 1)))]
960690286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
960790286Sobrien  "neg{b}\t%0"
960890286Sobrien  [(set_attr "type" "negnot")
960990286Sobrien   (set_attr "mode" "QI")])
961090286Sobrien
961190286Sobrien;; Changing of sign for FP values is doable using integer unit too.
961290286Sobrien
961390286Sobrien(define_expand "negsf2"
961490286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
961590286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
961690286Sobrien	      (clobber (reg:CC 17))])]
9617146906Skan  "TARGET_80387 || TARGET_SSE_MATH"
9618146906Skan  "if (TARGET_SSE_MATH)
961990286Sobrien     {
962090286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
962190286Sobrien       if (memory_operand (operands[0], VOIDmode)
962290286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
962390286Sobrien	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
962490286Sobrien       else
962518334Speter	{
962690286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
962790286Sobrien	     in register.  */
962890286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
962990286Sobrien	  rtx dest = operands[0];
9630132727Skan	  rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
963118334Speter
963290286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
963390286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
9634132727Skan	  reg = force_reg (V4SFmode,
9635132727Skan			   gen_rtx_CONST_VECTOR (V4SFmode,
9636132727Skan			     gen_rtvec (4, imm, CONST0_RTX (SFmode),
9637132727Skan					CONST0_RTX (SFmode),
9638132727Skan					CONST0_RTX (SFmode))));
963990286Sobrien	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
964090286Sobrien	  if (dest != operands[0])
964190286Sobrien	    emit_move_insn (dest, operands[0]);
964250650Sobrien	}
964390286Sobrien       DONE;
964490286Sobrien     }
964590286Sobrien   ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
964618334Speter
964790286Sobrien(define_insn "negsf2_memory"
964890286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
964990286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
965090286Sobrien   (clobber (reg:CC 17))]
965190286Sobrien  "ix86_unary_operator_ok (NEG, SFmode, operands)"
965290286Sobrien  "#")
965318334Speter
965490286Sobrien(define_insn "negsf2_ifs"
965590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
965690286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9657132727Skan   (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
965890286Sobrien   (clobber (reg:CC 17))]
965990286Sobrien  "TARGET_SSE
966090286Sobrien   && (reload_in_progress || reload_completed
966190286Sobrien       || (register_operand (operands[0], VOIDmode)
966290286Sobrien	   && register_operand (operands[1], VOIDmode)))"
966390286Sobrien  "#")
966418334Speter
966590286Sobrien(define_split
966690286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
966790286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "")))
966890286Sobrien   (use (match_operand:SF 2 "" ""))
966990286Sobrien   (clobber (reg:CC 17))]
967018334Speter  ""
967190286Sobrien  [(parallel [(set (match_dup 0)
967290286Sobrien		   (neg:SF (match_dup 1)))
967390286Sobrien	      (clobber (reg:CC 17))])])
967490286Sobrien
967590286Sobrien(define_split
967690286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
967790286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
9678132727Skan   (use (match_operand:V4SF 2 "" ""))
967990286Sobrien   (clobber (reg:CC 17))]
968090286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
968190286Sobrien  [(parallel [(set (match_dup 0)
968290286Sobrien		   (neg:SF (match_dup 1)))
968390286Sobrien	      (clobber (reg:CC 17))])])
968490286Sobrien
968590286Sobrien(define_split
968690286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
968790286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
9688132727Skan   (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
968990286Sobrien   (clobber (reg:CC 17))]
969090286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
9691146906Skan  [(set (match_dup 0)
9692146906Skan	(xor:V4SF (match_dup 1)
9693146906Skan		  (match_dup 2)))]
969418334Speter{
9695146906Skan  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9696146906Skan  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
969790286Sobrien  if (operands_match_p (operands[0], operands[2]))
969818334Speter    {
969990286Sobrien      rtx tmp;
970090286Sobrien      tmp = operands[1];
970190286Sobrien      operands[1] = operands[2];
970290286Sobrien      operands[2] = tmp;
970390286Sobrien    }
970490286Sobrien})
970518334Speter
970618334Speter
970790286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
970890286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
970990286Sobrien;; to itself.
971090286Sobrien(define_insn "*negsf2_if"
971190286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
971290286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
971390286Sobrien   (clobber (reg:CC 17))]
9714146906Skan  "TARGET_80387
971590286Sobrien   && ix86_unary_operator_ok (NEG, SFmode, operands)"
971690286Sobrien  "#")
971718334Speter
971890286Sobrien(define_split
9719117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
972090286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
972190286Sobrien   (clobber (reg:CC 17))]
9722117404Skan  "TARGET_80387 && reload_completed"
972390286Sobrien  [(set (match_dup 0)
972490286Sobrien	(neg:SF (match_dup 1)))]
972590286Sobrien  "")
972690286Sobrien
972790286Sobrien(define_split
9728117404Skan  [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
972990286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
973090286Sobrien   (clobber (reg:CC 17))]
9731117404Skan  "TARGET_80387 && reload_completed"
973290286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
973390286Sobrien	      (clobber (reg:CC 17))])]
9734117404Skan  "operands[1] = gen_int_mode (0x80000000, SImode);
9735132727Skan   operands[0] = gen_lowpart (SImode, operands[0]);")
973690286Sobrien
973790286Sobrien(define_split
973890286Sobrien  [(set (match_operand 0 "memory_operand" "")
973990286Sobrien	(neg (match_operand 1 "memory_operand" "")))
974090286Sobrien   (clobber (reg:CC 17))]
974190286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
974290286Sobrien  [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
974390286Sobrien	      (clobber (reg:CC 17))])]
974490286Sobrien{
974590286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
974690286Sobrien
9747132727Skan  if (GET_MODE (operands[1]) == XFmode)
974890286Sobrien    size = 10;
974990286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
9750117404Skan  operands[1] = gen_int_mode (0x80, QImode);
975190286Sobrien})
975290286Sobrien
975390286Sobrien(define_expand "negdf2"
975490286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
975590286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
975690286Sobrien	      (clobber (reg:CC 17))])]
9757146906Skan  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9758146906Skan  "if (TARGET_SSE2 && TARGET_SSE_MATH)
975990286Sobrien     {
976090286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
976190286Sobrien       if (memory_operand (operands[0], VOIDmode)
976290286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
976390286Sobrien	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
976490286Sobrien       else
976518334Speter	{
976690286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
976790286Sobrien	     in register.  */
9768132727Skan	  rtx reg;
976990286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
9770117404Skan	  rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
977190286Sobrien#else
977290286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
977390286Sobrien#endif
977490286Sobrien	  rtx dest = operands[0];
977518334Speter
977690286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
977790286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
9778132727Skan	  imm = gen_lowpart (DFmode, imm);
9779132727Skan	  reg = force_reg (V2DFmode,
9780132727Skan			   gen_rtx_CONST_VECTOR (V2DFmode,
9781132727Skan			     gen_rtvec (2, imm, CONST0_RTX (DFmode))));
978290286Sobrien	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
978390286Sobrien	  if (dest != operands[0])
978490286Sobrien	    emit_move_insn (dest, operands[0]);
978518334Speter	}
978690286Sobrien       DONE;
978790286Sobrien     }
978890286Sobrien   ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
978918334Speter
979090286Sobrien(define_insn "negdf2_memory"
979190286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
979290286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
979390286Sobrien   (clobber (reg:CC 17))]
979490286Sobrien  "ix86_unary_operator_ok (NEG, DFmode, operands)"
979590286Sobrien  "#")
979650650Sobrien
979790286Sobrien(define_insn "negdf2_ifs"
979890286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
979990286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9800132727Skan   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
980190286Sobrien   (clobber (reg:CC 17))]
980290286Sobrien  "!TARGET_64BIT && TARGET_SSE2
980390286Sobrien   && (reload_in_progress || reload_completed
980490286Sobrien       || (register_operand (operands[0], VOIDmode)
980590286Sobrien	   && register_operand (operands[1], VOIDmode)))"
980690286Sobrien  "#")
980750650Sobrien
980890286Sobrien(define_insn "*negdf2_ifs_rex64"
9809117404Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9810132727Skan	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9811132727Skan   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
981290286Sobrien   (clobber (reg:CC 17))]
981390286Sobrien  "TARGET_64BIT && TARGET_SSE2
981490286Sobrien   && (reload_in_progress || reload_completed
981590286Sobrien       || (register_operand (operands[0], VOIDmode)
981690286Sobrien	   && register_operand (operands[1], VOIDmode)))"
981790286Sobrien  "#")
981818334Speter
981990286Sobrien(define_split
982090286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
982190286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "")))
9822132727Skan   (use (match_operand:V2DF 2 "" ""))
982390286Sobrien   (clobber (reg:CC 17))]
982418334Speter  ""
982590286Sobrien  [(parallel [(set (match_dup 0)
982690286Sobrien		   (neg:DF (match_dup 1)))
982790286Sobrien	      (clobber (reg:CC 17))])])
982850650Sobrien
982990286Sobrien(define_split
983090286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
983190286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
9832132727Skan   (use (match_operand:V2DF 2 "" ""))
983390286Sobrien   (clobber (reg:CC 17))]
983490286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
983590286Sobrien   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
983690286Sobrien  [(parallel [(set (match_dup 0)
983790286Sobrien		   (neg:DF (match_dup 1)))
983890286Sobrien	      (clobber (reg:CC 17))])])
983950650Sobrien
984090286Sobrien(define_split
984190286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
984290286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
9843132727Skan   (use (match_operand:V2DF 2 "" ""))
984490286Sobrien   (clobber (reg:CC 17))]
984590286Sobrien  "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
984690286Sobrien  [(parallel [(set (match_dup 0)
984790286Sobrien		   (xor:DI (match_dup 1) (match_dup 2)))
984890286Sobrien	      (clobber (reg:CC 17))])]
984990286Sobrien   "operands[0] = gen_lowpart (DImode, operands[0]);
985090286Sobrien    operands[1] = gen_lowpart (DImode, operands[1]);
985190286Sobrien    operands[2] = gen_lowpart (DImode, operands[2]);")
985252296Sobrien
985390286Sobrien(define_split
985490286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
985590286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
9856132727Skan   (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
985790286Sobrien   (clobber (reg:CC 17))]
985890286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
9859146906Skan  [(set (match_dup 0)
9860146906Skan	(xor:V2DF (match_dup 1)
9861146906Skan		  (match_dup 2)))]
986290286Sobrien{
9863132727Skan  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9864146906Skan  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9865132727Skan  /* Avoid possible reformatting on the operands.  */
9866132727Skan  if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9867132727Skan    emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
986890286Sobrien  if (operands_match_p (operands[0], operands[2]))
986990286Sobrien    {
987090286Sobrien      rtx tmp;
987190286Sobrien      tmp = operands[1];
987290286Sobrien      operands[1] = operands[2];
987390286Sobrien      operands[2] = tmp;
987490286Sobrien    }
987590286Sobrien})
987652296Sobrien
987790286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
987890286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
987990286Sobrien;; to itself.
988090286Sobrien(define_insn "*negdf2_if"
988190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
988290286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
988390286Sobrien   (clobber (reg:CC 17))]
988490286Sobrien  "!TARGET_64BIT && TARGET_80387
988590286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
988690286Sobrien  "#")
988750650Sobrien
988890286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
988990286Sobrien;; we need another scratch register to get constant from.
989090286Sobrien;; Forcing constant to mem if no register available in peep2 should be
989190286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
989290286Sobrien(define_insn "*negdf2_if_rex64"
989390286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
989490286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
989590286Sobrien   (clobber (reg:CC 17))]
989690286Sobrien  "TARGET_64BIT && TARGET_80387
989790286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
989890286Sobrien  "#")
989990286Sobrien
990050650Sobrien(define_split
9901117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
990290286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
990390286Sobrien   (clobber (reg:CC 17))]
9904117404Skan  "TARGET_80387 && reload_completed"
990590286Sobrien  [(set (match_dup 0)
990690286Sobrien	(neg:DF (match_dup 1)))]
990790286Sobrien  "")
990850650Sobrien
990990286Sobrien(define_split
9910117404Skan  [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
991190286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
991290286Sobrien   (clobber (reg:CC 17))]
9913117404Skan  "!TARGET_64BIT && TARGET_80387 && reload_completed"
991490286Sobrien  [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
991590286Sobrien	      (clobber (reg:CC 17))])]
9916117404Skan  "operands[4] = gen_int_mode (0x80000000, SImode);
991790286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
991818334Speter
991990286Sobrien(define_expand "negxf2"
992090286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
992190286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
992290286Sobrien	      (clobber (reg:CC 17))])]
9923132727Skan  "TARGET_80387"
992490286Sobrien  "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
992518334Speter
992690286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
992790286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
992890286Sobrien;; to itself.
992990286Sobrien(define_insn "*negxf2_if"
993090286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
993190286Sobrien	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
993290286Sobrien   (clobber (reg:CC 17))]
9933132727Skan  "TARGET_80387
993490286Sobrien   && ix86_unary_operator_ok (NEG, XFmode, operands)"
993590286Sobrien  "#")
993618334Speter
993790286Sobrien(define_split
9938117404Skan  [(set (match_operand:XF 0 "fp_register_operand" "")
993990286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
994090286Sobrien   (clobber (reg:CC 17))]
9941117404Skan  "TARGET_80387 && reload_completed"
994290286Sobrien  [(set (match_dup 0)
994390286Sobrien	(neg:XF (match_dup 1)))]
994490286Sobrien  "")
994518334Speter
994690286Sobrien(define_split
9947117404Skan  [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
994890286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
994990286Sobrien   (clobber (reg:CC 17))]
9950117404Skan  "TARGET_80387 && reload_completed"
995190286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
995290286Sobrien	      (clobber (reg:CC 17))])]
995390286Sobrien  "operands[1] = GEN_INT (0x8000);
995490286Sobrien   operands[0] = gen_rtx_REG (SImode,
995590286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
995618334Speter
9957132727Skan;; Conditionalize these after reload. If they matches before reload, we 
995890286Sobrien;; lose the clobber and ability to use integer instructions.
995990286Sobrien
996090286Sobrien(define_insn "*negsf2_1"
996118334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
996250650Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
996390286Sobrien  "TARGET_80387 && reload_completed"
996452296Sobrien  "fchs"
996590286Sobrien  [(set_attr "type" "fsgn")
996690286Sobrien   (set_attr "mode" "SF")
996790286Sobrien   (set_attr "ppro_uops" "few")])
996818334Speter
996990286Sobrien(define_insn "*negdf2_1"
997018334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
997150650Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
997290286Sobrien  "TARGET_80387 && reload_completed"
997352296Sobrien  "fchs"
997490286Sobrien  [(set_attr "type" "fsgn")
997590286Sobrien   (set_attr "mode" "DF")
997690286Sobrien   (set_attr "ppro_uops" "few")])
997718334Speter
997890286Sobrien(define_insn "*negextendsfdf2"
997918334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
998090286Sobrien	(neg:DF (float_extend:DF
998190286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
998218334Speter  "TARGET_80387"
998352296Sobrien  "fchs"
998490286Sobrien  [(set_attr "type" "fsgn")
998590286Sobrien   (set_attr "mode" "DF")
998690286Sobrien   (set_attr "ppro_uops" "few")])
998718334Speter
998890286Sobrien(define_insn "*negxf2_1"
998918334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
999050650Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
9991132727Skan  "TARGET_80387 && reload_completed"
999252296Sobrien  "fchs"
999390286Sobrien  [(set_attr "type" "fsgn")
999490286Sobrien   (set_attr "mode" "XF")
999590286Sobrien   (set_attr "ppro_uops" "few")])
999618334Speter
999790286Sobrien(define_insn "*negextenddfxf2"
999818334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
999990286Sobrien	(neg:XF (float_extend:XF
1000090286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
10001132727Skan  "TARGET_80387"
1000290286Sobrien  "fchs"
1000390286Sobrien  [(set_attr "type" "fsgn")
1000490286Sobrien   (set_attr "mode" "XF")
1000590286Sobrien   (set_attr "ppro_uops" "few")])
1000690286Sobrien
1000790286Sobrien(define_insn "*negextendsfxf2"
1000890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1000990286Sobrien	(neg:XF (float_extend:XF
1001090286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1001118334Speter  "TARGET_80387"
1001252296Sobrien  "fchs"
1001390286Sobrien  [(set_attr "type" "fsgn")
1001490286Sobrien   (set_attr "mode" "XF")
1001590286Sobrien   (set_attr "ppro_uops" "few")])
1001618334Speter
1001718334Speter;; Absolute value instructions
1001818334Speter
1001990286Sobrien(define_expand "abssf2"
1002090286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
1002190286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
1002290286Sobrien	      (clobber (reg:CC 17))])]
10023146906Skan  "TARGET_80387 || TARGET_SSE_MATH"
10024146906Skan  "if (TARGET_SSE_MATH)
1002590286Sobrien     {
1002690286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
1002790286Sobrien       if (memory_operand (operands[0], VOIDmode)
1002890286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
1002990286Sobrien	 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
1003090286Sobrien       else
1003190286Sobrien	{
1003290286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
1003390286Sobrien	     in register.  */
10034132727Skan	  rtx reg = gen_reg_rtx (V4SFmode);
1003590286Sobrien	  rtx dest = operands[0];
10036132727Skan	  rtx imm;
1003790286Sobrien
1003890286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
1003990286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
10040132727Skan	  imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10041132727Skan	  reg = force_reg (V4SFmode,
10042132727Skan			   gen_rtx_CONST_VECTOR (V4SFmode,
10043132727Skan			   gen_rtvec (4, imm, CONST0_RTX (SFmode),
10044132727Skan				      CONST0_RTX (SFmode),
10045132727Skan				      CONST0_RTX (SFmode))));
1004690286Sobrien	  emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
1004790286Sobrien	  if (dest != operands[0])
1004890286Sobrien	    emit_move_insn (dest, operands[0]);
1004990286Sobrien	}
1005090286Sobrien       DONE;
1005190286Sobrien     }
1005290286Sobrien   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
1005390286Sobrien
1005490286Sobrien(define_insn "abssf2_memory"
1005590286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
1005690286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "0")))
1005790286Sobrien   (clobber (reg:CC 17))]
1005890286Sobrien  "ix86_unary_operator_ok (ABS, SFmode, operands)"
1005990286Sobrien  "#")
1006090286Sobrien
1006190286Sobrien(define_insn "abssf2_ifs"
10062132727Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10063132727Skan	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10064132727Skan   (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
1006590286Sobrien   (clobber (reg:CC 17))]
1006690286Sobrien  "TARGET_SSE
1006790286Sobrien   && (reload_in_progress || reload_completed
1006890286Sobrien       || (register_operand (operands[0], VOIDmode)
10069132727Skan	    && register_operand (operands[1], VOIDmode)))"
1007090286Sobrien  "#")
1007190286Sobrien
1007290286Sobrien(define_split
1007390286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
1007490286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "")))
10075132727Skan   (use (match_operand:V4SF 2 "" ""))
1007690286Sobrien   (clobber (reg:CC 17))]
1007790286Sobrien  ""
1007890286Sobrien  [(parallel [(set (match_dup 0)
1007990286Sobrien		   (abs:SF (match_dup 1)))
1008090286Sobrien	      (clobber (reg:CC 17))])])
1008190286Sobrien
1008290286Sobrien(define_split
1008390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1008490286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
10085132727Skan   (use (match_operand:V4SF 2 "" ""))
1008690286Sobrien   (clobber (reg:CC 17))]
1008790286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
1008890286Sobrien  [(parallel [(set (match_dup 0)
1008990286Sobrien		   (abs:SF (match_dup 1)))
1009090286Sobrien	      (clobber (reg:CC 17))])])
1009190286Sobrien
1009290286Sobrien(define_split
1009390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1009490286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
10095132727Skan   (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
1009690286Sobrien   (clobber (reg:CC 17))]
1009790286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
10098146906Skan  [(set (match_dup 0)
10099146906Skan	(and:V4SF (match_dup 1)
10100146906Skan		  (match_dup 2)))]
10101132727Skan{
10102146906Skan  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10103146906Skan  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10104132727Skan  if (operands_match_p (operands[0], operands[2]))
10105132727Skan    {
10106132727Skan      rtx tmp;
10107132727Skan      tmp = operands[1];
10108132727Skan      operands[1] = operands[2];
10109132727Skan      operands[2] = tmp;
10110132727Skan    }
10111132727Skan})
1011290286Sobrien
1011390286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1011490286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1011590286Sobrien;; to itself.
1011690286Sobrien(define_insn "*abssf2_if"
1011790286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
1011890286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
1011990286Sobrien   (clobber (reg:CC 17))]
10120146906Skan  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
1012190286Sobrien  "#")
1012290286Sobrien
1012390286Sobrien(define_split
10124117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
1012590286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1012690286Sobrien   (clobber (reg:CC 17))]
10127132727Skan  "TARGET_80387 && reload_completed"
1012890286Sobrien  [(set (match_dup 0)
1012990286Sobrien	(abs:SF (match_dup 1)))]
1013090286Sobrien  "")
1013190286Sobrien
1013290286Sobrien(define_split
10133117404Skan  [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
1013490286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1013590286Sobrien   (clobber (reg:CC 17))]
10136117404Skan  "TARGET_80387 && reload_completed"
1013790286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1013890286Sobrien	      (clobber (reg:CC 17))])]
10139117404Skan  "operands[1] = gen_int_mode (~0x80000000, SImode);
10140132727Skan   operands[0] = gen_lowpart (SImode, operands[0]);")
1014190286Sobrien
1014290286Sobrien(define_split
1014390286Sobrien  [(set (match_operand 0 "memory_operand" "")
1014490286Sobrien	(abs (match_operand 1 "memory_operand" "")))
1014590286Sobrien   (clobber (reg:CC 17))]
1014690286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
1014790286Sobrien  [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
1014890286Sobrien	      (clobber (reg:CC 17))])]
1014990286Sobrien{
1015090286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
1015190286Sobrien
10152132727Skan  if (GET_MODE (operands[1]) == XFmode)
1015390286Sobrien    size = 10;
1015490286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
10155117404Skan  operands[1] = gen_int_mode (~0x80, QImode);
1015690286Sobrien})
1015790286Sobrien
1015890286Sobrien(define_expand "absdf2"
1015990286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
1016090286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
1016190286Sobrien	      (clobber (reg:CC 17))])]
10162146906Skan  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10163146906Skan  "if (TARGET_SSE2 && TARGET_SSE_MATH)
1016490286Sobrien     {
1016590286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
1016690286Sobrien       if (memory_operand (operands[0], VOIDmode)
1016790286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
1016890286Sobrien	 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
1016990286Sobrien       else
1017090286Sobrien	{
1017190286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
1017290286Sobrien	     in register.  */
10173132727Skan	  rtx reg = gen_reg_rtx (V2DFmode);
1017490286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
10175132727Skan	  rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
1017690286Sobrien#else
10177132727Skan	  rtx imm = immed_double_const (~0, ~0x80000000, DImode);
1017890286Sobrien#endif
1017990286Sobrien	  rtx dest = operands[0];
1018090286Sobrien
1018190286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
1018290286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
10183132727Skan
10184132727Skan	  /* Produce LONG_DOUBLE with the proper immediate argument.  */
10185132727Skan	  imm = gen_lowpart (DFmode, imm);
10186132727Skan	  reg = force_reg (V2DFmode,
10187132727Skan			   gen_rtx_CONST_VECTOR (V2DFmode,
10188132727Skan			   gen_rtvec (2, imm, CONST0_RTX (DFmode))));
1018990286Sobrien	  emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
1019090286Sobrien	  if (dest != operands[0])
1019190286Sobrien	    emit_move_insn (dest, operands[0]);
1019290286Sobrien	}
1019390286Sobrien       DONE;
1019490286Sobrien     }
1019590286Sobrien   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
1019690286Sobrien
1019790286Sobrien(define_insn "absdf2_memory"
1019890286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
1019990286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "0")))
1020090286Sobrien   (clobber (reg:CC 17))]
1020190286Sobrien  "ix86_unary_operator_ok (ABS, DFmode, operands)"
1020290286Sobrien  "#")
1020390286Sobrien
1020490286Sobrien(define_insn "absdf2_ifs"
10205132727Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10206132727Skan	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10207132727Skan   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
1020890286Sobrien   (clobber (reg:CC 17))]
1020990286Sobrien  "!TARGET_64BIT && TARGET_SSE2
1021090286Sobrien   && (reload_in_progress || reload_completed
1021190286Sobrien       || (register_operand (operands[0], VOIDmode)
1021290286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1021390286Sobrien  "#")
1021490286Sobrien
1021590286Sobrien(define_insn "*absdf2_ifs_rex64"
10216132727Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10217132727Skan	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10218132727Skan   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
1021990286Sobrien   (clobber (reg:CC 17))]
1022090286Sobrien  "TARGET_64BIT && TARGET_SSE2
1022190286Sobrien   && (reload_in_progress || reload_completed
1022290286Sobrien       || (register_operand (operands[0], VOIDmode)
1022390286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1022490286Sobrien  "#")
1022590286Sobrien
1022690286Sobrien(define_split
1022790286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
1022890286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "")))
10229132727Skan   (use (match_operand:V2DF 2 "" ""))
1023090286Sobrien   (clobber (reg:CC 17))]
1023190286Sobrien  ""
1023290286Sobrien  [(parallel [(set (match_dup 0)
1023390286Sobrien		   (abs:DF (match_dup 1)))
1023490286Sobrien	      (clobber (reg:CC 17))])])
1023590286Sobrien
1023690286Sobrien(define_split
1023790286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1023890286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
10239132727Skan   (use (match_operand:V2DF 2 "" ""))
1024090286Sobrien   (clobber (reg:CC 17))]
1024190286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
1024290286Sobrien  [(parallel [(set (match_dup 0)
1024390286Sobrien		   (abs:DF (match_dup 1)))
1024490286Sobrien	      (clobber (reg:CC 17))])])
1024590286Sobrien
1024690286Sobrien(define_split
1024790286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1024890286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
10249132727Skan   (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
1025090286Sobrien   (clobber (reg:CC 17))]
1025190286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
10252146906Skan  [(set (match_dup 0)
10253146906Skan	(and:V2DF (match_dup 1)
10254146906Skan		  (match_dup 2)))]
10255132727Skan{
10256132727Skan  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10257146906Skan  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10258132727Skan  /* Avoid possible reformatting on the operands.  */
10259132727Skan  if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10260132727Skan    emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10261132727Skan  if (operands_match_p (operands[0], operands[2]))
10262132727Skan    {
10263132727Skan      rtx tmp;
10264132727Skan      tmp = operands[1];
10265132727Skan      operands[1] = operands[2];
10266132727Skan      operands[2] = tmp;
10267132727Skan    }
10268132727Skan})
1026990286Sobrien
1027090286Sobrien
1027190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1027290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1027390286Sobrien;; to itself.
1027490286Sobrien(define_insn "*absdf2_if"
1027590286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
1027690286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1027790286Sobrien   (clobber (reg:CC 17))]
1027890286Sobrien  "!TARGET_64BIT && TARGET_80387
1027990286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1028090286Sobrien  "#")
1028190286Sobrien
1028290286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
1028390286Sobrien;; we need another scratch register to get constant from.
1028490286Sobrien;; Forcing constant to mem if no register available in peep2 should be
1028590286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
1028690286Sobrien(define_insn "*absdf2_if_rex64"
1028790286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
1028890286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1028990286Sobrien   (clobber (reg:CC 17))]
1029090286Sobrien  "TARGET_64BIT && TARGET_80387
1029190286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1029290286Sobrien  "#")
1029390286Sobrien
1029490286Sobrien(define_split
10295117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
1029690286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1029790286Sobrien   (clobber (reg:CC 17))]
10298117404Skan  "TARGET_80387 && reload_completed"
1029990286Sobrien  [(set (match_dup 0)
1030090286Sobrien	(abs:DF (match_dup 1)))]
1030190286Sobrien  "")
1030290286Sobrien
1030390286Sobrien(define_split
10304117404Skan  [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
1030590286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1030690286Sobrien   (clobber (reg:CC 17))]
10307117404Skan  "!TARGET_64BIT && TARGET_80387 && reload_completed"
1030890286Sobrien  [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
1030990286Sobrien	      (clobber (reg:CC 17))])]
10310117404Skan  "operands[4] = gen_int_mode (~0x80000000, SImode);
1031190286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
1031290286Sobrien
1031390286Sobrien(define_expand "absxf2"
1031490286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
1031590286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
1031690286Sobrien	      (clobber (reg:CC 17))])]
10317132727Skan  "TARGET_80387"
1031890286Sobrien  "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
1031990286Sobrien
1032090286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1032190286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1032290286Sobrien;; to itself.
1032390286Sobrien(define_insn "*absxf2_if"
1032490286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
1032590286Sobrien	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1032690286Sobrien   (clobber (reg:CC 17))]
10327132727Skan  "TARGET_80387
1032890286Sobrien   && ix86_unary_operator_ok (ABS, XFmode, operands)"
1032990286Sobrien  "#")
1033090286Sobrien
1033190286Sobrien(define_split
10332117404Skan  [(set (match_operand:XF 0 "fp_register_operand" "")
1033390286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1033490286Sobrien   (clobber (reg:CC 17))]
10335117404Skan  "TARGET_80387 && reload_completed"
1033690286Sobrien  [(set (match_dup 0)
1033790286Sobrien	(abs:XF (match_dup 1)))]
1033890286Sobrien  "")
1033990286Sobrien
1034090286Sobrien(define_split
10341117404Skan  [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
1034290286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1034390286Sobrien   (clobber (reg:CC 17))]
10344117404Skan  "TARGET_80387 && reload_completed"
1034590286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1034690286Sobrien	      (clobber (reg:CC 17))])]
1034790286Sobrien  "operands[1] = GEN_INT (~0x8000);
1034890286Sobrien   operands[0] = gen_rtx_REG (SImode,
1034990286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1035090286Sobrien
1035190286Sobrien(define_insn "*abssf2_1"
1035218334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
1035350650Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
1035490286Sobrien  "TARGET_80387 && reload_completed"
1035550650Sobrien  "fabs"
1035690286Sobrien  [(set_attr "type" "fsgn")
1035790286Sobrien   (set_attr "mode" "SF")])
1035818334Speter
1035990286Sobrien(define_insn "*absdf2_1"
1036018334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1036150650Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
1036290286Sobrien  "TARGET_80387 && reload_completed"
1036350650Sobrien  "fabs"
1036490286Sobrien  [(set_attr "type" "fsgn")
1036590286Sobrien   (set_attr "mode" "DF")])
1036618334Speter
1036790286Sobrien(define_insn "*absextendsfdf2"
1036818334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1036990286Sobrien	(abs:DF (float_extend:DF
1037090286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1037118334Speter  "TARGET_80387"
1037250650Sobrien  "fabs"
1037390286Sobrien  [(set_attr "type" "fsgn")
1037490286Sobrien   (set_attr "mode" "DF")])
1037518334Speter
1037690286Sobrien(define_insn "*absxf2_1"
1037718334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1037850650Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
10379132727Skan  "TARGET_80387 && reload_completed"
1038050650Sobrien  "fabs"
1038190286Sobrien  [(set_attr "type" "fsgn")
1038290286Sobrien   (set_attr "mode" "DF")])
1038318334Speter
1038490286Sobrien(define_insn "*absextenddfxf2"
1038518334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1038690286Sobrien	(abs:XF (float_extend:XF
1038790286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
10388132727Skan  "TARGET_80387"
1038950650Sobrien  "fabs"
1039090286Sobrien  [(set_attr "type" "fsgn")
1039190286Sobrien   (set_attr "mode" "XF")])
1039218334Speter
1039390286Sobrien(define_insn "*absextendsfxf2"
1039490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1039590286Sobrien	(abs:XF (float_extend:XF
1039690286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1039790286Sobrien  "TARGET_80387"
1039890286Sobrien  "fabs"
1039990286Sobrien  [(set_attr "type" "fsgn")
1040090286Sobrien   (set_attr "mode" "XF")])
1040190286Sobrien
1040290286Sobrien;; One complement instructions
1040318334Speter
1040490286Sobrien(define_expand "one_cmpldi2"
1040590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1040690286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
1040790286Sobrien  "TARGET_64BIT"
1040890286Sobrien  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
1040918334Speter
1041090286Sobrien(define_insn "*one_cmpldi2_1_rex64"
1041190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1041290286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
1041390286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
1041490286Sobrien  "not{q}\t%0"
1041590286Sobrien  [(set_attr "type" "negnot")
1041690286Sobrien   (set_attr "mode" "DI")])
1041718334Speter
1041890286Sobrien(define_insn "*one_cmpldi2_2_rex64"
1041990286Sobrien  [(set (reg 17)
1042090286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
1042190286Sobrien		 (const_int 0)))
1042290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1042390286Sobrien	(not:DI (match_dup 1)))]
1042490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1042590286Sobrien   && ix86_unary_operator_ok (NOT, DImode, operands)"
1042690286Sobrien  "#"
1042790286Sobrien  [(set_attr "type" "alu1")
1042890286Sobrien   (set_attr "mode" "DI")])
1042918334Speter
1043090286Sobrien(define_split
10431146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
10432146906Skan	(match_operator 2 "compare_operator"
10433146906Skan	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10434146906Skan	   (const_int 0)]))
10435146906Skan   (set (match_operand:DI 1 "nonimmediate_operand" "")
10436146906Skan	(not:DI (match_dup 3)))]
1043790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10438146906Skan  [(parallel [(set (match_dup 0)
10439146906Skan		   (match_op_dup 2
10440146906Skan		     [(xor:DI (match_dup 3) (const_int -1))
10441146906Skan		      (const_int 0)]))
10442146906Skan	      (set (match_dup 1)
10443146906Skan		   (xor:DI (match_dup 3) (const_int -1)))])]
1044490286Sobrien  "")
1044518334Speter
1044690286Sobrien(define_expand "one_cmplsi2"
1044790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1044890286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1044990286Sobrien  ""
1045090286Sobrien  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
1045118334Speter
1045290286Sobrien(define_insn "*one_cmplsi2_1"
1045390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1045490286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
1045590286Sobrien  "ix86_unary_operator_ok (NOT, SImode, operands)"
1045690286Sobrien  "not{l}\t%0"
1045790286Sobrien  [(set_attr "type" "negnot")
1045890286Sobrien   (set_attr "mode" "SI")])
1045918334Speter
1046090286Sobrien;; ??? Currently never generated - xor is used instead.
1046190286Sobrien(define_insn "*one_cmplsi2_1_zext"
1046290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1046390286Sobrien	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
1046490286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
1046590286Sobrien  "not{l}\t%k0"
1046690286Sobrien  [(set_attr "type" "negnot")
1046790286Sobrien   (set_attr "mode" "SI")])
1046818334Speter
1046990286Sobrien(define_insn "*one_cmplsi2_2"
1047090286Sobrien  [(set (reg 17)
1047190286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
1047290286Sobrien		 (const_int 0)))
1047390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1047490286Sobrien	(not:SI (match_dup 1)))]
1047590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1047690286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1047790286Sobrien  "#"
1047890286Sobrien  [(set_attr "type" "alu1")
1047990286Sobrien   (set_attr "mode" "SI")])
1048018334Speter
1048190286Sobrien(define_split
10482146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
10483146906Skan	(match_operator 2 "compare_operator"
10484146906Skan	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10485146906Skan	   (const_int 0)]))
10486146906Skan   (set (match_operand:SI 1 "nonimmediate_operand" "")
10487146906Skan	(not:SI (match_dup 3)))]
1048890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
10489146906Skan  [(parallel [(set (match_dup 0)
10490146906Skan		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10491146906Skan				    (const_int 0)]))
10492146906Skan	      (set (match_dup 1)
10493146906Skan		   (xor:SI (match_dup 3) (const_int -1)))])]
1049490286Sobrien  "")
1049518334Speter
1049690286Sobrien;; ??? Currently never generated - xor is used instead.
1049790286Sobrien(define_insn "*one_cmplsi2_2_zext"
1049890286Sobrien  [(set (reg 17)
1049990286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
1050090286Sobrien		 (const_int 0)))
1050190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1050290286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1050390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1050490286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1050590286Sobrien  "#"
1050690286Sobrien  [(set_attr "type" "alu1")
1050790286Sobrien   (set_attr "mode" "SI")])
1050818334Speter
1050990286Sobrien(define_split
10510146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
10511146906Skan	(match_operator 2 "compare_operator"
10512146906Skan	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10513146906Skan	   (const_int 0)]))
10514146906Skan   (set (match_operand:DI 1 "register_operand" "")
10515146906Skan	(zero_extend:DI (not:SI (match_dup 3))))]
1051690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
10517146906Skan  [(parallel [(set (match_dup 0)
10518146906Skan		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10519146906Skan				    (const_int 0)]))
10520146906Skan	      (set (match_dup 1)
10521146906Skan		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
1052290286Sobrien  "")
1052318334Speter
1052490286Sobrien(define_expand "one_cmplhi2"
1052590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1052690286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1052790286Sobrien  "TARGET_HIMODE_MATH"
1052890286Sobrien  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
1052952296Sobrien
1053090286Sobrien(define_insn "*one_cmplhi2_1"
1053150650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1053250650Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
1053390286Sobrien  "ix86_unary_operator_ok (NOT, HImode, operands)"
1053490286Sobrien  "not{w}\t%0"
1053590286Sobrien  [(set_attr "type" "negnot")
1053690286Sobrien   (set_attr "mode" "HI")])
1053718334Speter
1053890286Sobrien(define_insn "*one_cmplhi2_2"
1053990286Sobrien  [(set (reg 17)
1054090286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
1054190286Sobrien		 (const_int 0)))
1054290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1054390286Sobrien	(not:HI (match_dup 1)))]
1054490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1054590286Sobrien   && ix86_unary_operator_ok (NEG, HImode, operands)"
1054690286Sobrien  "#"
1054790286Sobrien  [(set_attr "type" "alu1")
1054890286Sobrien   (set_attr "mode" "HI")])
1054952296Sobrien
1055090286Sobrien(define_split
10551146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
10552146906Skan	(match_operator 2 "compare_operator"
10553146906Skan	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10554146906Skan	   (const_int 0)]))
10555146906Skan   (set (match_operand:HI 1 "nonimmediate_operand" "")
10556146906Skan	(not:HI (match_dup 3)))]
1055790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
10558146906Skan  [(parallel [(set (match_dup 0)
10559146906Skan		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10560146906Skan		      		    (const_int 0)]))
10561146906Skan	      (set (match_dup 1)
10562146906Skan		   (xor:HI (match_dup 3) (const_int -1)))])]
1056390286Sobrien  "")
1056452296Sobrien
1056590286Sobrien;; %%% Potential partial reg stall on alternative 1.  What to do?
1056690286Sobrien(define_expand "one_cmplqi2"
1056790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1056890286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1056990286Sobrien  "TARGET_QIMODE_MATH"
1057090286Sobrien  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
1057190286Sobrien
1057290286Sobrien(define_insn "*one_cmplqi2_1"
1057390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1057490286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
1057590286Sobrien  "ix86_unary_operator_ok (NOT, QImode, operands)"
1057690286Sobrien  "@
1057790286Sobrien   not{b}\t%0
1057890286Sobrien   not{l}\t%k0"
1057990286Sobrien  [(set_attr "type" "negnot")
1058090286Sobrien   (set_attr "mode" "QI,SI")])
1058190286Sobrien
1058290286Sobrien(define_insn "*one_cmplqi2_2"
1058390286Sobrien  [(set (reg 17)
1058490286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
1058590286Sobrien		 (const_int 0)))
1058690286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1058790286Sobrien	(not:QI (match_dup 1)))]
1058890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1058990286Sobrien   && ix86_unary_operator_ok (NOT, QImode, operands)"
1059090286Sobrien  "#"
1059190286Sobrien  [(set_attr "type" "alu1")
1059290286Sobrien   (set_attr "mode" "QI")])
1059390286Sobrien
1059490286Sobrien(define_split
10595146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
10596146906Skan	(match_operator 2 "compare_operator"
10597146906Skan	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10598146906Skan	   (const_int 0)]))
10599146906Skan   (set (match_operand:QI 1 "nonimmediate_operand" "")
10600146906Skan	(not:QI (match_dup 3)))]
1060190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
10602146906Skan  [(parallel [(set (match_dup 0)
10603146906Skan		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10604146906Skan		      		    (const_int 0)]))
10605146906Skan	      (set (match_dup 1)
10606146906Skan		   (xor:QI (match_dup 3) (const_int -1)))])]
1060790286Sobrien  "")
1060818334Speter
1060990286Sobrien;; Arithmetic shift instructions
1061018334Speter
1061118334Speter;; DImode shifts are implemented using the i386 "shift double" opcode,
1061218334Speter;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
1061318334Speter;; is variable, then the count is in %cl and the "imm" operand is dropped
1061418334Speter;; from the assembler input.
1061590286Sobrien;;
1061618334Speter;; This instruction shifts the target reg/mem as usual, but instead of
1061718334Speter;; shifting in zeros, bits are shifted in from reg operand.  If the insn
1061818334Speter;; is a left shift double, bits are taken from the high order bits of
1061918334Speter;; reg, else if the insn is a shift right double, bits are taken from the
1062018334Speter;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
1062118334Speter;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
1062290286Sobrien;;
1062318334Speter;; Since sh[lr]d does not change the `reg' operand, that is done
1062418334Speter;; separately, making all shifts emit pairs of shift double and normal
1062518334Speter;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
1062618334Speter;; support a 63 bit shift, each shift where the count is in a reg expands
1062750650Sobrien;; to a pair of shifts, a branch, a shift by 32 and a label.
1062890286Sobrien;;
1062918334Speter;; If the shift count is a constant, we need never emit more than one
1063018334Speter;; shift pair, instead using moves and sign extension for counts greater
1063118334Speter;; than 31.
1063218334Speter
1063318334Speter(define_expand "ashldi3"
1063490286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1063590286Sobrien		   (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
1063690286Sobrien			      (match_operand:QI 2 "nonmemory_operand" "")))
1063790286Sobrien	      (clobber (reg:CC 17))])]
1063818334Speter  ""
1063918334Speter{
1064090286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1064118334Speter    {
1064290286Sobrien      emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
1064390286Sobrien      DONE;
1064418334Speter    }
1064590286Sobrien  ix86_expand_binary_operator (ASHIFT, DImode, operands);
1064618334Speter  DONE;
1064790286Sobrien})
1064818334Speter
1064990286Sobrien(define_insn "*ashldi3_1_rex64"
1065090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
1065190286Sobrien	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
1065290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
1065390286Sobrien   (clobber (reg:CC 17))]
1065490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1065518334Speter{
1065690286Sobrien  switch (get_attr_type (insn))
1065790286Sobrien    {
1065890286Sobrien    case TYPE_ALU:
1065990286Sobrien      if (operands[2] != const1_rtx)
1066090286Sobrien	abort ();
1066190286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1066290286Sobrien	abort ();
1066390286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1066418334Speter
1066590286Sobrien    case TYPE_LEA:
1066690286Sobrien      if (GET_CODE (operands[2]) != CONST_INT
1066790286Sobrien	  || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
1066890286Sobrien	abort ();
1066990286Sobrien      operands[1] = gen_rtx_MULT (DImode, operands[1],
1067090286Sobrien				  GEN_INT (1 << INTVAL (operands[2])));
1067190286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
1067218334Speter
1067390286Sobrien    default:
1067490286Sobrien      if (REG_P (operands[2]))
1067590286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1067690286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1067790286Sobrien	       && INTVAL (operands[2]) == 1
10678117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1067990286Sobrien	return "sal{q}\t%0";
1068090286Sobrien      else
1068190286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1068290286Sobrien    }
1068390286Sobrien}
1068490286Sobrien  [(set (attr "type")
1068590286Sobrien     (cond [(eq_attr "alternative" "1")
1068690286Sobrien	      (const_string "lea")
1068790286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1068890286Sobrien		          (const_int 0))
1068990286Sobrien		      (match_operand 0 "register_operand" ""))
1069090286Sobrien		 (match_operand 2 "const1_operand" ""))
1069190286Sobrien	      (const_string "alu")
1069290286Sobrien	   ]
1069390286Sobrien	   (const_string "ishift")))
1069490286Sobrien   (set_attr "mode" "DI")])
1069518334Speter
1069690286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1069790286Sobrien(define_split
1069890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1069990286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1070090286Sobrien		   (match_operand:QI 2 "immediate_operand" "")))
1070190286Sobrien   (clobber (reg:CC 17))]
1070290286Sobrien  "TARGET_64BIT && reload_completed
1070390286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1070490286Sobrien  [(set (match_dup 0)
1070590286Sobrien	(mult:DI (match_dup 1)
1070690286Sobrien		 (match_dup 2)))]
10707117404Skan  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
1070890286Sobrien
1070990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1071090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1071190286Sobrien;; zero are optimized away.
1071290286Sobrien(define_insn "*ashldi3_cmp_rex64"
1071390286Sobrien  [(set (reg 17)
1071490286Sobrien	(compare
1071590286Sobrien	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1071690286Sobrien		     (match_operand:QI 2 "immediate_operand" "e"))
1071790286Sobrien	  (const_int 0)))
1071890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1071990286Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))]
1072090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1072190286Sobrien   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1072290286Sobrien{
1072390286Sobrien  switch (get_attr_type (insn))
1072418334Speter    {
1072590286Sobrien    case TYPE_ALU:
1072690286Sobrien      if (operands[2] != const1_rtx)
1072790286Sobrien	abort ();
1072890286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1072918334Speter
1073090286Sobrien    default:
1073190286Sobrien      if (REG_P (operands[2]))
1073290286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1073390286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1073490286Sobrien	       && INTVAL (operands[2]) == 1
10735117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1073690286Sobrien	return "sal{q}\t%0";
1073790286Sobrien      else
1073890286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1073918334Speter    }
1074090286Sobrien}
1074190286Sobrien  [(set (attr "type")
1074290286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1074390286Sobrien		          (const_int 0))
1074490286Sobrien		      (match_operand 0 "register_operand" ""))
1074590286Sobrien		 (match_operand 2 "const1_operand" ""))
1074690286Sobrien	      (const_string "alu")
1074790286Sobrien	   ]
1074890286Sobrien	   (const_string "ishift")))
1074990286Sobrien   (set_attr "mode" "DI")])
1075018334Speter
1075190286Sobrien(define_insn "ashldi3_1"
1075290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1075318334Speter	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1075490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1075590286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1075690286Sobrien   (clobber (reg:CC 17))]
1075790286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1075890286Sobrien  "#"
1075990286Sobrien  [(set_attr "type" "multi")])
1076090286Sobrien
1076190286Sobrien(define_insn "*ashldi3_2"
1076290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1076390286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1076490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1076590286Sobrien   (clobber (reg:CC 17))]
1076690286Sobrien  "!TARGET_64BIT"
1076790286Sobrien  "#"
1076890286Sobrien  [(set_attr "type" "multi")])
1076990286Sobrien
1077090286Sobrien(define_split
1077190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1077290286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1077390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1077490286Sobrien   (clobber (match_scratch:SI 3 ""))
1077590286Sobrien   (clobber (reg:CC 17))]
1077690286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1077790286Sobrien  [(const_int 0)]
1077890286Sobrien  "ix86_split_ashldi (operands, operands[3]); DONE;")
1077990286Sobrien
1078090286Sobrien(define_split
1078190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1078290286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1078390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1078490286Sobrien   (clobber (reg:CC 17))]
1078590286Sobrien  "!TARGET_64BIT && reload_completed"
1078690286Sobrien  [(const_int 0)]
1078790286Sobrien  "ix86_split_ashldi (operands, NULL_RTX); DONE;")
1078890286Sobrien
1078990286Sobrien(define_insn "x86_shld_1"
1079090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1079190286Sobrien        (ior:SI (ashift:SI (match_dup 0)
1079290286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1079390286Sobrien		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1079490286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1079590286Sobrien   (clobber (reg:CC 17))]
1079618334Speter  ""
1079790286Sobrien  "@
1079890286Sobrien   shld{l}\t{%2, %1, %0|%0, %1, %2}
1079990286Sobrien   shld{l}\t{%s2%1, %0|%0, %1, %2}"
1080090286Sobrien  [(set_attr "type" "ishift")
1080190286Sobrien   (set_attr "prefix_0f" "1")
1080290286Sobrien   (set_attr "mode" "SI")
1080390286Sobrien   (set_attr "pent_pair" "np")
1080490286Sobrien   (set_attr "athlon_decode" "vector")
1080590286Sobrien   (set_attr "ppro_uops" "few")])
1080690286Sobrien
1080790286Sobrien(define_expand "x86_shift_adj_1"
1080890286Sobrien  [(set (reg:CCZ 17)
1080990286Sobrien	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
1081090286Sobrien			     (const_int 32))
1081190286Sobrien		     (const_int 0)))
1081290286Sobrien   (set (match_operand:SI 0 "register_operand" "")
1081390286Sobrien        (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1081490286Sobrien			 (match_operand:SI 1 "register_operand" "")
1081590286Sobrien			 (match_dup 0)))
1081690286Sobrien   (set (match_dup 1)
1081790286Sobrien	(if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1081890286Sobrien			 (match_operand:SI 3 "register_operand" "r")
1081990286Sobrien			 (match_dup 1)))]
1082090286Sobrien  "TARGET_CMOVE"
1082190286Sobrien  "")
1082290286Sobrien
1082390286Sobrien(define_expand "x86_shift_adj_2"
1082490286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1082590286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1082690286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1082790286Sobrien  ""
1082818334Speter{
1082990286Sobrien  rtx label = gen_label_rtx ();
1083090286Sobrien  rtx tmp;
1083118334Speter
1083290286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1083318334Speter
1083490286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1083590286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1083690286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1083790286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1083890286Sobrien			      pc_rtx);
1083990286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1084090286Sobrien  JUMP_LABEL (tmp) = label;
1084118334Speter
1084290286Sobrien  emit_move_insn (operands[0], operands[1]);
1084390286Sobrien  emit_move_insn (operands[1], const0_rtx);
1084418334Speter
1084590286Sobrien  emit_label (label);
1084690286Sobrien  LABEL_NUSES (label) = 1;
1084790286Sobrien
1084890286Sobrien  DONE;
1084990286Sobrien})
1085090286Sobrien
1085152296Sobrien(define_expand "ashlsi3"
1085252296Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1085352296Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
1085490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1085590286Sobrien   (clobber (reg:CC 17))]
1085652296Sobrien  ""
1085790286Sobrien  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
1085818334Speter
1085990286Sobrien(define_insn "*ashlsi3_1"
1086090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
1086190286Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
1086290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1086390286Sobrien   (clobber (reg:CC 17))]
1086490286Sobrien  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1086590286Sobrien{
1086690286Sobrien  switch (get_attr_type (insn))
1086790286Sobrien    {
1086890286Sobrien    case TYPE_ALU:
1086990286Sobrien      if (operands[2] != const1_rtx)
1087090286Sobrien	abort ();
1087190286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1087290286Sobrien	abort ();
1087390286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1087490286Sobrien
1087590286Sobrien    case TYPE_LEA:
1087690286Sobrien      return "#";
1087790286Sobrien
1087890286Sobrien    default:
1087990286Sobrien      if (REG_P (operands[2]))
1088090286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1088190286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1088290286Sobrien	       && INTVAL (operands[2]) == 1
10883117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1088490286Sobrien	return "sal{l}\t%0";
1088590286Sobrien      else
1088690286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1088790286Sobrien    }
1088890286Sobrien}
1088990286Sobrien  [(set (attr "type")
1089090286Sobrien     (cond [(eq_attr "alternative" "1")
1089190286Sobrien	      (const_string "lea")
1089290286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1089390286Sobrien		          (const_int 0))
1089490286Sobrien		      (match_operand 0 "register_operand" ""))
1089590286Sobrien		 (match_operand 2 "const1_operand" ""))
1089690286Sobrien	      (const_string "alu")
1089790286Sobrien	   ]
1089890286Sobrien	   (const_string "ishift")))
1089990286Sobrien   (set_attr "mode" "SI")])
1090090286Sobrien
1090190286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1090290286Sobrien(define_split
1090390286Sobrien  [(set (match_operand 0 "register_operand" "")
10904117404Skan	(ashift (match_operand 1 "index_register_operand" "")
1090590286Sobrien                (match_operand:QI 2 "const_int_operand" "")))
1090690286Sobrien   (clobber (reg:CC 17))]
1090790286Sobrien  "reload_completed
1090890286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1090990286Sobrien  [(const_int 0)]
1091090286Sobrien{
1091190286Sobrien  rtx pat;
1091290286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
1091390286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
10914117404Skan  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
1091590286Sobrien  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
1091690286Sobrien  if (Pmode != SImode)
1091790286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
1091890286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
1091990286Sobrien  DONE;
1092090286Sobrien})
1092190286Sobrien
10922117404Skan;; Rare case of shifting RSP is handled by generating move and shift
10923117404Skan(define_split
10924117404Skan  [(set (match_operand 0 "register_operand" "")
10925117404Skan	(ashift (match_operand 1 "register_operand" "")
10926117404Skan                (match_operand:QI 2 "const_int_operand" "")))
10927117404Skan   (clobber (reg:CC 17))]
10928117404Skan  "reload_completed
10929117404Skan   && true_regnum (operands[0]) != true_regnum (operands[1])"
10930117404Skan  [(const_int 0)]
10931117404Skan{
10932117404Skan  rtx pat, clob;
10933117404Skan  emit_move_insn (operands[1], operands[0]);
10934117404Skan  pat = gen_rtx_SET (VOIDmode, operands[0],
10935117404Skan		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10936117404Skan				     operands[0], operands[2]));
10937117404Skan  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10938117404Skan  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10939117404Skan  DONE;
10940117404Skan})
10941117404Skan
1094290286Sobrien(define_insn "*ashlsi3_1_zext"
1094390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1094490286Sobrien	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
1094590286Sobrien			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
1094690286Sobrien   (clobber (reg:CC 17))]
1094790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1094890286Sobrien{
1094990286Sobrien  switch (get_attr_type (insn))
1095090286Sobrien    {
1095190286Sobrien    case TYPE_ALU:
1095290286Sobrien      if (operands[2] != const1_rtx)
1095390286Sobrien	abort ();
1095490286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1095590286Sobrien
1095690286Sobrien    case TYPE_LEA:
1095790286Sobrien      return "#";
1095890286Sobrien
1095990286Sobrien    default:
1096090286Sobrien      if (REG_P (operands[2]))
1096190286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1096290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1096390286Sobrien	       && INTVAL (operands[2]) == 1
10964117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1096590286Sobrien	return "sal{l}\t%k0";
1096690286Sobrien      else
1096790286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1096890286Sobrien    }
1096990286Sobrien}
1097090286Sobrien  [(set (attr "type")
1097190286Sobrien     (cond [(eq_attr "alternative" "1")
1097290286Sobrien	      (const_string "lea")
1097390286Sobrien            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1097490286Sobrien		     (const_int 0))
1097590286Sobrien		 (match_operand 2 "const1_operand" ""))
1097690286Sobrien	      (const_string "alu")
1097790286Sobrien	   ]
1097890286Sobrien	   (const_string "ishift")))
1097990286Sobrien   (set_attr "mode" "SI")])
1098090286Sobrien
1098190286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1098290286Sobrien(define_split
1098390286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1098490286Sobrien	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
1098590286Sobrien				(match_operand:QI 2 "const_int_operand" ""))))
1098690286Sobrien   (clobber (reg:CC 17))]
10987132727Skan  "TARGET_64BIT && reload_completed
1098890286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
10989132727Skan  [(set (match_dup 0) (zero_extend:DI
10990132727Skan			(subreg:SI (mult:SI (match_dup 1)
10991132727Skan					    (match_dup 2)) 0)))]
1099290286Sobrien{
1099390286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
10994117404Skan  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
1099590286Sobrien})
1099690286Sobrien
1099790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1099890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1099990286Sobrien;; zero are optimized away.
1100090286Sobrien(define_insn "*ashlsi3_cmp"
1100190286Sobrien  [(set (reg 17)
1100290286Sobrien	(compare
1100390286Sobrien	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11004102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1100590286Sobrien	  (const_int 0)))
1100690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1100790286Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))]
1100890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1100990286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1101090286Sobrien{
1101190286Sobrien  switch (get_attr_type (insn))
1101290286Sobrien    {
1101390286Sobrien    case TYPE_ALU:
1101490286Sobrien      if (operands[2] != const1_rtx)
1101590286Sobrien	abort ();
1101690286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1101790286Sobrien
1101890286Sobrien    default:
1101990286Sobrien      if (REG_P (operands[2]))
1102090286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1102190286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1102290286Sobrien	       && INTVAL (operands[2]) == 1
11023117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1102490286Sobrien	return "sal{l}\t%0";
1102590286Sobrien      else
1102690286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1102790286Sobrien    }
1102890286Sobrien}
1102990286Sobrien  [(set (attr "type")
1103090286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1103190286Sobrien		          (const_int 0))
1103290286Sobrien		      (match_operand 0 "register_operand" ""))
1103390286Sobrien		 (match_operand 2 "const1_operand" ""))
1103490286Sobrien	      (const_string "alu")
1103590286Sobrien	   ]
1103690286Sobrien	   (const_string "ishift")))
1103790286Sobrien   (set_attr "mode" "SI")])
1103890286Sobrien
1103990286Sobrien(define_insn "*ashlsi3_cmp_zext"
1104090286Sobrien  [(set (reg 17)
1104190286Sobrien	(compare
1104290286Sobrien	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
11043102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1104490286Sobrien	  (const_int 0)))
1104590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1104690286Sobrien	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
1104790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1104890286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1104990286Sobrien{
1105090286Sobrien  switch (get_attr_type (insn))
1105190286Sobrien    {
1105290286Sobrien    case TYPE_ALU:
1105390286Sobrien      if (operands[2] != const1_rtx)
1105490286Sobrien	abort ();
1105590286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1105690286Sobrien
1105790286Sobrien    default:
1105890286Sobrien      if (REG_P (operands[2]))
1105990286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1106090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1106190286Sobrien	       && INTVAL (operands[2]) == 1
11062117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1106390286Sobrien	return "sal{l}\t%k0";
1106490286Sobrien      else
1106590286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1106690286Sobrien    }
1106790286Sobrien}
1106890286Sobrien  [(set (attr "type")
1106990286Sobrien     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1107090286Sobrien		     (const_int 0))
1107190286Sobrien		 (match_operand 2 "const1_operand" ""))
1107290286Sobrien	      (const_string "alu")
1107390286Sobrien	   ]
1107490286Sobrien	   (const_string "ishift")))
1107590286Sobrien   (set_attr "mode" "SI")])
1107690286Sobrien
1107752296Sobrien(define_expand "ashlhi3"
1107852296Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1107952296Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
1108090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1108190286Sobrien   (clobber (reg:CC 17))]
1108290286Sobrien  "TARGET_HIMODE_MATH"
1108390286Sobrien  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
1108418334Speter
1108590286Sobrien(define_insn "*ashlhi3_1_lea"
1108690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
1108790286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
1108890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1108990286Sobrien   (clobber (reg:CC 17))]
1109090286Sobrien  "!TARGET_PARTIAL_REG_STALL
1109190286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1109290286Sobrien{
1109390286Sobrien  switch (get_attr_type (insn))
1109490286Sobrien    {
1109590286Sobrien    case TYPE_LEA:
1109690286Sobrien      return "#";
1109790286Sobrien    case TYPE_ALU:
1109890286Sobrien      if (operands[2] != const1_rtx)
1109990286Sobrien	abort ();
1110090286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1110190286Sobrien
1110290286Sobrien    default:
1110390286Sobrien      if (REG_P (operands[2]))
1110490286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1110590286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1110690286Sobrien	       && INTVAL (operands[2]) == 1
11107117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1110890286Sobrien	return "sal{w}\t%0";
1110990286Sobrien      else
1111090286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1111190286Sobrien    }
1111290286Sobrien}
1111390286Sobrien  [(set (attr "type")
1111490286Sobrien     (cond [(eq_attr "alternative" "1")
1111590286Sobrien	      (const_string "lea")
1111690286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1111790286Sobrien		          (const_int 0))
1111890286Sobrien		      (match_operand 0 "register_operand" ""))
1111990286Sobrien		 (match_operand 2 "const1_operand" ""))
1112090286Sobrien	      (const_string "alu")
1112190286Sobrien	   ]
1112290286Sobrien	   (const_string "ishift")))
1112390286Sobrien   (set_attr "mode" "HI,SI")])
1112490286Sobrien
1112590286Sobrien(define_insn "*ashlhi3_1"
1112690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1112790286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1112890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI")))
1112990286Sobrien   (clobber (reg:CC 17))]
1113090286Sobrien  "TARGET_PARTIAL_REG_STALL
1113190286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1113290286Sobrien{
1113390286Sobrien  switch (get_attr_type (insn))
1113490286Sobrien    {
1113590286Sobrien    case TYPE_ALU:
1113690286Sobrien      if (operands[2] != const1_rtx)
1113790286Sobrien	abort ();
1113890286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1113990286Sobrien
1114090286Sobrien    default:
1114190286Sobrien      if (REG_P (operands[2]))
1114290286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1114390286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1114490286Sobrien	       && INTVAL (operands[2]) == 1
11145117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1114690286Sobrien	return "sal{w}\t%0";
1114790286Sobrien      else
1114890286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1114990286Sobrien    }
1115090286Sobrien}
1115190286Sobrien  [(set (attr "type")
1115290286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1115390286Sobrien		          (const_int 0))
1115490286Sobrien		      (match_operand 0 "register_operand" ""))
1115590286Sobrien		 (match_operand 2 "const1_operand" ""))
1115690286Sobrien	      (const_string "alu")
1115790286Sobrien	   ]
1115890286Sobrien	   (const_string "ishift")))
1115990286Sobrien   (set_attr "mode" "HI")])
1116090286Sobrien
1116190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1116290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1116390286Sobrien;; zero are optimized away.
1116490286Sobrien(define_insn "*ashlhi3_cmp"
1116590286Sobrien  [(set (reg 17)
1116690286Sobrien	(compare
1116790286Sobrien	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11168102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1116990286Sobrien	  (const_int 0)))
1117090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1117190286Sobrien	(ashift:HI (match_dup 1) (match_dup 2)))]
1117290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1117390286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1117490286Sobrien{
1117590286Sobrien  switch (get_attr_type (insn))
1117690286Sobrien    {
1117790286Sobrien    case TYPE_ALU:
1117890286Sobrien      if (operands[2] != const1_rtx)
1117990286Sobrien	abort ();
1118090286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1118190286Sobrien
1118290286Sobrien    default:
1118390286Sobrien      if (REG_P (operands[2]))
1118490286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1118590286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1118690286Sobrien	       && INTVAL (operands[2]) == 1
11187117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1118890286Sobrien	return "sal{w}\t%0";
1118990286Sobrien      else
1119090286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1119190286Sobrien    }
1119290286Sobrien}
1119390286Sobrien  [(set (attr "type")
1119490286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1119590286Sobrien		          (const_int 0))
1119690286Sobrien		      (match_operand 0 "register_operand" ""))
1119790286Sobrien		 (match_operand 2 "const1_operand" ""))
1119890286Sobrien	      (const_string "alu")
1119990286Sobrien	   ]
1120090286Sobrien	   (const_string "ishift")))
1120190286Sobrien   (set_attr "mode" "HI")])
1120290286Sobrien
1120352296Sobrien(define_expand "ashlqi3"
1120452296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1120552296Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
1120690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1120790286Sobrien   (clobber (reg:CC 17))]
1120890286Sobrien  "TARGET_QIMODE_MATH"
1120990286Sobrien  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
1121018334Speter
1121190286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
1121218334Speter
1121390286Sobrien(define_insn "*ashlqi3_1_lea"
1121490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
1121590286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
1121690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
1121790286Sobrien   (clobber (reg:CC 17))]
1121890286Sobrien  "!TARGET_PARTIAL_REG_STALL
1121990286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1122090286Sobrien{
1122190286Sobrien  switch (get_attr_type (insn))
1122290286Sobrien    {
1122390286Sobrien    case TYPE_LEA:
1122490286Sobrien      return "#";
1122590286Sobrien    case TYPE_ALU:
1122690286Sobrien      if (operands[2] != const1_rtx)
1122790286Sobrien	abort ();
1122890286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1122990286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1123090286Sobrien      else
1123190286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1123218334Speter
1123390286Sobrien    default:
1123490286Sobrien      if (REG_P (operands[2]))
1123590286Sobrien	{
1123690286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1123790286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1123890286Sobrien	  else
1123990286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1124090286Sobrien	}
1124190286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1124290286Sobrien	       && INTVAL (operands[2]) == 1
11243117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1124490286Sobrien	{
1124590286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1124690286Sobrien	    return "sal{l}\t%0";
1124790286Sobrien	  else
1124890286Sobrien	    return "sal{b}\t%0";
1124990286Sobrien	}
1125090286Sobrien      else
1125190286Sobrien	{
1125290286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1125390286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1125490286Sobrien	  else
1125590286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1125690286Sobrien	}
1125790286Sobrien    }
1125890286Sobrien}
1125990286Sobrien  [(set (attr "type")
1126090286Sobrien     (cond [(eq_attr "alternative" "2")
1126190286Sobrien	      (const_string "lea")
1126290286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1126390286Sobrien		          (const_int 0))
1126490286Sobrien		      (match_operand 0 "register_operand" ""))
1126590286Sobrien		 (match_operand 2 "const1_operand" ""))
1126690286Sobrien	      (const_string "alu")
1126790286Sobrien	   ]
1126890286Sobrien	   (const_string "ishift")))
1126990286Sobrien   (set_attr "mode" "QI,SI,SI")])
1127018334Speter
1127190286Sobrien(define_insn "*ashlqi3_1"
1127290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1127390286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1127490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
1127590286Sobrien   (clobber (reg:CC 17))]
1127690286Sobrien  "TARGET_PARTIAL_REG_STALL
1127790286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1127890286Sobrien{
1127990286Sobrien  switch (get_attr_type (insn))
1128090286Sobrien    {
1128190286Sobrien    case TYPE_ALU:
1128290286Sobrien      if (operands[2] != const1_rtx)
1128390286Sobrien	abort ();
1128490286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1128590286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1128690286Sobrien      else
1128790286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1128852296Sobrien
1128990286Sobrien    default:
1129090286Sobrien      if (REG_P (operands[2]))
1129190286Sobrien	{
1129290286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1129390286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1129490286Sobrien	  else
1129590286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1129690286Sobrien	}
1129790286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1129890286Sobrien	       && INTVAL (operands[2]) == 1
11299117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1130090286Sobrien	{
1130190286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1130290286Sobrien	    return "sal{l}\t%0";
1130390286Sobrien	  else
1130490286Sobrien	    return "sal{b}\t%0";
1130590286Sobrien	}
1130690286Sobrien      else
1130790286Sobrien	{
1130890286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1130990286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1131090286Sobrien	  else
1131190286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1131290286Sobrien	}
1131390286Sobrien    }
1131490286Sobrien}
1131590286Sobrien  [(set (attr "type")
1131690286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1131790286Sobrien		          (const_int 0))
1131890286Sobrien		      (match_operand 0 "register_operand" ""))
1131990286Sobrien		 (match_operand 2 "const1_operand" ""))
1132090286Sobrien	      (const_string "alu")
1132190286Sobrien	   ]
1132290286Sobrien	   (const_string "ishift")))
1132390286Sobrien   (set_attr "mode" "QI,SI")])
1132418334Speter
1132590286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1132690286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1132790286Sobrien;; zero are optimized away.
1132890286Sobrien(define_insn "*ashlqi3_cmp"
1132990286Sobrien  [(set (reg 17)
1133090286Sobrien	(compare
1133190286Sobrien	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11332102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1133390286Sobrien	  (const_int 0)))
1133490286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1133590286Sobrien	(ashift:QI (match_dup 1) (match_dup 2)))]
1133690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1133790286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1133890286Sobrien{
1133990286Sobrien  switch (get_attr_type (insn))
1134090286Sobrien    {
1134190286Sobrien    case TYPE_ALU:
1134290286Sobrien      if (operands[2] != const1_rtx)
1134390286Sobrien	abort ();
1134490286Sobrien      return "add{b}\t{%0, %0|%0, %0}";
1134518334Speter
1134690286Sobrien    default:
1134790286Sobrien      if (REG_P (operands[2]))
1134890286Sobrien	return "sal{b}\t{%b2, %0|%0, %b2}";
1134990286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1135090286Sobrien	       && INTVAL (operands[2]) == 1
11351117404Skan	       && (TARGET_SHIFT1 || optimize_size))
1135290286Sobrien	return "sal{b}\t%0";
1135390286Sobrien      else
1135490286Sobrien	return "sal{b}\t{%2, %0|%0, %2}";
1135590286Sobrien    }
1135690286Sobrien}
1135790286Sobrien  [(set (attr "type")
1135890286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1135990286Sobrien		          (const_int 0))
1136090286Sobrien		      (match_operand 0 "register_operand" ""))
1136190286Sobrien		 (match_operand 2 "const1_operand" ""))
1136290286Sobrien	      (const_string "alu")
1136390286Sobrien	   ]
1136490286Sobrien	   (const_string "ishift")))
1136590286Sobrien   (set_attr "mode" "QI")])
1136618334Speter
1136718334Speter;; See comment above `ashldi3' about how this works.
1136818334Speter
1136918334Speter(define_expand "ashrdi3"
1137090286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1137190286Sobrien		   (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1137290286Sobrien				(match_operand:QI 2 "nonmemory_operand" "")))
1137390286Sobrien	      (clobber (reg:CC 17))])]
1137418334Speter  ""
1137518334Speter{
1137690286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1137718334Speter    {
1137890286Sobrien      emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
1137990286Sobrien      DONE;
1138018334Speter    }
1138190286Sobrien  ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
1138218334Speter  DONE;
1138390286Sobrien})
1138418334Speter
1138590286Sobrien(define_insn "ashrdi3_63_rex64"
1138690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
1138790286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
1138890286Sobrien		     (match_operand:DI 2 "const_int_operand" "i,i")))
1138990286Sobrien   (clobber (reg:CC 17))]
1139090286Sobrien  "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
1139190286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1139290286Sobrien  "@
1139390286Sobrien   {cqto|cqo}
1139490286Sobrien   sar{q}\t{%2, %0|%0, %2}"
1139590286Sobrien  [(set_attr "type" "imovx,ishift")
1139690286Sobrien   (set_attr "prefix_0f" "0,*")
1139790286Sobrien   (set_attr "length_immediate" "0,*")
1139890286Sobrien   (set_attr "modrm" "0,1")
1139990286Sobrien   (set_attr "mode" "DI")])
1140050650Sobrien
1140190286Sobrien(define_insn "*ashrdi3_1_one_bit_rex64"
1140290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1140390286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1140590286Sobrien   (clobber (reg:CC 17))]
1140690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11407117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1140890286Sobrien  "sar{q}\t%0"
1140990286Sobrien  [(set_attr "type" "ishift")
1141090286Sobrien   (set (attr "length") 
1141190286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1141290286Sobrien	(const_string "2")
1141390286Sobrien	(const_string "*")))])
1141450650Sobrien
1141590286Sobrien(define_insn "*ashrdi3_1_rex64"
1141690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1141790286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1141890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1141990286Sobrien   (clobber (reg:CC 17))]
1142090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1142190286Sobrien  "@
1142290286Sobrien   sar{q}\t{%2, %0|%0, %2}
1142390286Sobrien   sar{q}\t{%b2, %0|%0, %b2}"
1142490286Sobrien  [(set_attr "type" "ishift")
1142590286Sobrien   (set_attr "mode" "DI")])
1142650650Sobrien
1142790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1142890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1142990286Sobrien;; zero are optimized away.
1143090286Sobrien(define_insn "*ashrdi3_one_bit_cmp_rex64"
1143190286Sobrien  [(set (reg 17)
1143290286Sobrien	(compare
1143390286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1143590286Sobrien	  (const_int 0)))
1143690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1143790286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1143890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439117404Skan   && (TARGET_SHIFT1 || optimize_size)
1144090286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1144190286Sobrien  "sar{q}\t%0"
1144290286Sobrien  [(set_attr "type" "ishift")
1144390286Sobrien   (set (attr "length") 
1144490286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1144590286Sobrien	(const_string "2")
1144690286Sobrien	(const_string "*")))])
1144750650Sobrien
1144890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1144990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1145090286Sobrien;; zero are optimized away.
1145190286Sobrien(define_insn "*ashrdi3_cmp_rex64"
1145290286Sobrien  [(set (reg 17)
1145390286Sobrien	(compare
1145490286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1145590286Sobrien		       (match_operand:QI 2 "const_int_operand" "n"))
1145690286Sobrien	  (const_int 0)))
1145790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1145890286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1145990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1146090286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1146190286Sobrien  "sar{q}\t{%2, %0|%0, %2}"
1146290286Sobrien  [(set_attr "type" "ishift")
1146390286Sobrien   (set_attr "mode" "DI")])
1146418334Speter
1146518334Speter
1146690286Sobrien(define_insn "ashrdi3_1"
1146790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1146890286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1146990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1147090286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1147190286Sobrien   (clobber (reg:CC 17))]
1147290286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1147390286Sobrien  "#"
1147490286Sobrien  [(set_attr "type" "multi")])
1147518334Speter
1147690286Sobrien(define_insn "*ashrdi3_2"
1147790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1147890286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1147990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1148090286Sobrien   (clobber (reg:CC 17))]
1148190286Sobrien  "!TARGET_64BIT"
1148290286Sobrien  "#"
1148390286Sobrien  [(set_attr "type" "multi")])
1148418334Speter
1148590286Sobrien(define_split
1148690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1148790286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1148890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1148990286Sobrien   (clobber (match_scratch:SI 3 ""))
1149090286Sobrien   (clobber (reg:CC 17))]
1149190286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1149290286Sobrien  [(const_int 0)]
1149390286Sobrien  "ix86_split_ashrdi (operands, operands[3]); DONE;")
1149418334Speter
1149590286Sobrien(define_split
1149690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1149790286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1149890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1149990286Sobrien   (clobber (reg:CC 17))]
1150090286Sobrien  "!TARGET_64BIT && reload_completed"
1150190286Sobrien  [(const_int 0)]
1150290286Sobrien  "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
1150318334Speter
1150490286Sobrien(define_insn "x86_shrd_1"
1150590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1150690286Sobrien        (ior:SI (ashiftrt:SI (match_dup 0)
1150790286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1150890286Sobrien		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1150990286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1151090286Sobrien   (clobber (reg:CC 17))]
1151118334Speter  ""
1151290286Sobrien  "@
1151390286Sobrien   shrd{l}\t{%2, %1, %0|%0, %1, %2}
1151490286Sobrien   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
1151590286Sobrien  [(set_attr "type" "ishift")
1151690286Sobrien   (set_attr "prefix_0f" "1")
1151790286Sobrien   (set_attr "pent_pair" "np")
1151890286Sobrien   (set_attr "ppro_uops" "few")
1151990286Sobrien   (set_attr "mode" "SI")])
1152090286Sobrien
1152190286Sobrien(define_expand "x86_shift_adj_3"
1152290286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1152390286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1152490286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1152590286Sobrien  ""
1152618334Speter{
1152790286Sobrien  rtx label = gen_label_rtx ();
1152890286Sobrien  rtx tmp;
1152918334Speter
1153090286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1153118334Speter
1153290286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1153390286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1153490286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1153590286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1153690286Sobrien			      pc_rtx);
1153790286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1153890286Sobrien  JUMP_LABEL (tmp) = label;
1153918334Speter
1154090286Sobrien  emit_move_insn (operands[0], operands[1]);
1154190286Sobrien  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
1154218334Speter
1154390286Sobrien  emit_label (label);
1154490286Sobrien  LABEL_NUSES (label) = 1;
1154590286Sobrien
1154690286Sobrien  DONE;
1154790286Sobrien})
1154890286Sobrien
1154952296Sobrien(define_insn "ashrsi3_31"
1155090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
1155190286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
1155290286Sobrien		     (match_operand:SI 2 "const_int_operand" "i,i")))
1155390286Sobrien   (clobber (reg:CC 17))]
1155490286Sobrien  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
1155590286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1155652296Sobrien  "@
1155790286Sobrien   {cltd|cdq}
1155890286Sobrien   sar{l}\t{%2, %0|%0, %2}"
1155990286Sobrien  [(set_attr "type" "imovx,ishift")
1156090286Sobrien   (set_attr "prefix_0f" "0,*")
1156190286Sobrien   (set_attr "length_immediate" "0,*")
1156290286Sobrien   (set_attr "modrm" "0,1")
1156390286Sobrien   (set_attr "mode" "SI")])
1156452296Sobrien
1156590286Sobrien(define_insn "*ashrsi3_31_zext"
1156690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*d,r")
1156790286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
1156890286Sobrien				     (match_operand:SI 2 "const_int_operand" "i,i"))))
1156990286Sobrien   (clobber (reg:CC 17))]
1157090286Sobrien  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
1157190286Sobrien   && INTVAL (operands[2]) == 31
1157290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1157390286Sobrien  "@
1157490286Sobrien   {cltd|cdq}
1157590286Sobrien   sar{l}\t{%2, %k0|%k0, %2}"
1157690286Sobrien  [(set_attr "type" "imovx,ishift")
1157790286Sobrien   (set_attr "prefix_0f" "0,*")
1157890286Sobrien   (set_attr "length_immediate" "0,*")
1157990286Sobrien   (set_attr "modrm" "0,1")
1158090286Sobrien   (set_attr "mode" "SI")])
1158190286Sobrien
1158290286Sobrien(define_expand "ashrsi3"
1158390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1158490286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1158590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1158690286Sobrien   (clobber (reg:CC 17))]
1158790286Sobrien  ""
1158890286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
1158990286Sobrien
1159090286Sobrien(define_insn "*ashrsi3_1_one_bit"
1159150650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1159250650Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11593132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1159490286Sobrien   (clobber (reg:CC 17))]
1159590286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11596117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1159790286Sobrien  "sar{l}\t%0"
1159890286Sobrien  [(set_attr "type" "ishift")
1159990286Sobrien   (set (attr "length") 
1160090286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1160190286Sobrien	(const_string "2")
1160290286Sobrien	(const_string "*")))])
1160318334Speter
1160490286Sobrien(define_insn "*ashrsi3_1_one_bit_zext"
1160590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1160690286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11607132727Skan				     (match_operand:QI 2 "const1_operand" ""))))
1160890286Sobrien   (clobber (reg:CC 17))]
1160990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11610117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1161190286Sobrien  "sar{l}\t%k0"
1161290286Sobrien  [(set_attr "type" "ishift")
1161390286Sobrien   (set_attr "length" "2")])
1161490286Sobrien
1161590286Sobrien(define_insn "*ashrsi3_1"
1161690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1161790286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1161890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1161990286Sobrien   (clobber (reg:CC 17))]
1162090286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1162190286Sobrien  "@
1162290286Sobrien   sar{l}\t{%2, %0|%0, %2}
1162390286Sobrien   sar{l}\t{%b2, %0|%0, %b2}"
1162490286Sobrien  [(set_attr "type" "ishift")
1162590286Sobrien   (set_attr "mode" "SI")])
1162690286Sobrien
1162790286Sobrien(define_insn "*ashrsi3_1_zext"
1162890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1162990286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1163090286Sobrien				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1163190286Sobrien   (clobber (reg:CC 17))]
1163290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1163390286Sobrien  "@
1163490286Sobrien   sar{l}\t{%2, %k0|%k0, %2}
1163590286Sobrien   sar{l}\t{%b2, %k0|%k0, %b2}"
1163690286Sobrien  [(set_attr "type" "ishift")
1163790286Sobrien   (set_attr "mode" "SI")])
1163890286Sobrien
1163990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1164090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1164190286Sobrien;; zero are optimized away.
1164290286Sobrien(define_insn "*ashrsi3_one_bit_cmp"
1164390286Sobrien  [(set (reg 17)
1164490286Sobrien	(compare
1164590286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11646132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1164790286Sobrien	  (const_int 0)))
1164890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1164990286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1165090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11651117404Skan   && (TARGET_SHIFT1 || optimize_size)
1165290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1165390286Sobrien  "sar{l}\t%0"
1165490286Sobrien  [(set_attr "type" "ishift")
1165590286Sobrien   (set (attr "length") 
1165690286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1165790286Sobrien	(const_string "2")
1165890286Sobrien	(const_string "*")))])
1165990286Sobrien
1166090286Sobrien(define_insn "*ashrsi3_one_bit_cmp_zext"
1166190286Sobrien  [(set (reg 17)
1166290286Sobrien	(compare
1166390286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1166590286Sobrien	  (const_int 0)))
1166690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1166790286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1166890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11669117404Skan   && (TARGET_SHIFT1 || optimize_size)
1167090286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1167190286Sobrien  "sar{l}\t%k0"
1167290286Sobrien  [(set_attr "type" "ishift")
1167390286Sobrien   (set_attr "length" "2")])
1167490286Sobrien
1167590286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1167690286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1167790286Sobrien;; zero are optimized away.
1167890286Sobrien(define_insn "*ashrsi3_cmp"
1167990286Sobrien  [(set (reg 17)
1168090286Sobrien	(compare
1168190286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1168390286Sobrien	  (const_int 0)))
1168490286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1168590286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1168690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1168790286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1168890286Sobrien  "sar{l}\t{%2, %0|%0, %2}"
1168990286Sobrien  [(set_attr "type" "ishift")
1169090286Sobrien   (set_attr "mode" "SI")])
1169190286Sobrien
1169290286Sobrien(define_insn "*ashrsi3_cmp_zext"
1169390286Sobrien  [(set (reg 17)
1169490286Sobrien	(compare
1169590286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11696102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1169790286Sobrien	  (const_int 0)))
1169890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1169990286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1170090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1170190286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1170290286Sobrien  "sar{l}\t{%2, %k0|%k0, %2}"
1170390286Sobrien  [(set_attr "type" "ishift")
1170490286Sobrien   (set_attr "mode" "SI")])
1170590286Sobrien
1170690286Sobrien(define_expand "ashrhi3"
1170790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1170890286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1170990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1171090286Sobrien   (clobber (reg:CC 17))]
1171190286Sobrien  "TARGET_HIMODE_MATH"
1171290286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
1171390286Sobrien
1171490286Sobrien(define_insn "*ashrhi3_1_one_bit"
1171550650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1171650650Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1171890286Sobrien   (clobber (reg:CC 17))]
1171990286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11720117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1172190286Sobrien  "sar{w}\t%0"
1172290286Sobrien  [(set_attr "type" "ishift")
1172390286Sobrien   (set (attr "length") 
1172490286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1172590286Sobrien	(const_string "2")
1172690286Sobrien	(const_string "*")))])
1172718334Speter
1172890286Sobrien(define_insn "*ashrhi3_1"
1172990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1173090286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1173190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1173290286Sobrien   (clobber (reg:CC 17))]
1173390286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1173490286Sobrien  "@
1173590286Sobrien   sar{w}\t{%2, %0|%0, %2}
1173690286Sobrien   sar{w}\t{%b2, %0|%0, %b2}"
1173790286Sobrien  [(set_attr "type" "ishift")
1173890286Sobrien   (set_attr "mode" "HI")])
1173990286Sobrien
1174090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1174190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1174290286Sobrien;; zero are optimized away.
1174390286Sobrien(define_insn "*ashrhi3_one_bit_cmp"
1174490286Sobrien  [(set (reg 17)
1174590286Sobrien	(compare
1174690286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1174890286Sobrien	  (const_int 0)))
1174990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1175090286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1175190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11752117404Skan   && (TARGET_SHIFT1 || optimize_size)
1175390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1175490286Sobrien  "sar{w}\t%0"
1175590286Sobrien  [(set_attr "type" "ishift")
1175690286Sobrien   (set (attr "length") 
1175790286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1175890286Sobrien	(const_string "2")
1175990286Sobrien	(const_string "*")))])
1176090286Sobrien
1176190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1176290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1176390286Sobrien;; zero are optimized away.
1176490286Sobrien(define_insn "*ashrhi3_cmp"
1176590286Sobrien  [(set (reg 17)
1176690286Sobrien	(compare
1176790286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1176990286Sobrien	  (const_int 0)))
1177090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1177190286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1177290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1177390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1177490286Sobrien  "sar{w}\t{%2, %0|%0, %2}"
1177590286Sobrien  [(set_attr "type" "ishift")
1177690286Sobrien   (set_attr "mode" "HI")])
1177790286Sobrien
1177890286Sobrien(define_expand "ashrqi3"
1177990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1178090286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1178190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1178290286Sobrien   (clobber (reg:CC 17))]
1178390286Sobrien  "TARGET_QIMODE_MATH"
1178490286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
1178590286Sobrien
1178690286Sobrien(define_insn "*ashrqi3_1_one_bit"
1178750650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1178850650Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1179090286Sobrien   (clobber (reg:CC 17))]
1179190286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1179390286Sobrien  "sar{b}\t%0"
1179490286Sobrien  [(set_attr "type" "ishift")
1179590286Sobrien   (set (attr "length") 
1179690286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1179790286Sobrien	(const_string "2")
1179890286Sobrien	(const_string "*")))])
1179990286Sobrien
11800117404Skan(define_insn "*ashrqi3_1_one_bit_slp"
11801117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802117404Skan	(ashiftrt:QI (match_dup 0)
11803132727Skan		     (match_operand:QI 1 "const1_operand" "")))
11804117404Skan   (clobber (reg:CC 17))]
11805117404Skan  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806117404Skan   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807117404Skan   && (TARGET_SHIFT1 || optimize_size)"
11808117404Skan  "sar{b}\t%0"
11809117404Skan  [(set_attr "type" "ishift1")
11810117404Skan   (set (attr "length") 
11811117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
11812117404Skan	(const_string "2")
11813117404Skan	(const_string "*")))])
11814117404Skan
1181590286Sobrien(define_insn "*ashrqi3_1"
1181690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1181790286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1181890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1181990286Sobrien   (clobber (reg:CC 17))]
1182090286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1182190286Sobrien  "@
1182290286Sobrien   sar{b}\t{%2, %0|%0, %2}
1182390286Sobrien   sar{b}\t{%b2, %0|%0, %b2}"
1182490286Sobrien  [(set_attr "type" "ishift")
1182590286Sobrien   (set_attr "mode" "QI")])
1182690286Sobrien
11827117404Skan(define_insn "*ashrqi3_1_slp"
11828117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829117404Skan	(ashiftrt:QI (match_dup 0)
11830117404Skan		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831117404Skan   (clobber (reg:CC 17))]
11832117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11834117404Skan  "@
11835117404Skan   sar{b}\t{%1, %0|%0, %1}
11836117404Skan   sar{b}\t{%b1, %0|%0, %b1}"
11837117404Skan  [(set_attr "type" "ishift1")
11838117404Skan   (set_attr "mode" "QI")])
11839117404Skan
1184090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1184190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1184290286Sobrien;; zero are optimized away.
1184390286Sobrien(define_insn "*ashrqi3_one_bit_cmp"
1184490286Sobrien  [(set (reg 17)
1184590286Sobrien	(compare
1184690286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847132727Skan		       (match_operand:QI 2 "const1_operand" "I"))
1184890286Sobrien	  (const_int 0)))
11849102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1185090286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1185190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
11852117404Skan   && (TARGET_SHIFT1 || optimize_size)
1185390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1185490286Sobrien  "sar{b}\t%0"
1185590286Sobrien  [(set_attr "type" "ishift")
1185690286Sobrien   (set (attr "length") 
1185790286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1185890286Sobrien	(const_string "2")
1185990286Sobrien	(const_string "*")))])
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 "*ashrqi3_cmp"
1186590286Sobrien  [(set (reg 17)
1186690286Sobrien	(compare
1186790286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11868102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1186990286Sobrien	  (const_int 0)))
11870102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1187190286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1187290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1187390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1187490286Sobrien  "sar{b}\t{%2, %0|%0, %2}"
1187590286Sobrien  [(set_attr "type" "ishift")
1187690286Sobrien   (set_attr "mode" "QI")])
1187718334Speter
1187890286Sobrien;; Logical shift instructions
1187918334Speter
1188018334Speter;; See comment above `ashldi3' about how this works.
1188118334Speter
1188218334Speter(define_expand "lshrdi3"
1188390286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1188490286Sobrien		   (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1188590286Sobrien			        (match_operand:QI 2 "nonmemory_operand" "")))
1188690286Sobrien	      (clobber (reg:CC 17))])]
1188718334Speter  ""
1188818334Speter{
1188990286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1189018334Speter    {
1189190286Sobrien      emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
1189290286Sobrien      DONE;
1189318334Speter    }
1189490286Sobrien  ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
1189518334Speter  DONE;
1189690286Sobrien})
1189718334Speter
1189890286Sobrien(define_insn "*lshrdi3_1_one_bit_rex64"
1189990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1190090286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11901132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1190290286Sobrien   (clobber (reg:CC 17))]
1190390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11904117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1190590286Sobrien  "shr{q}\t%0"
1190690286Sobrien  [(set_attr "type" "ishift")
1190790286Sobrien   (set (attr "length") 
1190890286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1190990286Sobrien	(const_string "2")
1191090286Sobrien	(const_string "*")))])
1191150650Sobrien
1191290286Sobrien(define_insn "*lshrdi3_1_rex64"
1191390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1191490286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1191590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1191690286Sobrien   (clobber (reg:CC 17))]
1191790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1191890286Sobrien  "@
1191990286Sobrien   shr{q}\t{%2, %0|%0, %2}
1192090286Sobrien   shr{q}\t{%b2, %0|%0, %b2}"
1192190286Sobrien  [(set_attr "type" "ishift")
1192290286Sobrien   (set_attr "mode" "DI")])
1192350650Sobrien
1192490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1192590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1192690286Sobrien;; zero are optimized away.
1192790286Sobrien(define_insn "*lshrdi3_cmp_one_bit_rex64"
1192890286Sobrien  [(set (reg 17)
1192990286Sobrien	(compare
1193090286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11931132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1193290286Sobrien	  (const_int 0)))
1193390286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1193490286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1193590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11936117404Skan   && (TARGET_SHIFT1 || optimize_size)
1193790286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1193890286Sobrien  "shr{q}\t%0"
1193990286Sobrien  [(set_attr "type" "ishift")
1194090286Sobrien   (set (attr "length") 
1194190286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1194290286Sobrien	(const_string "2")
1194390286Sobrien	(const_string "*")))])
1194450650Sobrien
1194590286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1194690286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1194790286Sobrien;; zero are optimized away.
1194890286Sobrien(define_insn "*lshrdi3_cmp_rex64"
1194990286Sobrien  [(set (reg 17)
1195090286Sobrien	(compare
1195190286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1195290286Sobrien		       (match_operand:QI 2 "const_int_operand" "e"))
1195390286Sobrien	  (const_int 0)))
1195490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1195590286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1195690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1195790286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1195890286Sobrien  "shr{q}\t{%2, %0|%0, %2}"
1195990286Sobrien  [(set_attr "type" "ishift")
1196090286Sobrien   (set_attr "mode" "DI")])
1196150650Sobrien
1196290286Sobrien(define_insn "lshrdi3_1"
1196390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1196418334Speter	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1196590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1196690286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1196790286Sobrien   (clobber (reg:CC 17))]
1196890286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1196990286Sobrien  "#"
1197090286Sobrien  [(set_attr "type" "multi")])
1197118334Speter
1197290286Sobrien(define_insn "*lshrdi3_2"
1197390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1197490286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1197590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1197690286Sobrien   (clobber (reg:CC 17))]
1197790286Sobrien  "!TARGET_64BIT"
1197890286Sobrien  "#"
1197990286Sobrien  [(set_attr "type" "multi")])
1198018334Speter
1198190286Sobrien(define_split 
1198290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1198390286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1198490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1198590286Sobrien   (clobber (match_scratch:SI 3 ""))
1198690286Sobrien   (clobber (reg:CC 17))]
1198790286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1198890286Sobrien  [(const_int 0)]
1198990286Sobrien  "ix86_split_lshrdi (operands, operands[3]); DONE;")
1199018334Speter
1199190286Sobrien(define_split 
1199290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1199390286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1199490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1199590286Sobrien   (clobber (reg:CC 17))]
1199690286Sobrien  "!TARGET_64BIT && reload_completed"
1199790286Sobrien  [(const_int 0)]
1199890286Sobrien  "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
1199918334Speter
1200090286Sobrien(define_expand "lshrsi3"
1200190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1200290286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1200390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1200490286Sobrien   (clobber (reg:CC 17))]
1200590286Sobrien  ""
1200690286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
1200718334Speter
1200890286Sobrien(define_insn "*lshrsi3_1_one_bit"
1200990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1201090286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12011132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1201290286Sobrien   (clobber (reg:CC 17))]
1201390286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12014117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1201590286Sobrien  "shr{l}\t%0"
1201690286Sobrien  [(set_attr "type" "ishift")
1201790286Sobrien   (set (attr "length") 
1201890286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1201990286Sobrien	(const_string "2")
1202090286Sobrien	(const_string "*")))])
1202118334Speter
1202290286Sobrien(define_insn "*lshrsi3_1_one_bit_zext"
1202390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1202490286Sobrien	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12025132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1202690286Sobrien   (clobber (reg:CC 17))]
1202790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12028117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1202990286Sobrien  "shr{l}\t%k0"
1203090286Sobrien  [(set_attr "type" "ishift")
1203190286Sobrien   (set_attr "length" "2")])
1203218334Speter
1203390286Sobrien(define_insn "*lshrsi3_1"
1203490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1203590286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1203690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1203790286Sobrien   (clobber (reg:CC 17))]
1203890286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1203990286Sobrien  "@
1204090286Sobrien   shr{l}\t{%2, %0|%0, %2}
1204190286Sobrien   shr{l}\t{%b2, %0|%0, %b2}"
1204290286Sobrien  [(set_attr "type" "ishift")
1204390286Sobrien   (set_attr "mode" "SI")])
1204418334Speter
1204590286Sobrien(define_insn "*lshrsi3_1_zext"
1204690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1204790286Sobrien	(zero_extend:DI
1204890286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1204990286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1205090286Sobrien   (clobber (reg:CC 17))]
1205190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1205290286Sobrien  "@
1205390286Sobrien   shr{l}\t{%2, %k0|%k0, %2}
1205490286Sobrien   shr{l}\t{%b2, %k0|%k0, %b2}"
1205590286Sobrien  [(set_attr "type" "ishift")
1205690286Sobrien   (set_attr "mode" "SI")])
1205718334Speter
1205890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1205990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1206090286Sobrien;; zero are optimized away.
1206190286Sobrien(define_insn "*lshrsi3_one_bit_cmp"
1206290286Sobrien  [(set (reg 17)
1206390286Sobrien	(compare
1206490286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12065132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1206690286Sobrien	  (const_int 0)))
1206790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1206890286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1206990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
12070117404Skan   && (TARGET_SHIFT1 || optimize_size)
1207190286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1207290286Sobrien  "shr{l}\t%0"
1207390286Sobrien  [(set_attr "type" "ishift")
1207490286Sobrien   (set (attr "length") 
1207590286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1207690286Sobrien	(const_string "2")
1207790286Sobrien	(const_string "*")))])
1207818334Speter
1207990286Sobrien(define_insn "*lshrsi3_cmp_one_bit_zext"
1208090286Sobrien  [(set (reg 17)
1208190286Sobrien	(compare
1208290286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12083132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1208490286Sobrien	  (const_int 0)))
1208590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1208690286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1208790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12088117404Skan   && (TARGET_SHIFT1 || optimize_size)
1208990286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1209090286Sobrien  "shr{l}\t%k0"
1209190286Sobrien  [(set_attr "type" "ishift")
1209290286Sobrien   (set_attr "length" "2")])
1209318334Speter
1209490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1209590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1209690286Sobrien;; zero are optimized away.
1209790286Sobrien(define_insn "*lshrsi3_cmp"
1209890286Sobrien  [(set (reg 17)
1209990286Sobrien	(compare
1210090286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12101102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1210290286Sobrien	  (const_int 0)))
1210390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1210490286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1210590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1210690286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1210790286Sobrien  "shr{l}\t{%2, %0|%0, %2}"
1210890286Sobrien  [(set_attr "type" "ishift")
1210990286Sobrien   (set_attr "mode" "SI")])
1211090286Sobrien
1211190286Sobrien(define_insn "*lshrsi3_cmp_zext"
1211290286Sobrien  [(set (reg 17)
1211390286Sobrien	(compare
1211490286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12115102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1211690286Sobrien	  (const_int 0)))
1211790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1211890286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1211990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1212090286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1212190286Sobrien  "shr{l}\t{%2, %k0|%k0, %2}"
1212290286Sobrien  [(set_attr "type" "ishift")
1212390286Sobrien   (set_attr "mode" "SI")])
1212490286Sobrien
1212590286Sobrien(define_expand "lshrhi3"
1212690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1212790286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1212890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1212990286Sobrien   (clobber (reg:CC 17))]
1213090286Sobrien  "TARGET_HIMODE_MATH"
1213190286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
1213290286Sobrien
1213390286Sobrien(define_insn "*lshrhi3_1_one_bit"
1213450650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1213550650Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1213790286Sobrien   (clobber (reg:CC 17))]
1213890286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12139117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1214090286Sobrien  "shr{w}\t%0"
1214190286Sobrien  [(set_attr "type" "ishift")
1214290286Sobrien   (set (attr "length") 
1214390286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1214490286Sobrien	(const_string "2")
1214590286Sobrien	(const_string "*")))])
1214618334Speter
1214790286Sobrien(define_insn "*lshrhi3_1"
1214890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1214990286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1215090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1215190286Sobrien   (clobber (reg:CC 17))]
1215290286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1215390286Sobrien  "@
1215490286Sobrien   shr{w}\t{%2, %0|%0, %2}
1215590286Sobrien   shr{w}\t{%b2, %0|%0, %b2}"
1215690286Sobrien  [(set_attr "type" "ishift")
1215790286Sobrien   (set_attr "mode" "HI")])
1215890286Sobrien
1215990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1216090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1216190286Sobrien;; zero are optimized away.
1216290286Sobrien(define_insn "*lshrhi3_one_bit_cmp"
1216390286Sobrien  [(set (reg 17)
1216490286Sobrien	(compare
1216590286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12166132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1216790286Sobrien	  (const_int 0)))
1216890286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1216990286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1217090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
12171117404Skan   && (TARGET_SHIFT1 || optimize_size)
1217290286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1217390286Sobrien  "shr{w}\t%0"
1217490286Sobrien  [(set_attr "type" "ishift")
1217590286Sobrien   (set (attr "length") 
1217690286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1217790286Sobrien	(const_string "2")
1217890286Sobrien	(const_string "*")))])
1217990286Sobrien
1218090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1218190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1218290286Sobrien;; zero are optimized away.
1218390286Sobrien(define_insn "*lshrhi3_cmp"
1218490286Sobrien  [(set (reg 17)
1218590286Sobrien	(compare
1218690286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12187102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1218890286Sobrien	  (const_int 0)))
1218990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1219090286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1219190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1219290286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1219390286Sobrien  "shr{w}\t{%2, %0|%0, %2}"
1219490286Sobrien  [(set_attr "type" "ishift")
1219590286Sobrien   (set_attr "mode" "HI")])
1219690286Sobrien
1219790286Sobrien(define_expand "lshrqi3"
1219890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1219990286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1220090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1220190286Sobrien   (clobber (reg:CC 17))]
1220290286Sobrien  "TARGET_QIMODE_MATH"
1220390286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
1220490286Sobrien
1220590286Sobrien(define_insn "*lshrqi3_1_one_bit"
1220650650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1220750650Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12208132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1220990286Sobrien   (clobber (reg:CC 17))]
1221090286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12211117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1221290286Sobrien  "shr{b}\t%0"
1221390286Sobrien  [(set_attr "type" "ishift")
1221490286Sobrien   (set (attr "length") 
1221590286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1221690286Sobrien	(const_string "2")
1221790286Sobrien	(const_string "*")))])
1221890286Sobrien
12219117404Skan(define_insn "*lshrqi3_1_one_bit_slp"
12220117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221117404Skan	(lshiftrt:QI (match_dup 0)
12222132727Skan		     (match_operand:QI 1 "const1_operand" "")))
12223117404Skan   (clobber (reg:CC 17))]
12224117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225117404Skan   && (TARGET_SHIFT1 || optimize_size)"
12226117404Skan  "shr{b}\t%0"
12227117404Skan  [(set_attr "type" "ishift1")
12228117404Skan   (set (attr "length") 
12229117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
12230117404Skan	(const_string "2")
12231117404Skan	(const_string "*")))])
12232117404Skan
1223390286Sobrien(define_insn "*lshrqi3_1"
1223490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1223590286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1223690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1223790286Sobrien   (clobber (reg:CC 17))]
1223890286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1223990286Sobrien  "@
1224090286Sobrien   shr{b}\t{%2, %0|%0, %2}
1224190286Sobrien   shr{b}\t{%b2, %0|%0, %b2}"
1224290286Sobrien  [(set_attr "type" "ishift")
1224390286Sobrien   (set_attr "mode" "QI")])
1224490286Sobrien
12245117404Skan(define_insn "*lshrqi3_1_slp"
12246117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247117404Skan	(lshiftrt:QI (match_dup 0)
12248117404Skan		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249117404Skan   (clobber (reg:CC 17))]
12250117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12251117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12252117404Skan  "@
12253117404Skan   shr{b}\t{%1, %0|%0, %1}
12254117404Skan   shr{b}\t{%b1, %0|%0, %b1}"
12255117404Skan  [(set_attr "type" "ishift1")
12256117404Skan   (set_attr "mode" "QI")])
12257117404Skan
1225890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1225990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1226090286Sobrien;; zero are optimized away.
1226190286Sobrien(define_insn "*lshrqi2_one_bit_cmp"
1226290286Sobrien  [(set (reg 17)
1226390286Sobrien	(compare
1226490286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12265132727Skan		       (match_operand:QI 2 "const1_operand" ""))
1226690286Sobrien	  (const_int 0)))
1226790286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1226890286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1226990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
12270117404Skan   && (TARGET_SHIFT1 || optimize_size)
1227190286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1227290286Sobrien  "shr{b}\t%0"
1227390286Sobrien  [(set_attr "type" "ishift")
1227490286Sobrien   (set (attr "length") 
1227590286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1227690286Sobrien	(const_string "2")
1227790286Sobrien	(const_string "*")))])
1227890286Sobrien
1227990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1228090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1228190286Sobrien;; zero are optimized away.
1228290286Sobrien(define_insn "*lshrqi2_cmp"
1228390286Sobrien  [(set (reg 17)
1228490286Sobrien	(compare
1228590286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12286102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1228790286Sobrien	  (const_int 0)))
1228890286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1228990286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1229090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1229190286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1229290286Sobrien  "shr{b}\t{%2, %0|%0, %2}"
1229390286Sobrien  [(set_attr "type" "ishift")
1229490286Sobrien   (set_attr "mode" "QI")])
1229518334Speter
1229690286Sobrien;; Rotate instructions
1229718334Speter
1229890286Sobrien(define_expand "rotldi3"
1229990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1230090286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
1230190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1230290286Sobrien   (clobber (reg:CC 17))]
1230390286Sobrien  "TARGET_64BIT"
1230490286Sobrien  "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
1230518334Speter
1230690286Sobrien(define_insn "*rotlsi3_1_one_bit_rex64"
1230790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1230890286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12309132727Skan		   (match_operand:QI 2 "const1_operand" "")))
1231090286Sobrien   (clobber (reg:CC 17))]
1231190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12312117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1231390286Sobrien  "rol{q}\t%0"
12314117404Skan  [(set_attr "type" "rotate")
1231590286Sobrien   (set (attr "length") 
1231690286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1231790286Sobrien	(const_string "2")
1231890286Sobrien	(const_string "*")))])
1231918334Speter
1232090286Sobrien(define_insn "*rotldi3_1_rex64"
1232190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1232290286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1232390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
1232490286Sobrien   (clobber (reg:CC 17))]
1232590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
1232690286Sobrien  "@
1232790286Sobrien   rol{q}\t{%2, %0|%0, %2}
1232890286Sobrien   rol{q}\t{%b2, %0|%0, %b2}"
12329117404Skan  [(set_attr "type" "rotate")
1233090286Sobrien   (set_attr "mode" "DI")])
1233190286Sobrien
1233290286Sobrien(define_expand "rotlsi3"
1233390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1233490286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
1233590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1233690286Sobrien   (clobber (reg:CC 17))]
1233718334Speter  ""
1233890286Sobrien  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
1233918334Speter
1234090286Sobrien(define_insn "*rotlsi3_1_one_bit"
1234150650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1234290286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12343132727Skan		   (match_operand:QI 2 "const1_operand" "")))
1234490286Sobrien   (clobber (reg:CC 17))]
1234590286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12346117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1234790286Sobrien  "rol{l}\t%0"
12348117404Skan  [(set_attr "type" "rotate")
1234990286Sobrien   (set (attr "length") 
1235090286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1235190286Sobrien	(const_string "2")
1235290286Sobrien	(const_string "*")))])
1235318334Speter
1235490286Sobrien(define_insn "*rotlsi3_1_one_bit_zext"
1235590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1235690286Sobrien	(zero_extend:DI
1235790286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12358132727Skan		     (match_operand:QI 2 "const1_operand" ""))))
1235990286Sobrien   (clobber (reg:CC 17))]
1236090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12361117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1236290286Sobrien  "rol{l}\t%k0"
12363117404Skan  [(set_attr "type" "rotate")
1236490286Sobrien   (set_attr "length" "2")])
1236518334Speter
1236690286Sobrien(define_insn "*rotlsi3_1"
1236790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1236890286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1236990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1237090286Sobrien   (clobber (reg:CC 17))]
1237190286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
1237290286Sobrien  "@
1237390286Sobrien   rol{l}\t{%2, %0|%0, %2}
1237490286Sobrien   rol{l}\t{%b2, %0|%0, %b2}"
12375117404Skan  [(set_attr "type" "rotate")
1237690286Sobrien   (set_attr "mode" "SI")])
1237718334Speter
1237890286Sobrien(define_insn "*rotlsi3_1_zext"
1237990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1238090286Sobrien	(zero_extend:DI
1238190286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
1238290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1238390286Sobrien   (clobber (reg:CC 17))]
1238490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
1238590286Sobrien  "@
1238690286Sobrien   rol{l}\t{%2, %k0|%k0, %2}
1238790286Sobrien   rol{l}\t{%b2, %k0|%k0, %b2}"
12388117404Skan  [(set_attr "type" "rotate")
1238990286Sobrien   (set_attr "mode" "SI")])
1239018334Speter
1239190286Sobrien(define_expand "rotlhi3"
1239290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1239390286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
1239490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1239590286Sobrien   (clobber (reg:CC 17))]
1239690286Sobrien  "TARGET_HIMODE_MATH"
1239790286Sobrien  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
1239818334Speter
1239990286Sobrien(define_insn "*rotlhi3_1_one_bit"
1240090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1240190286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402132727Skan		   (match_operand:QI 2 "const1_operand" "")))
1240390286Sobrien   (clobber (reg:CC 17))]
1240490286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12405117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1240690286Sobrien  "rol{w}\t%0"
12407117404Skan  [(set_attr "type" "rotate")
1240890286Sobrien   (set (attr "length") 
1240990286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1241090286Sobrien	(const_string "2")
1241190286Sobrien	(const_string "*")))])
1241218334Speter
1241390286Sobrien(define_insn "*rotlhi3_1"
1241490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1241590286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1241690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1241790286Sobrien   (clobber (reg:CC 17))]
1241890286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
1241990286Sobrien  "@
1242090286Sobrien   rol{w}\t{%2, %0|%0, %2}
1242190286Sobrien   rol{w}\t{%b2, %0|%0, %b2}"
12422117404Skan  [(set_attr "type" "rotate")
1242390286Sobrien   (set_attr "mode" "HI")])
1242418334Speter
1242590286Sobrien(define_expand "rotlqi3"
1242690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1242790286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
1242890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1242990286Sobrien   (clobber (reg:CC 17))]
1243090286Sobrien  "TARGET_QIMODE_MATH"
1243190286Sobrien  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
1243218334Speter
12433117404Skan(define_insn "*rotlqi3_1_one_bit_slp"
12434117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12435117404Skan	(rotate:QI (match_dup 0)
12436132727Skan		   (match_operand:QI 1 "const1_operand" "")))
12437117404Skan   (clobber (reg:CC 17))]
12438117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12439117404Skan   && (TARGET_SHIFT1 || optimize_size)"
12440117404Skan  "rol{b}\t%0"
12441117404Skan  [(set_attr "type" "rotate1")
12442117404Skan   (set (attr "length") 
12443117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
12444117404Skan	(const_string "2")
12445117404Skan	(const_string "*")))])
12446117404Skan
1244790286Sobrien(define_insn "*rotlqi3_1_one_bit"
1244890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1244990286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450132727Skan		   (match_operand:QI 2 "const1_operand" "")))
1245190286Sobrien   (clobber (reg:CC 17))]
1245290286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12453117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1245490286Sobrien  "rol{b}\t%0"
12455117404Skan  [(set_attr "type" "rotate")
1245690286Sobrien   (set (attr "length") 
1245790286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1245890286Sobrien	(const_string "2")
1245990286Sobrien	(const_string "*")))])
1246018334Speter
12461117404Skan(define_insn "*rotlqi3_1_slp"
12462117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463117404Skan	(rotate:QI (match_dup 0)
12464117404Skan		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465117404Skan   (clobber (reg:CC 17))]
12466117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12468117404Skan  "@
12469117404Skan   rol{b}\t{%1, %0|%0, %1}
12470117404Skan   rol{b}\t{%b1, %0|%0, %b1}"
12471117404Skan  [(set_attr "type" "rotate1")
12472117404Skan   (set_attr "mode" "QI")])
12473117404Skan
1247490286Sobrien(define_insn "*rotlqi3_1"
1247590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1247690286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1247790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1247890286Sobrien   (clobber (reg:CC 17))]
1247990286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
1248090286Sobrien  "@
1248190286Sobrien   rol{b}\t{%2, %0|%0, %2}
1248290286Sobrien   rol{b}\t{%b2, %0|%0, %b2}"
12483117404Skan  [(set_attr "type" "rotate")
1248490286Sobrien   (set_attr "mode" "QI")])
1248518334Speter
1248690286Sobrien(define_expand "rotrdi3"
1248790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1248890286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
1248990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1249090286Sobrien   (clobber (reg:CC 17))]
1249190286Sobrien  "TARGET_64BIT"
1249290286Sobrien  "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
1249318334Speter
1249490286Sobrien(define_insn "*rotrdi3_1_one_bit_rex64"
1249590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1249690286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12497132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1249890286Sobrien   (clobber (reg:CC 17))]
1249990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12500117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1250190286Sobrien  "ror{q}\t%0"
12502117404Skan  [(set_attr "type" "rotate")
1250390286Sobrien   (set (attr "length") 
1250490286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1250590286Sobrien	(const_string "2")
1250690286Sobrien	(const_string "*")))])
1250718334Speter
1250890286Sobrien(define_insn "*rotrdi3_1_rex64"
1250990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1251090286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1251190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1251290286Sobrien   (clobber (reg:CC 17))]
1251390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
1251490286Sobrien  "@
1251590286Sobrien   ror{q}\t{%2, %0|%0, %2}
1251690286Sobrien   ror{q}\t{%b2, %0|%0, %b2}"
12517117404Skan  [(set_attr "type" "rotate")
1251890286Sobrien   (set_attr "mode" "DI")])
1251990286Sobrien
1252090286Sobrien(define_expand "rotrsi3"
1252190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1252290286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
1252390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1252490286Sobrien   (clobber (reg:CC 17))]
1252590286Sobrien  ""
1252690286Sobrien  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
1252790286Sobrien
1252890286Sobrien(define_insn "*rotrsi3_1_one_bit"
1252950650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1253090286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12531132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1253290286Sobrien   (clobber (reg:CC 17))]
1253390286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12534117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1253590286Sobrien  "ror{l}\t%0"
12536117404Skan  [(set_attr "type" "rotate")
1253790286Sobrien   (set (attr "length") 
1253890286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1253990286Sobrien	(const_string "2")
1254090286Sobrien	(const_string "*")))])
1254118334Speter
1254290286Sobrien(define_insn "*rotrsi3_1_one_bit_zext"
1254390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1254490286Sobrien	(zero_extend:DI
1254590286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12546132727Skan		       (match_operand:QI 2 "const1_operand" ""))))
1254790286Sobrien   (clobber (reg:CC 17))]
1254890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12549117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1255090286Sobrien  "ror{l}\t%k0"
12551117404Skan  [(set_attr "type" "rotate")
1255290286Sobrien   (set (attr "length") 
1255390286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1255490286Sobrien	(const_string "2")
1255590286Sobrien	(const_string "*")))])
1255618334Speter
1255790286Sobrien(define_insn "*rotrsi3_1"
1255890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1255990286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1256090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1256190286Sobrien   (clobber (reg:CC 17))]
1256290286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1256390286Sobrien  "@
1256490286Sobrien   ror{l}\t{%2, %0|%0, %2}
1256590286Sobrien   ror{l}\t{%b2, %0|%0, %b2}"
12566117404Skan  [(set_attr "type" "rotate")
1256790286Sobrien   (set_attr "mode" "SI")])
1256818334Speter
1256990286Sobrien(define_insn "*rotrsi3_1_zext"
1257090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1257190286Sobrien	(zero_extend:DI
1257290286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
1257390286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1257490286Sobrien   (clobber (reg:CC 17))]
1257590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1257690286Sobrien  "@
1257790286Sobrien   ror{l}\t{%2, %k0|%k0, %2}
1257890286Sobrien   ror{l}\t{%b2, %k0|%k0, %b2}"
12579117404Skan  [(set_attr "type" "rotate")
1258090286Sobrien   (set_attr "mode" "SI")])
1258118334Speter
1258290286Sobrien(define_expand "rotrhi3"
1258390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1258490286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
1258590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1258690286Sobrien   (clobber (reg:CC 17))]
1258790286Sobrien  "TARGET_HIMODE_MATH"
1258890286Sobrien  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
1258918334Speter
1259090286Sobrien(define_insn "*rotrhi3_one_bit"
1259190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1259290286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12593132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1259490286Sobrien   (clobber (reg:CC 17))]
1259590286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12596117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1259790286Sobrien  "ror{w}\t%0"
12598117404Skan  [(set_attr "type" "rotate")
1259990286Sobrien   (set (attr "length") 
1260090286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1260190286Sobrien	(const_string "2")
1260290286Sobrien	(const_string "*")))])
1260318334Speter
1260490286Sobrien(define_insn "*rotrhi3"
1260590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1260690286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1260790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1260890286Sobrien   (clobber (reg:CC 17))]
1260990286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
1261090286Sobrien  "@
1261190286Sobrien   ror{w}\t{%2, %0|%0, %2}
1261290286Sobrien   ror{w}\t{%b2, %0|%0, %b2}"
12613117404Skan  [(set_attr "type" "rotate")
1261490286Sobrien   (set_attr "mode" "HI")])
1261518334Speter
1261690286Sobrien(define_expand "rotrqi3"
1261790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1261890286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
1261990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1262090286Sobrien   (clobber (reg:CC 17))]
1262190286Sobrien  "TARGET_QIMODE_MATH"
1262290286Sobrien  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
1262318334Speter
1262490286Sobrien(define_insn "*rotrqi3_1_one_bit"
1262590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1262690286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12627132727Skan		     (match_operand:QI 2 "const1_operand" "")))
1262890286Sobrien   (clobber (reg:CC 17))]
1262990286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12630117404Skan   && (TARGET_SHIFT1 || optimize_size)"
1263190286Sobrien  "ror{b}\t%0"
12632117404Skan  [(set_attr "type" "rotate")
1263390286Sobrien   (set (attr "length") 
1263490286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1263590286Sobrien	(const_string "2")
1263690286Sobrien	(const_string "*")))])
1263718334Speter
12638117404Skan(define_insn "*rotrqi3_1_one_bit_slp"
12639117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12640117404Skan	(rotatert:QI (match_dup 0)
12641132727Skan		     (match_operand:QI 1 "const1_operand" "")))
12642117404Skan   (clobber (reg:CC 17))]
12643117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12644117404Skan   && (TARGET_SHIFT1 || optimize_size)"
12645117404Skan  "ror{b}\t%0"
12646117404Skan  [(set_attr "type" "rotate1")
12647117404Skan   (set (attr "length") 
12648117404Skan     (if_then_else (match_operand 0 "register_operand" "") 
12649117404Skan	(const_string "2")
12650117404Skan	(const_string "*")))])
12651117404Skan
1265290286Sobrien(define_insn "*rotrqi3_1"
1265390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1265490286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1265590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1265690286Sobrien   (clobber (reg:CC 17))]
1265790286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
1265890286Sobrien  "@
1265990286Sobrien   ror{b}\t{%2, %0|%0, %2}
1266090286Sobrien   ror{b}\t{%b2, %0|%0, %b2}"
12661117404Skan  [(set_attr "type" "rotate")
1266290286Sobrien   (set_attr "mode" "QI")])
12663117404Skan
12664117404Skan(define_insn "*rotrqi3_1_slp"
12665117404Skan  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12666117404Skan	(rotatert:QI (match_dup 0)
12667117404Skan		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12668117404Skan   (clobber (reg:CC 17))]
12669117404Skan  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12670117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12671117404Skan  "@
12672117404Skan   ror{b}\t{%1, %0|%0, %1}
12673117404Skan   ror{b}\t{%b1, %0|%0, %b1}"
12674117404Skan  [(set_attr "type" "rotate1")
12675117404Skan   (set_attr "mode" "QI")])
1267690286Sobrien
1267790286Sobrien;; Bit set / bit test instructions
1267818334Speter
1267990286Sobrien(define_expand "extv"
1268090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1268190286Sobrien	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
1268290286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1268390286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1268490286Sobrien  ""
1268518334Speter{
1268690286Sobrien  /* Handle extractions from %ah et al.  */
1268790286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1268890286Sobrien    FAIL;
1268918334Speter
1269090286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1269190286Sobrien     matches the predicate, so check it again here.  */
1269290286Sobrien  if (! register_operand (operands[1], VOIDmode))
1269390286Sobrien    FAIL;
1269490286Sobrien})
1269518334Speter
1269690286Sobrien(define_expand "extzv"
1269790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1269890286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
1269990286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1270090286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1270190286Sobrien  ""
1270290286Sobrien{
1270390286Sobrien  /* Handle extractions from %ah et al.  */
1270490286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1270590286Sobrien    FAIL;
1270618334Speter
1270790286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1270890286Sobrien     matches the predicate, so check it again here.  */
1270990286Sobrien  if (! register_operand (operands[1], VOIDmode))
1271090286Sobrien    FAIL;
1271190286Sobrien})
1271218334Speter
1271390286Sobrien(define_expand "insv"
12714132727Skan  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12715132727Skan		      (match_operand 1 "immediate_operand" "")
12716132727Skan		      (match_operand 2 "immediate_operand" ""))
12717132727Skan        (match_operand 3 "register_operand" ""))]
1271890286Sobrien  ""
1271990286Sobrien{
1272090286Sobrien  /* Handle extractions from %ah et al.  */
1272190286Sobrien  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
1272290286Sobrien    FAIL;
1272318334Speter
1272490286Sobrien  /* From mips.md: insert_bit_field doesn't verify that our source
1272590286Sobrien     matches the predicate, so check it again here.  */
1272690286Sobrien  if (! register_operand (operands[0], VOIDmode))
1272790286Sobrien    FAIL;
12728132727Skan
12729132727Skan  if (TARGET_64BIT)
12730132727Skan    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12731132727Skan  else
12732132727Skan    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12733132727Skan
12734132727Skan  DONE;
1273590286Sobrien})
1273618334Speter
1273790286Sobrien;; %%% bts, btr, btc, bt.
1273818334Speter
1273918334Speter;; Store-flag instructions.
1274018334Speter
1274118334Speter;; For all sCOND expanders, also expand the compare or test insn that
1274218334Speter;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
1274318334Speter
1274490286Sobrien;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
1274590286Sobrien;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
1274690286Sobrien;; way, which can later delete the movzx if only QImode is needed.
1274790286Sobrien
1274818334Speter(define_expand "seq"
1274990286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1275090286Sobrien        (eq:QI (reg:CC 17) (const_int 0)))]
1275118334Speter  ""
1275290286Sobrien  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
1275318334Speter
1275418334Speter(define_expand "sne"
1275590286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1275690286Sobrien        (ne:QI (reg:CC 17) (const_int 0)))]
1275718334Speter  ""
1275890286Sobrien  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
1275918334Speter
1276018334Speter(define_expand "sgt"
1276190286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1276290286Sobrien        (gt:QI (reg:CC 17) (const_int 0)))]
1276318334Speter  ""
1276490286Sobrien  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
1276518334Speter
1276618334Speter(define_expand "sgtu"
1276790286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1276890286Sobrien        (gtu:QI (reg:CC 17) (const_int 0)))]
1276918334Speter  ""
1277090286Sobrien  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
1277118334Speter
1277218334Speter(define_expand "slt"
1277390286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1277490286Sobrien        (lt:QI (reg:CC 17) (const_int 0)))]
1277518334Speter  ""
1277690286Sobrien  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
1277718334Speter
1277818334Speter(define_expand "sltu"
1277990286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1278090286Sobrien        (ltu:QI (reg:CC 17) (const_int 0)))]
1278118334Speter  ""
1278290286Sobrien  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
1278318334Speter
1278418334Speter(define_expand "sge"
1278590286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1278690286Sobrien        (ge:QI (reg:CC 17) (const_int 0)))]
1278718334Speter  ""
1278890286Sobrien  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
1278918334Speter
1279018334Speter(define_expand "sgeu"
1279190286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1279290286Sobrien        (geu:QI (reg:CC 17) (const_int 0)))]
1279318334Speter  ""
1279490286Sobrien  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
1279518334Speter
1279618334Speter(define_expand "sle"
1279790286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1279890286Sobrien        (le:QI (reg:CC 17) (const_int 0)))]
1279918334Speter  ""
1280090286Sobrien  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
1280118334Speter
1280218334Speter(define_expand "sleu"
1280390286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1280490286Sobrien        (leu:QI (reg:CC 17) (const_int 0)))]
1280518334Speter  ""
1280690286Sobrien  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
1280718334Speter
1280890286Sobrien(define_expand "sunordered"
1280990286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1281090286Sobrien        (unordered:QI (reg:CC 17) (const_int 0)))]
1281190286Sobrien  "TARGET_80387 || TARGET_SSE"
1281290286Sobrien  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
1281352296Sobrien
1281490286Sobrien(define_expand "sordered"
1281590286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1281690286Sobrien        (ordered:QI (reg:CC 17) (const_int 0)))]
1281790286Sobrien  "TARGET_80387"
1281890286Sobrien  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
1281990286Sobrien
1282090286Sobrien(define_expand "suneq"
1282190286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1282290286Sobrien        (uneq:QI (reg:CC 17) (const_int 0)))]
1282390286Sobrien  "TARGET_80387 || TARGET_SSE"
1282490286Sobrien  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
1282590286Sobrien
1282690286Sobrien(define_expand "sunge"
1282790286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1282890286Sobrien        (unge:QI (reg:CC 17) (const_int 0)))]
1282990286Sobrien  "TARGET_80387 || TARGET_SSE"
1283090286Sobrien  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
1283190286Sobrien
1283290286Sobrien(define_expand "sungt"
1283390286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1283490286Sobrien        (ungt:QI (reg:CC 17) (const_int 0)))]
1283590286Sobrien  "TARGET_80387 || TARGET_SSE"
1283690286Sobrien  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
1283790286Sobrien
1283890286Sobrien(define_expand "sunle"
1283990286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1284090286Sobrien        (unle:QI (reg:CC 17) (const_int 0)))]
1284190286Sobrien  "TARGET_80387 || TARGET_SSE"
1284290286Sobrien  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
1284390286Sobrien
1284490286Sobrien(define_expand "sunlt"
1284590286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1284690286Sobrien        (unlt:QI (reg:CC 17) (const_int 0)))]
1284790286Sobrien  "TARGET_80387 || TARGET_SSE"
1284890286Sobrien  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
1284990286Sobrien
1285090286Sobrien(define_expand "sltgt"
1285190286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1285290286Sobrien        (ltgt:QI (reg:CC 17) (const_int 0)))]
1285390286Sobrien  "TARGET_80387 || TARGET_SSE"
1285490286Sobrien  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
1285590286Sobrien
1285690286Sobrien(define_insn "*setcc_1"
1285752296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1285890286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1285990286Sobrien	  [(reg 17) (const_int 0)]))]
1286090286Sobrien  ""
1286190286Sobrien  "set%C1\t%0"
1286290286Sobrien  [(set_attr "type" "setcc")
1286390286Sobrien   (set_attr "mode" "QI")])
1286490286Sobrien
1286590286Sobrien(define_insn "setcc_2"
1286690286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1286790286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1286890286Sobrien	  [(reg 17) (const_int 0)]))]
1286990286Sobrien  ""
1287090286Sobrien  "set%C1\t%0"
1287190286Sobrien  [(set_attr "type" "setcc")
1287290286Sobrien   (set_attr "mode" "QI")])
1287390286Sobrien
1287490286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1287590286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1287690286Sobrien;; conditions this is safe on x86, so help combine not create
1287790286Sobrien;;
1287890286Sobrien;;	seta	%al
1287990286Sobrien;;	testb	%al, %al
1288090286Sobrien;;	sete	%al
1288190286Sobrien
1288290286Sobrien(define_split 
1288390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1288490286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1288590286Sobrien	         [(reg 17) (const_int 0)])
1288690286Sobrien	    (const_int 0)))]
1288790286Sobrien  ""
1288890286Sobrien  [(set (match_dup 0) (match_dup 1))]
1288952296Sobrien{
1289090286Sobrien  PUT_MODE (operands[1], QImode);
1289190286Sobrien})
1289252296Sobrien
1289390286Sobrien(define_split 
1289490286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1289590286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1289690286Sobrien	         [(reg 17) (const_int 0)])
1289790286Sobrien	    (const_int 0)))]
1289890286Sobrien  ""
1289990286Sobrien  [(set (match_dup 0) (match_dup 1))]
1290090286Sobrien{
1290190286Sobrien  PUT_MODE (operands[1], QImode);
1290290286Sobrien})
1290352296Sobrien
1290490286Sobrien(define_split 
1290590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1290690286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1290790286Sobrien	         [(reg 17) (const_int 0)])
1290890286Sobrien	    (const_int 0)))]
1290990286Sobrien  ""
1291090286Sobrien  [(set (match_dup 0) (match_dup 1))]
1291190286Sobrien{
1291290286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1291390286Sobrien  operands[1] = new_op1;
1291490286Sobrien  PUT_MODE (new_op1, QImode);
1291590286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1291690286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1291790286Sobrien
1291890286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1291990286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1292090286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1292190286Sobrien    FAIL;
1292290286Sobrien})
1292390286Sobrien
1292490286Sobrien(define_split 
1292590286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1292690286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1292790286Sobrien	         [(reg 17) (const_int 0)])
1292890286Sobrien	    (const_int 0)))]
1292990286Sobrien  ""
1293090286Sobrien  [(set (match_dup 0) (match_dup 1))]
1293190286Sobrien{
1293290286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1293390286Sobrien  operands[1] = new_op1;
1293490286Sobrien  PUT_MODE (new_op1, QImode);
1293590286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1293690286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1293790286Sobrien
1293890286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1293990286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1294090286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1294190286Sobrien    FAIL;
1294290286Sobrien})
1294390286Sobrien
1294490286Sobrien;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
1294590286Sobrien;; subsequent logical operations are used to imitate conditional moves.
1294690286Sobrien;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12947132727Skan;; it directly.  Further holding this value in pseudo register might bring
1294890286Sobrien;; problem in implicit normalization in spill code.
1294990286Sobrien;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
1295090286Sobrien;; instructions after reload by splitting the conditional move patterns.
1295190286Sobrien
1295290286Sobrien(define_insn "*sse_setccsf"
1295390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1295490286Sobrien	(match_operator:SF 1 "sse_comparison_operator"
1295590286Sobrien	  [(match_operand:SF 2 "register_operand" "0")
1295690286Sobrien	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
1295790286Sobrien  "TARGET_SSE && reload_completed"
1295890286Sobrien  "cmp%D1ss\t{%3, %0|%0, %3}"
12959117404Skan  [(set_attr "type" "ssecmp")
1296090286Sobrien   (set_attr "mode" "SF")])
1296190286Sobrien
1296290286Sobrien(define_insn "*sse_setccdf"
1296390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1296490286Sobrien	(match_operator:DF 1 "sse_comparison_operator"
1296590286Sobrien	  [(match_operand:DF 2 "register_operand" "0")
1296690286Sobrien	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
1296790286Sobrien  "TARGET_SSE2 && reload_completed"
1296890286Sobrien  "cmp%D1sd\t{%3, %0|%0, %3}"
12969117404Skan  [(set_attr "type" "ssecmp")
1297090286Sobrien   (set_attr "mode" "DF")])
1297118334Speter
1297218334Speter;; Basic conditional jump instructions.
1297318334Speter;; We ignore the overflow flag for signed branch instructions.
1297418334Speter
1297518334Speter;; For all bCOND expanders, also expand the compare or test insn that
1297690286Sobrien;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
1297718334Speter
1297818334Speter(define_expand "beq"
1297990286Sobrien  [(set (pc)
1298090286Sobrien	(if_then_else (match_dup 1)
1298118334Speter		      (label_ref (match_operand 0 "" ""))
1298218334Speter		      (pc)))]
1298318334Speter  ""
1298490286Sobrien  "ix86_expand_branch (EQ, operands[0]); DONE;")
1298518334Speter
1298618334Speter(define_expand "bne"
1298790286Sobrien  [(set (pc)
1298890286Sobrien	(if_then_else (match_dup 1)
1298918334Speter		      (label_ref (match_operand 0 "" ""))
1299018334Speter		      (pc)))]
1299118334Speter  ""
1299290286Sobrien  "ix86_expand_branch (NE, operands[0]); DONE;")
1299318334Speter
1299418334Speter(define_expand "bgt"
1299590286Sobrien  [(set (pc)
1299690286Sobrien	(if_then_else (match_dup 1)
1299718334Speter		      (label_ref (match_operand 0 "" ""))
1299818334Speter		      (pc)))]
1299918334Speter  ""
1300090286Sobrien  "ix86_expand_branch (GT, operands[0]); DONE;")
1300118334Speter
1300218334Speter(define_expand "bgtu"
1300390286Sobrien  [(set (pc)
1300490286Sobrien	(if_then_else (match_dup 1)
1300518334Speter		      (label_ref (match_operand 0 "" ""))
1300618334Speter		      (pc)))]
1300718334Speter  ""
1300890286Sobrien  "ix86_expand_branch (GTU, operands[0]); DONE;")
1300918334Speter
1301018334Speter(define_expand "blt"
1301190286Sobrien  [(set (pc)
1301290286Sobrien	(if_then_else (match_dup 1)
1301318334Speter		      (label_ref (match_operand 0 "" ""))
1301418334Speter		      (pc)))]
1301518334Speter  ""
1301690286Sobrien  "ix86_expand_branch (LT, operands[0]); DONE;")
1301718334Speter
1301818334Speter(define_expand "bltu"
1301990286Sobrien  [(set (pc)
1302090286Sobrien	(if_then_else (match_dup 1)
1302118334Speter		      (label_ref (match_operand 0 "" ""))
1302218334Speter		      (pc)))]
1302318334Speter  ""
1302490286Sobrien  "ix86_expand_branch (LTU, operands[0]); DONE;")
1302518334Speter
1302618334Speter(define_expand "bge"
1302790286Sobrien  [(set (pc)
1302890286Sobrien	(if_then_else (match_dup 1)
1302918334Speter		      (label_ref (match_operand 0 "" ""))
1303018334Speter		      (pc)))]
1303118334Speter  ""
1303290286Sobrien  "ix86_expand_branch (GE, operands[0]); DONE;")
1303318334Speter
1303418334Speter(define_expand "bgeu"
1303590286Sobrien  [(set (pc)
1303690286Sobrien	(if_then_else (match_dup 1)
1303718334Speter		      (label_ref (match_operand 0 "" ""))
1303818334Speter		      (pc)))]
1303918334Speter  ""
1304090286Sobrien  "ix86_expand_branch (GEU, operands[0]); DONE;")
1304118334Speter
1304218334Speter(define_expand "ble"
1304390286Sobrien  [(set (pc)
1304490286Sobrien	(if_then_else (match_dup 1)
1304518334Speter		      (label_ref (match_operand 0 "" ""))
1304618334Speter		      (pc)))]
1304718334Speter  ""
1304890286Sobrien  "ix86_expand_branch (LE, operands[0]); DONE;")
1304918334Speter
1305018334Speter(define_expand "bleu"
1305190286Sobrien  [(set (pc)
1305290286Sobrien	(if_then_else (match_dup 1)
1305318334Speter		      (label_ref (match_operand 0 "" ""))
1305418334Speter		      (pc)))]
1305518334Speter  ""
1305690286Sobrien  "ix86_expand_branch (LEU, operands[0]); DONE;")
1305718334Speter
1305890286Sobrien(define_expand "bunordered"
1305918334Speter  [(set (pc)
1306090286Sobrien	(if_then_else (match_dup 1)
1306190286Sobrien		      (label_ref (match_operand 0 "" ""))
1306218334Speter		      (pc)))]
1306390286Sobrien  "TARGET_80387 || TARGET_SSE"
1306490286Sobrien  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
1306518334Speter
1306690286Sobrien(define_expand "bordered"
1306790286Sobrien  [(set (pc)
1306890286Sobrien	(if_then_else (match_dup 1)
1306990286Sobrien		      (label_ref (match_operand 0 "" ""))
1307090286Sobrien		      (pc)))]
1307190286Sobrien  "TARGET_80387 || TARGET_SSE"
1307290286Sobrien  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
1307318334Speter
1307490286Sobrien(define_expand "buneq"
1307518334Speter  [(set (pc)
1307690286Sobrien	(if_then_else (match_dup 1)
1307790286Sobrien		      (label_ref (match_operand 0 "" ""))
1307890286Sobrien		      (pc)))]
1307990286Sobrien  "TARGET_80387 || TARGET_SSE"
1308090286Sobrien  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
1308118334Speter
1308290286Sobrien(define_expand "bunge"
1308390286Sobrien  [(set (pc)
1308490286Sobrien	(if_then_else (match_dup 1)
1308590286Sobrien		      (label_ref (match_operand 0 "" ""))
1308690286Sobrien		      (pc)))]
1308790286Sobrien  "TARGET_80387 || TARGET_SSE"
1308890286Sobrien  "ix86_expand_branch (UNGE, operands[0]); DONE;")
1308918334Speter
1309090286Sobrien(define_expand "bungt"
1309118334Speter  [(set (pc)
1309290286Sobrien	(if_then_else (match_dup 1)
1309390286Sobrien		      (label_ref (match_operand 0 "" ""))
1309490286Sobrien		      (pc)))]
1309590286Sobrien  "TARGET_80387 || TARGET_SSE"
1309690286Sobrien  "ix86_expand_branch (UNGT, operands[0]); DONE;")
1309718334Speter
1309890286Sobrien(define_expand "bunle"
1309990286Sobrien  [(set (pc)
1310090286Sobrien	(if_then_else (match_dup 1)
1310190286Sobrien		      (label_ref (match_operand 0 "" ""))
1310290286Sobrien		      (pc)))]
1310390286Sobrien  "TARGET_80387 || TARGET_SSE"
1310490286Sobrien  "ix86_expand_branch (UNLE, operands[0]); DONE;")
1310518334Speter
1310690286Sobrien(define_expand "bunlt"
1310790286Sobrien  [(set (pc)
1310890286Sobrien	(if_then_else (match_dup 1)
1310990286Sobrien		      (label_ref (match_operand 0 "" ""))
1311090286Sobrien		      (pc)))]
1311190286Sobrien  "TARGET_80387 || TARGET_SSE"
1311290286Sobrien  "ix86_expand_branch (UNLT, operands[0]); DONE;")
1311318334Speter
1311490286Sobrien(define_expand "bltgt"
1311590286Sobrien  [(set (pc)
1311690286Sobrien	(if_then_else (match_dup 1)
1311790286Sobrien		      (label_ref (match_operand 0 "" ""))
1311890286Sobrien		      (pc)))]
1311990286Sobrien  "TARGET_80387 || TARGET_SSE"
1312090286Sobrien  "ix86_expand_branch (LTGT, operands[0]); DONE;")
1312118334Speter
1312290286Sobrien(define_insn "*jcc_1"
1312390286Sobrien  [(set (pc)
1312490286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1312590286Sobrien				      [(reg 17) (const_int 0)])
1312690286Sobrien		      (label_ref (match_operand 0 "" ""))
1312790286Sobrien		      (pc)))]
1312818334Speter  ""
1312990286Sobrien  "%+j%C1\t%l0"
1313090286Sobrien  [(set_attr "type" "ibr")
13131117404Skan   (set_attr "modrm" "0")
13132117404Skan   (set (attr "length")
1313390286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13134117404Skan				  (const_int -126))
1313590286Sobrien			      (lt (minus (match_dup 0) (pc))
13136117404Skan				  (const_int 128)))
13137117404Skan	     (const_int 2)
13138117404Skan	     (const_int 6)))])
1313918334Speter
1314090286Sobrien(define_insn "*jcc_2"
1314118334Speter  [(set (pc)
1314290286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1314390286Sobrien				      [(reg 17) (const_int 0)])
1314490286Sobrien		      (pc)
1314590286Sobrien		      (label_ref (match_operand 0 "" ""))))]
1314618334Speter  ""
1314790286Sobrien  "%+j%c1\t%l0"
1314890286Sobrien  [(set_attr "type" "ibr")
13149117404Skan   (set_attr "modrm" "0")
13150117404Skan   (set (attr "length")
1315190286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13152117404Skan				  (const_int -126))
1315390286Sobrien			      (lt (minus (match_dup 0) (pc))
13154117404Skan				  (const_int 128)))
13155117404Skan	     (const_int 2)
13156117404Skan	     (const_int 6)))])
1315790286Sobrien
1315890286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1315990286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1316090286Sobrien;; conditions this is safe on x86, so help combine not create
1316190286Sobrien;;
1316290286Sobrien;;	seta	%al
1316390286Sobrien;;	testb	%al, %al
1316490286Sobrien;;	je	Lfoo
1316590286Sobrien
1316690286Sobrien(define_split 
1316790286Sobrien  [(set (pc)
1316890286Sobrien	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
1316990286Sobrien				      [(reg 17) (const_int 0)])
1317090286Sobrien			  (const_int 0))
1317190286Sobrien		      (label_ref (match_operand 1 "" ""))
1317290286Sobrien		      (pc)))]
1317390286Sobrien  ""
1317490286Sobrien  [(set (pc)
1317590286Sobrien	(if_then_else (match_dup 0)
1317690286Sobrien		      (label_ref (match_dup 1))
1317790286Sobrien		      (pc)))]
1317818334Speter{
1317990286Sobrien  PUT_MODE (operands[0], VOIDmode);
1318090286Sobrien})
1318190286Sobrien  
1318290286Sobrien(define_split 
1318390286Sobrien  [(set (pc)
1318490286Sobrien	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
1318590286Sobrien				      [(reg 17) (const_int 0)])
1318690286Sobrien			  (const_int 0))
1318790286Sobrien		      (label_ref (match_operand 1 "" ""))
1318890286Sobrien		      (pc)))]
1318990286Sobrien  ""
1319090286Sobrien  [(set (pc)
1319190286Sobrien	(if_then_else (match_dup 0)
1319290286Sobrien		      (label_ref (match_dup 1))
1319390286Sobrien		      (pc)))]
1319490286Sobrien{
1319590286Sobrien  rtx new_op0 = copy_rtx (operands[0]);
1319690286Sobrien  operands[0] = new_op0;
1319790286Sobrien  PUT_MODE (new_op0, VOIDmode);
1319890286Sobrien  PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
1319990286Sobrien					GET_MODE (XEXP (new_op0, 0))));
1320052296Sobrien
1320190286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1320290286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1320390286Sobrien  if (! ix86_comparison_operator (new_op0, VOIDmode))
1320490286Sobrien    FAIL;
1320590286Sobrien})
1320652296Sobrien
1320790286Sobrien;; Define combination compare-and-branch fp compare instructions to use
1320890286Sobrien;; during early optimization.  Splitting the operation apart early makes
1320990286Sobrien;; for bad code when we want to reverse the operation.
1321018334Speter
1321190286Sobrien(define_insn "*fp_jcc_1"
1321290286Sobrien  [(set (pc)
1321390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1321490286Sobrien			[(match_operand 1 "register_operand" "f")
1321590286Sobrien			 (match_operand 2 "register_operand" "f")])
1321690286Sobrien	  (label_ref (match_operand 3 "" ""))
1321790286Sobrien	  (pc)))
1321890286Sobrien   (clobber (reg:CCFP 18))
1321990286Sobrien   (clobber (reg:CCFP 17))]
1322090286Sobrien  "TARGET_CMOVE && TARGET_80387
1322190286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1322290286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1322390286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1322490286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1322590286Sobrien  "#")
1322618334Speter
1322790286Sobrien(define_insn "*fp_jcc_1_sse"
1322890286Sobrien  [(set (pc)
1322990286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1323090286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1323190286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1323290286Sobrien	  (label_ref (match_operand 3 "" ""))
1323390286Sobrien	  (pc)))
1323490286Sobrien   (clobber (reg:CCFP 18))
1323590286Sobrien   (clobber (reg:CCFP 17))]
1323690286Sobrien  "TARGET_80387
1323790286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1323890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1323990286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1324090286Sobrien  "#")
1324118334Speter
1324290286Sobrien(define_insn "*fp_jcc_1_sse_only"
1324390286Sobrien  [(set (pc)
1324490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1324590286Sobrien			[(match_operand 1 "register_operand" "x")
1324690286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1324790286Sobrien	  (label_ref (match_operand 3 "" ""))
1324890286Sobrien	  (pc)))
1324990286Sobrien   (clobber (reg:CCFP 18))
1325090286Sobrien   (clobber (reg:CCFP 17))]
1325190286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1325290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1325390286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1325490286Sobrien  "#")
1325518334Speter
1325690286Sobrien(define_insn "*fp_jcc_2"
1325718334Speter  [(set (pc)
1325890286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1325990286Sobrien			[(match_operand 1 "register_operand" "f")
1326090286Sobrien			 (match_operand 2 "register_operand" "f")])
1326190286Sobrien	  (pc)
1326290286Sobrien	  (label_ref (match_operand 3 "" ""))))
1326390286Sobrien   (clobber (reg:CCFP 18))
1326490286Sobrien   (clobber (reg:CCFP 17))]
1326590286Sobrien  "TARGET_CMOVE && TARGET_80387
1326690286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1326790286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1326890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1326990286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1327090286Sobrien  "#")
1327118334Speter
1327290286Sobrien(define_insn "*fp_jcc_2_sse"
1327390286Sobrien  [(set (pc)
1327490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1327590286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1327690286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1327790286Sobrien	  (pc)
1327890286Sobrien	  (label_ref (match_operand 3 "" ""))))
1327990286Sobrien   (clobber (reg:CCFP 18))
1328090286Sobrien   (clobber (reg:CCFP 17))]
1328190286Sobrien  "TARGET_80387
1328290286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1328390286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1328490286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1328590286Sobrien  "#")
1328618334Speter
1328790286Sobrien(define_insn "*fp_jcc_2_sse_only"
1328890286Sobrien  [(set (pc)
1328990286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1329090286Sobrien			[(match_operand 1 "register_operand" "x")
1329190286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1329290286Sobrien	  (pc)
1329390286Sobrien	  (label_ref (match_operand 3 "" ""))))
1329490286Sobrien   (clobber (reg:CCFP 18))
1329590286Sobrien   (clobber (reg:CCFP 17))]
1329690286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1329790286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1329890286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1329990286Sobrien  "#")
1330018334Speter
1330190286Sobrien(define_insn "*fp_jcc_3"
1330290286Sobrien  [(set (pc)
1330390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1330490286Sobrien			[(match_operand 1 "register_operand" "f")
1330590286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1330690286Sobrien	  (label_ref (match_operand 3 "" ""))
1330790286Sobrien	  (pc)))
1330890286Sobrien   (clobber (reg:CCFP 18))
1330990286Sobrien   (clobber (reg:CCFP 17))
1331090286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1331190286Sobrien  "TARGET_80387
1331290286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1331390286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1331490286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1331590286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1331690286Sobrien		      operands[1], operands[2]) == CCFPmode
1331790286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1331890286Sobrien  "#")
1331918334Speter
1332090286Sobrien(define_insn "*fp_jcc_4"
1332150650Sobrien  [(set (pc)
1332290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1332390286Sobrien			[(match_operand 1 "register_operand" "f")
1332490286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1332590286Sobrien	  (pc)
1332690286Sobrien	  (label_ref (match_operand 3 "" ""))))
1332790286Sobrien   (clobber (reg:CCFP 18))
1332890286Sobrien   (clobber (reg:CCFP 17))
1332990286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1333090286Sobrien  "TARGET_80387
1333190286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1333290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1333390286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1333490286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1333590286Sobrien		      operands[1], operands[2]) == CCFPmode
1333690286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1333790286Sobrien  "#")
1333850650Sobrien
1333990286Sobrien(define_insn "*fp_jcc_5"
1334050650Sobrien  [(set (pc)
1334190286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1334290286Sobrien			[(match_operand 1 "register_operand" "f")
1334390286Sobrien			 (match_operand 2 "register_operand" "f")])
1334490286Sobrien	  (label_ref (match_operand 3 "" ""))
1334590286Sobrien	  (pc)))
1334690286Sobrien   (clobber (reg:CCFP 18))
1334790286Sobrien   (clobber (reg:CCFP 17))
1334890286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1334990286Sobrien  "TARGET_80387
1335090286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1335190286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1335290286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1335390286Sobrien  "#")
1335450650Sobrien
1335590286Sobrien(define_insn "*fp_jcc_6"
1335650650Sobrien  [(set (pc)
1335790286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1335890286Sobrien			[(match_operand 1 "register_operand" "f")
1335990286Sobrien			 (match_operand 2 "register_operand" "f")])
1336090286Sobrien	  (pc)
1336190286Sobrien	  (label_ref (match_operand 3 "" ""))))
1336290286Sobrien   (clobber (reg:CCFP 18))
1336390286Sobrien   (clobber (reg:CCFP 17))
1336490286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1336590286Sobrien  "TARGET_80387
1336690286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1336790286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1336890286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1336990286Sobrien  "#")
1337050650Sobrien
1337190286Sobrien(define_split
1337250650Sobrien  [(set (pc)
1337390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1337490286Sobrien			[(match_operand 1 "register_operand" "")
1337590286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1337690286Sobrien	  (match_operand 3 "" "")
1337790286Sobrien	  (match_operand 4 "" "")))
1337890286Sobrien   (clobber (reg:CCFP 18))
1337990286Sobrien   (clobber (reg:CCFP 17))]
1338090286Sobrien  "reload_completed"
1338190286Sobrien  [(const_int 0)]
1338250650Sobrien{
1338390286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1338490286Sobrien			operands[3], operands[4], NULL_RTX);
1338590286Sobrien  DONE;
1338690286Sobrien})
1338750650Sobrien
1338890286Sobrien(define_split
1338950650Sobrien  [(set (pc)
1339090286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1339190286Sobrien			[(match_operand 1 "register_operand" "")
1339290286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1339390286Sobrien	  (match_operand 3 "" "")
1339490286Sobrien	  (match_operand 4 "" "")))
1339590286Sobrien   (clobber (reg:CCFP 18))
1339690286Sobrien   (clobber (reg:CCFP 17))
1339790286Sobrien   (clobber (match_scratch:HI 5 "=a"))]
1339890286Sobrien  "reload_completed"
1339990286Sobrien  [(set (pc)
1340090286Sobrien	(if_then_else (match_dup 6)
1340190286Sobrien	  (match_dup 3)
1340290286Sobrien	  (match_dup 4)))]
1340350650Sobrien{
1340490286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1340590286Sobrien			operands[3], operands[4], operands[5]);
1340690286Sobrien  DONE;
1340790286Sobrien})
1340890286Sobrien
1340990286Sobrien;; Unconditional and other jump instructions
1341050650Sobrien
1341190286Sobrien(define_insn "jump"
1341250650Sobrien  [(set (pc)
1341390286Sobrien	(label_ref (match_operand 0 "" "")))]
1341450650Sobrien  ""
1341590286Sobrien  "jmp\t%l0"
13416117404Skan  [(set_attr "type" "ibr")
13417117404Skan   (set (attr "length")
13418117404Skan	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13419117404Skan				  (const_int -126))
13420117404Skan			      (lt (minus (match_dup 0) (pc))
13421117404Skan				  (const_int 128)))
13422117404Skan	     (const_int 2)
13423117404Skan	     (const_int 5)))
13424117404Skan   (set_attr "modrm" "0")])
1342590286Sobrien
1342690286Sobrien(define_expand "indirect_jump"
1342790286Sobrien  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
1342890286Sobrien  ""
1342990286Sobrien  "")
1343090286Sobrien
1343190286Sobrien(define_insn "*indirect_jump"
1343290286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
1343390286Sobrien  "!TARGET_64BIT"
1343490286Sobrien  "jmp\t%A0"
1343590286Sobrien  [(set_attr "type" "ibr")
1343690286Sobrien   (set_attr "length_immediate" "0")])
1343790286Sobrien
1343890286Sobrien(define_insn "*indirect_jump_rtx64"
1343990286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
1344090286Sobrien  "TARGET_64BIT"
1344190286Sobrien  "jmp\t%A0"
1344290286Sobrien  [(set_attr "type" "ibr")
1344390286Sobrien   (set_attr "length_immediate" "0")])
1344490286Sobrien
1344590286Sobrien(define_expand "tablejump"
1344690286Sobrien  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
1344790286Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
1344890286Sobrien  ""
1344950650Sobrien{
13450117404Skan  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13451117404Skan     relative.  Convert the relative address to an absolute address.  */
1345290286Sobrien  if (flag_pic)
1345390286Sobrien    {
13454117404Skan      rtx op0, op1;
13455117404Skan      enum rtx_code code;
13456117404Skan
1345790286Sobrien      if (TARGET_64BIT)
1345890286Sobrien	{
13459117404Skan	  code = PLUS;
13460117404Skan	  op0 = operands[0];
13461117404Skan	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1346290286Sobrien	}
13463117404Skan      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13464117404Skan	{
13465117404Skan	  code = PLUS;
13466117404Skan	  op0 = operands[0];
13467117404Skan	  op1 = pic_offset_table_rtx;
13468117404Skan	}
1346990286Sobrien      else
1347090286Sobrien	{
13471117404Skan	  code = MINUS;
13472117404Skan	  op0 = pic_offset_table_rtx;
13473117404Skan	  op1 = operands[0];
1347490286Sobrien	}
13475117404Skan
13476117404Skan      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13477117404Skan					 OPTAB_DIRECT);
1347890286Sobrien    }
1347990286Sobrien})
1348050650Sobrien
1348190286Sobrien(define_insn "*tablejump_1"
1348290286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
1348390286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1348490286Sobrien  "!TARGET_64BIT"
1348590286Sobrien  "jmp\t%A0"
1348690286Sobrien  [(set_attr "type" "ibr")
1348790286Sobrien   (set_attr "length_immediate" "0")])
1348818334Speter
1348990286Sobrien(define_insn "*tablejump_1_rtx64"
1349090286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
1349190286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1349290286Sobrien  "TARGET_64BIT"
1349390286Sobrien  "jmp\t%A0"
1349490286Sobrien  [(set_attr "type" "ibr")
1349590286Sobrien   (set_attr "length_immediate" "0")])
1349690286Sobrien
1349790286Sobrien;; Loop instruction
1349890286Sobrien;;
1349990286Sobrien;; This is all complicated by the fact that since this is a jump insn
1350090286Sobrien;; we must handle our own reloads.
1350118334Speter
1350290286Sobrien(define_expand "doloop_end"
1350390286Sobrien  [(use (match_operand 0 "" ""))        ; loop pseudo
1350490286Sobrien   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
1350590286Sobrien   (use (match_operand 2 "" ""))        ; max iterations
1350690286Sobrien   (use (match_operand 3 "" ""))        ; loop level 
1350790286Sobrien   (use (match_operand 4 "" ""))]       ; label
1350890286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1350990286Sobrien  "                                 
1351018334Speter{
1351190286Sobrien  /* Only use cloop on innermost loops.  */
1351290286Sobrien  if (INTVAL (operands[3]) > 1)
1351390286Sobrien    FAIL;
1351490286Sobrien  if (GET_MODE (operands[0]) != SImode)
1351590286Sobrien    FAIL;
1351690286Sobrien  emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
1351790286Sobrien					   operands[0]));
1351890286Sobrien  DONE;
1351918334Speter}")
1352018334Speter
1352190286Sobrien(define_insn "doloop_end_internal"
1352218334Speter  [(set (pc)
1352390286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
1352490286Sobrien			  (const_int 1))
1352590286Sobrien		      (label_ref (match_operand 0 "" ""))
1352690286Sobrien		      (pc)))
1352790286Sobrien   (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
1352890286Sobrien	(plus:SI (match_dup 1)
1352990286Sobrien		 (const_int -1)))
1353090286Sobrien   (clobber (match_scratch:SI 3 "=X,X,r"))
1353190286Sobrien   (clobber (reg:CC 17))]
1353290286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1353318334Speter{
1353490286Sobrien  if (which_alternative != 0)
1353590286Sobrien    return "#";
1353690286Sobrien  if (get_attr_length (insn) == 2)
1353790286Sobrien    return "%+loop\t%l0";
1353890286Sobrien  else
1353990286Sobrien    return "dec{l}\t%1\;%+jne\t%l0";
1354090286Sobrien}
1354190286Sobrien  [(set_attr "ppro_uops" "many")
13542117404Skan   (set (attr "length")
1354390286Sobrien	(if_then_else (and (eq_attr "alternative" "0")
1354490286Sobrien			   (and (ge (minus (match_dup 0) (pc))
13545117404Skan			            (const_int -126))
1354690286Sobrien			        (lt (minus (match_dup 0) (pc))
13547117404Skan			            (const_int 128))))
13548117404Skan		      (const_int 2)
13549117404Skan		      (const_int 16)))
13550117404Skan   ;; We don't know the type before shorten branches.  Optimistically expect
13551117404Skan   ;; the loop instruction to match.
13552117404Skan   (set (attr "type") (const_string "ibr"))])
1355318334Speter
1355490286Sobrien(define_split
1355590286Sobrien  [(set (pc)
1355690286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1355790286Sobrien			  (const_int 1))
1355890286Sobrien		      (match_operand 0 "" "")
1355990286Sobrien		      (pc)))
1356090286Sobrien   (set (match_dup 1)
1356190286Sobrien	(plus:SI (match_dup 1)
1356290286Sobrien		 (const_int -1)))
1356390286Sobrien   (clobber (match_scratch:SI 2 ""))
1356490286Sobrien   (clobber (reg:CC 17))]
1356590286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1356690286Sobrien   && reload_completed
1356790286Sobrien   && REGNO (operands[1]) != 2"
1356890286Sobrien  [(parallel [(set (reg:CCZ 17)
1356990286Sobrien		   (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
1357090286Sobrien				 (const_int 0)))
1357190286Sobrien	      (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
1357290286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1357390286Sobrien			   (match_dup 0)
1357490286Sobrien			   (pc)))]
1357590286Sobrien  "")
1357690286Sobrien  
1357790286Sobrien(define_split
1357890286Sobrien  [(set (pc)
1357990286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1358090286Sobrien			  (const_int 1))
1358190286Sobrien		      (match_operand 0 "" "")
1358290286Sobrien		      (pc)))
1358390286Sobrien   (set (match_operand:SI 2 "nonimmediate_operand" "")
1358490286Sobrien	(plus:SI (match_dup 1)
1358590286Sobrien		 (const_int -1)))
1358690286Sobrien   (clobber (match_scratch:SI 3 ""))
1358790286Sobrien   (clobber (reg:CC 17))]
1358890286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1358990286Sobrien   && reload_completed
1359090286Sobrien   && (! REG_P (operands[2])
1359190286Sobrien       || ! rtx_equal_p (operands[1], operands[2]))"
1359290286Sobrien  [(set (match_dup 3) (match_dup 1))
1359390286Sobrien   (parallel [(set (reg:CCZ 17)
1359490286Sobrien		   (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
1359590286Sobrien				(const_int 0)))
1359690286Sobrien	      (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
1359790286Sobrien   (set (match_dup 2) (match_dup 3))
1359890286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1359990286Sobrien			   (match_dup 0)
1360090286Sobrien			   (pc)))]
1360190286Sobrien  "")
1360218334Speter
1360390286Sobrien;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
1360418334Speter
1360590286Sobrien(define_peephole2
1360690286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1360790286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1360890286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1360990286Sobrien	  [(reg 17) (const_int 0)]))
1361090286Sobrien   (set (match_operand 3 "q_regs_operand" "")
1361190286Sobrien	(zero_extend (match_dup 1)))]
1361290286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1361390286Sobrien    || operands_match_p (operands[1], operands[3]))
1361490286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1361590286Sobrien  [(set (match_dup 4) (match_dup 0))
1361690286Sobrien   (set (strict_low_part (match_dup 5))
1361790286Sobrien	(match_dup 2))]
1361818334Speter{
1361990286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13620132727Skan  operands[5] = gen_lowpart (QImode, operands[3]);
1362190286Sobrien  ix86_expand_clear (operands[3]);
1362290286Sobrien})
1362318334Speter
1362490286Sobrien;; Similar, but match zero_extendhisi2_and, which adds a clobber.
1362518334Speter
1362690286Sobrien(define_peephole2
1362790286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1362890286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1362990286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1363090286Sobrien	  [(reg 17) (const_int 0)]))
1363190286Sobrien   (parallel [(set (match_operand 3 "q_regs_operand" "")
1363290286Sobrien		   (zero_extend (match_dup 1)))
1363390286Sobrien	      (clobber (reg:CC 17))])]
1363490286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1363590286Sobrien    || operands_match_p (operands[1], operands[3]))
1363690286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1363790286Sobrien  [(set (match_dup 4) (match_dup 0))
1363890286Sobrien   (set (strict_low_part (match_dup 5))
1363990286Sobrien	(match_dup 2))]
1364090286Sobrien{
1364190286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13642132727Skan  operands[5] = gen_lowpart (QImode, operands[3]);
1364390286Sobrien  ix86_expand_clear (operands[3]);
1364490286Sobrien})
1364590286Sobrien
1364690286Sobrien;; Call instructions.
1364718334Speter
1364890286Sobrien;; The predicates normally associated with named expanders are not properly
1364990286Sobrien;; checked for calls.  This is a bug in the generic code, but it isn't that
1365090286Sobrien;; easy to fix.  Ignore it for now and be prepared to fix things up.
1365118334Speter
1365218334Speter;; Call subroutine returning no value.
1365318334Speter
1365418334Speter(define_expand "call_pop"
1365590286Sobrien  [(parallel [(call (match_operand:QI 0 "" "")
1365690286Sobrien		    (match_operand:SI 1 "" ""))
1365718334Speter	      (set (reg:SI 7)
1365818334Speter		   (plus:SI (reg:SI 7)
1365990286Sobrien			    (match_operand:SI 3 "" "")))])]
1366090286Sobrien  "!TARGET_64BIT"
1366118334Speter{
13662132727Skan  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13663117404Skan  DONE;
1366490286Sobrien})
1366518334Speter
1366690286Sobrien(define_insn "*call_pop_0"
1366790286Sobrien  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
1366890286Sobrien	 (match_operand:SI 1 "" ""))
1366918334Speter   (set (reg:SI 7) (plus:SI (reg:SI 7)
1367090286Sobrien			    (match_operand:SI 2 "immediate_operand" "")))]
1367190286Sobrien  "!TARGET_64BIT"
1367218334Speter{
1367390286Sobrien  if (SIBLING_CALL_P (insn))
1367490286Sobrien    return "jmp\t%P0";
1367590286Sobrien  else
1367690286Sobrien    return "call\t%P0";
1367790286Sobrien}
1367890286Sobrien  [(set_attr "type" "call")])
1367990286Sobrien  
1368090286Sobrien(define_insn "*call_pop_1"
1368190286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1368290286Sobrien	 (match_operand:SI 1 "" ""))
1368390286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1368490286Sobrien			    (match_operand:SI 2 "immediate_operand" "i")))]
1368590286Sobrien  "!TARGET_64BIT"
1368690286Sobrien{
1368790286Sobrien  if (constant_call_address_operand (operands[0], Pmode))
1368818334Speter    {
1368990286Sobrien      if (SIBLING_CALL_P (insn))
1369090286Sobrien	return "jmp\t%P0";
1369190286Sobrien      else
1369290286Sobrien	return "call\t%P0";
1369318334Speter    }
1369490286Sobrien  if (SIBLING_CALL_P (insn))
1369590286Sobrien    return "jmp\t%A0";
1369618334Speter  else
1369790286Sobrien    return "call\t%A0";
1369890286Sobrien}
1369990286Sobrien  [(set_attr "type" "call")])
1370018334Speter
1370118334Speter(define_expand "call"
1370290286Sobrien  [(call (match_operand:QI 0 "" "")
1370390286Sobrien	 (match_operand 1 "" ""))
1370490286Sobrien   (use (match_operand 2 "" ""))]
1370518334Speter  ""
1370618334Speter{
13707132727Skan  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13708117404Skan  DONE;
1370990286Sobrien})
1371018334Speter
13711132727Skan(define_expand "sibcall"
13712132727Skan  [(call (match_operand:QI 0 "" "")
13713132727Skan	 (match_operand 1 "" ""))
13714132727Skan   (use (match_operand 2 "" ""))]
13715132727Skan  ""
13716132727Skan{
13717132727Skan  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13718132727Skan  DONE;
13719132727Skan})
13720132727Skan
1372190286Sobrien(define_insn "*call_0"
1372290286Sobrien  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
1372390286Sobrien	 (match_operand 1 "" ""))]
1372418334Speter  ""
1372518334Speter{
1372690286Sobrien  if (SIBLING_CALL_P (insn))
1372790286Sobrien    return "jmp\t%P0";
1372890286Sobrien  else
1372990286Sobrien    return "call\t%P0";
1373090286Sobrien}
1373190286Sobrien  [(set_attr "type" "call")])
1373290286Sobrien
1373390286Sobrien(define_insn "*call_1"
1373490286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1373590286Sobrien	 (match_operand 1 "" ""))]
13736132727Skan  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
1373790286Sobrien{
1373890286Sobrien  if (constant_call_address_operand (operands[0], QImode))
13739132727Skan    return "call\t%P0";
13740132727Skan  return "call\t%A0";
1374190286Sobrien}
1374290286Sobrien  [(set_attr "type" "call")])
1374318334Speter
13744132727Skan(define_insn "*sibcall_1"
13745132727Skan  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13746132727Skan	 (match_operand 1 "" ""))]
13747132727Skan  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13748132727Skan{
13749132727Skan  if (constant_call_address_operand (operands[0], QImode))
13750132727Skan    return "jmp\t%P0";
13751132727Skan  return "jmp\t%A0";
13752132727Skan}
13753132727Skan  [(set_attr "type" "call")])
13754132727Skan
1375590286Sobrien(define_insn "*call_1_rex64"
1375690286Sobrien  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
1375790286Sobrien	 (match_operand 1 "" ""))]
13758132727Skan  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
1375990286Sobrien{
1376090286Sobrien  if (constant_call_address_operand (operands[0], QImode))
13761132727Skan    return "call\t%P0";
13762132727Skan  return "call\t%A0";
1376390286Sobrien}
1376490286Sobrien  [(set_attr "type" "call")])
1376518334Speter
13766132727Skan(define_insn "*sibcall_1_rex64"
13767132727Skan  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13768132727Skan	 (match_operand 1 "" ""))]
13769132727Skan  "SIBLING_CALL_P (insn) && TARGET_64BIT"
13770132727Skan  "jmp\t%P0"
13771132727Skan  [(set_attr "type" "call")])
13772132727Skan
13773132727Skan(define_insn "*sibcall_1_rex64_v"
13774132727Skan  [(call (mem:QI (reg:DI 40))
13775132727Skan	 (match_operand 0 "" ""))]
13776132727Skan  "SIBLING_CALL_P (insn) && TARGET_64BIT"
13777132727Skan  "jmp\t*%%r11"
13778132727Skan  [(set_attr "type" "call")])
13779132727Skan
13780132727Skan
1378118334Speter;; Call subroutine, returning value in operand 0
1378218334Speter
1378318334Speter(define_expand "call_value_pop"
1378418334Speter  [(parallel [(set (match_operand 0 "" "")
1378590286Sobrien		   (call (match_operand:QI 1 "" "")
1378690286Sobrien			 (match_operand:SI 2 "" "")))
1378718334Speter	      (set (reg:SI 7)
1378818334Speter		   (plus:SI (reg:SI 7)
1378990286Sobrien			    (match_operand:SI 4 "" "")))])]
1379090286Sobrien  "!TARGET_64BIT"
1379118334Speter{
13792117404Skan  ix86_expand_call (operands[0], operands[1], operands[2],
13793132727Skan		    operands[3], operands[4], 0);
13794117404Skan  DONE;
1379590286Sobrien})
1379618334Speter
1379718334Speter(define_expand "call_value"
1379818334Speter  [(set (match_operand 0 "" "")
1379990286Sobrien	(call (match_operand:QI 1 "" "")
1380090286Sobrien	      (match_operand:SI 2 "" "")))
1380190286Sobrien   (use (match_operand:SI 3 "" ""))]
1380218334Speter  ;; Operand 2 not used on the i386.
1380318334Speter  ""
1380418334Speter{
13805132727Skan  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
1380690286Sobrien  DONE;
1380790286Sobrien})
1380818334Speter
13809132727Skan(define_expand "sibcall_value"
13810132727Skan  [(set (match_operand 0 "" "")
13811132727Skan	(call (match_operand:QI 1 "" "")
13812132727Skan	      (match_operand:SI 2 "" "")))
13813132727Skan   (use (match_operand:SI 3 "" ""))]
13814132727Skan  ;; Operand 2 not used on the i386.
13815132727Skan  ""
13816132727Skan{
13817132727Skan  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13818132727Skan  DONE;
13819132727Skan})
13820132727Skan
1382118334Speter;; Call subroutine returning any type.
1382218334Speter
1382318334Speter(define_expand "untyped_call"
1382418334Speter  [(parallel [(call (match_operand 0 "" "")
1382518334Speter		    (const_int 0))
1382618334Speter	      (match_operand 1 "" "")
1382718334Speter	      (match_operand 2 "" "")])]
1382818334Speter  ""
1382918334Speter{
1383018334Speter  int i;
1383118334Speter
1383218334Speter  /* In order to give reg-stack an easier job in validating two
1383318334Speter     coprocessor registers as containing a possible return value,
1383418334Speter     simply pretend the untyped call returns a complex long double
1383518334Speter     value.  */
1383650650Sobrien
13837117404Skan  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13838117404Skan		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13839117404Skan		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13840132727Skan		    NULL, 0);
1384118334Speter
1384218334Speter  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1384318334Speter    {
1384418334Speter      rtx set = XVECEXP (operands[2], 0, i);
1384518334Speter      emit_move_insn (SET_DEST (set), SET_SRC (set));
1384618334Speter    }
1384718334Speter
1384818334Speter  /* The optimizer does not know that the call sets the function value
1384918334Speter     registers we stored in the result block.  We avoid problems by
1385018334Speter     claiming that all hard registers are used and clobbered at this
1385118334Speter     point.  */
13852117404Skan  emit_insn (gen_blockage (const0_rtx));
1385318334Speter
1385418334Speter  DONE;
1385590286Sobrien})
1385690286Sobrien
1385790286Sobrien;; Prologue and epilogue instructions
1385818334Speter
1385918334Speter;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1386018334Speter;; all of memory.  This blocks insns from being moved across this point.
1386118334Speter
1386218334Speter(define_insn "blockage"
13863117404Skan  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
1386418334Speter  ""
1386552296Sobrien  ""
1386690286Sobrien  [(set_attr "length" "0")])
1386718334Speter
1386818334Speter;; Insn emitted into the body of a function to return from a function.
1386918334Speter;; This is only done if the function's epilogue is known to be simple.
1387090286Sobrien;; See comments for ix86_can_use_return_insn_p in i386.c.
1387118334Speter
1387250650Sobrien(define_expand "return"
1387318334Speter  [(return)]
1387450650Sobrien  "ix86_can_use_return_insn_p ()"
1387590286Sobrien{
1387690286Sobrien  if (current_function_pops_args)
1387790286Sobrien    {
1387890286Sobrien      rtx popc = GEN_INT (current_function_pops_args);
1387990286Sobrien      emit_jump_insn (gen_return_pop_internal (popc));
1388090286Sobrien      DONE;
1388190286Sobrien    }
1388290286Sobrien})
1388350650Sobrien
1388450650Sobrien(define_insn "return_internal"
1388550650Sobrien  [(return)]
1388650650Sobrien  "reload_completed"
1388752296Sobrien  "ret"
1388890286Sobrien  [(set_attr "length" "1")
1388990286Sobrien   (set_attr "length_immediate" "0")
1389090286Sobrien   (set_attr "modrm" "0")])
1389150650Sobrien
13892132727Skan;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13893132727Skan;; instruction Athlon and K8 have.
13894132727Skan
13895132727Skan(define_insn "return_internal_long"
13896132727Skan  [(return)
13897132727Skan   (unspec [(const_int 0)] UNSPEC_REP)]
13898132727Skan  "reload_completed"
13899132727Skan  "rep {;} ret"
13900132727Skan  [(set_attr "length" "1")
13901132727Skan   (set_attr "length_immediate" "0")
13902132727Skan   (set_attr "prefix_rep" "1")
13903132727Skan   (set_attr "modrm" "0")])
13904132727Skan
1390550650Sobrien(define_insn "return_pop_internal"
1390650650Sobrien  [(return)
1390750650Sobrien   (use (match_operand:SI 0 "const_int_operand" ""))]
1390850650Sobrien  "reload_completed"
1390990286Sobrien  "ret\t%0"
1391090286Sobrien  [(set_attr "length" "3")
1391190286Sobrien   (set_attr "length_immediate" "2")
1391290286Sobrien   (set_attr "modrm" "0")])
1391350650Sobrien
1391490286Sobrien(define_insn "return_indirect_internal"
1391590286Sobrien  [(return)
1391690286Sobrien   (use (match_operand:SI 0 "register_operand" "r"))]
1391790286Sobrien  "reload_completed"
1391890286Sobrien  "jmp\t%A0"
1391990286Sobrien  [(set_attr "type" "ibr")
1392090286Sobrien   (set_attr "length_immediate" "0")])
1392190286Sobrien
1392250650Sobrien(define_insn "nop"
1392350650Sobrien  [(const_int 0)]
1392450650Sobrien  ""
1392552296Sobrien  "nop"
1392690286Sobrien  [(set_attr "length" "1")
1392790286Sobrien   (set_attr "length_immediate" "0")
1392890286Sobrien   (set_attr "modrm" "0")
1392990286Sobrien   (set_attr "ppro_uops" "one")])
1393050650Sobrien
13931132727Skan;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13932132727Skan;; branch prediction penalty for the third jump in a 16-byte
13933132727Skan;; block on K8.
13934132727Skan
13935132727Skan(define_insn "align"
13936132727Skan  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13937132727Skan  ""
13938132727Skan{
13939132727Skan#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13940132727Skan  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13941132727Skan#else
13942132727Skan  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13943132727Skan     The align insn is used to avoid 3 jump instructions in the row to improve
13944132727Skan     branch prediction and the benefits hardly outweight the cost of extra 8
13945132727Skan     nops on the average inserted by full alignment pseudo operation.  */
13946132727Skan#endif
13947132727Skan  return "";
13948132727Skan}
13949132727Skan  [(set_attr "length" "16")])
13950132727Skan
1395150650Sobrien(define_expand "prologue"
1395250650Sobrien  [(const_int 1)]
1395350650Sobrien  ""
1395490286Sobrien  "ix86_expand_prologue (); DONE;")
1395550650Sobrien
13956117404Skan(define_insn "set_got"
1395790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
13958117404Skan	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
1395990286Sobrien   (clobber (reg:CC 17))]
1396090286Sobrien  "!TARGET_64BIT"
13961117404Skan  { return output_set_got (operands[0]); }
13962117404Skan  [(set_attr "type" "multi")
13963117404Skan   (set_attr "length" "12")])
1396450650Sobrien
1396550650Sobrien(define_expand "epilogue"
1396650650Sobrien  [(const_int 1)]
1396750650Sobrien  ""
1396890286Sobrien  "ix86_expand_epilogue (1); DONE;")
1396950650Sobrien
1397090286Sobrien(define_expand "sibcall_epilogue"
1397190286Sobrien  [(const_int 1)]
1397250650Sobrien  ""
1397390286Sobrien  "ix86_expand_epilogue (0); DONE;")
1397450650Sobrien
1397590286Sobrien(define_expand "eh_return"
13976117404Skan  [(use (match_operand 0 "register_operand" ""))]
1397750650Sobrien  ""
1397850650Sobrien{
13979117404Skan  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
1398050650Sobrien
1398190286Sobrien  /* Tricky bit: we write the address of the handler to which we will
1398290286Sobrien     be returning into someone else's stack frame, one word below the
1398390286Sobrien     stack address we wish to restore.  */
1398490286Sobrien  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
1398590286Sobrien  tmp = plus_constant (tmp, -UNITS_PER_WORD);
1398690286Sobrien  tmp = gen_rtx_MEM (Pmode, tmp);
1398790286Sobrien  emit_move_insn (tmp, ra);
1398818334Speter
1398990286Sobrien  if (Pmode == SImode)
1399090286Sobrien    emit_insn (gen_eh_return_si (sa));
1399190286Sobrien  else
1399290286Sobrien    emit_insn (gen_eh_return_di (sa));
1399390286Sobrien  emit_barrier ();
1399490286Sobrien  DONE;
1399590286Sobrien})
1399618334Speter
1399790286Sobrien(define_insn_and_split "eh_return_si"
13998117404Skan  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13999117404Skan		    UNSPECV_EH_RETURN)]
1400090286Sobrien  "!TARGET_64BIT"
1400190286Sobrien  "#"
1400290286Sobrien  "reload_completed"
1400390286Sobrien  [(const_int 1)]
1400490286Sobrien  "ix86_expand_epilogue (2); DONE;")
1400518334Speter
1400690286Sobrien(define_insn_and_split "eh_return_di"
14007117404Skan  [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14008117404Skan		    UNSPECV_EH_RETURN)]
1400990286Sobrien  "TARGET_64BIT"
1401090286Sobrien  "#"
1401190286Sobrien  "reload_completed"
1401290286Sobrien  [(const_int 1)]
1401390286Sobrien  "ix86_expand_epilogue (2); DONE;")
1401418334Speter
1401590286Sobrien(define_insn "leave"
1401690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
1401790286Sobrien   (set (reg:SI 6) (mem:SI (reg:SI 6)))
1401890286Sobrien   (clobber (mem:BLK (scratch)))]
1401990286Sobrien  "!TARGET_64BIT"
1402090286Sobrien  "leave"
14021132727Skan  [(set_attr "type" "leave")])
1402218334Speter
1402390286Sobrien(define_insn "leave_rex64"
1402490286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
1402590286Sobrien   (set (reg:DI 6) (mem:DI (reg:DI 6)))
1402690286Sobrien   (clobber (mem:BLK (scratch)))]
1402790286Sobrien  "TARGET_64BIT"
1402890286Sobrien  "leave"
14029132727Skan  [(set_attr "type" "leave")])
1403090286Sobrien
1403190286Sobrien(define_expand "ffssi2"
14032132727Skan  [(parallel
14033132727Skan     [(set (match_operand:SI 0 "register_operand" "") 
14034132727Skan	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14035132727Skan      (clobber (match_scratch:SI 2 ""))
14036132727Skan      (clobber (reg:CC 17))])]
1403718334Speter  ""
14038132727Skan  "")
1403918334Speter
14040132727Skan(define_insn_and_split "*ffs_cmove"
14041132727Skan  [(set (match_operand:SI 0 "register_operand" "=r") 
14042132727Skan	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14043132727Skan   (clobber (match_scratch:SI 2 "=&r"))
14044132727Skan   (clobber (reg:CC 17))]
14045132727Skan  "TARGET_CMOVE"
14046132727Skan  "#"
14047132727Skan  "&& reload_completed"
14048132727Skan  [(set (match_dup 2) (const_int -1))
14049132727Skan   (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14050132727Skan	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14051132727Skan   (set (match_dup 0) (if_then_else:SI
14052132727Skan			(eq (reg:CCZ 17) (const_int 0))
14053132727Skan			(match_dup 2)
14054132727Skan			(match_dup 0)))
14055132727Skan   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14056132727Skan	      (clobber (reg:CC 17))])]
14057132727Skan  "")
1405818334Speter
14059132727Skan(define_insn_and_split "*ffs_no_cmove"
14060132727Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14061132727Skan	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14062132727Skan   (clobber (match_scratch:SI 2 "=&q"))
14063132727Skan   (clobber (reg:CC 17))]
14064132727Skan  ""
14065132727Skan  "#"
14066132727Skan  "reload_completed"
14067132727Skan  [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14068132727Skan	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14069132727Skan   (set (strict_low_part (match_dup 3))
14070132727Skan	(eq:QI (reg:CCZ 17) (const_int 0)))
14071132727Skan   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14072132727Skan	      (clobber (reg:CC 17))])
14073132727Skan   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14074132727Skan	      (clobber (reg:CC 17))])
14075132727Skan   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14076132727Skan	      (clobber (reg:CC 17))])]
14077132727Skan{
14078132727Skan  operands[3] = gen_lowpart (QImode, operands[2]);
14079132727Skan  ix86_expand_clear (operands[2]);
1408090286Sobrien})
1408150650Sobrien
14082132727Skan(define_insn "*ffssi_1"
1408390286Sobrien  [(set (reg:CCZ 17)
14084132727Skan	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
1408590286Sobrien		     (const_int 0)))
1408690286Sobrien   (set (match_operand:SI 0 "register_operand" "=r")
14087132727Skan	(ctz:SI (match_dup 1)))]
1408818334Speter  ""
1408990286Sobrien  "bsf{l}\t{%1, %0|%0, %1}"
1409090286Sobrien  [(set_attr "prefix_0f" "1")
1409190286Sobrien   (set_attr "ppro_uops" "few")])
1409218334Speter
14093132727Skan(define_insn "ctzsi2"
14094132727Skan  [(set (match_operand:SI 0 "register_operand" "=r")
14095132727Skan	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14096132727Skan   (clobber (reg:CC 17))]
14097132727Skan  ""
14098132727Skan  "bsf{l}\t{%1, %0|%0, %1}"
14099132727Skan  [(set_attr "prefix_0f" "1")
14100132727Skan   (set_attr "ppro_uops" "few")])
14101132727Skan
14102132727Skan(define_expand "clzsi2"
14103132727Skan  [(parallel
14104132727Skan     [(set (match_operand:SI 0 "register_operand" "")
14105132727Skan	   (minus:SI (const_int 31)
14106132727Skan		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14107132727Skan      (clobber (reg:CC 17))])
14108132727Skan   (parallel
14109132727Skan     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14110132727Skan      (clobber (reg:CC 17))])]
14111132727Skan  ""
14112132727Skan  "")
14113132727Skan
14114132727Skan(define_insn "*bsr"
14115132727Skan  [(set (match_operand:SI 0 "register_operand" "=r")
14116132727Skan	(minus:SI (const_int 31)
14117132727Skan		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14118132727Skan   (clobber (reg:CC 17))]
14119132727Skan  ""
14120132727Skan  "bsr{l}\t{%1, %0|%0, %1}"
14121132727Skan  [(set_attr "prefix_0f" "1")
14122132727Skan   (set_attr "ppro_uops" "few")])
1412390286Sobrien
14124117404Skan;; Thread-local storage patterns for ELF.
14125117404Skan;;
14126117404Skan;; Note that these code sequences must appear exactly as shown
14127117404Skan;; in order to allow linker relaxation.
14128117404Skan
14129117404Skan(define_insn "*tls_global_dynamic_32_gnu"
14130117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
14131117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14132117404Skan		    (match_operand:SI 2 "tls_symbolic_operand" "")
14133117404Skan		    (match_operand:SI 3 "call_insn_operand" "")]
14134117404Skan		    UNSPEC_TLS_GD))
14135117404Skan   (clobber (match_scratch:SI 4 "=d"))
14136117404Skan   (clobber (match_scratch:SI 5 "=c"))
14137117404Skan   (clobber (reg:CC 17))]
14138117404Skan  "!TARGET_64BIT && TARGET_GNU_TLS"
14139117404Skan  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14140117404Skan  [(set_attr "type" "multi")
14141117404Skan   (set_attr "length" "12")])
14142117404Skan
14143117404Skan(define_insn "*tls_global_dynamic_32_sun"
14144117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
14145117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14146117404Skan		    (match_operand:SI 2 "tls_symbolic_operand" "")
14147117404Skan		    (match_operand:SI 3 "call_insn_operand" "")]
14148117404Skan		    UNSPEC_TLS_GD))
14149117404Skan   (clobber (match_scratch:SI 4 "=d"))
14150117404Skan   (clobber (match_scratch:SI 5 "=c"))
14151117404Skan   (clobber (reg:CC 17))]
14152117404Skan  "!TARGET_64BIT && TARGET_SUN_TLS"
14153117404Skan  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14154117404Skan	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14155117404Skan  [(set_attr "type" "multi")
14156117404Skan   (set_attr "length" "14")])
14157117404Skan
14158117404Skan(define_expand "tls_global_dynamic_32"
14159117404Skan  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14160117404Skan		   (unspec:SI
14161117404Skan		    [(match_dup 2)
14162117404Skan		     (match_operand:SI 1 "tls_symbolic_operand" "")
14163117404Skan		     (match_dup 3)]
14164117404Skan		    UNSPEC_TLS_GD))
14165117404Skan	      (clobber (match_scratch:SI 4 ""))
14166117404Skan	      (clobber (match_scratch:SI 5 ""))
14167117404Skan	      (clobber (reg:CC 17))])]
14168117404Skan  ""
14169117404Skan{
14170117404Skan  if (flag_pic)
14171117404Skan    operands[2] = pic_offset_table_rtx;
14172117404Skan  else
14173117404Skan    {
14174117404Skan      operands[2] = gen_reg_rtx (Pmode);
14175117404Skan      emit_insn (gen_set_got (operands[2]));
14176117404Skan    }
14177117404Skan  operands[3] = ix86_tls_get_addr ();
14178117404Skan})
14179117404Skan
14180117404Skan(define_insn "*tls_global_dynamic_64"
14181117404Skan  [(set (match_operand:DI 0 "register_operand" "=a")
14182117404Skan	(call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14183117404Skan		      (match_operand:DI 3 "" "")))
14184117404Skan   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14185117404Skan	      UNSPEC_TLS_GD)]
14186117404Skan  "TARGET_64BIT"
14187117404Skan  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14188117404Skan  [(set_attr "type" "multi")
14189117404Skan   (set_attr "length" "16")])
14190117404Skan
14191117404Skan(define_expand "tls_global_dynamic_64"
14192117404Skan  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14193117404Skan		   (call (mem:QI (match_dup 2)) (const_int 0)))
14194117404Skan	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14195117404Skan			 UNSPEC_TLS_GD)])]
14196117404Skan  ""
14197117404Skan{
14198117404Skan  operands[2] = ix86_tls_get_addr ();
14199117404Skan})
14200117404Skan
14201117404Skan(define_insn "*tls_local_dynamic_base_32_gnu"
14202117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
14203117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14204117404Skan                    (match_operand:SI 2 "call_insn_operand" "")]
14205117404Skan		   UNSPEC_TLS_LD_BASE))
14206117404Skan   (clobber (match_scratch:SI 3 "=d"))
14207117404Skan   (clobber (match_scratch:SI 4 "=c"))
14208117404Skan   (clobber (reg:CC 17))]
14209117404Skan  "!TARGET_64BIT && TARGET_GNU_TLS"
14210117404Skan  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14211117404Skan  [(set_attr "type" "multi")
14212117404Skan   (set_attr "length" "11")])
14213117404Skan
14214117404Skan(define_insn "*tls_local_dynamic_base_32_sun"
14215117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
14216117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14217117404Skan                    (match_operand:SI 2 "call_insn_operand" "")]
14218117404Skan		   UNSPEC_TLS_LD_BASE))
14219117404Skan   (clobber (match_scratch:SI 3 "=d"))
14220117404Skan   (clobber (match_scratch:SI 4 "=c"))
14221117404Skan   (clobber (reg:CC 17))]
14222117404Skan  "!TARGET_64BIT && TARGET_SUN_TLS"
14223117404Skan  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14224117404Skan	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14225117404Skan  [(set_attr "type" "multi")
14226117404Skan   (set_attr "length" "13")])
14227117404Skan
14228117404Skan(define_expand "tls_local_dynamic_base_32"
14229117404Skan  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14230117404Skan		   (unspec:SI [(match_dup 1) (match_dup 2)]
14231117404Skan			      UNSPEC_TLS_LD_BASE))
14232117404Skan	      (clobber (match_scratch:SI 3 ""))
14233117404Skan	      (clobber (match_scratch:SI 4 ""))
14234117404Skan	      (clobber (reg:CC 17))])]
14235117404Skan  ""
14236117404Skan{
14237117404Skan  if (flag_pic)
14238117404Skan    operands[1] = pic_offset_table_rtx;
14239117404Skan  else
14240117404Skan    {
14241117404Skan      operands[1] = gen_reg_rtx (Pmode);
14242117404Skan      emit_insn (gen_set_got (operands[1]));
14243117404Skan    }
14244117404Skan  operands[2] = ix86_tls_get_addr ();
14245117404Skan})
14246117404Skan
14247117404Skan(define_insn "*tls_local_dynamic_base_64"
14248117404Skan  [(set (match_operand:DI 0 "register_operand" "=a")
14249117404Skan	(call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14250117404Skan		      (match_operand:DI 2 "" "")))
14251117404Skan   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14252117404Skan  "TARGET_64BIT"
14253117404Skan  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14254117404Skan  [(set_attr "type" "multi")
14255117404Skan   (set_attr "length" "12")])
14256117404Skan
14257117404Skan(define_expand "tls_local_dynamic_base_64"
14258117404Skan  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14259117404Skan		   (call (mem:QI (match_dup 1)) (const_int 0)))
14260117404Skan	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14261117404Skan  ""
14262117404Skan{
14263117404Skan  operands[1] = ix86_tls_get_addr ();
14264117404Skan})
14265117404Skan
14266117404Skan;; Local dynamic of a single variable is a lose.  Show combine how
14267117404Skan;; to convert that back to global dynamic.
14268117404Skan
14269117404Skan(define_insn_and_split "*tls_local_dynamic_32_once"
14270117404Skan  [(set (match_operand:SI 0 "register_operand" "=a")
14271117404Skan	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14272117404Skan			     (match_operand:SI 2 "call_insn_operand" "")]
14273117404Skan			    UNSPEC_TLS_LD_BASE)
14274117404Skan		 (const:SI (unspec:SI
14275117404Skan			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
14276117404Skan			    UNSPEC_DTPOFF))))
14277117404Skan   (clobber (match_scratch:SI 4 "=d"))
14278117404Skan   (clobber (match_scratch:SI 5 "=c"))
14279117404Skan   (clobber (reg:CC 17))]
14280117404Skan  ""
14281117404Skan  "#"
14282117404Skan  ""
14283117404Skan  [(parallel [(set (match_dup 0)
14284117404Skan		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14285117404Skan			      UNSPEC_TLS_GD))
14286117404Skan	      (clobber (match_dup 4))
14287117404Skan	      (clobber (match_dup 5))
14288117404Skan	      (clobber (reg:CC 17))])]
14289117404Skan  "")
14290132727Skan
14291132727Skan;; Load and add the thread base pointer from %gs:0.
14292132727Skan
14293132727Skan(define_insn "*load_tp_si"
14294132727Skan  [(set (match_operand:SI 0 "register_operand" "=r")
14295132727Skan	(unspec:SI [(const_int 0)] UNSPEC_TP))]
14296132727Skan  "!TARGET_64BIT"
14297132727Skan  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14298132727Skan  [(set_attr "type" "imov")
14299132727Skan   (set_attr "modrm" "0")
14300132727Skan   (set_attr "length" "7")
14301132727Skan   (set_attr "memory" "load")
14302132727Skan   (set_attr "imm_disp" "false")])
14303132727Skan
14304132727Skan(define_insn "*add_tp_si"
14305132727Skan  [(set (match_operand:SI 0 "register_operand" "=r")
14306132727Skan	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14307132727Skan		 (match_operand:SI 1 "register_operand" "0")))
14308132727Skan   (clobber (reg:CC 17))]
14309132727Skan  "!TARGET_64BIT"
14310132727Skan  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14311132727Skan  [(set_attr "type" "alu")
14312132727Skan   (set_attr "modrm" "0")
14313132727Skan   (set_attr "length" "7")
14314132727Skan   (set_attr "memory" "load")
14315132727Skan   (set_attr "imm_disp" "false")])
14316132727Skan
14317132727Skan(define_insn "*load_tp_di"
14318132727Skan  [(set (match_operand:DI 0 "register_operand" "=r")
14319132727Skan	(unspec:DI [(const_int 0)] UNSPEC_TP))]
14320132727Skan  "TARGET_64BIT"
14321132727Skan  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14322132727Skan  [(set_attr "type" "imov")
14323132727Skan   (set_attr "modrm" "0")
14324132727Skan   (set_attr "length" "7")
14325132727Skan   (set_attr "memory" "load")
14326132727Skan   (set_attr "imm_disp" "false")])
14327132727Skan
14328132727Skan(define_insn "*add_tp_di"
14329132727Skan  [(set (match_operand:DI 0 "register_operand" "=r")
14330132727Skan	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14331132727Skan		 (match_operand:DI 1 "register_operand" "0")))
14332132727Skan   (clobber (reg:CC 17))]
14333132727Skan  "TARGET_64BIT"
14334132727Skan  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14335132727Skan  [(set_attr "type" "alu")
14336132727Skan   (set_attr "modrm" "0")
14337132727Skan   (set_attr "length" "7")
14338132727Skan   (set_attr "memory" "load")
14339132727Skan   (set_attr "imm_disp" "false")])
14340117404Skan
1434190286Sobrien;; These patterns match the binary 387 instructions for addM3, subM3,
1434290286Sobrien;; mulM3 and divM3.  There are three patterns for each of DFmode and
1434390286Sobrien;; SFmode.  The first is the normal insn, the second the same insn but
1434490286Sobrien;; with one operand a conversion, and the third the same insn but with
1434590286Sobrien;; the other operand a conversion.  The conversion may be SFmode or
1434690286Sobrien;; SImode if the target mode DFmode, but only SImode if the target mode
1434790286Sobrien;; is SFmode.
1434818334Speter
1434990286Sobrien;; Gcc is slightly more smart about handling normal two address instructions
1435090286Sobrien;; so use special patterns for add and mull.
1435190286Sobrien(define_insn "*fop_sf_comm_nosse"
1435290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1435390286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1435496294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1435590286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
1435690286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1435796294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1435896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1435990286Sobrien  "* return output_387_binary_op (insn, operands);"
1436090286Sobrien  [(set (attr "type") 
1436190286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1436290286Sobrien	   (const_string "fmul")
1436390286Sobrien	   (const_string "fop")))
1436490286Sobrien   (set_attr "mode" "SF")])
1436518334Speter
1436690286Sobrien(define_insn "*fop_sf_comm"
1436790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1436890286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1436996294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
1437090286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
1437190286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1437296294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1437396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1437490286Sobrien  "* return output_387_binary_op (insn, operands);"
1437590286Sobrien  [(set (attr "type") 
1437690286Sobrien	(if_then_else (eq_attr "alternative" "1")
1437790286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14378117404Skan	      (const_string "ssemul")
14379117404Skan	      (const_string "sseadd"))
14380117404Skan	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1438190286Sobrien	      (const_string "fmul")
1438290286Sobrien	      (const_string "fop"))))
1438390286Sobrien   (set_attr "mode" "SF")])
1438418334Speter
1438590286Sobrien(define_insn "*fop_sf_comm_sse"
1438690286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1438790286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1438896294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1438990286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1439096294Sobrien  "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1439196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1439290286Sobrien  "* return output_387_binary_op (insn, operands);"
14393117404Skan  [(set (attr "type") 
14394117404Skan        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14395117404Skan	   (const_string "ssemul")
14396117404Skan	   (const_string "sseadd")))
1439790286Sobrien   (set_attr "mode" "SF")])
1439818334Speter
1439990286Sobrien(define_insn "*fop_df_comm_nosse"
1440090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1440190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1440296294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1440390286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
1440490286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1440596294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1440696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1440790286Sobrien  "* return output_387_binary_op (insn, operands);"
1440890286Sobrien  [(set (attr "type") 
1440990286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1441090286Sobrien	   (const_string "fmul")
1441190286Sobrien	   (const_string "fop")))
1441290286Sobrien   (set_attr "mode" "DF")])
1441318334Speter
1441490286Sobrien(define_insn "*fop_df_comm"
1441590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1441690286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1441796294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
1441890286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
1441990286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
1442096294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1442196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1442290286Sobrien  "* return output_387_binary_op (insn, operands);"
1442390286Sobrien  [(set (attr "type") 
1442490286Sobrien	(if_then_else (eq_attr "alternative" "1")
1442590286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14426117404Skan	      (const_string "ssemul")
14427117404Skan	      (const_string "sseadd"))
14428117404Skan	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1442990286Sobrien	      (const_string "fmul")
1443090286Sobrien	      (const_string "fop"))))
1443190286Sobrien   (set_attr "mode" "DF")])
1443218334Speter
1443390286Sobrien(define_insn "*fop_df_comm_sse"
1443490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1443590286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1443696294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1443790286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1443890286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1443996294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1444096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1444190286Sobrien  "* return output_387_binary_op (insn, operands);"
14442117404Skan  [(set (attr "type") 
14443117404Skan        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14444117404Skan	   (const_string "ssemul")
14445117404Skan	   (const_string "sseadd")))
1444690286Sobrien   (set_attr "mode" "DF")])
1444718334Speter
1444890286Sobrien(define_insn "*fop_xf_comm"
1444990286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1445090286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1445190286Sobrien			[(match_operand:XF 1 "register_operand" "%0")
1445290286Sobrien			 (match_operand:XF 2 "register_operand" "f")]))]
14453132727Skan  "TARGET_80387
1445490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1445590286Sobrien  "* return output_387_binary_op (insn, operands);"
1445690286Sobrien  [(set (attr "type") 
1445790286Sobrien        (if_then_else (match_operand:XF 3 "mult_operator" "") 
1445890286Sobrien           (const_string "fmul")
1445990286Sobrien           (const_string "fop")))
1446090286Sobrien   (set_attr "mode" "XF")])
1446118334Speter
1446290286Sobrien(define_insn "*fop_sf_1_nosse"
1446390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1446490286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1446590286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
1446690286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
1446790286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1446890286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1446990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1447090286Sobrien  "* return output_387_binary_op (insn, operands);"
1447190286Sobrien  [(set (attr "type") 
1447290286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1447390286Sobrien                 (const_string "fmul")
1447490286Sobrien               (match_operand:SF 3 "div_operator" "") 
1447590286Sobrien                 (const_string "fdiv")
1447690286Sobrien              ]
1447790286Sobrien              (const_string "fop")))
1447890286Sobrien   (set_attr "mode" "SF")])
1447918334Speter
1448090286Sobrien(define_insn "*fop_sf_1"
1448190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
1448290286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1448390286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
1448490286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
1448590286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1448690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1448790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1448890286Sobrien  "* return output_387_binary_op (insn, operands);"
1448990286Sobrien  [(set (attr "type") 
14490117404Skan        (cond [(and (eq_attr "alternative" "2")
14491117404Skan	            (match_operand:SF 3 "mult_operator" ""))
14492117404Skan                 (const_string "ssemul")
14493117404Skan	       (and (eq_attr "alternative" "2")
14494117404Skan	            (match_operand:SF 3 "div_operator" ""))
14495117404Skan                 (const_string "ssediv")
14496117404Skan	       (eq_attr "alternative" "2")
14497117404Skan                 (const_string "sseadd")
1449890286Sobrien	       (match_operand:SF 3 "mult_operator" "") 
1449990286Sobrien                 (const_string "fmul")
1450090286Sobrien               (match_operand:SF 3 "div_operator" "") 
1450190286Sobrien                 (const_string "fdiv")
1450290286Sobrien              ]
1450390286Sobrien              (const_string "fop")))
1450490286Sobrien   (set_attr "mode" "SF")])
1450518334Speter
1450690286Sobrien(define_insn "*fop_sf_1_sse"
1450790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1450890286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1450990286Sobrien			[(match_operand:SF 1 "register_operand" "0")
1451090286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1451190286Sobrien  "TARGET_SSE_MATH
1451290286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1451390286Sobrien  "* return output_387_binary_op (insn, operands);"
14514117404Skan  [(set (attr "type") 
14515117404Skan        (cond [(match_operand:SF 3 "mult_operator" "")
14516117404Skan                 (const_string "ssemul")
14517117404Skan	       (match_operand:SF 3 "div_operator" "")
14518117404Skan                 (const_string "ssediv")
14519117404Skan              ]
14520117404Skan              (const_string "sseadd")))
1452190286Sobrien   (set_attr "mode" "SF")])
1452218334Speter
1452390286Sobrien;; ??? Add SSE splitters for these!
1452490286Sobrien(define_insn "*fop_sf_2"
1452590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1452690286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1452790286Sobrien	  [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1452890286Sobrien	   (match_operand:SF 2 "register_operand" "0,0")]))]
1452990286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1453090286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1453190286Sobrien  [(set (attr "type") 
1453290286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1453390286Sobrien                 (const_string "fmul")
1453490286Sobrien               (match_operand:SF 3 "div_operator" "") 
1453590286Sobrien                 (const_string "fdiv")
1453690286Sobrien              ]
1453790286Sobrien              (const_string "fop")))
1453890286Sobrien   (set_attr "fp_int_src" "true")
1453990286Sobrien   (set_attr "ppro_uops" "many")
1454090286Sobrien   (set_attr "mode" "SI")])
1454118334Speter
1454290286Sobrien(define_insn "*fop_sf_3"
1454390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1454490286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1454590286Sobrien	  [(match_operand:SF 1 "register_operand" "0,0")
1454690286Sobrien	   (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1454790286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1454890286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1454990286Sobrien  [(set (attr "type") 
1455090286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1455190286Sobrien                 (const_string "fmul")
1455290286Sobrien               (match_operand:SF 3 "div_operator" "") 
1455390286Sobrien                 (const_string "fdiv")
1455490286Sobrien              ]
1455590286Sobrien              (const_string "fop")))
1455690286Sobrien   (set_attr "fp_int_src" "true")
1455790286Sobrien   (set_attr "ppro_uops" "many")
1455890286Sobrien   (set_attr "mode" "SI")])
1455918334Speter
1456090286Sobrien(define_insn "*fop_df_1_nosse"
1456190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1456290286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1456390286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
1456490286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
1456590286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1456690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1456790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1456890286Sobrien  "* return output_387_binary_op (insn, operands);"
1456990286Sobrien  [(set (attr "type") 
1457090286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1457190286Sobrien                 (const_string "fmul")
14572117404Skan               (match_operand:DF 3 "div_operator" "")
1457390286Sobrien                 (const_string "fdiv")
1457490286Sobrien              ]
1457590286Sobrien              (const_string "fop")))
1457690286Sobrien   (set_attr "mode" "DF")])
1457718334Speter
1457818334Speter
1457990286Sobrien(define_insn "*fop_df_1"
1458090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
1458190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1458290286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
1458390286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
1458490286Sobrien  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1458590286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1458690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1458790286Sobrien  "* return output_387_binary_op (insn, operands);"
1458890286Sobrien  [(set (attr "type") 
14589117404Skan        (cond [(and (eq_attr "alternative" "2")
14590117404Skan	            (match_operand:SF 3 "mult_operator" ""))
14591117404Skan                 (const_string "ssemul")
14592117404Skan	       (and (eq_attr "alternative" "2")
14593117404Skan	            (match_operand:SF 3 "div_operator" ""))
14594117404Skan                 (const_string "ssediv")
14595117404Skan	       (eq_attr "alternative" "2")
14596117404Skan                 (const_string "sseadd")
1459790286Sobrien	       (match_operand:DF 3 "mult_operator" "") 
1459890286Sobrien                 (const_string "fmul")
1459990286Sobrien               (match_operand:DF 3 "div_operator" "") 
1460090286Sobrien                 (const_string "fdiv")
1460190286Sobrien              ]
1460290286Sobrien              (const_string "fop")))
1460390286Sobrien   (set_attr "mode" "DF")])
1460418334Speter
1460590286Sobrien(define_insn "*fop_df_1_sse"
1460690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1460790286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1460890286Sobrien			[(match_operand:DF 1 "register_operand" "0")
1460990286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1461090286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1461190286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1461290286Sobrien  "* return output_387_binary_op (insn, operands);"
14613117404Skan  [(set_attr "mode" "DF")
14614117404Skan   (set (attr "type") 
14615117404Skan        (cond [(match_operand:SF 3 "mult_operator" "")
14616117404Skan                 (const_string "ssemul")
14617117404Skan	       (match_operand:SF 3 "div_operator" "")
14618117404Skan                 (const_string "ssediv")
14619117404Skan              ]
14620117404Skan              (const_string "sseadd")))])
1462118334Speter
1462290286Sobrien;; ??? Add SSE splitters for these!
1462390286Sobrien(define_insn "*fop_df_2"
1462490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1462590286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1462690286Sobrien	   [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1462790286Sobrien	    (match_operand:DF 2 "register_operand" "0,0")]))]
1462890286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1462990286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1463090286Sobrien  [(set (attr "type") 
1463190286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1463290286Sobrien                 (const_string "fmul")
1463390286Sobrien               (match_operand:DF 3 "div_operator" "") 
1463490286Sobrien                 (const_string "fdiv")
1463590286Sobrien              ]
1463690286Sobrien              (const_string "fop")))
1463790286Sobrien   (set_attr "fp_int_src" "true")
1463890286Sobrien   (set_attr "ppro_uops" "many")
1463990286Sobrien   (set_attr "mode" "SI")])
1464018334Speter
1464190286Sobrien(define_insn "*fop_df_3"
1464290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1464390286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1464490286Sobrien	   [(match_operand:DF 1 "register_operand" "0,0")
1464590286Sobrien	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1464690286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1464790286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1464890286Sobrien  [(set (attr "type") 
1464990286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1465090286Sobrien                 (const_string "fmul")
1465190286Sobrien               (match_operand:DF 3 "div_operator" "") 
1465290286Sobrien                 (const_string "fdiv")
1465390286Sobrien              ]
1465490286Sobrien              (const_string "fop")))
1465590286Sobrien   (set_attr "fp_int_src" "true")
1465690286Sobrien   (set_attr "ppro_uops" "many")
1465790286Sobrien   (set_attr "mode" "SI")])
1465818334Speter
1465990286Sobrien(define_insn "*fop_df_4"
1466090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1466190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1466290286Sobrien	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1466390286Sobrien	    (match_operand:DF 2 "register_operand" "0,f")]))]
1466490286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1466590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1466690286Sobrien  "* return output_387_binary_op (insn, operands);"
1466790286Sobrien  [(set (attr "type") 
1466890286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1466990286Sobrien                 (const_string "fmul")
1467090286Sobrien               (match_operand:DF 3 "div_operator" "") 
1467190286Sobrien                 (const_string "fdiv")
1467290286Sobrien              ]
1467390286Sobrien              (const_string "fop")))
1467490286Sobrien   (set_attr "mode" "SF")])
1467518334Speter
1467690286Sobrien(define_insn "*fop_df_5"
1467718334Speter  [(set (match_operand:DF 0 "register_operand" "=f,f")
1467890286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1467990286Sobrien	  [(match_operand:DF 1 "register_operand" "0,f")
1468090286Sobrien	   (float_extend:DF
1468190286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1468290286Sobrien  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1468350650Sobrien  "* return output_387_binary_op (insn, operands);"
1468450650Sobrien  [(set (attr "type") 
1468590286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1468690286Sobrien                 (const_string "fmul")
1468790286Sobrien               (match_operand:DF 3 "div_operator" "") 
1468890286Sobrien                 (const_string "fdiv")
1468950650Sobrien              ]
1469090286Sobrien              (const_string "fop")))
1469190286Sobrien   (set_attr "mode" "SF")])
1469218334Speter
14693132727Skan(define_insn "*fop_df_6"
14694132727Skan  [(set (match_operand:DF 0 "register_operand" "=f,f")
14695132727Skan	(match_operator:DF 3 "binary_fp_operator"
14696132727Skan	  [(float_extend:DF
14697132727Skan	    (match_operand:SF 1 "register_operand" "0,f"))
14698132727Skan	   (float_extend:DF
14699132727Skan	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14700132727Skan  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1470150650Sobrien  "* return output_387_binary_op (insn, operands);"
1470250650Sobrien  [(set (attr "type") 
14703132727Skan        (cond [(match_operand:DF 3 "mult_operator" "") 
1470490286Sobrien                 (const_string "fmul")
14705132727Skan               (match_operand:DF 3 "div_operator" "") 
1470690286Sobrien                 (const_string "fdiv")
1470750650Sobrien              ]
1470890286Sobrien              (const_string "fop")))
14709132727Skan   (set_attr "mode" "SF")])
1471018334Speter
14711132727Skan(define_insn "*fop_xf_1"
14712132727Skan  [(set (match_operand:XF 0 "register_operand" "=f,f")
14713132727Skan	(match_operator:XF 3 "binary_fp_operator"
14714132727Skan			[(match_operand:XF 1 "register_operand" "0,f")
14715132727Skan			 (match_operand:XF 2 "register_operand" "f,0")]))]
1471690286Sobrien  "TARGET_80387
1471790286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1471890286Sobrien  "* return output_387_binary_op (insn, operands);"
1471990286Sobrien  [(set (attr "type") 
14720132727Skan        (cond [(match_operand:XF 3 "mult_operator" "") 
1472190286Sobrien                 (const_string "fmul")
14722132727Skan               (match_operand:XF 3 "div_operator" "") 
1472390286Sobrien                 (const_string "fdiv")
1472490286Sobrien              ]
1472590286Sobrien              (const_string "fop")))
1472690286Sobrien   (set_attr "mode" "XF")])
1472790286Sobrien
1472890286Sobrien(define_insn "*fop_xf_2"
1472918334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1473090286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1473190286Sobrien	   [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1473290286Sobrien	    (match_operand:XF 2 "register_operand" "0,0")]))]
14733132727Skan  "TARGET_80387 && TARGET_USE_FIOP"
1473490286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1473590286Sobrien  [(set (attr "type") 
1473690286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1473790286Sobrien                 (const_string "fmul")
1473890286Sobrien               (match_operand:XF 3 "div_operator" "") 
1473990286Sobrien                 (const_string "fdiv")
1474090286Sobrien              ]
1474190286Sobrien              (const_string "fop")))
1474290286Sobrien   (set_attr "fp_int_src" "true")
1474390286Sobrien   (set_attr "mode" "SI")
1474490286Sobrien   (set_attr "ppro_uops" "many")])
1474590286Sobrien
1474690286Sobrien(define_insn "*fop_xf_3"
1474790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1474890286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1474990286Sobrien	  [(match_operand:XF 1 "register_operand" "0,0")
1475090286Sobrien	   (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14751132727Skan  "TARGET_80387 && TARGET_USE_FIOP"
1475290286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1475390286Sobrien  [(set (attr "type") 
1475490286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1475590286Sobrien                 (const_string "fmul")
1475690286Sobrien               (match_operand:XF 3 "div_operator" "") 
1475790286Sobrien                 (const_string "fdiv")
1475890286Sobrien              ]
1475990286Sobrien              (const_string "fop")))
1476090286Sobrien   (set_attr "fp_int_src" "true")
1476190286Sobrien   (set_attr "mode" "SI")
1476290286Sobrien   (set_attr "ppro_uops" "many")])
1476390286Sobrien
1476490286Sobrien(define_insn "*fop_xf_4"
1476590286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1476690286Sobrien	(match_operator:XF 3 "binary_fp_operator"
14767132727Skan	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
1476850650Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
14769132727Skan  "TARGET_80387"
1477090286Sobrien  "* return output_387_binary_op (insn, operands);"
1477190286Sobrien  [(set (attr "type") 
1477290286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1477390286Sobrien                 (const_string "fmul")
1477490286Sobrien               (match_operand:XF 3 "div_operator" "") 
1477590286Sobrien                 (const_string "fdiv")
1477690286Sobrien              ]
1477790286Sobrien              (const_string "fop")))
1477890286Sobrien   (set_attr "mode" "SF")])
1477990286Sobrien
1478090286Sobrien(define_insn "*fop_xf_5"
1478118334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1478290286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1478350650Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1478418334Speter	   (float_extend:XF
14785132727Skan	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14786132727Skan  "TARGET_80387"
1478750650Sobrien  "* return output_387_binary_op (insn, operands);"
1478850650Sobrien  [(set (attr "type") 
1478990286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1479090286Sobrien                 (const_string "fmul")
1479190286Sobrien               (match_operand:XF 3 "div_operator" "") 
1479290286Sobrien                 (const_string "fdiv")
1479350650Sobrien              ]
1479490286Sobrien              (const_string "fop")))
1479590286Sobrien   (set_attr "mode" "SF")])
1479618334Speter
1479790286Sobrien(define_insn "*fop_xf_6"
1479890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1479990286Sobrien	(match_operator:XF 3 "binary_fp_operator"
14800132727Skan	  [(float_extend:XF
14801132727Skan	    (match_operand 1 "register_operand" "0,f"))
14802132727Skan	   (float_extend:XF
14803132727Skan	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
1480418334Speter  "TARGET_80387"
1480550650Sobrien  "* return output_387_binary_op (insn, operands);"
1480650650Sobrien  [(set (attr "type") 
1480790286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1480890286Sobrien                 (const_string "fmul")
1480990286Sobrien               (match_operand:XF 3 "div_operator" "") 
1481090286Sobrien                 (const_string "fdiv")
1481190286Sobrien              ]
1481290286Sobrien              (const_string "fop")))
14813132727Skan   (set_attr "mode" "SF")])
1481490286Sobrien
1481590286Sobrien(define_split
1481690286Sobrien  [(set (match_operand 0 "register_operand" "")
1481790286Sobrien	(match_operator 3 "binary_fp_operator"
1481890286Sobrien	   [(float (match_operand:SI 1 "register_operand" ""))
1481990286Sobrien	    (match_operand 2 "register_operand" "")]))]
1482090286Sobrien  "TARGET_80387 && reload_completed
1482190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1482290286Sobrien  [(const_int 0)]
1482390286Sobrien{ 
1482490286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
1482590286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1482690286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1482790286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1482890286Sobrien					  GET_MODE (operands[3]),
1482990286Sobrien					  operands[4],
1483090286Sobrien					  operands[2])));
1483190286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
1483290286Sobrien  DONE;
1483390286Sobrien})
1483490286Sobrien
1483590286Sobrien(define_split
1483690286Sobrien  [(set (match_operand 0 "register_operand" "")
1483790286Sobrien	(match_operator 3 "binary_fp_operator"
1483890286Sobrien	   [(match_operand 1 "register_operand" "")
1483990286Sobrien	    (float (match_operand:SI 2 "register_operand" ""))]))]
1484090286Sobrien  "TARGET_80387 && reload_completed
1484190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1484290286Sobrien  [(const_int 0)]
1484390286Sobrien{
1484490286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
1484590286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1484690286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1484790286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1484890286Sobrien					  GET_MODE (operands[3]),
1484990286Sobrien					  operands[1],
1485090286Sobrien					  operands[4])));
1485190286Sobrien  ix86_free_from_memory (GET_MODE (operands[2]));
1485290286Sobrien  DONE;
1485390286Sobrien})
1485418334Speter
1485590286Sobrien;; FPU special functions.
1485690286Sobrien
1485790286Sobrien(define_expand "sqrtsf2"
1485890286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1485990286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
1486090286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
1486190286Sobrien{
1486290286Sobrien  if (!TARGET_SSE_MATH)
1486390286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
1486490286Sobrien})
1486590286Sobrien
1486690286Sobrien(define_insn "sqrtsf2_1"
1486790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1486890286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
1486990286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1487090286Sobrien   && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1487190286Sobrien  "@
1487290286Sobrien   fsqrt
1487390286Sobrien   sqrtss\t{%1, %0|%0, %1}"
1487490286Sobrien  [(set_attr "type" "fpspc,sse")
1487590286Sobrien   (set_attr "mode" "SF,SF")
1487690286Sobrien   (set_attr "athlon_decode" "direct,*")])
1487790286Sobrien
1487890286Sobrien(define_insn "sqrtsf2_1_sse_only"
1487990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1488090286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
1488190286Sobrien  "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1488290286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1488390286Sobrien  [(set_attr "type" "sse")
1488490286Sobrien   (set_attr "mode" "SF")
1488590286Sobrien   (set_attr "athlon_decode" "*")])
1488690286Sobrien
1488790286Sobrien(define_insn "sqrtsf2_i387"
1488890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1488990286Sobrien	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
1489090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1489190286Sobrien   && !TARGET_SSE_MATH"
1489290286Sobrien  "fsqrt"
1489390286Sobrien  [(set_attr "type" "fpspc")
1489490286Sobrien   (set_attr "mode" "SF")
1489590286Sobrien   (set_attr "athlon_decode" "direct")])
1489690286Sobrien
1489790286Sobrien(define_expand "sqrtdf2"
1489890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1489990286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
1490090286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
1490190286Sobrien   || (TARGET_SSE2 && TARGET_SSE_MATH)"
1490290286Sobrien{
1490390286Sobrien  if (!TARGET_SSE2 || !TARGET_SSE_MATH)
1490490286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
1490590286Sobrien})
1490690286Sobrien
1490790286Sobrien(define_insn "sqrtdf2_1"
1490890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1490990286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
1491090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1491190286Sobrien   && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1491290286Sobrien  "@
1491390286Sobrien   fsqrt
1491490286Sobrien   sqrtsd\t{%1, %0|%0, %1}"
1491590286Sobrien  [(set_attr "type" "fpspc,sse")
1491690286Sobrien   (set_attr "mode" "DF,DF")
1491790286Sobrien   (set_attr "athlon_decode" "direct,*")])
1491890286Sobrien
1491990286Sobrien(define_insn "sqrtdf2_1_sse_only"
1492090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1492190286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
1492290286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1492390286Sobrien  "sqrtsd\t{%1, %0|%0, %1}"
1492490286Sobrien  [(set_attr "type" "sse")
1492590286Sobrien   (set_attr "mode" "DF")
1492690286Sobrien   (set_attr "athlon_decode" "*")])
1492790286Sobrien
1492890286Sobrien(define_insn "sqrtdf2_i387"
1492990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1493090286Sobrien	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
1493190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1493290286Sobrien   && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
1493390286Sobrien  "fsqrt"
1493490286Sobrien  [(set_attr "type" "fpspc")
1493590286Sobrien   (set_attr "mode" "DF")
1493690286Sobrien   (set_attr "athlon_decode" "direct")])
1493790286Sobrien
1493890286Sobrien(define_insn "*sqrtextendsfdf2"
1493990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1494090286Sobrien	(sqrt:DF (float_extend:DF
1494190286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1494290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1494390286Sobrien   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1494490286Sobrien  "fsqrt"
1494590286Sobrien  [(set_attr "type" "fpspc")
1494690286Sobrien   (set_attr "mode" "DF")
1494790286Sobrien   (set_attr "athlon_decode" "direct")])
1494890286Sobrien
1494990286Sobrien(define_insn "sqrtxf2"
1495090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1495190286Sobrien	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14952132727Skan  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
1495390286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1495490286Sobrien  "fsqrt"
1495590286Sobrien  [(set_attr "type" "fpspc")
1495690286Sobrien   (set_attr "mode" "XF")
1495790286Sobrien   (set_attr "athlon_decode" "direct")])
1495890286Sobrien
1495990286Sobrien(define_insn "*sqrtextenddfxf2"
1496090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1496190286Sobrien	(sqrt:XF (float_extend:XF
1496290286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
14963132727Skan  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1496490286Sobrien  "fsqrt"
1496590286Sobrien  [(set_attr "type" "fpspc")
1496690286Sobrien   (set_attr "mode" "XF")
1496790286Sobrien   (set_attr "athlon_decode" "direct")])
1496890286Sobrien
1496990286Sobrien(define_insn "*sqrtextendsfxf2"
1497090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1497190286Sobrien	(sqrt:XF (float_extend:XF
1497290286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
14973132727Skan  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1497490286Sobrien  "fsqrt"
1497590286Sobrien  [(set_attr "type" "fpspc")
1497690286Sobrien   (set_attr "mode" "XF")
1497790286Sobrien   (set_attr "athlon_decode" "direct")])
1497890286Sobrien
1497990286Sobrien(define_insn "sindf2"
1498090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
14981117404Skan	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
1498290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1498390286Sobrien   && flag_unsafe_math_optimizations"
1498490286Sobrien  "fsin"
1498590286Sobrien  [(set_attr "type" "fpspc")
1498690286Sobrien   (set_attr "mode" "DF")])
1498790286Sobrien
1498890286Sobrien(define_insn "sinsf2"
1498990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
14990117404Skan	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
1499190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1499290286Sobrien   && flag_unsafe_math_optimizations"
1499390286Sobrien  "fsin"
1499490286Sobrien  [(set_attr "type" "fpspc")
1499590286Sobrien   (set_attr "mode" "SF")])
1499690286Sobrien
1499790286Sobrien(define_insn "*sinextendsfdf2"
1499890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1499990286Sobrien	(unspec:DF [(float_extend:DF
15000117404Skan		     (match_operand:SF 1 "register_operand" "0"))]
15001117404Skan		   UNSPEC_SIN))]
1500290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1500390286Sobrien   && flag_unsafe_math_optimizations"
1500490286Sobrien  "fsin"
1500590286Sobrien  [(set_attr "type" "fpspc")
1500690286Sobrien   (set_attr "mode" "DF")])
1500790286Sobrien
1500890286Sobrien(define_insn "sinxf2"
1500990286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
15010117404Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15011132727Skan  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
1501290286Sobrien   && flag_unsafe_math_optimizations"
1501390286Sobrien  "fsin"
1501490286Sobrien  [(set_attr "type" "fpspc")
1501590286Sobrien   (set_attr "mode" "XF")])
1501690286Sobrien
1501790286Sobrien(define_insn "cosdf2"
1501890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
15019117404Skan	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
1502090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1502190286Sobrien   && flag_unsafe_math_optimizations"
1502290286Sobrien  "fcos"
1502390286Sobrien  [(set_attr "type" "fpspc")
1502490286Sobrien   (set_attr "mode" "DF")])
1502590286Sobrien
1502690286Sobrien(define_insn "cossf2"
1502790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
15028117404Skan	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
1502990286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1503090286Sobrien   && flag_unsafe_math_optimizations"
1503190286Sobrien  "fcos"
1503290286Sobrien  [(set_attr "type" "fpspc")
1503390286Sobrien   (set_attr "mode" "SF")])
1503490286Sobrien
1503590286Sobrien(define_insn "*cosextendsfdf2"
1503690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1503790286Sobrien	(unspec:DF [(float_extend:DF
15038117404Skan		     (match_operand:SF 1 "register_operand" "0"))]
15039117404Skan		   UNSPEC_COS))]
1504090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1504190286Sobrien   && flag_unsafe_math_optimizations"
1504290286Sobrien  "fcos"
1504390286Sobrien  [(set_attr "type" "fpspc")
1504490286Sobrien   (set_attr "mode" "DF")])
1504590286Sobrien
1504690286Sobrien(define_insn "cosxf2"
1504790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
15048117404Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15049132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1505090286Sobrien   && flag_unsafe_math_optimizations"
1505190286Sobrien  "fcos"
1505290286Sobrien  [(set_attr "type" "fpspc")
1505390286Sobrien   (set_attr "mode" "XF")])
1505490286Sobrien
15055132727Skan(define_insn "atan2df3_1"
15056132727Skan  [(set (match_operand:DF 0 "register_operand" "=f")
15057132727Skan	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
15058132727Skan		    (match_operand:DF 1 "register_operand" "u")]
15059132727Skan		   UNSPEC_FPATAN))
15060132727Skan   (clobber (match_scratch:DF 3 "=1"))]
15061132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1506290286Sobrien   && flag_unsafe_math_optimizations"
15063132727Skan  "fpatan"
1506490286Sobrien  [(set_attr "type" "fpspc")
15065132727Skan   (set_attr "mode" "DF")])
15066132727Skan
15067132727Skan(define_expand "atan2df3"
15068132727Skan  [(use (match_operand:DF 0 "register_operand" "=f"))
15069132727Skan   (use (match_operand:DF 2 "register_operand" "0"))
15070132727Skan   (use (match_operand:DF 1 "register_operand" "u"))]
15071132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15072132727Skan   && flag_unsafe_math_optimizations"
15073132727Skan{
15074132727Skan  rtx copy = gen_reg_rtx (DFmode);
15075132727Skan  emit_move_insn (copy, operands[1]);
15076132727Skan  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15077132727Skan  DONE;
15078132727Skan})
15079132727Skan
15080132727Skan(define_insn "atan2sf3_1"
15081132727Skan  [(set (match_operand:SF 0 "register_operand" "=f")
15082132727Skan        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15083132727Skan		    (match_operand:SF 1 "register_operand" "u")]
15084132727Skan		   UNSPEC_FPATAN))
15085132727Skan   (clobber (match_scratch:SF 3 "=1"))]
15086132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15087132727Skan   && flag_unsafe_math_optimizations"
15088132727Skan  "fpatan"
15089132727Skan  [(set_attr "type" "fpspc")
15090132727Skan   (set_attr "mode" "SF")])
15091132727Skan
15092132727Skan(define_expand "atan2sf3"
15093132727Skan  [(use (match_operand:SF 0 "register_operand" "=f"))
15094132727Skan   (use (match_operand:SF 2 "register_operand" "0"))
15095132727Skan   (use (match_operand:SF 1 "register_operand" "u"))]
15096132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15097132727Skan   && flag_unsafe_math_optimizations"
15098132727Skan{
15099132727Skan  rtx copy = gen_reg_rtx (SFmode);
15100132727Skan  emit_move_insn (copy, operands[1]);
15101132727Skan  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15102132727Skan  DONE;
15103132727Skan})
15104132727Skan
15105132727Skan(define_insn "atan2xf3_1"
15106132727Skan  [(set (match_operand:XF 0 "register_operand" "=f")
15107132727Skan        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15108132727Skan	            (match_operand:XF 1 "register_operand" "u")]
15109132727Skan	           UNSPEC_FPATAN))
15110132727Skan   (clobber (match_scratch:XF 3 "=1"))]
15111132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15112132727Skan   && flag_unsafe_math_optimizations"
15113132727Skan  "fpatan"
15114132727Skan  [(set_attr "type" "fpspc")
1511590286Sobrien   (set_attr "mode" "XF")])
15116132727Skan
15117132727Skan(define_expand "atan2xf3"
15118132727Skan  [(use (match_operand:XF 0 "register_operand" "=f"))
15119132727Skan   (use (match_operand:XF 2 "register_operand" "0"))
15120132727Skan   (use (match_operand:XF 1 "register_operand" "u"))]
15121132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15122132727Skan   && flag_unsafe_math_optimizations"
15123132727Skan{
15124132727Skan  rtx copy = gen_reg_rtx (XFmode);
15125132727Skan  emit_move_insn (copy, operands[1]);
15126132727Skan  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15127132727Skan  DONE;
15128132727Skan})
15129132727Skan
15130132727Skan(define_insn "*fyl2x_sfxf3"
15131132727Skan  [(set (match_operand:SF 0 "register_operand" "=f")
15132132727Skan         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15133132727Skan		     (match_operand:XF 1 "register_operand" "u")]
15134132727Skan		    UNSPEC_FYL2X))
15135132727Skan   (clobber (match_scratch:SF 3 "=1"))]
15136132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137132727Skan   && flag_unsafe_math_optimizations"
15138132727Skan  "fyl2x"
15139132727Skan  [(set_attr "type" "fpspc")
15140132727Skan   (set_attr "mode" "SF")])
15141132727Skan
15142132727Skan(define_insn "*fyl2x_dfxf3"
15143132727Skan  [(set (match_operand:DF 0 "register_operand" "=f")
15144132727Skan         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15145132727Skan		     (match_operand:XF 1 "register_operand" "u")]
15146132727Skan		    UNSPEC_FYL2X))
15147132727Skan   (clobber (match_scratch:DF 3 "=1"))]
15148132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15149132727Skan   && flag_unsafe_math_optimizations"
15150132727Skan  "fyl2x"
15151132727Skan  [(set_attr "type" "fpspc")
15152132727Skan   (set_attr "mode" "DF")])
15153132727Skan
15154132727Skan(define_insn "*fyl2x_xf3"
15155132727Skan  [(set (match_operand:XF 0 "register_operand" "=f")
15156132727Skan        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15157132727Skan		    (match_operand:XF 1 "register_operand" "u")]
15158132727Skan	           UNSPEC_FYL2X))
15159132727Skan   (clobber (match_scratch:XF 3 "=1"))]
15160132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15161132727Skan   && flag_unsafe_math_optimizations"
15162132727Skan  "fyl2x"
15163132727Skan  [(set_attr "type" "fpspc")
15164132727Skan   (set_attr "mode" "XF")])
15165132727Skan
15166132727Skan(define_expand "logsf2"
15167132727Skan  [(parallel [(set (match_operand:SF 0 "register_operand" "")
15168132727Skan		   (unspec:SF [(match_operand:SF 1 "register_operand" "")
15169132727Skan			       (match_dup 2)] UNSPEC_FYL2X))
15170132727Skan	      (clobber (match_scratch:SF 3 ""))])]
15171132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15172132727Skan   && flag_unsafe_math_optimizations"
15173132727Skan{
15174132727Skan  rtx temp;
15175132727Skan
15176132727Skan  operands[2] = gen_reg_rtx (XFmode);
15177132727Skan  temp = standard_80387_constant_rtx (4); /* fldln2 */
15178132727Skan  emit_move_insn (operands[2], temp);
15179132727Skan})
15180132727Skan
15181132727Skan(define_expand "logdf2"
15182132727Skan  [(parallel [(set (match_operand:DF 0 "register_operand" "")
15183132727Skan		   (unspec:DF [(match_operand:DF 1 "register_operand" "")
15184132727Skan			       (match_dup 2)] UNSPEC_FYL2X))
15185132727Skan	      (clobber (match_scratch:DF 3 ""))])]
15186132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15187132727Skan   && flag_unsafe_math_optimizations"
15188132727Skan{
15189132727Skan  rtx temp;
15190132727Skan
15191132727Skan  operands[2] = gen_reg_rtx (XFmode);
15192132727Skan  temp = standard_80387_constant_rtx (4); /* fldln2 */
15193132727Skan  emit_move_insn (operands[2], temp);
15194132727Skan})
15195132727Skan
15196132727Skan(define_expand "logxf2"
15197132727Skan  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15198132727Skan		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
15199132727Skan			       (match_dup 2)] UNSPEC_FYL2X))
15200132727Skan	      (clobber (match_scratch:XF 3 ""))])]
15201132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15202132727Skan   && flag_unsafe_math_optimizations"
15203132727Skan{
15204132727Skan  rtx temp;
15205132727Skan
15206132727Skan  operands[2] = gen_reg_rtx (XFmode);
15207132727Skan  temp = standard_80387_constant_rtx (4); /* fldln2 */
15208132727Skan  emit_move_insn (operands[2], temp);
15209132727Skan})
15210132727Skan
15211132727Skan(define_insn "*fscale_sfxf3"
15212132727Skan  [(set (match_operand:SF 0 "register_operand" "=f")
15213132727Skan	 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15214132727Skan		     (match_operand:XF 1 "register_operand" "u")]
15215132727Skan		    UNSPEC_FSCALE))
15216132727Skan   (clobber (match_scratch:SF 3 "=1"))]
15217132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15218132727Skan   && flag_unsafe_math_optimizations"
15219132727Skan  "fscale\;fstp\t%y1"
15220132727Skan  [(set_attr "type" "fpspc")
15221132727Skan   (set_attr "mode" "SF")])
15222132727Skan
15223132727Skan(define_insn "*fscale_dfxf3"
15224132727Skan  [(set (match_operand:DF 0 "register_operand" "=f")
15225132727Skan	 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15226132727Skan		     (match_operand:XF 1 "register_operand" "u")]
15227132727Skan		    UNSPEC_FSCALE))
15228132727Skan   (clobber (match_scratch:DF 3 "=1"))]
15229132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15230132727Skan   && flag_unsafe_math_optimizations"
15231132727Skan  "fscale\;fstp\t%y1"
15232132727Skan  [(set_attr "type" "fpspc")
15233132727Skan   (set_attr "mode" "DF")])
15234132727Skan
15235132727Skan(define_insn "*fscale_xf3"
15236132727Skan  [(set (match_operand:XF 0 "register_operand" "=f")
15237132727Skan	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15238132727Skan		    (match_operand:XF 1 "register_operand" "u")]
15239132727Skan	           UNSPEC_FSCALE))
15240132727Skan   (clobber (match_scratch:XF 3 "=1"))]
15241132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15242132727Skan   && flag_unsafe_math_optimizations"
15243132727Skan  "fscale\;fstp\t%y1"
15244132727Skan  [(set_attr "type" "fpspc")
15245132727Skan   (set_attr "mode" "XF")])
15246132727Skan
15247132727Skan(define_insn "*frndintxf2"
15248132727Skan  [(set (match_operand:XF 0 "register_operand" "=f")
15249132727Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15250132727Skan	 UNSPEC_FRNDINT))]
15251132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15252132727Skan   && flag_unsafe_math_optimizations"
15253132727Skan  "frndint"
15254132727Skan  [(set_attr "type" "fpspc")
15255132727Skan   (set_attr "mode" "XF")])
15256132727Skan
15257132727Skan(define_insn "*f2xm1xf2"
15258132727Skan  [(set (match_operand:XF 0 "register_operand" "=f")
15259132727Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260132727Skan	 UNSPEC_F2XM1))]
15261132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15262132727Skan   && flag_unsafe_math_optimizations"
15263132727Skan  "f2xm1"
15264132727Skan  [(set_attr "type" "fpspc")
15265132727Skan   (set_attr "mode" "XF")])
15266132727Skan
15267132727Skan(define_expand "expsf2"
15268132727Skan  [(set (match_dup 2)
15269132727Skan	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
15270132727Skan   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15271132727Skan   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15272132727Skan   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15273132727Skan   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15274132727Skan   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15275132727Skan   (parallel [(set (match_operand:SF 0 "register_operand" "")
15276132727Skan		   (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15277132727Skan	      (clobber (match_scratch:SF 5 ""))])]
15278132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15279132727Skan   && flag_unsafe_math_optimizations"
15280132727Skan{
15281132727Skan  rtx temp;
15282132727Skan  int i;
15283132727Skan
15284132727Skan  for (i=2; i<10; i++)
15285132727Skan    operands[i] = gen_reg_rtx (XFmode);
15286132727Skan  temp = standard_80387_constant_rtx (5); /* fldl2e */
15287132727Skan  emit_move_insn (operands[3], temp);
15288132727Skan  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15289132727Skan})
15290132727Skan
15291132727Skan(define_expand "expdf2"
15292132727Skan  [(set (match_dup 2)
15293132727Skan	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
15294132727Skan   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15295132727Skan   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15296132727Skan   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15297132727Skan   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15298132727Skan   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15299132727Skan   (parallel [(set (match_operand:DF 0 "register_operand" "")
15300132727Skan		   (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15301132727Skan	      (clobber (match_scratch:DF 5 ""))])]
15302132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15303132727Skan   && flag_unsafe_math_optimizations"
15304132727Skan{
15305132727Skan  rtx temp;
15306132727Skan  int i;
15307132727Skan
15308132727Skan  for (i=2; i<10; i++)
15309132727Skan    operands[i] = gen_reg_rtx (XFmode);
15310132727Skan  temp = standard_80387_constant_rtx (5); /* fldl2e */
15311132727Skan  emit_move_insn (operands[3], temp);
15312132727Skan  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15313132727Skan})
15314132727Skan
15315132727Skan(define_expand "expxf2"
15316132727Skan  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15317132727Skan			       (match_dup 2)))
15318132727Skan   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15319132727Skan   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15320132727Skan   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15321132727Skan   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15322132727Skan   (parallel [(set (match_operand:XF 0 "register_operand" "")
15323132727Skan		   (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15324132727Skan	      (clobber (match_scratch:XF 5 ""))])]
15325132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15326132727Skan   && flag_unsafe_math_optimizations"
15327132727Skan{
15328132727Skan  rtx temp;
15329132727Skan  int i;
15330132727Skan
15331132727Skan  for (i=2; i<9; i++)
15332132727Skan    operands[i] = gen_reg_rtx (XFmode);
15333132727Skan  temp = standard_80387_constant_rtx (5); /* fldl2e */
15334132727Skan  emit_move_insn (operands[2], temp);
15335132727Skan  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15336132727Skan})
15337132727Skan
15338132727Skan(define_expand "atansf2"
15339132727Skan  [(parallel [(set (match_operand:SF 0 "register_operand" "")
15340132727Skan		   (unspec:SF [(match_dup 2)
15341132727Skan			       (match_operand:SF 1 "register_operand" "")]
15342132727Skan		    UNSPEC_FPATAN))
15343132727Skan	      (clobber (match_scratch:SF 3 ""))])]
15344132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15345132727Skan   && flag_unsafe_math_optimizations"
15346132727Skan{
15347132727Skan  operands[2] = gen_reg_rtx (SFmode);
15348132727Skan  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15349132727Skan})
15350132727Skan
15351132727Skan(define_expand "atandf2"
15352132727Skan  [(parallel [(set (match_operand:DF 0 "register_operand" "")
15353132727Skan		   (unspec:DF [(match_dup 2)
15354132727Skan			       (match_operand:DF 1 "register_operand" "")]
15355132727Skan		    UNSPEC_FPATAN))
15356132727Skan	      (clobber (match_scratch:DF 3 ""))])]
15357132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15358132727Skan   && flag_unsafe_math_optimizations"
15359132727Skan{
15360132727Skan  operands[2] = gen_reg_rtx (DFmode);
15361132727Skan  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15362132727Skan})
15363132727Skan
15364132727Skan(define_expand "atanxf2"
15365132727Skan  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15366132727Skan		   (unspec:XF [(match_dup 2)
15367132727Skan			       (match_operand:XF 1 "register_operand" "")]
15368132727Skan		    UNSPEC_FPATAN))
15369132727Skan	      (clobber (match_scratch:XF 3 ""))])]
15370132727Skan  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15371132727Skan   && flag_unsafe_math_optimizations"
15372132727Skan{
15373132727Skan  operands[2] = gen_reg_rtx (XFmode);
15374132727Skan  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15375132727Skan})
1537690286Sobrien
1537790286Sobrien;; Block operation instructions
1537890286Sobrien
1537990286Sobrien(define_insn "cld"
1538090286Sobrien [(set (reg:SI 19) (const_int 0))]
1538190286Sobrien ""
1538290286Sobrien "cld"
1538390286Sobrien  [(set_attr "type" "cld")])
1538490286Sobrien
1538590286Sobrien(define_expand "movstrsi"
1538690286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1538790286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1538890286Sobrien   (use (match_operand:SI 2 "nonmemory_operand" ""))
1538990286Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
15390132727Skan  "! optimize_size"
1539118334Speter{
1539290286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1539390286Sobrien   DONE;
1539490286Sobrien else
1539590286Sobrien   FAIL;
1539690286Sobrien})
1539790286Sobrien
1539890286Sobrien(define_expand "movstrdi"
1539990286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1540090286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1540190286Sobrien   (use (match_operand:DI 2 "nonmemory_operand" ""))
1540290286Sobrien   (use (match_operand:DI 3 "const_int_operand" ""))]
1540390286Sobrien  "TARGET_64BIT"
1540490286Sobrien{
1540590286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1540690286Sobrien   DONE;
1540790286Sobrien else
1540890286Sobrien   FAIL;
1540990286Sobrien})
1541090286Sobrien
1541190286Sobrien;; Most CPUs don't like single string operations
1541290286Sobrien;; Handle this case here to simplify previous expander.
1541390286Sobrien
15414132727Skan(define_expand "strmov"
15415132727Skan  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15416132727Skan   (set (match_operand 1 "memory_operand" "") (match_dup 4))
15417132727Skan   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
1541890286Sobrien	      (clobber (reg:CC 17))])
15419132727Skan   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
1542090286Sobrien	      (clobber (reg:CC 17))])]
1542190286Sobrien  ""
1542290286Sobrien{
15423132727Skan  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
1542450650Sobrien
15425132727Skan  /* If .md ever supports :P for Pmode, these can be directly
15426132727Skan     in the pattern above.  */
15427132727Skan  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15428132727Skan  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
1542950650Sobrien
1543090286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1543190286Sobrien    {
15432132727Skan      emit_insn (gen_strmov_singleop (operands[0], operands[1],
15433132727Skan				      operands[2], operands[3],
15434132727Skan				      operands[5], operands[6]));
1543590286Sobrien      DONE;
1543690286Sobrien    }
1543750650Sobrien
15438132727Skan  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
1543990286Sobrien})
1544050650Sobrien
15441132727Skan(define_expand "strmov_singleop"
15442132727Skan  [(parallel [(set (match_operand 1 "memory_operand" "")
15443132727Skan		   (match_operand 3 "memory_operand" ""))
15444132727Skan	      (set (match_operand 0 "register_operand" "")
15445132727Skan		   (match_operand 4 "" ""))
15446132727Skan	      (set (match_operand 2 "register_operand" "")
15447132727Skan		   (match_operand 5 "" ""))
15448132727Skan	      (use (reg:SI 19))])]
15449132727Skan  "TARGET_SINGLE_STRINGOP || optimize_size"
15450132727Skan  "")
1545118334Speter
15452132727Skan(define_insn "*strmovdi_rex_1"
1545390286Sobrien  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
1545490286Sobrien	(mem:DI (match_operand:DI 3 "register_operand" "1")))
1545590286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1545690286Sobrien	(plus:DI (match_dup 2)
1545790286Sobrien		 (const_int 8)))
1545890286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1545990286Sobrien	(plus:DI (match_dup 3)
1546090286Sobrien		 (const_int 8)))
1546190286Sobrien   (use (reg:SI 19))]
1546290286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1546390286Sobrien  "movsq"
1546490286Sobrien  [(set_attr "type" "str")
1546590286Sobrien   (set_attr "mode" "DI")
1546690286Sobrien   (set_attr "memory" "both")])
1546790286Sobrien
15468132727Skan(define_insn "*strmovsi_1"
1546990286Sobrien  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
1547090286Sobrien	(mem:SI (match_operand:SI 3 "register_operand" "1")))
1547190286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1547290286Sobrien	(plus:SI (match_dup 2)
1547390286Sobrien		 (const_int 4)))
1547490286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1547590286Sobrien	(plus:SI (match_dup 3)
1547690286Sobrien		 (const_int 4)))
1547790286Sobrien   (use (reg:SI 19))]
1547890286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1547990286Sobrien  "{movsl|movsd}"
1548090286Sobrien  [(set_attr "type" "str")
1548190286Sobrien   (set_attr "mode" "SI")
1548290286Sobrien   (set_attr "memory" "both")])
1548390286Sobrien
15484132727Skan(define_insn "*strmovsi_rex_1"
1548590286Sobrien  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
1548690286Sobrien	(mem:SI (match_operand:DI 3 "register_operand" "1")))
1548790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1548890286Sobrien	(plus:DI (match_dup 2)
1548990286Sobrien		 (const_int 4)))
1549090286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1549190286Sobrien	(plus:DI (match_dup 3)
1549290286Sobrien		 (const_int 4)))
1549390286Sobrien   (use (reg:SI 19))]
1549490286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1549590286Sobrien  "{movsl|movsd}"
1549690286Sobrien  [(set_attr "type" "str")
1549790286Sobrien   (set_attr "mode" "SI")
1549890286Sobrien   (set_attr "memory" "both")])
1549990286Sobrien
15500132727Skan(define_insn "*strmovhi_1"
1550190286Sobrien  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
1550290286Sobrien	(mem:HI (match_operand:SI 3 "register_operand" "1")))
1550390286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1550490286Sobrien	(plus:SI (match_dup 2)
1550590286Sobrien		 (const_int 2)))
1550690286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1550790286Sobrien	(plus:SI (match_dup 3)
1550890286Sobrien		 (const_int 2)))
1550990286Sobrien   (use (reg:SI 19))]
1551090286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1551190286Sobrien  "movsw"
1551290286Sobrien  [(set_attr "type" "str")
1551390286Sobrien   (set_attr "memory" "both")
1551490286Sobrien   (set_attr "mode" "HI")])
1551590286Sobrien
15516132727Skan(define_insn "*strmovhi_rex_1"
1551790286Sobrien  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
1551890286Sobrien	(mem:HI (match_operand:DI 3 "register_operand" "1")))
1551990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1552090286Sobrien	(plus:DI (match_dup 2)
1552190286Sobrien		 (const_int 2)))
1552290286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1552390286Sobrien	(plus:DI (match_dup 3)
1552490286Sobrien		 (const_int 2)))
1552590286Sobrien   (use (reg:SI 19))]
1552690286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1552790286Sobrien  "movsw"
1552890286Sobrien  [(set_attr "type" "str")
1552990286Sobrien   (set_attr "memory" "both")
1553090286Sobrien   (set_attr "mode" "HI")])
1553190286Sobrien
15532132727Skan(define_insn "*strmovqi_1"
1553390286Sobrien  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
1553490286Sobrien	(mem:QI (match_operand:SI 3 "register_operand" "1")))
1553590286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1553690286Sobrien	(plus:SI (match_dup 2)
1553790286Sobrien		 (const_int 1)))
1553890286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1553990286Sobrien	(plus:SI (match_dup 3)
1554090286Sobrien		 (const_int 1)))
1554190286Sobrien   (use (reg:SI 19))]
1554290286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1554390286Sobrien  "movsb"
1554490286Sobrien  [(set_attr "type" "str")
1554590286Sobrien   (set_attr "memory" "both")
1554690286Sobrien   (set_attr "mode" "QI")])
1554790286Sobrien
15548132727Skan(define_insn "*strmovqi_rex_1"
1554990286Sobrien  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
1555090286Sobrien	(mem:QI (match_operand:DI 3 "register_operand" "1")))
1555190286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1555290286Sobrien	(plus:DI (match_dup 2)
1555390286Sobrien		 (const_int 1)))
1555490286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1555590286Sobrien	(plus:DI (match_dup 3)
1555690286Sobrien		 (const_int 1)))
1555790286Sobrien   (use (reg:SI 19))]
1555890286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1555990286Sobrien  "movsb"
1556090286Sobrien  [(set_attr "type" "str")
1556190286Sobrien   (set_attr "memory" "both")
1556290286Sobrien   (set_attr "mode" "QI")])
1556390286Sobrien
15564132727Skan(define_expand "rep_mov"
15565132727Skan  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15566132727Skan	      (set (match_operand 0 "register_operand" "")
15567132727Skan		   (match_operand 5 "" ""))
15568132727Skan	      (set (match_operand 2 "register_operand" "")
15569132727Skan		   (match_operand 6 "" ""))
15570132727Skan	      (set (match_operand 1 "memory_operand" "")
15571132727Skan		   (match_operand 3 "memory_operand" ""))
15572132727Skan	      (use (match_dup 4))
15573132727Skan	      (use (reg:SI 19))])]
15574132727Skan  ""
15575132727Skan  "")
15576132727Skan
15577132727Skan(define_insn "*rep_movdi_rex64"
1557890286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1557990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1558090286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1558190286Sobrien			    (const_int 3))
1558290286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1558390286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1558490286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
1558590286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1558690286Sobrien   (set (mem:BLK (match_dup 3))
1558790286Sobrien	(mem:BLK (match_dup 4)))
1558890286Sobrien   (use (match_dup 5))
1558990286Sobrien   (use (reg:SI 19))]
1559090286Sobrien  "TARGET_64BIT"
1559190286Sobrien  "{rep\;movsq|rep movsq}"
1559290286Sobrien  [(set_attr "type" "str")
1559390286Sobrien   (set_attr "prefix_rep" "1")
1559490286Sobrien   (set_attr "memory" "both")
1559590286Sobrien   (set_attr "mode" "DI")])
1559690286Sobrien
15597132727Skan(define_insn "*rep_movsi"
1559890286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1559990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1560090286Sobrien        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
1560190286Sobrien			    (const_int 2))
1560290286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1560390286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1560490286Sobrien        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
1560590286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1560690286Sobrien   (set (mem:BLK (match_dup 3))
1560790286Sobrien	(mem:BLK (match_dup 4)))
1560890286Sobrien   (use (match_dup 5))
1560990286Sobrien   (use (reg:SI 19))]
1561090286Sobrien  "!TARGET_64BIT"
1561190286Sobrien  "{rep\;movsl|rep movsd}"
1561290286Sobrien  [(set_attr "type" "str")
1561390286Sobrien   (set_attr "prefix_rep" "1")
1561490286Sobrien   (set_attr "memory" "both")
1561590286Sobrien   (set_attr "mode" "SI")])
1561690286Sobrien
15617132727Skan(define_insn "*rep_movsi_rex64"
1561890286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1561990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1562090286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1562190286Sobrien			    (const_int 2))
1562290286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1562390286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1562490286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
1562590286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1562690286Sobrien   (set (mem:BLK (match_dup 3))
1562790286Sobrien	(mem:BLK (match_dup 4)))
1562890286Sobrien   (use (match_dup 5))
1562990286Sobrien   (use (reg:SI 19))]
1563090286Sobrien  "TARGET_64BIT"
1563190286Sobrien  "{rep\;movsl|rep movsd}"
1563290286Sobrien  [(set_attr "type" "str")
1563390286Sobrien   (set_attr "prefix_rep" "1")
1563490286Sobrien   (set_attr "memory" "both")
1563590286Sobrien   (set_attr "mode" "SI")])
1563690286Sobrien
15637132727Skan(define_insn "*rep_movqi"
1563890286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1563990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1564090286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1564190286Sobrien		 (match_operand:SI 5 "register_operand" "2")))
1564290286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1564390286Sobrien        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
1564490286Sobrien   (set (mem:BLK (match_dup 3))
1564590286Sobrien	(mem:BLK (match_dup 4)))
1564690286Sobrien   (use (match_dup 5))
1564790286Sobrien   (use (reg:SI 19))]
1564890286Sobrien  "!TARGET_64BIT"
1564990286Sobrien  "{rep\;movsb|rep movsb}"
1565090286Sobrien  [(set_attr "type" "str")
1565190286Sobrien   (set_attr "prefix_rep" "1")
1565290286Sobrien   (set_attr "memory" "both")
1565390286Sobrien   (set_attr "mode" "SI")])
1565490286Sobrien
15655132727Skan(define_insn "*rep_movqi_rex64"
1565690286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1565790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1565890286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1565990286Sobrien		 (match_operand:DI 5 "register_operand" "2")))
1566090286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1566190286Sobrien        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
1566290286Sobrien   (set (mem:BLK (match_dup 3))
1566390286Sobrien	(mem:BLK (match_dup 4)))
1566490286Sobrien   (use (match_dup 5))
1566590286Sobrien   (use (reg:SI 19))]
1566690286Sobrien  "TARGET_64BIT"
1566790286Sobrien  "{rep\;movsb|rep movsb}"
1566890286Sobrien  [(set_attr "type" "str")
1566990286Sobrien   (set_attr "prefix_rep" "1")
1567090286Sobrien   (set_attr "memory" "both")
1567190286Sobrien   (set_attr "mode" "SI")])
1567290286Sobrien
1567390286Sobrien(define_expand "clrstrsi"
1567490286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1567590286Sobrien    (use (match_operand:SI 1 "nonmemory_operand" ""))
1567690286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1567718334Speter  ""
1567818334Speter{
1567990286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1568090286Sobrien   DONE;
1568190286Sobrien else
1568290286Sobrien   FAIL;
1568390286Sobrien})
1568418334Speter
1568590286Sobrien(define_expand "clrstrdi"
1568690286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1568790286Sobrien    (use (match_operand:DI 1 "nonmemory_operand" ""))
1568890286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1568990286Sobrien  "TARGET_64BIT"
1569090286Sobrien{
1569190286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1569290286Sobrien   DONE;
1569390286Sobrien else
1569490286Sobrien   FAIL;
1569590286Sobrien})
1569650650Sobrien
1569790286Sobrien;; Most CPUs don't like single string operations
1569890286Sobrien;; Handle this case here to simplify previous expander.
1569950650Sobrien
15700132727Skan(define_expand "strset"
15701132727Skan  [(set (match_operand 1 "memory_operand" "")
15702132727Skan	(match_operand 2 "register_operand" ""))
15703132727Skan   (parallel [(set (match_operand 0 "register_operand" "")
15704132727Skan		   (match_dup 3))
1570590286Sobrien	      (clobber (reg:CC 17))])]
1570690286Sobrien  ""
1570790286Sobrien{
15708132727Skan  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15709132727Skan    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
1571090286Sobrien
15711132727Skan  /* If .md ever supports :P for Pmode, this can be directly
15712132727Skan     in the pattern above.  */
15713132727Skan  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15714132727Skan			      GEN_INT (GET_MODE_SIZE (GET_MODE
15715132727Skan						      (operands[2]))));
1571690286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1571790286Sobrien    {
15718132727Skan      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15719132727Skan				      operands[3]));
1572090286Sobrien      DONE;
1572190286Sobrien    }
1572290286Sobrien})
1572390286Sobrien
15724132727Skan(define_expand "strset_singleop"
15725132727Skan  [(parallel [(set (match_operand 1 "memory_operand" "")
15726132727Skan		   (match_operand 2 "register_operand" ""))
15727132727Skan	      (set (match_operand 0 "register_operand" "")
15728132727Skan		   (match_operand 3 "" ""))
15729132727Skan	      (use (reg:SI 19))])]
15730132727Skan  "TARGET_SINGLE_STRINGOP || optimize_size"
15731132727Skan  "")
1573290286Sobrien
15733132727Skan(define_insn "*strsetdi_rex_1"
1573490286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1573590286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1573690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1573790286Sobrien	(plus:DI (match_dup 1)
1573890286Sobrien		 (const_int 8)))
1573990286Sobrien   (use (reg:SI 19))]
1574090286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1574190286Sobrien  "stosq"
1574290286Sobrien  [(set_attr "type" "str")
1574390286Sobrien   (set_attr "memory" "store")
1574490286Sobrien   (set_attr "mode" "DI")])
1574590286Sobrien
15746132727Skan(define_insn "*strsetsi_1"
1574790286Sobrien  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
1574890286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1574990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1575090286Sobrien	(plus:SI (match_dup 1)
1575190286Sobrien		 (const_int 4)))
1575290286Sobrien   (use (reg:SI 19))]
1575390286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1575490286Sobrien  "{stosl|stosd}"
1575590286Sobrien  [(set_attr "type" "str")
1575690286Sobrien   (set_attr "memory" "store")
1575790286Sobrien   (set_attr "mode" "SI")])
1575890286Sobrien
15759132727Skan(define_insn "*strsetsi_rex_1"
1576090286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1576190286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1576290286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1576390286Sobrien	(plus:DI (match_dup 1)
1576490286Sobrien		 (const_int 4)))
1576590286Sobrien   (use (reg:SI 19))]
1576690286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1576790286Sobrien  "{stosl|stosd}"
1576890286Sobrien  [(set_attr "type" "str")
1576990286Sobrien   (set_attr "memory" "store")
1577090286Sobrien   (set_attr "mode" "SI")])
1577190286Sobrien
15772132727Skan(define_insn "*strsethi_1"
1577390286Sobrien  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
1577490286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1577590286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1577690286Sobrien	(plus:SI (match_dup 1)
1577790286Sobrien		 (const_int 2)))
1577890286Sobrien   (use (reg:SI 19))]
1577990286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1578090286Sobrien  "stosw"
1578190286Sobrien  [(set_attr "type" "str")
1578290286Sobrien   (set_attr "memory" "store")
1578390286Sobrien   (set_attr "mode" "HI")])
1578490286Sobrien
15785132727Skan(define_insn "*strsethi_rex_1"
1578690286Sobrien  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
1578790286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1578890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1578990286Sobrien	(plus:DI (match_dup 1)
1579090286Sobrien		 (const_int 2)))
1579190286Sobrien   (use (reg:SI 19))]
1579290286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1579390286Sobrien  "stosw"
1579490286Sobrien  [(set_attr "type" "str")
1579590286Sobrien   (set_attr "memory" "store")
1579690286Sobrien   (set_attr "mode" "HI")])
1579790286Sobrien
15798132727Skan(define_insn "*strsetqi_1"
1579990286Sobrien  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
1580090286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1580190286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1580290286Sobrien	(plus:SI (match_dup 1)
1580390286Sobrien		 (const_int 1)))
1580490286Sobrien   (use (reg:SI 19))]
1580590286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1580690286Sobrien  "stosb"
1580790286Sobrien  [(set_attr "type" "str")
1580890286Sobrien   (set_attr "memory" "store")
1580990286Sobrien   (set_attr "mode" "QI")])
1581090286Sobrien
15811132727Skan(define_insn "*strsetqi_rex_1"
1581290286Sobrien  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
1581390286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1581490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1581590286Sobrien	(plus:DI (match_dup 1)
1581690286Sobrien		 (const_int 1)))
1581790286Sobrien   (use (reg:SI 19))]
1581890286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1581990286Sobrien  "stosb"
1582090286Sobrien  [(set_attr "type" "str")
1582190286Sobrien   (set_attr "memory" "store")
1582290286Sobrien   (set_attr "mode" "QI")])
1582390286Sobrien
15824132727Skan(define_expand "rep_stos"
15825132727Skan  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15826132727Skan	      (set (match_operand 0 "register_operand" "")
15827132727Skan		   (match_operand 4 "" ""))
15828132727Skan	      (set (match_operand 2 "memory_operand" "") (const_int 0))
15829132727Skan	      (use (match_operand 3 "register_operand" ""))
15830132727Skan	      (use (match_dup 1))
15831132727Skan	      (use (reg:SI 19))])]
15832132727Skan  ""
15833132727Skan  "")
15834132727Skan
15835132727Skan(define_insn "*rep_stosdi_rex64"
1583690286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1583790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1583890286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1583990286Sobrien			    (const_int 3))
1584090286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1584190286Sobrien   (set (mem:BLK (match_dup 3))
1584290286Sobrien	(const_int 0))
1584390286Sobrien   (use (match_operand:DI 2 "register_operand" "a"))
1584490286Sobrien   (use (match_dup 4))
1584590286Sobrien   (use (reg:SI 19))]
1584690286Sobrien  "TARGET_64BIT"
1584790286Sobrien  "{rep\;stosq|rep stosq}"
1584890286Sobrien  [(set_attr "type" "str")
1584990286Sobrien   (set_attr "prefix_rep" "1")
1585090286Sobrien   (set_attr "memory" "store")
1585190286Sobrien   (set_attr "mode" "DI")])
1585290286Sobrien
15853132727Skan(define_insn "*rep_stossi"
1585490286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1585590286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1585690286Sobrien        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
1585790286Sobrien			    (const_int 2))
1585890286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1585990286Sobrien   (set (mem:BLK (match_dup 3))
1586090286Sobrien	(const_int 0))
1586190286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1586290286Sobrien   (use (match_dup 4))
1586390286Sobrien   (use (reg:SI 19))]
1586490286Sobrien  "!TARGET_64BIT"
1586590286Sobrien  "{rep\;stosl|rep stosd}"
1586690286Sobrien  [(set_attr "type" "str")
1586790286Sobrien   (set_attr "prefix_rep" "1")
1586890286Sobrien   (set_attr "memory" "store")
1586990286Sobrien   (set_attr "mode" "SI")])
1587090286Sobrien
15871132727Skan(define_insn "*rep_stossi_rex64"
1587290286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1587390286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1587490286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1587590286Sobrien			    (const_int 2))
1587690286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1587790286Sobrien   (set (mem:BLK (match_dup 3))
1587890286Sobrien	(const_int 0))
1587990286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1588090286Sobrien   (use (match_dup 4))
1588190286Sobrien   (use (reg:SI 19))]
1588290286Sobrien  "TARGET_64BIT"
1588390286Sobrien  "{rep\;stosl|rep stosd}"
1588490286Sobrien  [(set_attr "type" "str")
1588590286Sobrien   (set_attr "prefix_rep" "1")
1588690286Sobrien   (set_attr "memory" "store")
1588790286Sobrien   (set_attr "mode" "SI")])
1588890286Sobrien
15889132727Skan(define_insn "*rep_stosqi"
1589090286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1589190286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1589290286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1589390286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1589490286Sobrien   (set (mem:BLK (match_dup 3))
1589590286Sobrien	(const_int 0))
1589690286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1589790286Sobrien   (use (match_dup 4))
1589890286Sobrien   (use (reg:SI 19))]
1589990286Sobrien  "!TARGET_64BIT"
1590090286Sobrien  "{rep\;stosb|rep stosb}"
1590190286Sobrien  [(set_attr "type" "str")
1590290286Sobrien   (set_attr "prefix_rep" "1")
1590390286Sobrien   (set_attr "memory" "store")
1590490286Sobrien   (set_attr "mode" "QI")])
1590590286Sobrien
15906132727Skan(define_insn "*rep_stosqi_rex64"
1590790286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1590890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1590990286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1591090286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1591190286Sobrien   (set (mem:BLK (match_dup 3))
1591290286Sobrien	(const_int 0))
1591390286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1591490286Sobrien   (use (match_dup 4))
15915132727Skan   (use (reg:SI 19))]
1591690286Sobrien  "TARGET_64BIT"
1591790286Sobrien  "{rep\;stosb|rep stosb}"
1591890286Sobrien  [(set_attr "type" "str")
1591990286Sobrien   (set_attr "prefix_rep" "1")
1592090286Sobrien   (set_attr "memory" "store")
1592190286Sobrien   (set_attr "mode" "QI")])
1592290286Sobrien
1592390286Sobrien(define_expand "cmpstrsi"
1592450650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1592590286Sobrien	(compare:SI (match_operand:BLK 1 "general_operand" "")
1592690286Sobrien		    (match_operand:BLK 2 "general_operand" "")))
1592790286Sobrien   (use (match_operand 3 "general_operand" ""))
1592890286Sobrien   (use (match_operand 4 "immediate_operand" ""))]
15929132727Skan  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
1593050650Sobrien{
1593190286Sobrien  rtx addr1, addr2, out, outlow, count, countreg, align;
1593250650Sobrien
15933132727Skan  /* Can't use this if the user has appropriated esi or edi.  */
15934132727Skan  if (global_regs[4] || global_regs[5])
15935132727Skan    FAIL;
15936132727Skan
1593790286Sobrien  out = operands[0];
1593890286Sobrien  if (GET_CODE (out) != REG)
1593990286Sobrien    out = gen_reg_rtx (SImode);
1594050650Sobrien
1594190286Sobrien  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1594290286Sobrien  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15943132727Skan  if (addr1 != XEXP (operands[1], 0))
15944132727Skan    operands[1] = replace_equiv_address_nv (operands[1], addr1);
15945132727Skan  if (addr2 != XEXP (operands[2], 0))
15946132727Skan    operands[2] = replace_equiv_address_nv (operands[2], addr2);
15947132727Skan
1594890286Sobrien  count = operands[3];
1594990286Sobrien  countreg = ix86_zero_extend_to_Pmode (count);
1595050650Sobrien
1595190286Sobrien  /* %%% Iff we are testing strict equality, we can use known alignment
1595290286Sobrien     to good advantage.  This may be possible with combine, particularly
1595390286Sobrien     once cc0 is dead.  */
1595490286Sobrien  align = operands[4];
1595550650Sobrien
1595690286Sobrien  emit_insn (gen_cld ());
1595790286Sobrien  if (GET_CODE (count) == CONST_INT)
1595890286Sobrien    {
1595990286Sobrien      if (INTVAL (count) == 0)
1596090286Sobrien	{
1596190286Sobrien	  emit_move_insn (operands[0], const0_rtx);
1596290286Sobrien	  DONE;
1596390286Sobrien	}
15964132727Skan      emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15965132727Skan				    operands[1], operands[2]));
1596690286Sobrien    }
1596790286Sobrien  else
1596890286Sobrien    {
1596990286Sobrien      if (TARGET_64BIT)
15970132727Skan	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
1597190286Sobrien      else
15972132727Skan	emit_insn (gen_cmpsi_1 (countreg, countreg));
15973132727Skan      emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15974132727Skan				 operands[1], operands[2]));
1597590286Sobrien    }
1597690286Sobrien
1597790286Sobrien  outlow = gen_lowpart (QImode, out);
1597890286Sobrien  emit_insn (gen_cmpintqi (outlow));
1597990286Sobrien  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
1598090286Sobrien
1598190286Sobrien  if (operands[0] != out)
1598290286Sobrien    emit_move_insn (operands[0], out);
1598390286Sobrien
1598490286Sobrien  DONE;
1598590286Sobrien})
1598690286Sobrien
1598790286Sobrien;; Produce a tri-state integer (-1, 0, 1) from condition codes.
1598890286Sobrien
1598990286Sobrien(define_expand "cmpintqi"
1599090286Sobrien  [(set (match_dup 1)
1599190286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1599290286Sobrien   (set (match_dup 2)
1599390286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1599490286Sobrien   (parallel [(set (match_operand:QI 0 "register_operand" "")
1599590286Sobrien		   (minus:QI (match_dup 1)
1599690286Sobrien			     (match_dup 2)))
1599790286Sobrien	      (clobber (reg:CC 17))])]
1599890286Sobrien  ""
1599990286Sobrien  "operands[1] = gen_reg_rtx (QImode);
1600090286Sobrien   operands[2] = gen_reg_rtx (QImode);")
1600190286Sobrien
1600290286Sobrien;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
1600390286Sobrien;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
1600490286Sobrien
16005132727Skan(define_expand "cmpstrqi_nz_1"
16006132727Skan  [(parallel [(set (reg:CC 17)
16007132727Skan		   (compare:CC (match_operand 4 "memory_operand" "")
16008132727Skan			       (match_operand 5 "memory_operand" "")))
16009132727Skan	      (use (match_operand 2 "register_operand" ""))
16010132727Skan	      (use (match_operand:SI 3 "immediate_operand" ""))
16011132727Skan	      (use (reg:SI 19))
16012132727Skan	      (clobber (match_operand 0 "register_operand" ""))
16013132727Skan	      (clobber (match_operand 1 "register_operand" ""))
16014132727Skan	      (clobber (match_dup 2))])]
16015132727Skan  ""
16016132727Skan  "")
16017132727Skan
16018132727Skan(define_insn "*cmpstrqi_nz_1"
1601990286Sobrien  [(set (reg:CC 17)
1602090286Sobrien	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1602190286Sobrien		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
1602290286Sobrien   (use (match_operand:SI 6 "register_operand" "2"))
1602390286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1602490286Sobrien   (use (reg:SI 19))
1602590286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1602690286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1602790286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1602890286Sobrien  "!TARGET_64BIT"
1602990286Sobrien  "repz{\;| }cmpsb"
1603090286Sobrien  [(set_attr "type" "str")
1603190286Sobrien   (set_attr "mode" "QI")
1603290286Sobrien   (set_attr "prefix_rep" "1")])
1603390286Sobrien
16034132727Skan(define_insn "*cmpstrqi_nz_rex_1"
1603590286Sobrien  [(set (reg:CC 17)
1603690286Sobrien	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1603790286Sobrien		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
1603890286Sobrien   (use (match_operand:DI 6 "register_operand" "2"))
1603990286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1604090286Sobrien   (use (reg:SI 19))
1604190286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1604290286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1604390286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1604490286Sobrien  "TARGET_64BIT"
1604590286Sobrien  "repz{\;| }cmpsb"
1604690286Sobrien  [(set_attr "type" "str")
1604790286Sobrien   (set_attr "mode" "QI")
1604890286Sobrien   (set_attr "prefix_rep" "1")])
1604990286Sobrien
1605090286Sobrien;; The same, but the count is not known to not be zero.
1605190286Sobrien
16052132727Skan(define_expand "cmpstrqi_1"
16053132727Skan  [(parallel [(set (reg:CC 17)
16054132727Skan		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
16055132727Skan				     (const_int 0))
16056132727Skan		  (compare:CC (match_operand 4 "memory_operand" "")
16057132727Skan			      (match_operand 5 "memory_operand" ""))
16058132727Skan		  (const_int 0)))
16059132727Skan	      (use (match_operand:SI 3 "immediate_operand" ""))
16060132727Skan	      (use (reg:CC 17))
16061132727Skan	      (use (reg:SI 19))
16062132727Skan	      (clobber (match_operand 0 "register_operand" ""))
16063132727Skan	      (clobber (match_operand 1 "register_operand" ""))
16064132727Skan	      (clobber (match_dup 2))])]
16065132727Skan  ""
16066132727Skan  "")
16067132727Skan
16068132727Skan(define_insn "*cmpstrqi_1"
1606990286Sobrien  [(set (reg:CC 17)
1607090286Sobrien	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
1607190286Sobrien			     (const_int 0))
1607290286Sobrien	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1607390286Sobrien		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
1607490286Sobrien	  (const_int 0)))
1607590286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1607690286Sobrien   (use (reg:CC 17))
1607790286Sobrien   (use (reg:SI 19))
1607890286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1607990286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1608090286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1608190286Sobrien  "!TARGET_64BIT"
1608290286Sobrien  "repz{\;| }cmpsb"
1608390286Sobrien  [(set_attr "type" "str")
1608490286Sobrien   (set_attr "mode" "QI")
1608590286Sobrien   (set_attr "prefix_rep" "1")])
1608690286Sobrien
16087132727Skan(define_insn "*cmpstrqi_rex_1"
1608890286Sobrien  [(set (reg:CC 17)
1608990286Sobrien	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
1609090286Sobrien			     (const_int 0))
1609190286Sobrien	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1609290286Sobrien		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
1609390286Sobrien	  (const_int 0)))
1609490286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1609590286Sobrien   (use (reg:CC 17))
1609690286Sobrien   (use (reg:SI 19))
1609790286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1609890286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1609990286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1610090286Sobrien  "TARGET_64BIT"
1610190286Sobrien  "repz{\;| }cmpsb"
1610290286Sobrien  [(set_attr "type" "str")
1610390286Sobrien   (set_attr "mode" "QI")
1610490286Sobrien   (set_attr "prefix_rep" "1")])
1610590286Sobrien
1610690286Sobrien(define_expand "strlensi"
1610752296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1610890286Sobrien	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
1610990286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
16110117404Skan		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
1611190286Sobrien  ""
1611290286Sobrien{
1611390286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1611490286Sobrien   DONE;
1611590286Sobrien else
1611690286Sobrien   FAIL;
1611790286Sobrien})
1611890286Sobrien
1611990286Sobrien(define_expand "strlendi"
1612090286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1612190286Sobrien	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
1612290286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
16123117404Skan		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
1612490286Sobrien  ""
1612590286Sobrien{
1612690286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1612790286Sobrien   DONE;
1612890286Sobrien else
1612990286Sobrien   FAIL;
1613090286Sobrien})
1613190286Sobrien
16132132727Skan(define_expand "strlenqi_1"
16133132727Skan  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16134132727Skan	      (use (reg:SI 19))
16135132727Skan	      (clobber (match_operand 1 "register_operand" ""))
16136132727Skan	      (clobber (reg:CC 17))])]
16137132727Skan  ""
16138132727Skan  "")
16139132727Skan
16140132727Skan(define_insn "*strlenqi_1"
1614190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&c")
1614290286Sobrien	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
1614390286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1614490286Sobrien		    (match_operand:SI 3 "immediate_operand" "i")
16145117404Skan		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
1614690286Sobrien   (use (reg:SI 19))
1614790286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1614890286Sobrien   (clobber (reg:CC 17))]
1614990286Sobrien  "!TARGET_64BIT"
1615090286Sobrien  "repnz{\;| }scasb"
1615190286Sobrien  [(set_attr "type" "str")
1615290286Sobrien   (set_attr "mode" "QI")
1615390286Sobrien   (set_attr "prefix_rep" "1")])
1615490286Sobrien
16155132727Skan(define_insn "*strlenqi_rex_1"
1615690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&c")
1615790286Sobrien	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
1615890286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1615990286Sobrien		    (match_operand:DI 3 "immediate_operand" "i")
16160117404Skan		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
1616190286Sobrien   (use (reg:SI 19))
1616290286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1616390286Sobrien   (clobber (reg:CC 17))]
1616490286Sobrien  "TARGET_64BIT"
1616590286Sobrien  "repnz{\;| }scasb"
1616690286Sobrien  [(set_attr "type" "str")
1616790286Sobrien   (set_attr "mode" "QI")
1616890286Sobrien   (set_attr "prefix_rep" "1")])
1616990286Sobrien
1617090286Sobrien;; Peephole optimizations to clean up after cmpstr*.  This should be
1617190286Sobrien;; handled in combine, but it is not currently up to the task.
1617290286Sobrien;; When used for their truth value, the cmpstr* expanders generate
1617390286Sobrien;; code like this:
1617490286Sobrien;;
1617590286Sobrien;;   repz cmpsb
1617690286Sobrien;;   seta 	%al
1617790286Sobrien;;   setb 	%dl
1617890286Sobrien;;   cmpb 	%al, %dl
1617990286Sobrien;;   jcc	label
1618090286Sobrien;;
1618190286Sobrien;; The intermediate three instructions are unnecessary.
1618290286Sobrien
1618390286Sobrien;; This one handles cmpstr*_nz_1...
1618490286Sobrien(define_peephole2
1618590286Sobrien  [(parallel[
1618690286Sobrien     (set (reg:CC 17)
1618790286Sobrien	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1618890286Sobrien		      (mem:BLK (match_operand 5 "register_operand" ""))))
1618990286Sobrien     (use (match_operand 6 "register_operand" ""))
1619090286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1619190286Sobrien     (use (reg:SI 19))
1619290286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1619390286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1619490286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1619590286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1619690286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1619790286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1619890286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1619990286Sobrien   (set (reg 17)
1620090286Sobrien	(compare (match_dup 7) (match_dup 8)))
1620190286Sobrien  ]
1620290286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1620390286Sobrien  [(parallel[
1620490286Sobrien     (set (reg:CC 17)
1620590286Sobrien	  (compare:CC (mem:BLK (match_dup 4))
1620690286Sobrien		      (mem:BLK (match_dup 5))))
1620790286Sobrien     (use (match_dup 6))
1620890286Sobrien     (use (match_dup 3))
1620990286Sobrien     (use (reg:SI 19))
1621090286Sobrien     (clobber (match_dup 0))
1621190286Sobrien     (clobber (match_dup 1))
1621290286Sobrien     (clobber (match_dup 2))])]
1621350650Sobrien  "")
1621450650Sobrien
1621590286Sobrien;; ...and this one handles cmpstr*_1.
1621690286Sobrien(define_peephole2
1621790286Sobrien  [(parallel[
1621890286Sobrien     (set (reg:CC 17)
1621990286Sobrien	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
1622090286Sobrien			       (const_int 0))
1622190286Sobrien	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1622290286Sobrien		        (mem:BLK (match_operand 5 "register_operand" "")))
1622390286Sobrien	    (const_int 0)))
1622490286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1622590286Sobrien     (use (reg:CC 17))
1622690286Sobrien     (use (reg:SI 19))
1622790286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1622890286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1622990286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1623090286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1623190286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1623290286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1623390286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1623490286Sobrien   (set (reg 17)
1623590286Sobrien	(compare (match_dup 7) (match_dup 8)))
1623690286Sobrien  ]
1623790286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1623890286Sobrien  [(parallel[
1623990286Sobrien     (set (reg:CC 17)
1624090286Sobrien	  (if_then_else:CC (ne (match_dup 6)
1624190286Sobrien			       (const_int 0))
1624290286Sobrien	    (compare:CC (mem:BLK (match_dup 4))
1624390286Sobrien			(mem:BLK (match_dup 5)))
1624490286Sobrien	    (const_int 0)))
1624590286Sobrien     (use (match_dup 3))
1624690286Sobrien     (use (reg:CC 17))
1624790286Sobrien     (use (reg:SI 19))
1624890286Sobrien     (clobber (match_dup 0))
1624990286Sobrien     (clobber (match_dup 1))
1625090286Sobrien     (clobber (match_dup 2))])]
1625150650Sobrien  "")
1625250650Sobrien
1625390286Sobrien
1625490286Sobrien
1625590286Sobrien;; Conditional move instructions.
1625690286Sobrien
1625790286Sobrien(define_expand "movdicc"
1625890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1625990286Sobrien	(if_then_else:DI (match_operand 1 "comparison_operator" "")
1626090286Sobrien			 (match_operand:DI 2 "general_operand" "")
1626190286Sobrien			 (match_operand:DI 3 "general_operand" "")))]
1626290286Sobrien  "TARGET_64BIT"
1626390286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1626490286Sobrien
1626590286Sobrien(define_insn "x86_movdicc_0_m1_rex64"
1626690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
16267132727Skan	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
1626890286Sobrien	  (const_int -1)
1626990286Sobrien	  (const_int 0)))
1627090286Sobrien   (clobber (reg:CC 17))]
1627190286Sobrien  "TARGET_64BIT"
1627290286Sobrien  "sbb{q}\t%0, %0"
1627390286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1627490286Sobrien  ; fill in all the blanks.
1627590286Sobrien  [(set_attr "type" "alu")
16276117404Skan   (set_attr "pent_pair" "pu")
1627790286Sobrien   (set_attr "memory" "none")
1627890286Sobrien   (set_attr "imm_disp" "false")
1627990286Sobrien   (set_attr "mode" "DI")
1628090286Sobrien   (set_attr "length_immediate" "0")])
1628190286Sobrien
16282132727Skan(define_insn "movdicc_c_rex64"
1628390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1628490286Sobrien	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
1628590286Sobrien				[(reg 17) (const_int 0)])
1628690286Sobrien		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
1628790286Sobrien		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
1628890286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1628990286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1629090286Sobrien  "@
1629196294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1629296294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1629390286Sobrien  [(set_attr "type" "icmov")
1629490286Sobrien   (set_attr "mode" "DI")])
1629590286Sobrien
1629690286Sobrien(define_expand "movsicc"
1629790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1629890286Sobrien	(if_then_else:SI (match_operand 1 "comparison_operator" "")
1629990286Sobrien			 (match_operand:SI 2 "general_operand" "")
1630090286Sobrien			 (match_operand:SI 3 "general_operand" "")))]
1630190286Sobrien  ""
1630290286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1630390286Sobrien
1630490286Sobrien;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
1630590286Sobrien;; the register first winds up with `sbbl $0,reg', which is also weird.
1630690286Sobrien;; So just document what we're doing explicitly.
1630790286Sobrien
1630890286Sobrien(define_insn "x86_movsicc_0_m1"
1630990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
16310132727Skan	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
1631190286Sobrien	  (const_int -1)
1631290286Sobrien	  (const_int 0)))
1631390286Sobrien   (clobber (reg:CC 17))]
1631490286Sobrien  ""
1631590286Sobrien  "sbb{l}\t%0, %0"
1631690286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1631790286Sobrien  ; fill in all the blanks.
1631890286Sobrien  [(set_attr "type" "alu")
16319117404Skan   (set_attr "pent_pair" "pu")
1632090286Sobrien   (set_attr "memory" "none")
1632190286Sobrien   (set_attr "imm_disp" "false")
1632290286Sobrien   (set_attr "mode" "SI")
1632390286Sobrien   (set_attr "length_immediate" "0")])
1632490286Sobrien
1632590286Sobrien(define_insn "*movsicc_noc"
1632650650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1632790286Sobrien	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
1632890286Sobrien				[(reg 17) (const_int 0)])
1632950650Sobrien		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
1633050650Sobrien		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
1633190286Sobrien  "TARGET_CMOVE
1633290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1633390286Sobrien  "@
1633496294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1633596294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1633690286Sobrien  [(set_attr "type" "icmov")
1633790286Sobrien   (set_attr "mode" "SI")])
1633850650Sobrien
1633950650Sobrien(define_expand "movhicc"
1634050650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
1634150650Sobrien	(if_then_else:HI (match_operand 1 "comparison_operator" "")
16342132727Skan			 (match_operand:HI 2 "general_operand" "")
16343132727Skan			 (match_operand:HI 3 "general_operand" "")))]
16344132727Skan  "TARGET_HIMODE_MATH"
1634590286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1634650650Sobrien
1634790286Sobrien(define_insn "*movhicc_noc"
1634850650Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
1634990286Sobrien	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
1635090286Sobrien				[(reg 17) (const_int 0)])
1635150650Sobrien		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
1635250650Sobrien		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
1635390286Sobrien  "TARGET_CMOVE
1635490286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1635590286Sobrien  "@
1635696294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1635796294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1635890286Sobrien  [(set_attr "type" "icmov")
1635990286Sobrien   (set_attr "mode" "HI")])
1636050650Sobrien
16361132727Skan(define_expand "movqicc"
16362132727Skan  [(set (match_operand:QI 0 "register_operand" "")
16363132727Skan	(if_then_else:QI (match_operand 1 "comparison_operator" "")
16364132727Skan			 (match_operand:QI 2 "general_operand" "")
16365132727Skan			 (match_operand:QI 3 "general_operand" "")))]
16366132727Skan  "TARGET_QIMODE_MATH"
16367132727Skan  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16368132727Skan
16369132727Skan(define_insn_and_split "*movqicc_noc"
16370132727Skan  [(set (match_operand:QI 0 "register_operand" "=r,r")
16371132727Skan	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
16372132727Skan				[(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16373132727Skan		      (match_operand:QI 2 "register_operand" "r,0")
16374132727Skan		      (match_operand:QI 3 "register_operand" "0,r")))]
16375132727Skan  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16376132727Skan  "#"
16377132727Skan  "&& reload_completed"
16378132727Skan  [(set (match_dup 0)
16379132727Skan	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16380132727Skan		      (match_dup 2)
16381132727Skan		      (match_dup 3)))]
16382132727Skan  "operands[0] = gen_lowpart (SImode, operands[0]);
16383132727Skan   operands[2] = gen_lowpart (SImode, operands[2]);
16384132727Skan   operands[3] = gen_lowpart (SImode, operands[3]);"
16385132727Skan  [(set_attr "type" "icmov")
16386132727Skan   (set_attr "mode" "SI")])
16387132727Skan
1638850650Sobrien(define_expand "movsfcc"
1638950650Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1639050650Sobrien	(if_then_else:SF (match_operand 1 "comparison_operator" "")
1639150650Sobrien			 (match_operand:SF 2 "register_operand" "")
1639250650Sobrien			 (match_operand:SF 3 "register_operand" "")))]
1639350650Sobrien  "TARGET_CMOVE"
1639490286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1639550650Sobrien
1639690286Sobrien(define_insn "*movsfcc_1"
16397132727Skan  [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
1639890286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
1639990286Sobrien				[(reg 17) (const_int 0)])
16400132727Skan		      (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16401132727Skan		      (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
1640290286Sobrien  "TARGET_CMOVE
1640390286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1640490286Sobrien  "@
1640590286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1640690286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1640796294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1640896294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1640990286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1641090286Sobrien   (set_attr "mode" "SF,SF,SI,SI")])
1641150650Sobrien
1641290286Sobrien(define_expand "movdfcc"
1641390286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1641490286Sobrien	(if_then_else:DF (match_operand 1 "comparison_operator" "")
1641590286Sobrien			 (match_operand:DF 2 "register_operand" "")
1641690286Sobrien			 (match_operand:DF 3 "register_operand" "")))]
1641790286Sobrien  "TARGET_CMOVE"
1641890286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1641950650Sobrien
1642090286Sobrien(define_insn "*movdfcc_1"
16421132727Skan  [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
1642290286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1642390286Sobrien				[(reg 17) (const_int 0)])
16424132727Skan		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16425132727Skan		      (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
1642690286Sobrien  "!TARGET_64BIT && TARGET_CMOVE
1642790286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1642890286Sobrien  "@
1642990286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1643090286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1643190286Sobrien   #
1643290286Sobrien   #"
1643390286Sobrien  [(set_attr "type" "fcmov,fcmov,multi,multi")
1643490286Sobrien   (set_attr "mode" "DF")])
1643550650Sobrien
1643690286Sobrien(define_insn "*movdfcc_1_rex64"
16437132727Skan  [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
1643890286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1643990286Sobrien				[(reg 17) (const_int 0)])
16440132727Skan		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16441132727Skan		      (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
1644290286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1644390286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1644490286Sobrien  "@
1644590286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1644690286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1644796294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1644896294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1644990286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1645090286Sobrien   (set_attr "mode" "DF")])
1645150650Sobrien
1645290286Sobrien(define_split
16453117404Skan  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
1645490286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16455132727Skan				[(match_operand 4 "flags_reg_operand" "") (const_int 0)])
1645690286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "")
1645790286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "")))]
16458117404Skan  "!TARGET_64BIT && reload_completed"
1645990286Sobrien  [(set (match_dup 2)
1646090286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1646190286Sobrien		      (match_dup 5)
1646290286Sobrien		      (match_dup 7)))
1646390286Sobrien   (set (match_dup 3)
1646490286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1646590286Sobrien		      (match_dup 6)
1646690286Sobrien		      (match_dup 8)))]
1646790286Sobrien  "split_di (operands+2, 1, operands+5, operands+6);
1646890286Sobrien   split_di (operands+3, 1, operands+7, operands+8);
1646990286Sobrien   split_di (operands, 1, operands+2, operands+3);")
1647050650Sobrien
1647190286Sobrien(define_expand "movxfcc"
1647290286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1647390286Sobrien	(if_then_else:XF (match_operand 1 "comparison_operator" "")
1647490286Sobrien			 (match_operand:XF 2 "register_operand" "")
1647590286Sobrien			 (match_operand:XF 3 "register_operand" "")))]
1647690286Sobrien  "TARGET_CMOVE"
1647790286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1647890286Sobrien
1647990286Sobrien(define_insn "*movxfcc_1"
1648090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1648190286Sobrien	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
1648290286Sobrien				[(reg 17) (const_int 0)])
1648390286Sobrien		      (match_operand:XF 2 "register_operand" "f,0")
1648490286Sobrien		      (match_operand:XF 3 "register_operand" "0,f")))]
1648590286Sobrien  "TARGET_CMOVE"
1648690286Sobrien  "@
1648790286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1648890286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1648990286Sobrien  [(set_attr "type" "fcmov")
1649090286Sobrien   (set_attr "mode" "XF")])
1649190286Sobrien
1649290286Sobrien(define_expand "minsf3"
1649390286Sobrien  [(parallel [
1649490286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1649590286Sobrien	  (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1649690286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1649790286Sobrien			   (match_dup 1)
1649890286Sobrien			   (match_dup 2)))
1649990286Sobrien     (clobber (reg:CC 17))])]
1650090286Sobrien  "TARGET_SSE"
1650190286Sobrien  "")
1650290286Sobrien
1650390286Sobrien(define_insn "*minsf"
1650490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1650590286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
1650690286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1650790286Sobrien			 (match_dup 1)
1650890286Sobrien			 (match_dup 2)))
1650990286Sobrien   (clobber (reg:CC 17))]
1651090286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1651150650Sobrien  "#")
1651250650Sobrien
1651390286Sobrien(define_insn "*minsf_nonieee"
1651490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1651596294Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1651690286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1651790286Sobrien			 (match_dup 1)
1651890286Sobrien			 (match_dup 2)))
1651990286Sobrien   (clobber (reg:CC 17))]
1652096294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1652196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1652250650Sobrien  "#")
1652350650Sobrien
1652450650Sobrien(define_split
1652552296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1652690286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1652790286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1652890286Sobrien			 (match_operand:SF 3 "register_operand" "")
1652990286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1653090286Sobrien   (clobber (reg:CC 17))]
1653190286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1653290286Sobrien   && ((operands_match_p (operands[1], operands[3])
1653390286Sobrien	&& operands_match_p (operands[2], operands[4]))
1653490286Sobrien       || (operands_match_p (operands[1], operands[4])
1653590286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1653690286Sobrien  [(set (match_dup 0)
1653790286Sobrien	(if_then_else:SF (lt (match_dup 1)
1653890286Sobrien			     (match_dup 2))
1653990286Sobrien			 (match_dup 1)
1654090286Sobrien			 (match_dup 2)))])
1654150650Sobrien
16542132727Skan;; Conditional addition patterns
16543132727Skan(define_expand "addqicc"
16544132727Skan  [(match_operand:QI 0 "register_operand" "")
16545132727Skan   (match_operand 1 "comparison_operator" "")
16546132727Skan   (match_operand:QI 2 "register_operand" "")
16547132727Skan   (match_operand:QI 3 "const_int_operand" "")]
16548132727Skan  ""
16549132727Skan  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16550132727Skan
16551132727Skan(define_expand "addhicc"
16552132727Skan  [(match_operand:HI 0 "register_operand" "")
16553132727Skan   (match_operand 1 "comparison_operator" "")
16554132727Skan   (match_operand:HI 2 "register_operand" "")
16555132727Skan   (match_operand:HI 3 "const_int_operand" "")]
16556132727Skan  ""
16557132727Skan  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16558132727Skan
16559132727Skan(define_expand "addsicc"
16560132727Skan  [(match_operand:SI 0 "register_operand" "")
16561132727Skan   (match_operand 1 "comparison_operator" "")
16562132727Skan   (match_operand:SI 2 "register_operand" "")
16563132727Skan   (match_operand:SI 3 "const_int_operand" "")]
16564132727Skan  ""
16565132727Skan  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16566132727Skan
16567132727Skan(define_expand "adddicc"
16568132727Skan  [(match_operand:DI 0 "register_operand" "")
16569132727Skan   (match_operand 1 "comparison_operator" "")
16570132727Skan   (match_operand:DI 2 "register_operand" "")
16571132727Skan   (match_operand:DI 3 "const_int_operand" "")]
16572132727Skan  "TARGET_64BIT"
16573132727Skan  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16574132727Skan
1657590286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1657690286Sobrien
1657750650Sobrien(define_split
16578117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
1657990286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1658090286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1658190286Sobrien			 (match_operand:SF 3 "register_operand" "")
1658290286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1658390286Sobrien   (clobber (reg:CC 17))]
16584117404Skan  "reload_completed
1658590286Sobrien   && ((operands_match_p (operands[1], operands[3])
1658690286Sobrien	&& operands_match_p (operands[2], operands[4]))
1658790286Sobrien       || (operands_match_p (operands[1], operands[4])
1658890286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1658990286Sobrien  [(set (reg:CCFP 17)
1659090286Sobrien	(compare:CCFP (match_dup 2)
1659190286Sobrien		      (match_dup 1)))
1659250650Sobrien   (set (match_dup 0)
1659390286Sobrien	(if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
1659490286Sobrien			 (match_dup 1)
1659590286Sobrien			 (match_dup 2)))])
1659650650Sobrien
1659790286Sobrien(define_insn "*minsf_sse"
1659890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1659990286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
1660090286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1660190286Sobrien			 (match_dup 1)
1660290286Sobrien			 (match_dup 2)))]
1660390286Sobrien  "TARGET_SSE && reload_completed"
1660490286Sobrien  "minss\t{%2, %0|%0, %2}"
1660590286Sobrien  [(set_attr "type" "sse")
1660690286Sobrien   (set_attr "mode" "SF")])
1660750650Sobrien
1660890286Sobrien(define_expand "mindf3"
1660990286Sobrien  [(parallel [
1661090286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1661190286Sobrien	  (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1661290286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1661390286Sobrien			   (match_dup 1)
1661490286Sobrien			   (match_dup 2)))
1661590286Sobrien     (clobber (reg:CC 17))])]
1661690286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1661790286Sobrien  "#")
1661890286Sobrien
1661990286Sobrien(define_insn "*mindf"
1662090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1662190286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1662290286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1662390286Sobrien			 (match_dup 1)
1662490286Sobrien			 (match_dup 2)))
1662590286Sobrien   (clobber (reg:CC 17))]
1662690286Sobrien  "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
1662790286Sobrien  "#")
1662890286Sobrien
1662990286Sobrien(define_insn "*mindf_nonieee"
1663090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1663196294Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1663290286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1663390286Sobrien			 (match_dup 1)
1663490286Sobrien			 (match_dup 2)))
1663590286Sobrien   (clobber (reg:CC 17))]
1663696294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1663796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1663890286Sobrien  "#")
1663990286Sobrien
1664090286Sobrien(define_split
1664150650Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1664290286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1664390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1664490286Sobrien			 (match_operand:DF 3 "register_operand" "")
1664590286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1664690286Sobrien   (clobber (reg:CC 17))]
1664790286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1664890286Sobrien   && ((operands_match_p (operands[1], operands[3])
1664990286Sobrien	&& operands_match_p (operands[2], operands[4]))
1665090286Sobrien       || (operands_match_p (operands[1], operands[4])
1665190286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1665290286Sobrien  [(set (match_dup 0)
1665390286Sobrien	(if_then_else:DF (lt (match_dup 1)
1665490286Sobrien			     (match_dup 2))
1665590286Sobrien			 (match_dup 1)
1665690286Sobrien			 (match_dup 2)))])
1665750650Sobrien
1665890286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1665990286Sobrien(define_split
16660117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
1666190286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1666290286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1666390286Sobrien			 (match_operand:DF 3 "register_operand" "")
1666490286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1666590286Sobrien   (clobber (reg:CC 17))]
16666117404Skan  "reload_completed
1666790286Sobrien   && ((operands_match_p (operands[1], operands[3])
1666890286Sobrien	&& operands_match_p (operands[2], operands[4]))
1666990286Sobrien       || (operands_match_p (operands[1], operands[4])
1667090286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1667190286Sobrien  [(set (reg:CCFP 17)
1667290286Sobrien	(compare:CCFP (match_dup 2)
16673132727Skan		      (match_dup 1)))
1667490286Sobrien   (set (match_dup 0)
1667590286Sobrien	(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
1667690286Sobrien			 (match_dup 1)
1667790286Sobrien			 (match_dup 2)))])
1667850650Sobrien
1667990286Sobrien(define_insn "*mindf_sse"
1668090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1668190286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
1668290286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1668390286Sobrien			 (match_dup 1)
1668490286Sobrien			 (match_dup 2)))]
1668590286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1668690286Sobrien  "minsd\t{%2, %0|%0, %2}"
1668790286Sobrien  [(set_attr "type" "sse")
1668890286Sobrien   (set_attr "mode" "DF")])
1668950650Sobrien
1669090286Sobrien(define_expand "maxsf3"
1669190286Sobrien  [(parallel [
1669290286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1669390286Sobrien	  (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1669490286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1669590286Sobrien			   (match_dup 1)
1669690286Sobrien			   (match_dup 2)))
1669790286Sobrien     (clobber (reg:CC 17))])]
1669890286Sobrien  "TARGET_SSE"
1669990286Sobrien  "#")
1670050650Sobrien
1670190286Sobrien(define_insn "*maxsf"
1670290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1670390286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
1670490286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1670590286Sobrien			 (match_dup 1)
1670690286Sobrien			 (match_dup 2)))
1670790286Sobrien   (clobber (reg:CC 17))]
1670890286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1670990286Sobrien  "#")
1671050650Sobrien
1671190286Sobrien(define_insn "*maxsf_nonieee"
1671290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1671396294Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1671490286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1671590286Sobrien			 (match_dup 1)
1671690286Sobrien			 (match_dup 2)))
1671790286Sobrien   (clobber (reg:CC 17))]
1671896294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1671996294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1672090286Sobrien  "#")
1672150650Sobrien
1672290286Sobrien(define_split
1672390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1672490286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1672590286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1672690286Sobrien			 (match_operand:SF 3 "register_operand" "")
1672790286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1672890286Sobrien   (clobber (reg:CC 17))]
1672990286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1673090286Sobrien   && ((operands_match_p (operands[1], operands[3])
1673190286Sobrien	&& operands_match_p (operands[2], operands[4]))
1673290286Sobrien       || (operands_match_p (operands[1], operands[4])
1673390286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1673490286Sobrien  [(set (match_dup 0)
1673590286Sobrien	(if_then_else:SF (gt (match_dup 1)
1673690286Sobrien			     (match_dup 2))
1673790286Sobrien			 (match_dup 1)
1673890286Sobrien			 (match_dup 2)))])
1673950650Sobrien
1674090286Sobrien(define_split
16741117404Skan  [(set (match_operand:SF 0 "fp_register_operand" "")
1674290286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1674390286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1674490286Sobrien			 (match_operand:SF 3 "register_operand" "")
1674590286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1674690286Sobrien   (clobber (reg:CC 17))]
16747117404Skan  "reload_completed
1674890286Sobrien   && ((operands_match_p (operands[1], operands[3])
1674990286Sobrien	&& operands_match_p (operands[2], operands[4]))
1675090286Sobrien       || (operands_match_p (operands[1], operands[4])
1675190286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1675290286Sobrien  [(set (reg:CCFP 17)
1675390286Sobrien	(compare:CCFP (match_dup 1)
1675490286Sobrien		      (match_dup 2)))
1675590286Sobrien   (set (match_dup 0)
1675690286Sobrien	(if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
1675790286Sobrien			 (match_dup 1)
1675890286Sobrien			 (match_dup 2)))])
1675990286Sobrien
1676090286Sobrien(define_insn "*maxsf_sse"
1676190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1676290286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
1676390286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1676490286Sobrien			 (match_dup 1)
1676590286Sobrien			 (match_dup 2)))]
1676690286Sobrien  "TARGET_SSE && reload_completed"
1676790286Sobrien  "maxss\t{%2, %0|%0, %2}"
1676890286Sobrien  [(set_attr "type" "sse")
1676990286Sobrien   (set_attr "mode" "SF")])
1677090286Sobrien
1677190286Sobrien(define_expand "maxdf3"
1677290286Sobrien  [(parallel [
1677390286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1677490286Sobrien	  (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1677590286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1677690286Sobrien			   (match_dup 1)
1677790286Sobrien			   (match_dup 2)))
1677890286Sobrien     (clobber (reg:CC 17))])]
1677990286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1678050650Sobrien  "#")
1678150650Sobrien
1678290286Sobrien(define_insn "*maxdf"
1678390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1678490286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1678590286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1678690286Sobrien			 (match_dup 1)
1678790286Sobrien			 (match_dup 2)))
1678890286Sobrien   (clobber (reg:CC 17))]
1678990286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
1679050650Sobrien  "#")
1679150650Sobrien
1679290286Sobrien(define_insn "*maxdf_nonieee"
1679390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1679496294Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1679590286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1679690286Sobrien			 (match_dup 1)
1679790286Sobrien			 (match_dup 2)))
1679890286Sobrien   (clobber (reg:CC 17))]
1679996294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1680096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1680190286Sobrien  "#")
1680290286Sobrien
1680350650Sobrien(define_split
1680452296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1680590286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1680690286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1680790286Sobrien			 (match_operand:DF 3 "register_operand" "")
1680890286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1680990286Sobrien   (clobber (reg:CC 17))]
1681090286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1681190286Sobrien   && ((operands_match_p (operands[1], operands[3])
1681290286Sobrien	&& operands_match_p (operands[2], operands[4]))
1681390286Sobrien       || (operands_match_p (operands[1], operands[4])
1681490286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1681590286Sobrien  [(set (match_dup 0)
1681690286Sobrien	(if_then_else:DF (gt (match_dup 1)
1681790286Sobrien			     (match_dup 2))
1681890286Sobrien			 (match_dup 1)
1681990286Sobrien			 (match_dup 2)))])
1682050650Sobrien
1682150650Sobrien(define_split
16822117404Skan  [(set (match_operand:DF 0 "fp_register_operand" "")
1682390286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1682490286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1682590286Sobrien			 (match_operand:DF 3 "register_operand" "")
1682690286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1682790286Sobrien   (clobber (reg:CC 17))]
16828117404Skan  "reload_completed
1682990286Sobrien   && ((operands_match_p (operands[1], operands[3])
1683090286Sobrien	&& operands_match_p (operands[2], operands[4]))
1683190286Sobrien       || (operands_match_p (operands[1], operands[4])
1683290286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1683390286Sobrien  [(set (reg:CCFP 17)
1683490286Sobrien	(compare:CCFP (match_dup 1)
1683590286Sobrien		      (match_dup 2)))
1683650650Sobrien   (set (match_dup 0)
1683790286Sobrien	(if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
1683890286Sobrien			 (match_dup 1)
1683990286Sobrien			 (match_dup 2)))])
1684050650Sobrien
1684190286Sobrien(define_insn "*maxdf_sse"
1684290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1684390286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
1684490286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1684590286Sobrien			 (match_dup 1)
1684690286Sobrien			 (match_dup 2)))]
1684790286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1684890286Sobrien  "maxsd\t{%2, %0|%0, %2}"
1684990286Sobrien  [(set_attr "type" "sse")
1685090286Sobrien   (set_attr "mode" "DF")])
1685190286Sobrien
1685290286Sobrien;; Misc patterns (?)
1685350650Sobrien
1685490286Sobrien;; This pattern exists to put a dependency on all ebp-based memory accesses.
1685590286Sobrien;; Otherwise there will be nothing to keep
1685690286Sobrien;; 
1685790286Sobrien;; [(set (reg ebp) (reg esp))]
1685890286Sobrien;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
1685990286Sobrien;;  (clobber (eflags)]
1686090286Sobrien;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
1686190286Sobrien;;
1686290286Sobrien;; in proper program order.
16863132727Skan(define_insn "pro_epilogue_adjust_stack_1"
1686490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1686590286Sobrien	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
1686690286Sobrien	         (match_operand:SI 2 "immediate_operand" "i,i")))
1686790286Sobrien   (clobber (reg:CC 17))
1686890286Sobrien   (clobber (mem:BLK (scratch)))]
1686990286Sobrien  "!TARGET_64BIT"
1687090286Sobrien{
1687190286Sobrien  switch (get_attr_type (insn))
1687290286Sobrien    {
1687390286Sobrien    case TYPE_IMOV:
1687490286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
1687550650Sobrien
1687690286Sobrien    case TYPE_ALU:
1687790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1687890286Sobrien          && (INTVAL (operands[2]) == 128
1687990286Sobrien	      || (INTVAL (operands[2]) < 0
1688090286Sobrien	          && INTVAL (operands[2]) != -128)))
1688190286Sobrien	{
1688290286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1688390286Sobrien	  return "sub{l}\t{%2, %0|%0, %2}";
1688490286Sobrien	}
1688590286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
1688650650Sobrien
1688790286Sobrien    case TYPE_LEA:
1688890286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1688990286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
1689090286Sobrien
1689190286Sobrien    default:
1689290286Sobrien      abort ();
1689390286Sobrien    }
1689490286Sobrien}
1689590286Sobrien  [(set (attr "type")
1689690286Sobrien	(cond [(eq_attr "alternative" "0")
1689790286Sobrien		 (const_string "alu")
1689890286Sobrien	       (match_operand:SI 2 "const0_operand" "")
1689990286Sobrien		 (const_string "imov")
1690090286Sobrien	      ]
1690190286Sobrien	      (const_string "lea")))
1690290286Sobrien   (set_attr "mode" "SI")])
1690390286Sobrien
1690490286Sobrien(define_insn "pro_epilogue_adjust_stack_rex64"
1690590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1690690286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
1690790286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
1690890286Sobrien   (clobber (reg:CC 17))
1690990286Sobrien   (clobber (mem:BLK (scratch)))]
1691090286Sobrien  "TARGET_64BIT"
1691190286Sobrien{
1691290286Sobrien  switch (get_attr_type (insn))
1691350650Sobrien    {
1691490286Sobrien    case TYPE_IMOV:
1691590286Sobrien      return "mov{q}\t{%1, %0|%0, %1}";
1691650650Sobrien
1691790286Sobrien    case TYPE_ALU:
1691890286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
16919132727Skan	  /* Avoid overflows.  */
16920132727Skan	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
1692190286Sobrien          && (INTVAL (operands[2]) == 128
1692290286Sobrien	      || (INTVAL (operands[2]) < 0
1692390286Sobrien	          && INTVAL (operands[2]) != -128)))
1692490286Sobrien	{
1692590286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1692690286Sobrien	  return "sub{q}\t{%2, %0|%0, %2}";
1692790286Sobrien	}
1692890286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
1692950650Sobrien
1693090286Sobrien    case TYPE_LEA:
1693190286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1693290286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
1693350650Sobrien
1693450650Sobrien    default:
1693590286Sobrien      abort ();
1693650650Sobrien    }
1693790286Sobrien}
1693890286Sobrien  [(set (attr "type")
1693990286Sobrien	(cond [(eq_attr "alternative" "0")
1694090286Sobrien		 (const_string "alu")
1694190286Sobrien	       (match_operand:DI 2 "const0_operand" "")
1694290286Sobrien		 (const_string "imov")
1694390286Sobrien	      ]
1694490286Sobrien	      (const_string "lea")))
1694590286Sobrien   (set_attr "mode" "DI")])
1694650650Sobrien
16947132727Skan(define_insn "pro_epilogue_adjust_stack_rex64_2"
16948132727Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
16949132727Skan	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
16950132727Skan		 (match_operand:DI 3 "immediate_operand" "i,i")))
16951132727Skan   (use (match_operand:DI 2 "register_operand" "r,r"))
16952132727Skan   (clobber (reg:CC 17))
16953132727Skan   (clobber (mem:BLK (scratch)))]
16954132727Skan  "TARGET_64BIT"
16955132727Skan{
16956132727Skan  switch (get_attr_type (insn))
16957132727Skan    {
16958132727Skan    case TYPE_ALU:
16959132727Skan      return "add{q}\t{%2, %0|%0, %2}";
1696090286Sobrien
16961132727Skan    case TYPE_LEA:
16962132727Skan      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16963132727Skan      return "lea{q}\t{%a2, %0|%0, %a2}";
16964132727Skan
16965132727Skan    default:
16966132727Skan      abort ();
16967132727Skan    }
16968132727Skan}
16969132727Skan  [(set_attr "type" "alu,lea")
16970132727Skan   (set_attr "mode" "DI")])
16971132727Skan
1697290286Sobrien;; Placeholder for the conditional moves.  This one is split either to SSE
1697390286Sobrien;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
1697490286Sobrien;; fact is that compares supported by the cmp??ss instructions are exactly
1697590286Sobrien;; swapped of those supported by cmove sequence.
1697690286Sobrien;; The EQ/NE comparisons also needs bit care, since they are not directly
1697790286Sobrien;; supported by i387 comparisons and we do need to emit two conditional moves
1697890286Sobrien;; in tandem.
1697990286Sobrien
1698090286Sobrien(define_insn "sse_movsfcc"
1698190286Sobrien  [(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")
1698290286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1698390286Sobrien			[(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")
1698490286Sobrien			 (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")])
1698590286Sobrien		      (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")
1698690286Sobrien		      (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")))
1698790286Sobrien   (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1698890286Sobrien   (clobber (reg:CC 17))]
1698990286Sobrien  "TARGET_SSE
1699090286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16991132727Skan   /* Avoid combine from being smart and converting min/max
16992132727Skan      instruction patterns into conditional moves.  */
16993132727Skan   && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16994132727Skan	&& GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16995132727Skan       || !rtx_equal_p (operands[4], operands[2])
16996132727Skan       || !rtx_equal_p (operands[5], operands[3]))
1699790286Sobrien   && (!TARGET_IEEE_FP
1699890286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1699950650Sobrien  "#")
1700050650Sobrien
1700190286Sobrien(define_insn "sse_movsfcc_eq"
1700290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
1700390286Sobrien	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
1700490286Sobrien			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
1700590286Sobrien		      (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
1700690286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
1700790286Sobrien   (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
1700890286Sobrien   (clobber (reg:CC 17))]
1700990286Sobrien  "TARGET_SSE
1701090286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1701150650Sobrien  "#")
1701250650Sobrien
1701390286Sobrien(define_insn "sse_movdfcc"
17014102802Skan  [(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")
1701590286Sobrien	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17016102802Skan			[(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")
17017102802Skan			 (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")])
17018102802Skan		      (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")
17019102802Skan		      (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")))
1702090286Sobrien   (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1702190286Sobrien   (clobber (reg:CC 17))]
1702290286Sobrien  "TARGET_SSE2
1702390286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17024132727Skan   /* Avoid combine from being smart and converting min/max
17025132727Skan      instruction patterns into conditional moves.  */
17026132727Skan   && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17027132727Skan	&& GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17028132727Skan       || !rtx_equal_p (operands[4], operands[2])
17029132727Skan       || !rtx_equal_p (operands[5], operands[3]))
1703090286Sobrien   && (!TARGET_IEEE_FP
1703190286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1703290286Sobrien  "#")
1703390286Sobrien
1703490286Sobrien(define_insn "sse_movdfcc_eq"
17035102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17036102802Skan	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17037102802Skan			     (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17038102802Skan		      (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17039102802Skan		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
1704090286Sobrien   (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
1704190286Sobrien   (clobber (reg:CC 17))]
1704290286Sobrien  "TARGET_SSE
1704390286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1704490286Sobrien  "#")
1704590286Sobrien
1704690286Sobrien;; For non-sse moves just expand the usual cmove sequence.
1704750650Sobrien(define_split
1704890286Sobrien  [(set (match_operand 0 "register_operand" "")
1704990286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1705090286Sobrien			[(match_operand 4 "nonimmediate_operand" "")
1705190286Sobrien			 (match_operand 5 "register_operand" "")])
1705290286Sobrien		      (match_operand 2 "nonimmediate_operand" "")
1705390286Sobrien		      (match_operand 3 "nonimmediate_operand" "")))
1705490286Sobrien   (clobber (match_operand 6 "" ""))
1705590286Sobrien   (clobber (reg:CC 17))]
1705690286Sobrien  "!SSE_REG_P (operands[0]) && reload_completed
17057146906Skan   && (GET_MODE (operands[0]) == SFmode
17058146906Skan       || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
1705990286Sobrien  [(const_int 0)]
1706090286Sobrien{
1706190286Sobrien   ix86_compare_op0 = operands[5];
1706290286Sobrien   ix86_compare_op1 = operands[4];
1706390286Sobrien   operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
1706490286Sobrien				 VOIDmode, operands[5], operands[4]);
1706590286Sobrien   ix86_expand_fp_movcc (operands);
1706690286Sobrien   DONE;
1706790286Sobrien})
1706850650Sobrien
17069132727Skan;; Split SSE based conditional move into sequence:
1707090286Sobrien;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
1707190286Sobrien;; and   op2, op0   -  zero op2 if comparison was false
1707290286Sobrien;; nand  op0, op3   -  load op3 to op0 if comparison was false
17073117404Skan;; or	 op2, op0   -  get the nonzero one into the result.
1707450650Sobrien(define_split
17075146906Skan  [(set (match_operand:SF 0 "register_operand" "")
17076146906Skan	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
17077146906Skan			   [(match_operand:SF 4 "register_operand" "")
17078146906Skan			    (match_operand:SF 5 "nonimmediate_operand" "")])
17079146906Skan			 (match_operand:SF 2 "register_operand" "")
17080146906Skan			 (match_operand:SF 3 "register_operand" "")))
1708190286Sobrien   (clobber (match_operand 6 "" ""))
1708290286Sobrien   (clobber (reg:CC 17))]
1708390286Sobrien  "SSE_REG_P (operands[0]) && reload_completed"
1708490286Sobrien  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17085146906Skan   (set (match_dup 2) (and:V4SF (match_dup 2)
17086146906Skan			        (match_dup 8)))
17087146906Skan   (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17088146906Skan				          (match_dup 3)))
17089146906Skan   (set (match_dup 0) (ior:V4SF (match_dup 6)
17090146906Skan			        (match_dup 7)))]
1709190286Sobrien{
17092146906Skan  /* If op2 == op3, op3 would be clobbered before it is used.  */
17093146906Skan  if (operands_match_p (operands[2], operands[3]))
17094146906Skan    {
17095146906Skan      emit_move_insn (operands[0], operands[2]);
17096146906Skan      DONE;
17097146906Skan    }
17098146906Skan
17099146906Skan  PUT_MODE (operands[1], GET_MODE (operands[0]));
17100146906Skan  if (operands_match_p (operands[0], operands[4]))
17101146906Skan    operands[6] = operands[4], operands[7] = operands[2];
17102146906Skan  else
17103146906Skan    operands[6] = operands[2], operands[7] = operands[4];
17104146906Skan  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17105146906Skan  operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17106146906Skan  operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17107146906Skan  operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17108146906Skan  operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17109146906Skan  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17110146906Skan})
17111146906Skan
17112146906Skan(define_split
17113146906Skan  [(set (match_operand:DF 0 "register_operand" "")
17114146906Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17115146906Skan			   [(match_operand:DF 4 "register_operand" "")
17116146906Skan			    (match_operand:DF 5 "nonimmediate_operand" "")])
17117146906Skan			 (match_operand:DF 2 "register_operand" "")
17118146906Skan			 (match_operand:DF 3 "register_operand" "")))
17119146906Skan   (clobber (match_operand 6 "" ""))
17120146906Skan   (clobber (reg:CC 17))]
17121146906Skan  "SSE_REG_P (operands[0]) && reload_completed"
17122146906Skan  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17123146906Skan   (set (match_dup 2) (and:V2DF (match_dup 2)
17124146906Skan			        (match_dup 8)))
17125146906Skan   (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17126146906Skan				          (match_dup 3)))
17127146906Skan   (set (match_dup 0) (ior:V2DF (match_dup 6)
17128146906Skan			        (match_dup 7)))]
17129146906Skan{
17130132727Skan  if (GET_MODE (operands[2]) == DFmode
17131132727Skan      && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17132132727Skan    {
17133132727Skan      rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17134132727Skan      emit_insn (gen_sse2_unpcklpd (op, op, op));
17135132727Skan      op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17136132727Skan      emit_insn (gen_sse2_unpcklpd (op, op, op));
17137132727Skan    }
17138132727Skan
17139132727Skan  /* If op2 == op3, op3 would be clobbered before it is used.  */
17140102802Skan  if (operands_match_p (operands[2], operands[3]))
17141132727Skan    {
17142132727Skan      emit_move_insn (operands[0], operands[2]);
17143132727Skan      DONE;
17144132727Skan    }
17145132727Skan
1714690286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1714790286Sobrien  if (operands_match_p (operands[0], operands[4]))
1714890286Sobrien    operands[6] = operands[4], operands[7] = operands[2];
1714990286Sobrien  else
1715090286Sobrien    operands[6] = operands[2], operands[7] = operands[4];
17151146906Skan  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17152146906Skan  operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17153146906Skan  operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17154146906Skan  operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17155146906Skan  operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17156146906Skan  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
1715790286Sobrien})
1715850650Sobrien
17159132727Skan;; Special case of conditional move we can handle effectively.
1716090286Sobrien;; Do not brother with the integer/floating point case, since these are
1716190286Sobrien;; bot considerably slower, unlike in the generic case.
1716290286Sobrien(define_insn "*sse_movsfcc_const0_1"
17163102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1716490286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1716590286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1716690286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1716790286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1716890286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1716990286Sobrien  "TARGET_SSE"
1717090286Sobrien  "#")
1717150650Sobrien
1717290286Sobrien(define_insn "*sse_movsfcc_const0_2"
17173102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1717490286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1717590286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1717690286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1717790286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1717890286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1717990286Sobrien  "TARGET_SSE"
1718090286Sobrien  "#")
1718150650Sobrien
1718290286Sobrien(define_insn "*sse_movsfcc_const0_3"
17183102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1718490286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1718590286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1718690286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1718790286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1718890286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1718990286Sobrien  "TARGET_SSE"
1719090286Sobrien  "#")
1719150650Sobrien
1719290286Sobrien(define_insn "*sse_movsfcc_const0_4"
17193102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1719490286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1719590286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1719690286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1719790286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1719890286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1719990286Sobrien  "TARGET_SSE"
1720050650Sobrien  "#")
1720150650Sobrien
1720290286Sobrien(define_insn "*sse_movdfcc_const0_1"
17203102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
17204102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17205102802Skan			[(match_operand:DF 4 "register_operand" "0")
17206102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17207102802Skan		      (match_operand:DF 2 "register_operand" "Y")
17208102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1720990286Sobrien  "TARGET_SSE2"
1721050650Sobrien  "#")
1721150650Sobrien
1721290286Sobrien(define_insn "*sse_movdfcc_const0_2"
17213102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
17214102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17215102802Skan			[(match_operand:DF 4 "register_operand" "0")
17216102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17217102802Skan		      (match_operand:DF 2 "const0_operand" "X")
17218102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1721990286Sobrien  "TARGET_SSE2"
1722090286Sobrien  "#")
1722150650Sobrien
1722290286Sobrien(define_insn "*sse_movdfcc_const0_3"
17223102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
17224102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17225102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
17226102802Skan			 (match_operand:DF 5 "register_operand" "0")])
17227102802Skan		      (match_operand:DF 2 "register_operand" "Y")
17228102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1722990286Sobrien  "TARGET_SSE2"
1723090286Sobrien  "#")
1723150650Sobrien
1723290286Sobrien(define_insn "*sse_movdfcc_const0_4"
17233102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
17234102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17235102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
17236102802Skan			 (match_operand:DF 5 "register_operand" "0")])
17237102802Skan		      (match_operand:DF 2 "const0_operand" "X")
17238102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1723990286Sobrien  "TARGET_SSE2"
1724090286Sobrien  "#")
1724150650Sobrien
1724290286Sobrien(define_split
17243146906Skan  [(set (match_operand:SF 0 "register_operand" "")
17244146906Skan	(if_then_else:SF (match_operator 1 "comparison_operator"
17245146906Skan			   [(match_operand:SF 4 "nonimmediate_operand" "")
17246146906Skan			    (match_operand:SF 5 "nonimmediate_operand" "")])
17247146906Skan			 (match_operand:SF 2 "nonmemory_operand" "")
17248146906Skan			 (match_operand:SF 3 "nonmemory_operand" "")))]
1724990286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1725090286Sobrien   && (const0_operand (operands[2], GET_MODE (operands[0]))
1725190286Sobrien       || const0_operand (operands[3], GET_MODE (operands[0])))"
1725290286Sobrien  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17253146906Skan   (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
1725490286Sobrien{
17255146906Skan  PUT_MODE (operands[1], GET_MODE (operands[0]));
17256146906Skan  if (!sse_comparison_operator (operands[1], VOIDmode)
17257146906Skan      || !rtx_equal_p (operands[0], operands[4]))
17258146906Skan    {
17259146906Skan      rtx tmp = operands[5];
17260146906Skan      operands[5] = operands[4];
17261146906Skan      operands[4] = tmp;
17262146906Skan      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17263146906Skan    }
17264146906Skan  if (!rtx_equal_p (operands[0], operands[4]))
17265146906Skan    abort ();
17266146906Skan  operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17267146906Skan  if (const0_operand (operands[2], GET_MODE (operands[2])))
17268146906Skan    {
17269146906Skan      operands[7] = operands[3];
17270146906Skan      operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17271146906Skan    }
17272146906Skan  else
17273146906Skan    {
17274146906Skan      operands[7] = operands[2];
17275146906Skan      operands[6] = operands[8];
17276146906Skan    }
17277146906Skan  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17278146906Skan})
17279146906Skan
17280146906Skan(define_split
17281146906Skan  [(set (match_operand:DF 0 "register_operand" "")
17282146906Skan	(if_then_else:DF (match_operator 1 "comparison_operator"
17283146906Skan			   [(match_operand:DF 4 "nonimmediate_operand" "")
17284146906Skan			    (match_operand:DF 5 "nonimmediate_operand" "")])
17285146906Skan			 (match_operand:DF 2 "nonmemory_operand" "")
17286146906Skan			 (match_operand:DF 3 "nonmemory_operand" "")))]
17287146906Skan  "SSE_REG_P (operands[0]) && reload_completed
17288146906Skan   && (const0_operand (operands[2], GET_MODE (operands[0]))
17289146906Skan       || const0_operand (operands[3], GET_MODE (operands[0])))"
17290146906Skan  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17291146906Skan   (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17292146906Skan{
17293132727Skan  if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17294132727Skan      && GET_MODE (operands[2]) == DFmode)
17295132727Skan    {
17296132727Skan      if (REG_P (operands[2]))
17297132727Skan	{
17298132727Skan	  rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17299132727Skan	  emit_insn (gen_sse2_unpcklpd (op, op, op));
17300132727Skan	}
17301132727Skan      if (REG_P (operands[3]))
17302132727Skan	{
17303132727Skan	  rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17304132727Skan	  emit_insn (gen_sse2_unpcklpd (op, op, op));
17305132727Skan	}
17306132727Skan    }
1730790286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
17308117404Skan  if (!sse_comparison_operator (operands[1], VOIDmode)
17309117404Skan      || !rtx_equal_p (operands[0], operands[4]))
1731090286Sobrien    {
1731190286Sobrien      rtx tmp = operands[5];
1731290286Sobrien      operands[5] = operands[4];
1731390286Sobrien      operands[4] = tmp;
1731490286Sobrien      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
1731590286Sobrien    }
17316117404Skan  if (!rtx_equal_p (operands[0], operands[4]))
17317117404Skan    abort ();
17318146906Skan  operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17319146906Skan  if (const0_operand (operands[2], GET_MODE (operands[2])))
1732090286Sobrien    {
1732190286Sobrien      operands[7] = operands[3];
17322146906Skan      operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
1732390286Sobrien    }
1732490286Sobrien  else
1732590286Sobrien    {
1732690286Sobrien      operands[7] = operands[2];
17327146906Skan      operands[6] = operands[8];
1732890286Sobrien    }
17329146906Skan  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
1733090286Sobrien})
1733150650Sobrien
1733290286Sobrien(define_expand "allocate_stack_worker"
1733390286Sobrien  [(match_operand:SI 0 "register_operand" "")]
1733490286Sobrien  "TARGET_STACK_PROBE"
1733590286Sobrien{
17336132727Skan  if (reload_completed)
17337132727Skan    {
17338132727Skan      if (TARGET_64BIT)
17339132727Skan	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17340132727Skan      else
17341132727Skan	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17342132727Skan    }
1734390286Sobrien  else
17344132727Skan    {
17345132727Skan      if (TARGET_64BIT)
17346132727Skan	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17347132727Skan      else
17348132727Skan	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17349132727Skan    }
1735090286Sobrien  DONE;
1735190286Sobrien})
1735250650Sobrien
1735390286Sobrien(define_insn "allocate_stack_worker_1"
17354132727Skan  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17355132727Skan    UNSPECV_STACK_PROBE)
1735650650Sobrien   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17357132727Skan   (clobber (match_scratch:SI 1 "=0"))
1735890286Sobrien   (clobber (reg:CC 17))]
1735990286Sobrien  "!TARGET_64BIT && TARGET_STACK_PROBE"
1736090286Sobrien  "call\t__alloca"
1736190286Sobrien  [(set_attr "type" "multi")
1736290286Sobrien   (set_attr "length" "5")])
1736350650Sobrien
17364132727Skan(define_expand "allocate_stack_worker_postreload"
17365132727Skan  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17366132727Skan				    UNSPECV_STACK_PROBE)
17367132727Skan	      (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17368132727Skan	      (clobber (match_dup 0))
17369132727Skan	      (clobber (reg:CC 17))])]
17370132727Skan  ""
17371132727Skan  "")
17372132727Skan
1737390286Sobrien(define_insn "allocate_stack_worker_rex64"
17374132727Skan  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17375132727Skan    UNSPECV_STACK_PROBE)
1737690286Sobrien   (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17377132727Skan   (clobber (match_scratch:DI 1 "=0"))
1737890286Sobrien   (clobber (reg:CC 17))]
1737990286Sobrien  "TARGET_64BIT && TARGET_STACK_PROBE"
1738090286Sobrien  "call\t__alloca"
1738190286Sobrien  [(set_attr "type" "multi")
1738290286Sobrien   (set_attr "length" "5")])
1738390286Sobrien
17384132727Skan(define_expand "allocate_stack_worker_rex64_postreload"
17385132727Skan  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17386132727Skan				    UNSPECV_STACK_PROBE)
17387132727Skan	      (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17388132727Skan	      (clobber (match_dup 0))
17389132727Skan	      (clobber (reg:CC 17))])]
17390132727Skan  ""
17391132727Skan  "")
17392132727Skan
1739350650Sobrien(define_expand "allocate_stack"
1739490286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
1739590286Sobrien		   (minus:SI (reg:SI 7)
1739690286Sobrien			     (match_operand:SI 1 "general_operand" "")))
1739790286Sobrien	      (clobber (reg:CC 17))])
1739890286Sobrien   (parallel [(set (reg:SI 7)
1739990286Sobrien		   (minus:SI (reg:SI 7) (match_dup 1)))
1740090286Sobrien	      (clobber (reg:CC 17))])]
1740190286Sobrien  "TARGET_STACK_PROBE"
1740250650Sobrien{
1740350650Sobrien#ifdef CHECK_STACK_LIMIT
1740450650Sobrien  if (GET_CODE (operands[1]) == CONST_INT
1740550650Sobrien      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
1740650650Sobrien    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
1740750650Sobrien			   operands[1]));
1740850650Sobrien  else 
1740950650Sobrien#endif
1741050650Sobrien    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
1741150650Sobrien							    operands[1])));
1741250650Sobrien
1741350650Sobrien  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
1741450650Sobrien  DONE;
1741590286Sobrien})
1741650650Sobrien
1741790286Sobrien(define_expand "builtin_setjmp_receiver"
1741890286Sobrien  [(label_ref (match_operand 0 "" ""))]
1741990286Sobrien  "!TARGET_64BIT && flag_pic"
1742050650Sobrien{
17421117404Skan  emit_insn (gen_set_got (pic_offset_table_rtx));
1742256391Sobrien  DONE;
1742390286Sobrien})
1742490286Sobrien
1742590286Sobrien;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
1742656391Sobrien
1742790286Sobrien(define_split
1742890286Sobrien  [(set (match_operand 0 "register_operand" "")
1742990286Sobrien	(match_operator 3 "promotable_binary_operator"
1743090286Sobrien	   [(match_operand 1 "register_operand" "")
1743190286Sobrien	    (match_operand 2 "aligned_operand" "")]))
1743290286Sobrien   (clobber (reg:CC 17))]
1743390286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1743490286Sobrien   && ((GET_MODE (operands[0]) == HImode 
17435117404Skan	&& ((!optimize_size && !TARGET_FAST_PREFIX)
17436117404Skan	    || GET_CODE (operands[2]) != CONST_INT
1743790286Sobrien	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
1743890286Sobrien       || (GET_MODE (operands[0]) == QImode 
1743990286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1744090286Sobrien  [(parallel [(set (match_dup 0)
1744190286Sobrien		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1744290286Sobrien	      (clobber (reg:CC 17))])]
1744390286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1744490286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);
1744590286Sobrien   if (GET_CODE (operands[3]) != ASHIFT)
1744690286Sobrien     operands[2] = gen_lowpart (SImode, operands[2]);
1744790286Sobrien   PUT_MODE (operands[3], SImode);")
1744890286Sobrien
17449117404Skan; Promote the QImode tests, as i386 has encoding of the AND
17450117404Skan; instruction with 32-bit sign-extended immediate and thus the
17451117404Skan; instruction size is unchanged, except in the %eax case for
17452117404Skan; which it is increased by one byte, hence the ! optimize_size.
1745390286Sobrien(define_split
17454146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
17455146906Skan	(match_operator 2 "compare_operator"
17456146906Skan	  [(and (match_operand 3 "aligned_operand" "")
17457146906Skan		(match_operand 4 "const_int_operand" ""))
17458146906Skan	   (const_int 0)]))
17459146906Skan   (set (match_operand 1 "register_operand" "")
17460146906Skan	(and (match_dup 3) (match_dup 4)))]
1746190286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
17462117404Skan   /* Ensure that the operand will remain sign-extended immediate.  */
17463146906Skan   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
17464117404Skan   && ! optimize_size
17465146906Skan   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17466146906Skan       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
17467146906Skan  [(parallel [(set (match_dup 0)
17468146906Skan		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17469146906Skan			            (const_int 0)]))
17470146906Skan	      (set (match_dup 1)
17471146906Skan		   (and:SI (match_dup 3) (match_dup 4)))])]
17472146906Skan{
17473146906Skan  operands[4]
17474146906Skan    = gen_int_mode (INTVAL (operands[4])
17475146906Skan		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17476146906Skan  operands[1] = gen_lowpart (SImode, operands[1]);
17477146906Skan  operands[3] = gen_lowpart (SImode, operands[3]);
17478146906Skan})
1747990286Sobrien
17480117404Skan; Don't promote the QImode tests, as i386 doesn't have encoding of
17481117404Skan; the TEST instruction with 32-bit sign-extended immediate and thus
17482117404Skan; the instruction size would at least double, which is not what we
17483117404Skan; want even with ! optimize_size.
1748490286Sobrien(define_split
17485146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
17486146906Skan	(match_operator 1 "compare_operator"
17487146906Skan	  [(and (match_operand:HI 2 "aligned_operand" "")
17488146906Skan		(match_operand:HI 3 "const_int_operand" ""))
17489146906Skan	   (const_int 0)]))]
1749090286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
17491117404Skan   /* Ensure that the operand will remain sign-extended immediate.  */
17492146906Skan   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
17493117404Skan   && ! TARGET_FAST_PREFIX
17494117404Skan   && ! optimize_size"
17495146906Skan  [(set (match_dup 0)
17496146906Skan	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17497146906Skan		         (const_int 0)]))]
17498146906Skan{
17499146906Skan  operands[3]
17500146906Skan    = gen_int_mode (INTVAL (operands[3])
17501146906Skan		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17502146906Skan  operands[2] = gen_lowpart (SImode, operands[2]);
17503146906Skan})
1750490286Sobrien
1750590286Sobrien(define_split
1750690286Sobrien  [(set (match_operand 0 "register_operand" "")
1750790286Sobrien	(neg (match_operand 1 "register_operand" "")))
1750890286Sobrien   (clobber (reg:CC 17))]
1750990286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1751090286Sobrien   && (GET_MODE (operands[0]) == HImode
1751190286Sobrien       || (GET_MODE (operands[0]) == QImode 
1751290286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1751390286Sobrien  [(parallel [(set (match_dup 0)
1751490286Sobrien		   (neg:SI (match_dup 1)))
1751590286Sobrien	      (clobber (reg:CC 17))])]
1751690286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1751790286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1751890286Sobrien
1751990286Sobrien(define_split
1752090286Sobrien  [(set (match_operand 0 "register_operand" "")
1752190286Sobrien	(not (match_operand 1 "register_operand" "")))]
1752290286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1752390286Sobrien   && (GET_MODE (operands[0]) == HImode
1752490286Sobrien       || (GET_MODE (operands[0]) == QImode 
1752590286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1752690286Sobrien  [(set (match_dup 0)
1752790286Sobrien	(not:SI (match_dup 1)))]
1752890286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1752990286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1753090286Sobrien
1753190286Sobrien(define_split 
1753290286Sobrien  [(set (match_operand 0 "register_operand" "")
1753390286Sobrien	(if_then_else (match_operator 1 "comparison_operator" 
1753490286Sobrien				[(reg 17) (const_int 0)])
1753590286Sobrien		      (match_operand 2 "register_operand" "")
1753690286Sobrien		      (match_operand 3 "register_operand" "")))]
1753790286Sobrien  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
1753890286Sobrien   && (GET_MODE (operands[0]) == HImode
1753990286Sobrien       || (GET_MODE (operands[0]) == QImode 
1754090286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1754190286Sobrien  [(set (match_dup 0)
1754290286Sobrien	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
1754390286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1754490286Sobrien   operands[2] = gen_lowpart (SImode, operands[2]);
1754590286Sobrien   operands[3] = gen_lowpart (SImode, operands[3]);")
1754690286Sobrien			
1754790286Sobrien
1754890286Sobrien;; RTL Peephole optimizations, run before sched2.  These primarily look to
1754990286Sobrien;; transform a complex memory operation into two memory to register operations.
1755090286Sobrien
1755190286Sobrien;; Don't push memory operands
1755290286Sobrien(define_peephole2
1755390286Sobrien  [(set (match_operand:SI 0 "push_operand" "")
1755490286Sobrien	(match_operand:SI 1 "memory_operand" ""))
1755590286Sobrien   (match_scratch:SI 2 "r")]
1755690286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1755790286Sobrien  [(set (match_dup 2) (match_dup 1))
1755890286Sobrien   (set (match_dup 0) (match_dup 2))]
1755990286Sobrien  "")
1756090286Sobrien
1756190286Sobrien(define_peephole2
1756290286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
1756390286Sobrien	(match_operand:DI 1 "memory_operand" ""))
1756490286Sobrien   (match_scratch:DI 2 "r")]
1756590286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1756690286Sobrien  [(set (match_dup 2) (match_dup 1))
1756790286Sobrien   (set (match_dup 0) (match_dup 2))]
1756890286Sobrien  "")
1756990286Sobrien
1757090286Sobrien;; We need to handle SFmode only, because DFmode and XFmode is split to
1757190286Sobrien;; SImode pushes.
1757290286Sobrien(define_peephole2
1757390286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
1757490286Sobrien	(match_operand:SF 1 "memory_operand" ""))
1757590286Sobrien   (match_scratch:SF 2 "r")]
1757690286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1757790286Sobrien  [(set (match_dup 2) (match_dup 1))
1757890286Sobrien   (set (match_dup 0) (match_dup 2))]
1757990286Sobrien  "")
1758090286Sobrien
1758190286Sobrien(define_peephole2
1758290286Sobrien  [(set (match_operand:HI 0 "push_operand" "")
1758390286Sobrien	(match_operand:HI 1 "memory_operand" ""))
1758490286Sobrien   (match_scratch:HI 2 "r")]
1758590286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1758690286Sobrien  [(set (match_dup 2) (match_dup 1))
1758790286Sobrien   (set (match_dup 0) (match_dup 2))]
1758890286Sobrien  "")
1758990286Sobrien
1759090286Sobrien(define_peephole2
1759190286Sobrien  [(set (match_operand:QI 0 "push_operand" "")
1759290286Sobrien	(match_operand:QI 1 "memory_operand" ""))
1759390286Sobrien   (match_scratch:QI 2 "q")]
1759490286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1759590286Sobrien  [(set (match_dup 2) (match_dup 1))
1759690286Sobrien   (set (match_dup 0) (match_dup 2))]
1759790286Sobrien  "")
1759890286Sobrien
1759990286Sobrien;; Don't move an immediate directly to memory when the instruction
1760090286Sobrien;; gets too big.
1760190286Sobrien(define_peephole2
1760290286Sobrien  [(match_scratch:SI 1 "r")
1760390286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1760490286Sobrien        (const_int 0))]
1760590286Sobrien  "! optimize_size
1760690286Sobrien   && ! TARGET_USE_MOV0
1760790286Sobrien   && TARGET_SPLIT_LONG_MOVES
1760890286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1760990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1761090286Sobrien  [(parallel [(set (match_dup 1) (const_int 0))
1761190286Sobrien	      (clobber (reg:CC 17))])
1761290286Sobrien   (set (match_dup 0) (match_dup 1))]
1761390286Sobrien  "")
1761490286Sobrien
1761590286Sobrien(define_peephole2
1761690286Sobrien  [(match_scratch:HI 1 "r")
1761790286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1761890286Sobrien        (const_int 0))]
1761990286Sobrien  "! optimize_size
1762090286Sobrien   && ! TARGET_USE_MOV0
1762190286Sobrien   && TARGET_SPLIT_LONG_MOVES
1762290286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1762390286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1762490286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1762590286Sobrien	      (clobber (reg:CC 17))])
1762690286Sobrien   (set (match_dup 0) (match_dup 1))]
17627132727Skan  "operands[2] = gen_lowpart (SImode, operands[1]);")
1762890286Sobrien
1762990286Sobrien(define_peephole2
1763090286Sobrien  [(match_scratch:QI 1 "q")
1763190286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1763290286Sobrien        (const_int 0))]
1763390286Sobrien  "! optimize_size
1763490286Sobrien   && ! TARGET_USE_MOV0
1763590286Sobrien   && TARGET_SPLIT_LONG_MOVES
1763690286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1763790286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1763890286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1763990286Sobrien	      (clobber (reg:CC 17))])
1764090286Sobrien   (set (match_dup 0) (match_dup 1))]
17641132727Skan  "operands[2] = gen_lowpart (SImode, operands[1]);")
1764290286Sobrien
1764390286Sobrien(define_peephole2
1764490286Sobrien  [(match_scratch:SI 2 "r")
1764590286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1764690286Sobrien        (match_operand:SI 1 "immediate_operand" ""))]
1764790286Sobrien  "! optimize_size
1764890286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1764990286Sobrien   && TARGET_SPLIT_LONG_MOVES"
1765090286Sobrien  [(set (match_dup 2) (match_dup 1))
1765190286Sobrien   (set (match_dup 0) (match_dup 2))]
1765290286Sobrien  "")
1765390286Sobrien
1765490286Sobrien(define_peephole2
1765590286Sobrien  [(match_scratch:HI 2 "r")
1765690286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1765790286Sobrien        (match_operand:HI 1 "immediate_operand" ""))]
1765890286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1765990286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1766090286Sobrien  [(set (match_dup 2) (match_dup 1))
1766190286Sobrien   (set (match_dup 0) (match_dup 2))]
1766290286Sobrien  "")
1766390286Sobrien
1766490286Sobrien(define_peephole2
1766590286Sobrien  [(match_scratch:QI 2 "q")
1766690286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1766790286Sobrien        (match_operand:QI 1 "immediate_operand" ""))]
1766890286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1766990286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1767090286Sobrien  [(set (match_dup 2) (match_dup 1))
1767190286Sobrien   (set (match_dup 0) (match_dup 2))]
1767290286Sobrien  "")
1767390286Sobrien
1767490286Sobrien;; Don't compare memory with zero, load and use a test instead.
1767590286Sobrien(define_peephole2
17676146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
17677146906Skan 	(match_operator 1 "compare_operator"
17678146906Skan	  [(match_operand:SI 2 "memory_operand" "")
17679146906Skan	   (const_int 0)]))
1768090286Sobrien   (match_scratch:SI 3 "r")]
1768190286Sobrien  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17682146906Skan  [(set (match_dup 3) (match_dup 2))
17683146906Skan   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
1768490286Sobrien  "")
1768590286Sobrien
1768690286Sobrien;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
1768790286Sobrien;; Don't split NOTs with a displacement operand, because resulting XOR
17688132727Skan;; will not be pairable anyway.
1768990286Sobrien;;
1769090286Sobrien;; On AMD K6, NOT is vector decoded with memory operand that can not be
1769190286Sobrien;; represented using a modRM byte.  The XOR replacement is long decoded,
1769290286Sobrien;; so this split helps here as well.
1769390286Sobrien;;
1769490286Sobrien;; Note: Can't do this as a regular split because we can't get proper
1769590286Sobrien;; lifetime information then.
1769690286Sobrien
1769790286Sobrien(define_peephole2
1769890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1769990286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1770090286Sobrien  "!optimize_size
1770190286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1770290286Sobrien   && ((TARGET_PENTIUM 
1770390286Sobrien        && (GET_CODE (operands[0]) != MEM
1770490286Sobrien            || !memory_displacement_operand (operands[0], SImode)))
1770590286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
1770690286Sobrien  [(parallel [(set (match_dup 0)
1770790286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))
1770890286Sobrien	      (clobber (reg:CC 17))])]
1770990286Sobrien  "")
1771090286Sobrien
1771190286Sobrien(define_peephole2
1771290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1771390286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1771490286Sobrien  "!optimize_size
1771590286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1771690286Sobrien   && ((TARGET_PENTIUM 
1771790286Sobrien        && (GET_CODE (operands[0]) != MEM
1771890286Sobrien            || !memory_displacement_operand (operands[0], HImode)))
1771990286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
1772090286Sobrien  [(parallel [(set (match_dup 0)
1772190286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))
1772290286Sobrien	      (clobber (reg:CC 17))])]
1772390286Sobrien  "")
1772490286Sobrien
1772590286Sobrien(define_peephole2
1772690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1772790286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1772890286Sobrien  "!optimize_size
1772990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1773090286Sobrien   && ((TARGET_PENTIUM 
1773190286Sobrien        && (GET_CODE (operands[0]) != MEM
1773290286Sobrien            || !memory_displacement_operand (operands[0], QImode)))
1773390286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
1773490286Sobrien  [(parallel [(set (match_dup 0)
1773590286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))
1773690286Sobrien	      (clobber (reg:CC 17))])]
1773790286Sobrien  "")
1773890286Sobrien
1773990286Sobrien;; Non pairable "test imm, reg" instructions can be translated to
1774090286Sobrien;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
1774190286Sobrien;; byte opcode instead of two, have a short form for byte operands),
1774290286Sobrien;; so do it for other CPUs as well.  Given that the value was dead,
1774390286Sobrien;; this should not create any new dependencies.  Pass on the sub-word
1774490286Sobrien;; versions if we're concerned about partial register stalls.
1774590286Sobrien
1774690286Sobrien(define_peephole2
17747146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
17748146906Skan	(match_operator 1 "compare_operator"
17749146906Skan	  [(and:SI (match_operand:SI 2 "register_operand" "")
17750146906Skan		   (match_operand:SI 3 "immediate_operand" ""))
17751146906Skan	   (const_int 0)]))]
1775290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
17753146906Skan   && (true_regnum (operands[2]) != 0
17754146906Skan       || (GET_CODE (operands[3]) == CONST_INT
17755146906Skan	   && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
17756146906Skan   && peep2_reg_dead_p (1, operands[2])"
1775790286Sobrien  [(parallel
17758146906Skan     [(set (match_dup 0)
17759146906Skan	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17760146906Skan		            (const_int 0)]))
17761146906Skan      (set (match_dup 2)
17762146906Skan	   (and:SI (match_dup 2) (match_dup 3)))])]
1776390286Sobrien  "")
1776490286Sobrien
1776590286Sobrien;; We don't need to handle HImode case, because it will be promoted to SImode
1776690286Sobrien;; on ! TARGET_PARTIAL_REG_STALL
1776790286Sobrien
1776890286Sobrien(define_peephole2
17769146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
17770146906Skan	(match_operator 1 "compare_operator"
17771146906Skan	  [(and:QI (match_operand:QI 2 "register_operand" "")
17772146906Skan		   (match_operand:QI 3 "immediate_operand" ""))
17773146906Skan	   (const_int 0)]))]
1777490286Sobrien  "! TARGET_PARTIAL_REG_STALL
1777590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
17776146906Skan   && true_regnum (operands[2]) != 0
17777146906Skan   && peep2_reg_dead_p (1, operands[2])"
1777890286Sobrien  [(parallel
17779146906Skan     [(set (match_dup 0)
17780146906Skan	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17781146906Skan		            (const_int 0)]))
17782146906Skan      (set (match_dup 2)
17783146906Skan	   (and:QI (match_dup 2) (match_dup 3)))])]
1778490286Sobrien  "")
1778590286Sobrien
1778690286Sobrien(define_peephole2
17787146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
17788146906Skan	(match_operator 1 "compare_operator"
17789146906Skan	  [(and:SI
17790146906Skan	     (zero_extract:SI
17791146906Skan	       (match_operand 2 "ext_register_operand" "")
17792146906Skan	       (const_int 8)
17793146906Skan	       (const_int 8))
17794146906Skan	     (match_operand 3 "const_int_operand" ""))
17795146906Skan	   (const_int 0)]))]
1779690286Sobrien  "! TARGET_PARTIAL_REG_STALL
1779790286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
17798146906Skan   && true_regnum (operands[2]) != 0
17799146906Skan   && peep2_reg_dead_p (1, operands[2])"
17800146906Skan  [(parallel [(set (match_dup 0)
17801146906Skan		   (match_op_dup 1
17802146906Skan		     [(and:SI
17803146906Skan			(zero_extract:SI
17804146906Skan			  (match_dup 2)
17805146906Skan			  (const_int 8)
17806146906Skan			  (const_int 8))
17807146906Skan			(match_dup 3))
17808146906Skan		      (const_int 0)]))
17809146906Skan	      (set (zero_extract:SI (match_dup 2)
1781090286Sobrien				    (const_int 8)
1781190286Sobrien				    (const_int 8))
1781290286Sobrien		   (and:SI 
1781390286Sobrien		     (zero_extract:SI
17814146906Skan		       (match_dup 2)
1781590286Sobrien		       (const_int 8)
1781690286Sobrien		       (const_int 8))
17817146906Skan		     (match_dup 3)))])]
1781890286Sobrien  "")
1781990286Sobrien
1782090286Sobrien;; Don't do logical operations with memory inputs.
1782190286Sobrien(define_peephole2
1782290286Sobrien  [(match_scratch:SI 2 "r")
1782390286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1782490286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1782590286Sobrien                     [(match_dup 0)
1782690286Sobrien                      (match_operand:SI 1 "memory_operand" "")]))
1782790286Sobrien              (clobber (reg:CC 17))])]
1782890286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1782990286Sobrien  [(set (match_dup 2) (match_dup 1))
1783090286Sobrien   (parallel [(set (match_dup 0)
1783190286Sobrien                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
1783290286Sobrien              (clobber (reg:CC 17))])]
1783390286Sobrien  "")
1783490286Sobrien
1783590286Sobrien(define_peephole2
1783690286Sobrien  [(match_scratch:SI 2 "r")
1783790286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1783890286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1783990286Sobrien                     [(match_operand:SI 1 "memory_operand" "")
1784090286Sobrien                      (match_dup 0)]))
1784190286Sobrien              (clobber (reg:CC 17))])]
1784290286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1784390286Sobrien  [(set (match_dup 2) (match_dup 1))
1784490286Sobrien   (parallel [(set (match_dup 0)
1784590286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
1784690286Sobrien              (clobber (reg:CC 17))])]
1784790286Sobrien  "")
1784890286Sobrien
1784990286Sobrien; Don't do logical operations with memory outputs
1785090286Sobrien;
1785190286Sobrien; These two don't make sense for PPro/PII -- we're expanding a 4-uop
1785290286Sobrien; instruction into two 1-uop insns plus a 2-uop insn.  That last has
1785390286Sobrien; the same decoder scheduling characteristics as the original.
1785490286Sobrien
1785590286Sobrien(define_peephole2
1785690286Sobrien  [(match_scratch:SI 2 "r")
1785790286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1785890286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1785990286Sobrien                     [(match_dup 0)
1786090286Sobrien                      (match_operand:SI 1 "nonmemory_operand" "")]))
1786190286Sobrien              (clobber (reg:CC 17))])]
1786290286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1786390286Sobrien  [(set (match_dup 2) (match_dup 0))
1786490286Sobrien   (parallel [(set (match_dup 2)
1786590286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
1786690286Sobrien              (clobber (reg:CC 17))])
1786790286Sobrien   (set (match_dup 0) (match_dup 2))]
1786890286Sobrien  "")
1786990286Sobrien
1787090286Sobrien(define_peephole2
1787190286Sobrien  [(match_scratch:SI 2 "r")
1787290286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1787390286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1787490286Sobrien                     [(match_operand:SI 1 "nonmemory_operand" "")
1787590286Sobrien                      (match_dup 0)]))
1787690286Sobrien              (clobber (reg:CC 17))])]
1787790286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1787890286Sobrien  [(set (match_dup 2) (match_dup 0))
1787990286Sobrien   (parallel [(set (match_dup 2)
1788090286Sobrien                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1788190286Sobrien              (clobber (reg:CC 17))])
1788290286Sobrien   (set (match_dup 0) (match_dup 2))]
1788390286Sobrien  "")
1788490286Sobrien
1788590286Sobrien;; Attempt to always use XOR for zeroing registers.
1788690286Sobrien(define_peephole2
1788790286Sobrien  [(set (match_operand 0 "register_operand" "")
1788890286Sobrien	(const_int 0))]
1788990286Sobrien  "(GET_MODE (operands[0]) == QImode
1789090286Sobrien    || GET_MODE (operands[0]) == HImode
1789190286Sobrien    || GET_MODE (operands[0]) == SImode
1789290286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1789390286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1789490286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1789590286Sobrien  [(parallel [(set (match_dup 0) (const_int 0))
1789690286Sobrien	      (clobber (reg:CC 17))])]
17897132727Skan  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17898132727Skan			      operands[0]);")
1789990286Sobrien
1790090286Sobrien(define_peephole2
1790190286Sobrien  [(set (strict_low_part (match_operand 0 "register_operand" ""))
1790290286Sobrien	(const_int 0))]
1790390286Sobrien  "(GET_MODE (operands[0]) == QImode
1790490286Sobrien    || GET_MODE (operands[0]) == HImode)
1790590286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1790690286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1790790286Sobrien  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
1790890286Sobrien	      (clobber (reg:CC 17))])])
1790990286Sobrien
1791090286Sobrien;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
1791190286Sobrien(define_peephole2
1791290286Sobrien  [(set (match_operand 0 "register_operand" "")
1791390286Sobrien	(const_int -1))]
1791490286Sobrien  "(GET_MODE (operands[0]) == HImode
1791590286Sobrien    || GET_MODE (operands[0]) == SImode 
1791690286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1791790286Sobrien   && (optimize_size || TARGET_PENTIUM)
1791890286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1791990286Sobrien  [(parallel [(set (match_dup 0) (const_int -1))
1792090286Sobrien	      (clobber (reg:CC 17))])]
17921132727Skan  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17922132727Skan			      operands[0]);")
1792390286Sobrien
1792490286Sobrien;; Attempt to convert simple leas to adds. These can be created by
1792590286Sobrien;; move expanders.
1792690286Sobrien(define_peephole2
1792790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1792890286Sobrien  	(plus:SI (match_dup 0)
1792990286Sobrien		 (match_operand:SI 1 "nonmemory_operand" "")))]
1793090286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1793190286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1793290286Sobrien	      (clobber (reg:CC 17))])]
1793390286Sobrien  "")
1793490286Sobrien
1793590286Sobrien(define_peephole2
1793690286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1793790286Sobrien  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
1793890286Sobrien			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
1793990286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
1794090286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
1794190286Sobrien	      (clobber (reg:CC 17))])]
1794290286Sobrien  "operands[2] = gen_lowpart (SImode, operands[2]);")
1794390286Sobrien
1794490286Sobrien(define_peephole2
1794590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1794690286Sobrien  	(plus:DI (match_dup 0)
1794790286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "")))]
1794890286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1794990286Sobrien  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1795090286Sobrien	      (clobber (reg:CC 17))])]
1795190286Sobrien  "")
1795290286Sobrien
1795390286Sobrien(define_peephole2
1795490286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1795590286Sobrien  	(mult:SI (match_dup 0)
1795690286Sobrien		 (match_operand:SI 1 "const_int_operand" "")))]
1795790286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1795890286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1795990286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1796090286Sobrien	      (clobber (reg:CC 17))])]
1796190286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1796290286Sobrien
1796390286Sobrien(define_peephole2
1796490286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1796590286Sobrien  	(mult:DI (match_dup 0)
1796690286Sobrien		 (match_operand:DI 1 "const_int_operand" "")))]
1796790286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1796890286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1796990286Sobrien  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
1797090286Sobrien	      (clobber (reg:CC 17))])]
1797190286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1797290286Sobrien
1797390286Sobrien(define_peephole2
1797490286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1797590286Sobrien  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
1797690286Sobrien		   (match_operand:DI 2 "const_int_operand" "")) 0))]
17977117404Skan  "exact_log2 (INTVAL (operands[2])) >= 0
1797890286Sobrien   && REGNO (operands[0]) == REGNO (operands[1])
1797990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1798090286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1798190286Sobrien	      (clobber (reg:CC 17))])]
1798290286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
1798390286Sobrien
1798490286Sobrien;; The ESP adjustments can be done by the push and pop instructions.  Resulting
1798590286Sobrien;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
1798690286Sobrien;; many CPUs it is also faster, since special hardware to avoid esp
1798790286Sobrien;; dependencies is present.
1798890286Sobrien
1798990286Sobrien;; While some of these conversions may be done using splitters, we use peepholes
1799090286Sobrien;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
1799190286Sobrien
1799290286Sobrien;; Convert prologue esp subtractions to push.
1799390286Sobrien;; We need register to push.  In order to keep verify_flow_info happy we have
1799490286Sobrien;; two choices
1799590286Sobrien;; - use scratch and clobber it in order to avoid dependencies
1799690286Sobrien;; - use already live register
1799790286Sobrien;; We can't use the second way right now, since there is no reliable way how to
1799890286Sobrien;; verify that given register is live.  First choice will also most likely in
1799990286Sobrien;; fewer dependencies.  On the place of esp adjustments it is very likely that
1800090286Sobrien;; call clobbered registers are dead.  We may want to use base pointer as an
1800190286Sobrien;; alternative when no register is available later.
1800290286Sobrien
1800390286Sobrien(define_peephole2
1800490286Sobrien  [(match_scratch:SI 0 "r")
1800590286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1800690286Sobrien	      (clobber (reg:CC 17))
1800790286Sobrien	      (clobber (mem:BLK (scratch)))])]
1800890286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1800990286Sobrien  [(clobber (match_dup 0))
1801090286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1801190286Sobrien	      (clobber (mem:BLK (scratch)))])])
1801290286Sobrien
1801390286Sobrien(define_peephole2
1801490286Sobrien  [(match_scratch:SI 0 "r")
1801590286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1801690286Sobrien	      (clobber (reg:CC 17))
1801790286Sobrien	      (clobber (mem:BLK (scratch)))])]
1801890286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1801990286Sobrien  [(clobber (match_dup 0))
1802090286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1802190286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1802290286Sobrien	      (clobber (mem:BLK (scratch)))])])
1802390286Sobrien
1802490286Sobrien;; Convert esp subtractions to push.
1802590286Sobrien(define_peephole2
1802690286Sobrien  [(match_scratch:SI 0 "r")
1802790286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1802890286Sobrien	      (clobber (reg:CC 17))])]
1802990286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1803090286Sobrien  [(clobber (match_dup 0))
1803190286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1803290286Sobrien
1803390286Sobrien(define_peephole2
1803490286Sobrien  [(match_scratch:SI 0 "r")
1803590286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1803690286Sobrien	      (clobber (reg:CC 17))])]
1803790286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1803890286Sobrien  [(clobber (match_dup 0))
1803990286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1804090286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1804190286Sobrien
1804290286Sobrien;; Convert epilogue deallocator to pop.
1804390286Sobrien(define_peephole2
1804490286Sobrien  [(match_scratch:SI 0 "r")
1804590286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1804690286Sobrien	      (clobber (reg:CC 17))
1804790286Sobrien	      (clobber (mem:BLK (scratch)))])]
1804890286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1804990286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1805090286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1805190286Sobrien	      (clobber (mem:BLK (scratch)))])]
1805290286Sobrien  "")
1805390286Sobrien
1805490286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1805590286Sobrien;; We use two registers if available.
1805690286Sobrien(define_peephole2
1805790286Sobrien  [(match_scratch:SI 0 "r")
1805890286Sobrien   (match_scratch:SI 1 "r")
1805990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1806090286Sobrien	      (clobber (reg:CC 17))
1806190286Sobrien	      (clobber (mem:BLK (scratch)))])]
1806290286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1806390286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1806490286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1806590286Sobrien	      (clobber (mem:BLK (scratch)))])
1806690286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1806790286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1806890286Sobrien  "")
1806990286Sobrien
1807090286Sobrien(define_peephole2
1807190286Sobrien  [(match_scratch:SI 0 "r")
1807290286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1807390286Sobrien	      (clobber (reg:CC 17))
1807490286Sobrien	      (clobber (mem:BLK (scratch)))])]
1807590286Sobrien  "optimize_size"
1807690286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1807790286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1807890286Sobrien	      (clobber (mem:BLK (scratch)))])
1807990286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1808090286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1808190286Sobrien  "")
1808290286Sobrien
1808390286Sobrien;; Convert esp additions to pop.
1808490286Sobrien(define_peephole2
1808590286Sobrien  [(match_scratch:SI 0 "r")
1808690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1808790286Sobrien	      (clobber (reg:CC 17))])]
1808890286Sobrien  ""
1808990286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1809090286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1809190286Sobrien  "")
1809290286Sobrien
1809390286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1809490286Sobrien;; We use two registers if available.
1809590286Sobrien(define_peephole2
1809690286Sobrien  [(match_scratch:SI 0 "r")
1809790286Sobrien   (match_scratch:SI 1 "r")
1809890286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1809990286Sobrien	      (clobber (reg:CC 17))])]
1810090286Sobrien  ""
1810190286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1810290286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1810390286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1810490286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1810590286Sobrien  "")
1810690286Sobrien
1810790286Sobrien(define_peephole2
1810890286Sobrien  [(match_scratch:SI 0 "r")
1810990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1811090286Sobrien	      (clobber (reg:CC 17))])]
1811190286Sobrien  "optimize_size"
1811290286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1811390286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1811490286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1811590286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1811690286Sobrien  "")
1811790286Sobrien
1811890286Sobrien;; Convert compares with 1 to shorter inc/dec operations when CF is not
18119146906Skan;; required and register dies.  Similarly for 128 to plus -128.
1812090286Sobrien(define_peephole2
18121146906Skan  [(set (match_operand 0 "flags_reg_operand" "")
18122146906Skan	(match_operator 1 "compare_operator"
18123146906Skan	  [(match_operand 2 "register_operand" "")
18124146906Skan	   (match_operand 3 "const_int_operand" "")]))]
18125146906Skan  "(INTVAL (operands[3]) == -1
18126146906Skan    || INTVAL (operands[3]) == 1
18127146906Skan    || INTVAL (operands[3]) == 128)
18128146906Skan   && ix86_match_ccmode (insn, CCGCmode)
18129146906Skan   && peep2_reg_dead_p (1, operands[2])"
18130146906Skan  [(parallel [(set (match_dup 0)
18131146906Skan		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18132146906Skan	      (clobber (match_dup 2))])]
1813390286Sobrien  "")
1813490286Sobrien
1813590286Sobrien(define_peephole2
1813690286Sobrien  [(match_scratch:DI 0 "r")
1813790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1813890286Sobrien	      (clobber (reg:CC 17))
1813990286Sobrien	      (clobber (mem:BLK (scratch)))])]
1814090286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1814190286Sobrien  [(clobber (match_dup 0))
1814290286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1814390286Sobrien	      (clobber (mem:BLK (scratch)))])])
1814490286Sobrien
1814590286Sobrien(define_peephole2
1814690286Sobrien  [(match_scratch:DI 0 "r")
1814790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1814890286Sobrien	      (clobber (reg:CC 17))
1814990286Sobrien	      (clobber (mem:BLK (scratch)))])]
1815090286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1815190286Sobrien  [(clobber (match_dup 0))
1815290286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1815390286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1815490286Sobrien	      (clobber (mem:BLK (scratch)))])])
1815590286Sobrien
1815690286Sobrien;; Convert esp subtractions to push.
1815790286Sobrien(define_peephole2
1815890286Sobrien  [(match_scratch:DI 0 "r")
1815990286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1816090286Sobrien	      (clobber (reg:CC 17))])]
1816190286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1816290286Sobrien  [(clobber (match_dup 0))
1816390286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1816490286Sobrien
1816590286Sobrien(define_peephole2
1816690286Sobrien  [(match_scratch:DI 0 "r")
1816790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1816890286Sobrien	      (clobber (reg:CC 17))])]
1816990286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1817090286Sobrien  [(clobber (match_dup 0))
1817190286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1817290286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1817390286Sobrien
1817490286Sobrien;; Convert epilogue deallocator to pop.
1817590286Sobrien(define_peephole2
1817690286Sobrien  [(match_scratch:DI 0 "r")
1817790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1817890286Sobrien	      (clobber (reg:CC 17))
1817990286Sobrien	      (clobber (mem:BLK (scratch)))])]
1818090286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1818190286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1818290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1818390286Sobrien	      (clobber (mem:BLK (scratch)))])]
1818490286Sobrien  "")
1818590286Sobrien
1818690286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1818790286Sobrien;; We use two registers if available.
1818890286Sobrien(define_peephole2
1818990286Sobrien  [(match_scratch:DI 0 "r")
1819090286Sobrien   (match_scratch:DI 1 "r")
1819190286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1819290286Sobrien	      (clobber (reg:CC 17))
1819390286Sobrien	      (clobber (mem:BLK (scratch)))])]
1819490286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1819590286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1819690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1819790286Sobrien	      (clobber (mem:BLK (scratch)))])
1819890286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1819990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1820090286Sobrien  "")
1820190286Sobrien
1820290286Sobrien(define_peephole2
1820390286Sobrien  [(match_scratch:DI 0 "r")
1820490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1820590286Sobrien	      (clobber (reg:CC 17))
1820690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1820790286Sobrien  "optimize_size"
1820890286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1820990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1821090286Sobrien	      (clobber (mem:BLK (scratch)))])
1821190286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1821290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1821390286Sobrien  "")
1821490286Sobrien
1821590286Sobrien;; Convert esp additions to pop.
1821690286Sobrien(define_peephole2
1821790286Sobrien  [(match_scratch:DI 0 "r")
1821890286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1821990286Sobrien	      (clobber (reg:CC 17))])]
1822090286Sobrien  ""
1822190286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1822290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1822390286Sobrien  "")
1822490286Sobrien
1822590286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1822690286Sobrien;; We use two registers if available.
1822790286Sobrien(define_peephole2
1822890286Sobrien  [(match_scratch:DI 0 "r")
1822990286Sobrien   (match_scratch:DI 1 "r")
1823090286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1823190286Sobrien	      (clobber (reg:CC 17))])]
1823290286Sobrien  ""
1823390286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1823490286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1823590286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1823690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1823790286Sobrien  "")
1823890286Sobrien
1823990286Sobrien(define_peephole2
1824090286Sobrien  [(match_scratch:DI 0 "r")
1824190286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1824290286Sobrien	      (clobber (reg:CC 17))])]
1824390286Sobrien  "optimize_size"
1824490286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1824590286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1824690286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1824790286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1824890286Sobrien  "")
1824990286Sobrien
18250132727Skan;; Imul $32bit_imm, mem, reg is vector decoded, while
18251132727Skan;; imul $32bit_imm, reg, reg is direct decoded.
18252132727Skan(define_peephole2
18253132727Skan  [(match_scratch:DI 3 "r")
18254132727Skan   (parallel [(set (match_operand:DI 0 "register_operand" "")
18255132727Skan		   (mult:DI (match_operand:DI 1 "memory_operand" "")
18256132727Skan			    (match_operand:DI 2 "immediate_operand" "")))
18257132727Skan	      (clobber (reg:CC 17))])]
18258132727Skan  "TARGET_K8 && !optimize_size
18259132727Skan   && (GET_CODE (operands[2]) != CONST_INT
18260132727Skan       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18261132727Skan  [(set (match_dup 3) (match_dup 1))
18262132727Skan   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18263132727Skan	      (clobber (reg:CC 17))])]
18264132727Skan"")
18265132727Skan
18266132727Skan(define_peephole2
18267132727Skan  [(match_scratch:SI 3 "r")
18268132727Skan   (parallel [(set (match_operand:SI 0 "register_operand" "")
18269132727Skan		   (mult:SI (match_operand:SI 1 "memory_operand" "")
18270132727Skan			    (match_operand:SI 2 "immediate_operand" "")))
18271132727Skan	      (clobber (reg:CC 17))])]
18272132727Skan  "TARGET_K8 && !optimize_size
18273132727Skan   && (GET_CODE (operands[2]) != CONST_INT
18274132727Skan       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18275132727Skan  [(set (match_dup 3) (match_dup 1))
18276132727Skan   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18277132727Skan	      (clobber (reg:CC 17))])]
18278132727Skan"")
18279132727Skan
18280132727Skan(define_peephole2
18281132727Skan  [(match_scratch:SI 3 "r")
18282132727Skan   (parallel [(set (match_operand:DI 0 "register_operand" "")
18283132727Skan		   (zero_extend:DI
18284132727Skan		     (mult:SI (match_operand:SI 1 "memory_operand" "")
18285132727Skan			      (match_operand:SI 2 "immediate_operand" ""))))
18286132727Skan	      (clobber (reg:CC 17))])]
18287132727Skan  "TARGET_K8 && !optimize_size
18288132727Skan   && (GET_CODE (operands[2]) != CONST_INT
18289132727Skan       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18290132727Skan  [(set (match_dup 3) (match_dup 1))
18291132727Skan   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18292132727Skan	      (clobber (reg:CC 17))])]
18293132727Skan"")
18294132727Skan
18295132727Skan;; imul $8/16bit_imm, regmem, reg is vector decoded.
18296132727Skan;; Convert it into imul reg, reg
18297132727Skan;; It would be better to force assembler to encode instruction using long
18298132727Skan;; immediate, but there is apparently no way to do so.
18299132727Skan(define_peephole2
18300132727Skan  [(parallel [(set (match_operand:DI 0 "register_operand" "")
18301132727Skan		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18302132727Skan			    (match_operand:DI 2 "const_int_operand" "")))
18303132727Skan	      (clobber (reg:CC 17))])
18304132727Skan   (match_scratch:DI 3 "r")]
18305132727Skan  "TARGET_K8 && !optimize_size
18306132727Skan   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18307132727Skan  [(set (match_dup 3) (match_dup 2))
18308132727Skan   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18309132727Skan	      (clobber (reg:CC 17))])]
18310132727Skan{
18311132727Skan  if (!rtx_equal_p (operands[0], operands[1]))
18312132727Skan    emit_move_insn (operands[0], operands[1]);
18313132727Skan})
18314132727Skan
18315132727Skan(define_peephole2
18316132727Skan  [(parallel [(set (match_operand:SI 0 "register_operand" "")
18317132727Skan		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18318132727Skan			    (match_operand:SI 2 "const_int_operand" "")))
18319132727Skan	      (clobber (reg:CC 17))])
18320132727Skan   (match_scratch:SI 3 "r")]
18321132727Skan  "TARGET_K8 && !optimize_size
18322132727Skan   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18323132727Skan  [(set (match_dup 3) (match_dup 2))
18324132727Skan   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18325132727Skan	      (clobber (reg:CC 17))])]
18326132727Skan{
18327132727Skan  if (!rtx_equal_p (operands[0], operands[1]))
18328132727Skan    emit_move_insn (operands[0], operands[1]);
18329132727Skan})
18330132727Skan
18331132727Skan(define_peephole2
18332132727Skan  [(parallel [(set (match_operand:HI 0 "register_operand" "")
18333132727Skan		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18334132727Skan			    (match_operand:HI 2 "immediate_operand" "")))
18335132727Skan	      (clobber (reg:CC 17))])
18336132727Skan   (match_scratch:HI 3 "r")]
18337132727Skan  "TARGET_K8 && !optimize_size"
18338132727Skan  [(set (match_dup 3) (match_dup 2))
18339132727Skan   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18340132727Skan	      (clobber (reg:CC 17))])]
18341132727Skan{
18342132727Skan  if (!rtx_equal_p (operands[0], operands[1]))
18343132727Skan    emit_move_insn (operands[0], operands[1]);
18344132727Skan})
18345132727Skan
1834690286Sobrien;; Call-value patterns last so that the wildcard operand does not
1834790286Sobrien;; disrupt insn-recog's switch tables.
1834890286Sobrien
1834990286Sobrien(define_insn "*call_value_pop_0"
1835090286Sobrien  [(set (match_operand 0 "" "")
1835190286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1835290286Sobrien	      (match_operand:SI 2 "" "")))
1835390286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1835490286Sobrien			    (match_operand:SI 3 "immediate_operand" "")))]
1835590286Sobrien  "!TARGET_64BIT"
1835690286Sobrien{
1835790286Sobrien  if (SIBLING_CALL_P (insn))
1835890286Sobrien    return "jmp\t%P1";
1835990286Sobrien  else
1836090286Sobrien    return "call\t%P1";
1836190286Sobrien}
1836290286Sobrien  [(set_attr "type" "callv")])
1836390286Sobrien
1836490286Sobrien(define_insn "*call_value_pop_1"
1836590286Sobrien  [(set (match_operand 0 "" "")
1836690286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1836790286Sobrien	      (match_operand:SI 2 "" "")))
1836890286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1836990286Sobrien			    (match_operand:SI 3 "immediate_operand" "i")))]
1837090286Sobrien  "!TARGET_64BIT"
1837190286Sobrien{
1837290286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1837390286Sobrien    {
1837490286Sobrien      if (SIBLING_CALL_P (insn))
1837590286Sobrien	return "jmp\t%P1";
1837690286Sobrien      else
1837790286Sobrien	return "call\t%P1";
1837890286Sobrien    }
1837990286Sobrien  if (SIBLING_CALL_P (insn))
1838090286Sobrien    return "jmp\t%A1";
1838190286Sobrien  else
1838290286Sobrien    return "call\t%A1";
1838390286Sobrien}
1838490286Sobrien  [(set_attr "type" "callv")])
1838590286Sobrien
1838690286Sobrien(define_insn "*call_value_0"
1838790286Sobrien  [(set (match_operand 0 "" "")
1838890286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1838990286Sobrien	      (match_operand:SI 2 "" "")))]
1839090286Sobrien  "!TARGET_64BIT"
1839190286Sobrien{
1839290286Sobrien  if (SIBLING_CALL_P (insn))
1839390286Sobrien    return "jmp\t%P1";
1839490286Sobrien  else
1839590286Sobrien    return "call\t%P1";
1839690286Sobrien}
1839790286Sobrien  [(set_attr "type" "callv")])
1839890286Sobrien
1839990286Sobrien(define_insn "*call_value_0_rex64"
1840090286Sobrien  [(set (match_operand 0 "" "")
1840190286Sobrien	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
1840290286Sobrien	      (match_operand:DI 2 "const_int_operand" "")))]
1840390286Sobrien  "TARGET_64BIT"
1840490286Sobrien{
1840590286Sobrien  if (SIBLING_CALL_P (insn))
1840690286Sobrien    return "jmp\t%P1";
1840790286Sobrien  else
1840890286Sobrien    return "call\t%P1";
1840990286Sobrien}
1841090286Sobrien  [(set_attr "type" "callv")])
1841190286Sobrien
1841290286Sobrien(define_insn "*call_value_1"
1841390286Sobrien  [(set (match_operand 0 "" "")
1841490286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1841590286Sobrien	      (match_operand:SI 2 "" "")))]
18416132727Skan  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
1841790286Sobrien{
1841890286Sobrien  if (constant_call_address_operand (operands[1], QImode))
18419132727Skan    return "call\t%P1";
18420146906Skan  return "call\t%A1";
1842190286Sobrien}
1842290286Sobrien  [(set_attr "type" "callv")])
1842390286Sobrien
18424132727Skan(define_insn "*sibcall_value_1"
18425132727Skan  [(set (match_operand 0 "" "")
18426132727Skan	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18427132727Skan	      (match_operand:SI 2 "" "")))]
18428132727Skan  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18429132727Skan{
18430132727Skan  if (constant_call_address_operand (operands[1], QImode))
18431132727Skan    return "jmp\t%P1";
18432146906Skan  return "jmp\t%A1";
18433132727Skan}
18434132727Skan  [(set_attr "type" "callv")])
18435132727Skan
1843690286Sobrien(define_insn "*call_value_1_rex64"
1843790286Sobrien  [(set (match_operand 0 "" "")
1843890286Sobrien	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
1843990286Sobrien	      (match_operand:DI 2 "" "")))]
18440132727Skan  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
1844190286Sobrien{
1844290286Sobrien  if (constant_call_address_operand (operands[1], QImode))
18443132727Skan    return "call\t%P1";
18444132727Skan  return "call\t%A1";
1844590286Sobrien}
1844690286Sobrien  [(set_attr "type" "callv")])
18447132727Skan
18448132727Skan(define_insn "*sibcall_value_1_rex64"
18449132727Skan  [(set (match_operand 0 "" "")
18450132727Skan	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18451132727Skan	      (match_operand:DI 2 "" "")))]
18452132727Skan  "SIBLING_CALL_P (insn) && TARGET_64BIT"
18453132727Skan  "jmp\t%P1"
18454132727Skan  [(set_attr "type" "callv")])
18455132727Skan
18456132727Skan(define_insn "*sibcall_value_1_rex64_v"
18457132727Skan  [(set (match_operand 0 "" "")
18458132727Skan	(call (mem:QI (reg:DI 40))
18459132727Skan	      (match_operand:DI 1 "" "")))]
18460132727Skan  "SIBLING_CALL_P (insn) && TARGET_64BIT"
18461132727Skan  "jmp\t*%%r11"
18462132727Skan  [(set_attr "type" "callv")])
1846390286Sobrien
1846490286Sobrien(define_insn "trap"
1846590286Sobrien  [(trap_if (const_int 1) (const_int 5))]
1846690286Sobrien  ""
1846790286Sobrien  "int\t$5")
1846890286Sobrien
1846990286Sobrien;;; ix86 doesn't have conditional trap instructions, but we fake them
1847090286Sobrien;;; for the sake of bounds checking.  By emitting bounds checks as
1847190286Sobrien;;; conditional traps rather than as conditional jumps around
1847290286Sobrien;;; unconditional traps we avoid introducing spurious basic-block
1847390286Sobrien;;; boundaries and facilitate elimination of redundant checks.  In
1847490286Sobrien;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
1847590286Sobrien;;; interrupt 5.
1847690286Sobrien;;; 
1847790286Sobrien;;; FIXME: Static branch prediction rules for ix86 are such that
1847890286Sobrien;;; forward conditional branches predict as untaken.  As implemented
1847990286Sobrien;;; below, pseudo conditional traps violate that rule.  We should use
1848090286Sobrien;;; .pushsection/.popsection to place all of the `int 5's in a special
1848190286Sobrien;;; section loaded at the end of the text segment and branch forward
1848290286Sobrien;;; there on bounds-failure, and then jump back immediately (in case
1848390286Sobrien;;; the system chooses to ignore bounds violations, or to report
1848490286Sobrien;;; violations and continue execution).
1848590286Sobrien
1848690286Sobrien(define_expand "conditional_trap"
1848790286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1848890286Sobrien	     [(match_dup 2) (const_int 0)])
1848990286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1849090286Sobrien  ""
1849190286Sobrien{
1849290286Sobrien  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
1849390286Sobrien			      ix86_expand_compare (GET_CODE (operands[0]),
1849490286Sobrien						   NULL, NULL),
1849590286Sobrien			      operands[1]));
1849690286Sobrien  DONE;
1849790286Sobrien})
1849890286Sobrien
1849990286Sobrien(define_insn "*conditional_trap_1"
1850090286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1850190286Sobrien	     [(reg 17) (const_int 0)])
1850290286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1850390286Sobrien  ""
1850490286Sobrien{
1850590286Sobrien  operands[2] = gen_label_rtx ();
1850690286Sobrien  output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18507132727Skan  (*targetm.asm_out.internal_label) (asm_out_file, "L",
1850890286Sobrien			     CODE_LABEL_NUMBER (operands[2]));
1850990286Sobrien  RET;
1851090286Sobrien})
1851190286Sobrien
1851290286Sobrien	;; Pentium III SIMD instructions.
1851390286Sobrien
1851490286Sobrien;; Moves for SSE/MMX regs.
1851590286Sobrien
18516146906Skan(define_insn "*movv4sf_internal"
18517117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18518117404Skan	(match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18519146906Skan  "TARGET_SSE
18520146906Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18521117404Skan  "@
18522132727Skan    xorps\t%0, %0
18523132727Skan    movaps\t{%1, %0|%0, %1}
18524132727Skan    movaps\t{%1, %0|%0, %1}"
18525117404Skan  [(set_attr "type" "ssemov")
18526117404Skan   (set_attr "mode" "V4SF")])
1852790286Sobrien
18528132727Skan(define_split
18529132727Skan  [(set (match_operand:V4SF 0 "register_operand" "")
18530132727Skan	(match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18531146906Skan  "TARGET_SSE && reload_completed"
18532132727Skan  [(set (match_dup 0)
18533132727Skan	(vec_merge:V4SF
18534132727Skan	 (vec_duplicate:V4SF (match_dup 1))
18535132727Skan	 (match_dup 2)
18536132727Skan	 (const_int 1)))]
18537132727Skan{
18538132727Skan  operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18539132727Skan  operands[2] = CONST0_RTX (V4SFmode);
18540132727Skan})
18541132727Skan
18542146906Skan(define_insn "*movv4si_internal"
18543117404Skan  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18544117404Skan	(match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18545146906Skan  "TARGET_SSE
18546146906Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18547132727Skan{
18548132727Skan  switch (which_alternative)
18549132727Skan    {
18550132727Skan    case 0:
18551132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18552132727Skan	return "xorps\t%0, %0";
18553132727Skan      else
18554132727Skan	return "pxor\t%0, %0";
18555132727Skan    case 1:
18556132727Skan    case 2:
18557132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18558132727Skan	return "movaps\t{%1, %0|%0, %1}";
18559132727Skan      else
18560132727Skan	return "movdqa\t{%1, %0|%0, %1}";
18561132727Skan    default:
18562132727Skan      abort ();
18563132727Skan    }
18564132727Skan}
18565117404Skan  [(set_attr "type" "ssemov")
18566132727Skan   (set (attr "mode")
18567132727Skan        (cond [(eq_attr "alternative" "0,1")
18568132727Skan		 (if_then_else
18569132727Skan		   (ne (symbol_ref "optimize_size")
18570132727Skan		       (const_int 0))
18571132727Skan		   (const_string "V4SF")
18572132727Skan		   (const_string "TI"))
18573132727Skan	       (eq_attr "alternative" "2")
18574132727Skan		 (if_then_else
18575132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18576132727Skan			    (const_int 0))
18577132727Skan			(ne (symbol_ref "optimize_size")
18578132727Skan			    (const_int 0)))
18579132727Skan		   (const_string "V4SF")
18580132727Skan		   (const_string "TI"))]
18581132727Skan	       (const_string "TI")))])
1858290286Sobrien
18583146906Skan(define_insn "*movv2di_internal"
18584117404Skan  [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18585117404Skan	(match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18586146906Skan  "TARGET_SSE
18587146906Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18588132727Skan{
18589132727Skan  switch (which_alternative)
18590132727Skan    {
18591132727Skan    case 0:
18592132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18593132727Skan	return "xorps\t%0, %0";
18594132727Skan      else
18595132727Skan	return "pxor\t%0, %0";
18596132727Skan    case 1:
18597132727Skan    case 2:
18598132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18599132727Skan	return "movaps\t{%1, %0|%0, %1}";
18600132727Skan      else
18601132727Skan	return "movdqa\t{%1, %0|%0, %1}";
18602132727Skan    default:
18603132727Skan      abort ();
18604132727Skan    }
18605132727Skan}
18606117404Skan  [(set_attr "type" "ssemov")
18607132727Skan   (set (attr "mode")
18608132727Skan        (cond [(eq_attr "alternative" "0,1")
18609132727Skan		 (if_then_else
18610132727Skan		   (ne (symbol_ref "optimize_size")
18611132727Skan		       (const_int 0))
18612132727Skan		   (const_string "V4SF")
18613132727Skan		   (const_string "TI"))
18614132727Skan	       (eq_attr "alternative" "2")
18615132727Skan		 (if_then_else
18616132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18617132727Skan			    (const_int 0))
18618132727Skan			(ne (symbol_ref "optimize_size")
18619132727Skan			    (const_int 0)))
18620132727Skan		   (const_string "V4SF")
18621132727Skan		   (const_string "TI"))]
18622132727Skan	       (const_string "TI")))])
18623117404Skan
18624132727Skan(define_split
18625132727Skan  [(set (match_operand:V2DF 0 "register_operand" "")
18626132727Skan	(match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18627146906Skan  "TARGET_SSE2 && reload_completed"
18628132727Skan  [(set (match_dup 0)
18629132727Skan	(vec_merge:V2DF
18630132727Skan	 (vec_duplicate:V2DF (match_dup 1))
18631132727Skan	 (match_dup 2)
18632132727Skan	 (const_int 1)))]
18633132727Skan{
18634132727Skan  operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18635132727Skan  operands[2] = CONST0_RTX (V2DFmode);
18636132727Skan})
18637132727Skan
18638146906Skan(define_insn "*movv2si_internal"
18639146906Skan  [(set (match_operand:V2SI 0 "nonimmediate_operand"
18640146906Skan					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18641146906Skan	(match_operand:V2SI 1 "vector_move_operand"
18642146906Skan					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18643117404Skan  "TARGET_MMX
18644117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18645117404Skan  "@
18646117404Skan    pxor\t%0, %0
18647117404Skan    movq\t{%1, %0|%0, %1}
18648146906Skan    movq\t{%1, %0|%0, %1}
18649146906Skan    movdq2q\t{%1, %0|%0, %1}
18650146906Skan    movq2dq\t{%1, %0|%0, %1}
18651146906Skan    pxor\t%0, %0
18652146906Skan    movq\t{%1, %0|%0, %1}
18653117404Skan    movq\t{%1, %0|%0, %1}"
18654146906Skan  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18655117404Skan   (set_attr "mode" "DI")])
1865690286Sobrien
18657146906Skan(define_insn "*movv4hi_internal"
18658146906Skan  [(set (match_operand:V4HI 0 "nonimmediate_operand"
18659146906Skan					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18660146906Skan	(match_operand:V4HI 1 "vector_move_operand"
18661146906Skan					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18662117404Skan  "TARGET_MMX
18663117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18664117404Skan  "@
18665117404Skan    pxor\t%0, %0
18666117404Skan    movq\t{%1, %0|%0, %1}
18667146906Skan    movq\t{%1, %0|%0, %1}
18668146906Skan    movdq2q\t{%1, %0|%0, %1}
18669146906Skan    movq2dq\t{%1, %0|%0, %1}
18670146906Skan    pxor\t%0, %0
18671146906Skan    movq\t{%1, %0|%0, %1}
18672117404Skan    movq\t{%1, %0|%0, %1}"
18673146906Skan  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18674117404Skan   (set_attr "mode" "DI")])
1867590286Sobrien
18676146906Skan(define_insn "*movv8qi_internal"
18677146906Skan  [(set (match_operand:V8QI 0 "nonimmediate_operand"
18678146906Skan					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18679146906Skan	(match_operand:V8QI 1 "vector_move_operand"
18680146906Skan					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18681117404Skan  "TARGET_MMX
18682117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18683117404Skan  "@
18684117404Skan    pxor\t%0, %0
18685117404Skan    movq\t{%1, %0|%0, %1}
18686146906Skan    movq\t{%1, %0|%0, %1}
18687146906Skan    movdq2q\t{%1, %0|%0, %1}
18688146906Skan    movq2dq\t{%1, %0|%0, %1}
18689146906Skan    pxor\t%0, %0
18690146906Skan    movq\t{%1, %0|%0, %1}
18691117404Skan    movq\t{%1, %0|%0, %1}"
18692146906Skan  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18693117404Skan   (set_attr "mode" "DI")])
1869490286Sobrien
18695146906Skan(define_insn "*movv2sf_internal"
18696146906Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand"
18697146906Skan					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18698146906Skan        (match_operand:V2SF 1 "vector_move_operand"
18699146906Skan					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18700146906Skan  "TARGET_MMX
18701117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18702117404Skan  "@
18703117404Skan    pxor\t%0, %0
18704117404Skan    movq\t{%1, %0|%0, %1}
18705146906Skan    movq\t{%1, %0|%0, %1}
18706146906Skan    movdq2q\t{%1, %0|%0, %1}
18707146906Skan    movq2dq\t{%1, %0|%0, %1}
18708146906Skan    xorps\t%0, %0
18709146906Skan    movq\t{%1, %0|%0, %1}
18710117404Skan    movq\t{%1, %0|%0, %1}"
18711146906Skan  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18712117404Skan   (set_attr "mode" "DI")])
1871390286Sobrien
1871490286Sobrien(define_expand "movti"
18715117404Skan  [(set (match_operand:TI 0 "nonimmediate_operand" "")
18716117404Skan	(match_operand:TI 1 "nonimmediate_operand" ""))]
1871790286Sobrien  "TARGET_SSE || TARGET_64BIT"
1871890286Sobrien{
1871990286Sobrien  if (TARGET_64BIT)
1872090286Sobrien    ix86_expand_move (TImode, operands);
1872190286Sobrien  else
1872290286Sobrien    ix86_expand_vector_move (TImode, operands);
1872390286Sobrien  DONE;
1872490286Sobrien})
1872590286Sobrien
18726132727Skan(define_expand "movtf"
18727132727Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "")
18728132727Skan	(match_operand:TF 1 "nonimmediate_operand" ""))]
18729132727Skan  "TARGET_64BIT"
18730132727Skan{
18731146906Skan  ix86_expand_move (TFmode, operands);
18732132727Skan  DONE;
18733132727Skan})
18734132727Skan
18735146906Skan(define_insn "*movv2df_internal"
18736117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18737117404Skan	(match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18738146906Skan  "TARGET_SSE
18739117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18740132727Skan{
18741132727Skan  switch (which_alternative)
18742132727Skan    {
18743132727Skan    case 0:
18744132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18745132727Skan	return "xorps\t%0, %0";
18746132727Skan      else
18747132727Skan	return "xorpd\t%0, %0";
18748132727Skan    case 1:
18749132727Skan    case 2:
18750132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18751132727Skan	return "movaps\t{%1, %0|%0, %1}";
18752132727Skan      else
18753132727Skan	return "movapd\t{%1, %0|%0, %1}";
18754132727Skan    default:
18755132727Skan      abort ();
18756132727Skan    }
18757132727Skan}
18758117404Skan  [(set_attr "type" "ssemov")
18759132727Skan   (set (attr "mode")
18760146906Skan        (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
18761146906Skan		 (const_string "V4SF")
18762146906Skan	       (eq_attr "alternative" "0,1")
18763132727Skan		 (if_then_else
18764132727Skan		   (ne (symbol_ref "optimize_size")
18765132727Skan		       (const_int 0))
18766132727Skan		   (const_string "V4SF")
18767132727Skan		   (const_string "V2DF"))
18768132727Skan	       (eq_attr "alternative" "2")
18769132727Skan		 (if_then_else
18770132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18771132727Skan			    (const_int 0))
18772132727Skan			(ne (symbol_ref "optimize_size")
18773132727Skan			    (const_int 0)))
18774132727Skan		   (const_string "V4SF")
18775132727Skan		   (const_string "V2DF"))]
18776132727Skan	       (const_string "V2DF")))])
18777117404Skan
18778146906Skan(define_insn "*movv8hi_internal"
18779117404Skan  [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18780117404Skan	(match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18781146906Skan  "TARGET_SSE
18782117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18783132727Skan{
18784132727Skan  switch (which_alternative)
18785132727Skan    {
18786132727Skan    case 0:
18787132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18788132727Skan	return "xorps\t%0, %0";
18789132727Skan      else
18790132727Skan	return "pxor\t%0, %0";
18791132727Skan    case 1:
18792132727Skan    case 2:
18793132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18794132727Skan	return "movaps\t{%1, %0|%0, %1}";
18795132727Skan      else
18796132727Skan	return "movdqa\t{%1, %0|%0, %1}";
18797132727Skan    default:
18798132727Skan      abort ();
18799132727Skan    }
18800132727Skan}
18801117404Skan  [(set_attr "type" "ssemov")
18802132727Skan   (set (attr "mode")
18803132727Skan        (cond [(eq_attr "alternative" "0,1")
18804132727Skan		 (if_then_else
18805132727Skan		   (ne (symbol_ref "optimize_size")
18806132727Skan		       (const_int 0))
18807132727Skan		   (const_string "V4SF")
18808132727Skan		   (const_string "TI"))
18809132727Skan	       (eq_attr "alternative" "2")
18810132727Skan		 (if_then_else
18811132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18812132727Skan			    (const_int 0))
18813132727Skan			(ne (symbol_ref "optimize_size")
18814132727Skan			    (const_int 0)))
18815132727Skan		   (const_string "V4SF")
18816132727Skan		   (const_string "TI"))]
18817132727Skan	       (const_string "TI")))])
18818117404Skan
18819146906Skan(define_insn "*movv16qi_internal"
18820117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18821146906Skan	(match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
18822146906Skan  "TARGET_SSE
18823117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18824132727Skan{
18825132727Skan  switch (which_alternative)
18826132727Skan    {
18827132727Skan    case 0:
18828132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18829132727Skan	return "xorps\t%0, %0";
18830132727Skan      else
18831132727Skan	return "pxor\t%0, %0";
18832132727Skan    case 1:
18833132727Skan    case 2:
18834132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
18835132727Skan	return "movaps\t{%1, %0|%0, %1}";
18836132727Skan      else
18837132727Skan	return "movdqa\t{%1, %0|%0, %1}";
18838132727Skan    default:
18839132727Skan      abort ();
18840132727Skan    }
18841132727Skan}
18842117404Skan  [(set_attr "type" "ssemov")
18843132727Skan   (set (attr "mode")
18844132727Skan        (cond [(eq_attr "alternative" "0,1")
18845132727Skan		 (if_then_else
18846132727Skan		   (ne (symbol_ref "optimize_size")
18847132727Skan		       (const_int 0))
18848132727Skan		   (const_string "V4SF")
18849132727Skan		   (const_string "TI"))
18850132727Skan	       (eq_attr "alternative" "2")
18851132727Skan		 (if_then_else
18852132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18853132727Skan			    (const_int 0))
18854132727Skan			(ne (symbol_ref "optimize_size")
18855132727Skan			    (const_int 0)))
18856132727Skan		   (const_string "V4SF")
18857132727Skan		   (const_string "TI"))]
18858132727Skan	       (const_string "TI")))])
18859117404Skan
18860117404Skan(define_expand "movv2df"
18861117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18862117404Skan	(match_operand:V2DF 1 "nonimmediate_operand" ""))]
18863146906Skan  "TARGET_SSE"
18864117404Skan{
18865117404Skan  ix86_expand_vector_move (V2DFmode, operands);
18866117404Skan  DONE;
18867117404Skan})
18868117404Skan
18869117404Skan(define_expand "movv8hi"
18870117404Skan  [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18871117404Skan	(match_operand:V8HI 1 "nonimmediate_operand" ""))]
18872146906Skan  "TARGET_SSE"
18873117404Skan{
18874117404Skan  ix86_expand_vector_move (V8HImode, operands);
18875117404Skan  DONE;
18876117404Skan})
18877117404Skan
18878117404Skan(define_expand "movv16qi"
18879117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18880117404Skan	(match_operand:V16QI 1 "nonimmediate_operand" ""))]
18881146906Skan  "TARGET_SSE"
18882117404Skan{
18883117404Skan  ix86_expand_vector_move (V16QImode, operands);
18884117404Skan  DONE;
18885117404Skan})
18886117404Skan
1888790286Sobrien(define_expand "movv4sf"
18888117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18889117404Skan	(match_operand:V4SF 1 "nonimmediate_operand" ""))]
1889090286Sobrien  "TARGET_SSE"
1889190286Sobrien{
1889290286Sobrien  ix86_expand_vector_move (V4SFmode, operands);
1889390286Sobrien  DONE;
1889490286Sobrien})
1889590286Sobrien
1889690286Sobrien(define_expand "movv4si"
18897117404Skan  [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18898117404Skan	(match_operand:V4SI 1 "nonimmediate_operand" ""))]
18899117404Skan  "TARGET_SSE"
1890090286Sobrien{
1890190286Sobrien  ix86_expand_vector_move (V4SImode, operands);
1890290286Sobrien  DONE;
1890390286Sobrien})
1890490286Sobrien
18905117404Skan(define_expand "movv2di"
18906117404Skan  [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18907117404Skan	(match_operand:V2DI 1 "nonimmediate_operand" ""))]
18908117404Skan  "TARGET_SSE"
18909117404Skan{
18910117404Skan  ix86_expand_vector_move (V2DImode, operands);
18911117404Skan  DONE;
18912117404Skan})
18913117404Skan
1891490286Sobrien(define_expand "movv2si"
18915117404Skan  [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18916117404Skan	(match_operand:V2SI 1 "nonimmediate_operand" ""))]
1891790286Sobrien  "TARGET_MMX"
1891890286Sobrien{
1891990286Sobrien  ix86_expand_vector_move (V2SImode, operands);
1892090286Sobrien  DONE;
1892190286Sobrien})
1892290286Sobrien
1892390286Sobrien(define_expand "movv4hi"
18924117404Skan  [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18925117404Skan	(match_operand:V4HI 1 "nonimmediate_operand" ""))]
1892690286Sobrien  "TARGET_MMX"
1892790286Sobrien{
1892890286Sobrien  ix86_expand_vector_move (V4HImode, operands);
1892990286Sobrien  DONE;
1893090286Sobrien})
1893190286Sobrien
1893290286Sobrien(define_expand "movv8qi"
18933117404Skan  [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18934117404Skan	(match_operand:V8QI 1 "nonimmediate_operand" ""))]
1893590286Sobrien  "TARGET_MMX"
1893690286Sobrien{
1893790286Sobrien  ix86_expand_vector_move (V8QImode, operands);
1893890286Sobrien  DONE;
1893990286Sobrien})
1894090286Sobrien
1894190286Sobrien(define_expand "movv2sf"
18942117404Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18943117404Skan	(match_operand:V2SF 1 "nonimmediate_operand" ""))]
18944146906Skan  "TARGET_MMX"
1894590286Sobrien{
1894690286Sobrien  ix86_expand_vector_move (V2SFmode, operands);
1894790286Sobrien  DONE;
1894890286Sobrien})
1894990286Sobrien
18950132727Skan(define_insn "*pushti"
18951132727Skan  [(set (match_operand:TI 0 "push_operand" "=<")
18952132727Skan	(match_operand:TI 1 "register_operand" "x"))]
18953132727Skan  "TARGET_SSE"
18954132727Skan  "#")
18955132727Skan
18956117404Skan(define_insn "*pushv2df"
18957117404Skan  [(set (match_operand:V2DF 0 "push_operand" "=<")
18958117404Skan	(match_operand:V2DF 1 "register_operand" "x"))]
18959117404Skan  "TARGET_SSE"
18960117404Skan  "#")
18961117404Skan
18962117404Skan(define_insn "*pushv2di"
18963117404Skan  [(set (match_operand:V2DI 0 "push_operand" "=<")
18964117404Skan	(match_operand:V2DI 1 "register_operand" "x"))]
18965146906Skan  "TARGET_SSE"
18966117404Skan  "#")
18967117404Skan
18968117404Skan(define_insn "*pushv8hi"
18969117404Skan  [(set (match_operand:V8HI 0 "push_operand" "=<")
18970117404Skan	(match_operand:V8HI 1 "register_operand" "x"))]
18971146906Skan  "TARGET_SSE"
18972117404Skan  "#")
18973117404Skan
18974117404Skan(define_insn "*pushv16qi"
18975117404Skan  [(set (match_operand:V16QI 0 "push_operand" "=<")
18976117404Skan	(match_operand:V16QI 1 "register_operand" "x"))]
18977146906Skan  "TARGET_SSE"
18978117404Skan  "#")
18979117404Skan
18980117404Skan(define_insn "*pushv4sf"
18981117404Skan  [(set (match_operand:V4SF 0 "push_operand" "=<")
18982117404Skan	(match_operand:V4SF 1 "register_operand" "x"))]
18983117404Skan  "TARGET_SSE"
18984117404Skan  "#")
18985117404Skan
18986117404Skan(define_insn "*pushv4si"
18987117404Skan  [(set (match_operand:V4SI 0 "push_operand" "=<")
18988117404Skan	(match_operand:V4SI 1 "register_operand" "x"))]
18989146906Skan  "TARGET_SSE"
18990117404Skan  "#")
18991117404Skan
18992117404Skan(define_insn "*pushv2si"
18993117404Skan  [(set (match_operand:V2SI 0 "push_operand" "=<")
18994117404Skan	(match_operand:V2SI 1 "register_operand" "y"))]
18995117404Skan  "TARGET_MMX"
18996117404Skan  "#")
18997117404Skan
18998117404Skan(define_insn "*pushv4hi"
18999117404Skan  [(set (match_operand:V4HI 0 "push_operand" "=<")
19000117404Skan	(match_operand:V4HI 1 "register_operand" "y"))]
19001117404Skan  "TARGET_MMX"
19002117404Skan  "#")
19003117404Skan
19004117404Skan(define_insn "*pushv8qi"
19005117404Skan  [(set (match_operand:V8QI 0 "push_operand" "=<")
19006117404Skan	(match_operand:V8QI 1 "register_operand" "y"))]
19007117404Skan  "TARGET_MMX"
19008117404Skan  "#")
19009117404Skan
19010117404Skan(define_insn "*pushv2sf"
19011117404Skan  [(set (match_operand:V2SF 0 "push_operand" "=<")
19012117404Skan	(match_operand:V2SF 1 "register_operand" "y"))]
19013146906Skan  "TARGET_MMX"
19014117404Skan  "#")
19015117404Skan
19016117404Skan(define_split
19017117404Skan  [(set (match_operand 0 "push_operand" "")
19018117404Skan	(match_operand 1 "register_operand" ""))]
19019117404Skan  "!TARGET_64BIT && reload_completed
19020117404Skan   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19021117404Skan  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19022117404Skan   (set (match_dup 2) (match_dup 1))]
19023117404Skan  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19024117404Skan				 stack_pointer_rtx);
19025117404Skan   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19026117404Skan
19027117404Skan(define_split
19028117404Skan  [(set (match_operand 0 "push_operand" "")
19029117404Skan	(match_operand 1 "register_operand" ""))]
19030117404Skan  "TARGET_64BIT && reload_completed
19031117404Skan   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19032117404Skan  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19033117404Skan   (set (match_dup 2) (match_dup 1))]
19034117404Skan  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19035117404Skan				 stack_pointer_rtx);
19036117404Skan   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19037117404Skan
19038117404Skan
19039146906Skan(define_insn "*movti_internal"
1904090286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19041117404Skan	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19042117404Skan  "TARGET_SSE && !TARGET_64BIT
19043117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19044132727Skan{
19045132727Skan  switch (which_alternative)
19046132727Skan    {
19047132727Skan    case 0:
19048132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
19049132727Skan	return "xorps\t%0, %0";
19050132727Skan      else
19051132727Skan	return "pxor\t%0, %0";
19052132727Skan    case 1:
19053132727Skan    case 2:
19054132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
19055132727Skan	return "movaps\t{%1, %0|%0, %1}";
19056132727Skan      else
19057132727Skan	return "movdqa\t{%1, %0|%0, %1}";
19058132727Skan    default:
19059132727Skan      abort ();
19060132727Skan    }
19061132727Skan}
19062117404Skan  [(set_attr "type" "ssemov,ssemov,ssemov")
19063132727Skan   (set (attr "mode")
19064132727Skan        (cond [(eq_attr "alternative" "0,1")
19065132727Skan		 (if_then_else
19066132727Skan		   (ne (symbol_ref "optimize_size")
19067132727Skan		       (const_int 0))
19068132727Skan		   (const_string "V4SF")
19069132727Skan		   (const_string "TI"))
19070132727Skan	       (eq_attr "alternative" "2")
19071132727Skan		 (if_then_else
19072132727Skan		   (ne (symbol_ref "optimize_size")
19073132727Skan		       (const_int 0))
19074132727Skan		   (const_string "V4SF")
19075132727Skan		   (const_string "TI"))]
19076132727Skan	       (const_string "TI")))])
1907790286Sobrien
1907890286Sobrien(define_insn "*movti_rex64"
19079132727Skan  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19080132727Skan	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1908190286Sobrien  "TARGET_64BIT
1908290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19083132727Skan{
19084132727Skan  switch (which_alternative)
19085132727Skan    {
19086132727Skan    case 0:
19087132727Skan    case 1:
19088132727Skan      return "#";
19089132727Skan    case 2:
19090132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
19091132727Skan	return "xorps\t%0, %0";
19092132727Skan      else
19093132727Skan	return "pxor\t%0, %0";
19094132727Skan    case 3:
19095132727Skan    case 4:
19096132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
19097132727Skan	return "movaps\t{%1, %0|%0, %1}";
19098132727Skan      else
19099132727Skan	return "movdqa\t{%1, %0|%0, %1}";
19100132727Skan    default:
19101132727Skan      abort ();
19102132727Skan    }
19103132727Skan}
19104117404Skan  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19105132727Skan   (set (attr "mode")
19106132727Skan        (cond [(eq_attr "alternative" "2,3")
19107132727Skan		 (if_then_else
19108132727Skan		   (ne (symbol_ref "optimize_size")
19109132727Skan		       (const_int 0))
19110132727Skan		   (const_string "V4SF")
19111132727Skan		   (const_string "TI"))
19112132727Skan	       (eq_attr "alternative" "4")
19113132727Skan		 (if_then_else
19114132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19115132727Skan			    (const_int 0))
19116132727Skan			(ne (symbol_ref "optimize_size")
19117132727Skan			    (const_int 0)))
19118132727Skan		   (const_string "V4SF")
19119132727Skan		   (const_string "TI"))]
19120132727Skan	       (const_string "DI")))])
1912190286Sobrien
19122132727Skan(define_insn "*movtf_rex64"
19123132727Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19124132727Skan	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19125132727Skan  "TARGET_64BIT
19126132727Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19127132727Skan{
19128132727Skan  switch (which_alternative)
19129132727Skan    {
19130132727Skan    case 0:
19131132727Skan    case 1:
19132132727Skan      return "#";
19133132727Skan    case 2:
19134132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
19135132727Skan	return "xorps\t%0, %0";
19136132727Skan      else
19137132727Skan	return "pxor\t%0, %0";
19138132727Skan    case 3:
19139132727Skan    case 4:
19140132727Skan      if (get_attr_mode (insn) == MODE_V4SF)
19141132727Skan	return "movaps\t{%1, %0|%0, %1}";
19142132727Skan      else
19143132727Skan	return "movdqa\t{%1, %0|%0, %1}";
19144132727Skan    default:
19145132727Skan      abort ();
19146132727Skan    }
19147132727Skan}
19148132727Skan  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19149132727Skan   (set (attr "mode")
19150132727Skan        (cond [(eq_attr "alternative" "2,3")
19151132727Skan		 (if_then_else
19152132727Skan		   (ne (symbol_ref "optimize_size")
19153132727Skan		       (const_int 0))
19154132727Skan		   (const_string "V4SF")
19155132727Skan		   (const_string "TI"))
19156132727Skan	       (eq_attr "alternative" "4")
19157132727Skan		 (if_then_else
19158132727Skan		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19159132727Skan			    (const_int 0))
19160132727Skan			(ne (symbol_ref "optimize_size")
19161132727Skan			    (const_int 0)))
19162132727Skan		   (const_string "V4SF")
19163132727Skan		   (const_string "TI"))]
19164132727Skan	       (const_string "DI")))])
19165132727Skan
1916690286Sobrien(define_split
1916790286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1916890286Sobrien        (match_operand:TI 1 "general_operand" ""))]
1916990286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
1917090286Sobrien   && !SSE_REG_P (operands[1])"
1917190286Sobrien  [(const_int 0)]
1917290286Sobrien  "ix86_split_long_move (operands); DONE;")
1917390286Sobrien
19174132727Skan(define_split
19175132727Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "")
19176132727Skan        (match_operand:TF 1 "general_operand" ""))]
19177132727Skan  "reload_completed && !SSE_REG_P (operands[0])
19178132727Skan   && !SSE_REG_P (operands[1])"
19179132727Skan  [(const_int 0)]
19180132727Skan  "ix86_split_long_move (operands); DONE;")
19181132727Skan
1918290286Sobrien;; These two patterns are useful for specifying exactly whether to use
1918390286Sobrien;; movaps or movups
19184117404Skan(define_expand "sse_movaps"
19185117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19186117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19187117404Skan		     UNSPEC_MOVA))]
1918890286Sobrien  "TARGET_SSE"
19189117404Skan{
19190117404Skan  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19191117404Skan    {
19192117404Skan      rtx tmp = gen_reg_rtx (V4SFmode);
19193117404Skan      emit_insn (gen_sse_movaps (tmp, operands[1]));
19194117404Skan      emit_move_insn (operands[0], tmp);
19195117404Skan      DONE;
19196117404Skan    }
19197117404Skan})
1919890286Sobrien
19199117404Skan(define_insn "*sse_movaps_1"
1920090286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19201117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19202117404Skan		     UNSPEC_MOVA))]
19203117404Skan  "TARGET_SSE
19204117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19205117404Skan  "movaps\t{%1, %0|%0, %1}"
19206117404Skan  [(set_attr "type" "ssemov,ssemov")
19207117404Skan   (set_attr "mode" "V4SF")])
19208117404Skan
19209117404Skan(define_expand "sse_movups"
19210117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19211117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19212117404Skan		     UNSPEC_MOVU))]
1921390286Sobrien  "TARGET_SSE"
19214117404Skan{
19215117404Skan  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19216117404Skan    {
19217117404Skan      rtx tmp = gen_reg_rtx (V4SFmode);
19218117404Skan      emit_insn (gen_sse_movups (tmp, operands[1]));
19219117404Skan      emit_move_insn (operands[0], tmp);
19220117404Skan      DONE;
19221117404Skan    }
19222117404Skan})
1922390286Sobrien
19224117404Skan(define_insn "*sse_movups_1"
19225117404Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19226117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19227117404Skan		     UNSPEC_MOVU))]
19228117404Skan  "TARGET_SSE
19229117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19230117404Skan  "movups\t{%1, %0|%0, %1}"
19231117404Skan  [(set_attr "type" "ssecvt,ssecvt")
19232117404Skan   (set_attr "mode" "V4SF")])
1923390286Sobrien
1923490286Sobrien;; SSE Strange Moves.
1923590286Sobrien
1923690286Sobrien(define_insn "sse_movmskps"
1923790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
19238117404Skan	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19239117404Skan		   UNSPEC_MOVMSK))]
1924090286Sobrien  "TARGET_SSE"
1924190286Sobrien  "movmskps\t{%1, %0|%0, %1}"
19242117404Skan  [(set_attr "type" "ssecvt")
19243117404Skan   (set_attr "mode" "V4SF")])
1924490286Sobrien
1924590286Sobrien(define_insn "mmx_pmovmskb"
1924690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
19247117404Skan	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19248117404Skan		   UNSPEC_MOVMSK))]
1924990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1925090286Sobrien  "pmovmskb\t{%1, %0|%0, %1}"
19251117404Skan  [(set_attr "type" "ssecvt")
19252117404Skan   (set_attr "mode" "V4SF")])
1925390286Sobrien
19254117404Skan
1925590286Sobrien(define_insn "mmx_maskmovq"
1925690286Sobrien  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1925790286Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19258117404Skan		      (match_operand:V8QI 2 "register_operand" "y")]
19259117404Skan		     UNSPEC_MASKMOV))]
1926096294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1926190286Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1926290286Sobrien  "maskmovq\t{%2, %1|%1, %2}"
19263117404Skan  [(set_attr "type" "mmxcvt")
19264117404Skan   (set_attr "mode" "DI")])
1926590286Sobrien
1926696294Sobrien(define_insn "mmx_maskmovq_rex"
1926796294Sobrien  [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1926896294Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19269117404Skan		      (match_operand:V8QI 2 "register_operand" "y")]
19270117404Skan		     UNSPEC_MASKMOV))]
1927196294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1927296294Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1927396294Sobrien  "maskmovq\t{%2, %1|%1, %2}"
19274117404Skan  [(set_attr "type" "mmxcvt")
19275117404Skan   (set_attr "mode" "DI")])
1927696294Sobrien
1927790286Sobrien(define_insn "sse_movntv4sf"
1927890286Sobrien  [(set (match_operand:V4SF 0 "memory_operand" "=m")
19279117404Skan	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19280117404Skan		     UNSPEC_MOVNT))]
1928190286Sobrien  "TARGET_SSE"
1928290286Sobrien  "movntps\t{%1, %0|%0, %1}"
19283117404Skan  [(set_attr "type" "ssemov")
19284117404Skan   (set_attr "mode" "V4SF")])
1928590286Sobrien
1928690286Sobrien(define_insn "sse_movntdi"
1928790286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
19288117404Skan	(unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19289117404Skan		   UNSPEC_MOVNT))]
1929090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1929190286Sobrien  "movntq\t{%1, %0|%0, %1}"
19292117404Skan  [(set_attr "type" "mmxmov")
19293117404Skan   (set_attr "mode" "DI")])
1929490286Sobrien
1929590286Sobrien(define_insn "sse_movhlps"
1929690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1929790286Sobrien	(vec_merge:V4SF
1929890286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1929990286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1930090286Sobrien			  (parallel [(const_int 2)
1930190286Sobrien				     (const_int 3)
1930290286Sobrien				     (const_int 0)
1930390286Sobrien				     (const_int 1)]))
1930490286Sobrien	 (const_int 3)))]
1930590286Sobrien  "TARGET_SSE"
1930690286Sobrien  "movhlps\t{%2, %0|%0, %2}"
19307117404Skan  [(set_attr "type" "ssecvt")
19308117404Skan   (set_attr "mode" "V4SF")])
1930990286Sobrien
1931090286Sobrien(define_insn "sse_movlhps"
1931190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1931290286Sobrien	(vec_merge:V4SF
1931390286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1931490286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1931590286Sobrien			  (parallel [(const_int 2)
1931690286Sobrien				     (const_int 3)
1931790286Sobrien				     (const_int 0)
1931890286Sobrien				     (const_int 1)]))
1931990286Sobrien	 (const_int 12)))]
1932090286Sobrien  "TARGET_SSE"
1932190286Sobrien  "movlhps\t{%2, %0|%0, %2}"
19322117404Skan  [(set_attr "type" "ssecvt")
19323117404Skan   (set_attr "mode" "V4SF")])
1932490286Sobrien
1932590286Sobrien(define_insn "sse_movhps"
1932690286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1932790286Sobrien	(vec_merge:V4SF
1932890286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1932990286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1933090286Sobrien	 (const_int 12)))]
1933190286Sobrien  "TARGET_SSE
1933290286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1933390286Sobrien  "movhps\t{%2, %0|%0, %2}"
19334117404Skan  [(set_attr "type" "ssecvt")
19335117404Skan   (set_attr "mode" "V4SF")])
1933690286Sobrien
1933790286Sobrien(define_insn "sse_movlps"
1933890286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1933990286Sobrien	(vec_merge:V4SF
1934090286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1934190286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1934290286Sobrien	 (const_int 3)))]
1934390286Sobrien  "TARGET_SSE
1934490286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1934590286Sobrien  "movlps\t{%2, %0|%0, %2}"
19346117404Skan  [(set_attr "type" "ssecvt")
19347117404Skan   (set_attr "mode" "V4SF")])
1934890286Sobrien
19349117404Skan(define_expand "sse_loadss"
19350117404Skan  [(match_operand:V4SF 0 "register_operand" "")
19351117404Skan   (match_operand:SF 1 "memory_operand" "")]
19352117404Skan  "TARGET_SSE"
19353117404Skan{
19354117404Skan  emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19355117404Skan			       CONST0_RTX (V4SFmode)));
19356117404Skan  DONE;
19357117404Skan})
19358117404Skan
19359117404Skan(define_insn "sse_loadss_1"
1936090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1936190286Sobrien	(vec_merge:V4SF
19362117404Skan	 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19363117404Skan	 (match_operand:V4SF 2 "const0_operand" "X")
1936490286Sobrien	 (const_int 1)))]
1936590286Sobrien  "TARGET_SSE"
1936690286Sobrien  "movss\t{%1, %0|%0, %1}"
19367117404Skan  [(set_attr "type" "ssemov")
19368117404Skan   (set_attr "mode" "SF")])
1936990286Sobrien
1937090286Sobrien(define_insn "sse_movss"
1937190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1937290286Sobrien	(vec_merge:V4SF
1937390286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1937490286Sobrien	 (match_operand:V4SF 2 "register_operand" "x")
1937590286Sobrien	 (const_int 1)))]
1937690286Sobrien  "TARGET_SSE"
1937790286Sobrien  "movss\t{%2, %0|%0, %2}"
19378117404Skan  [(set_attr "type" "ssemov")
19379117404Skan   (set_attr "mode" "SF")])
1938090286Sobrien
1938190286Sobrien(define_insn "sse_storess"
1938290286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
1938390286Sobrien	(vec_select:SF
1938490286Sobrien	 (match_operand:V4SF 1 "register_operand" "x")
1938590286Sobrien	 (parallel [(const_int 0)])))]
1938690286Sobrien  "TARGET_SSE"
1938790286Sobrien  "movss\t{%1, %0|%0, %1}"
19388117404Skan  [(set_attr "type" "ssemov")
19389117404Skan   (set_attr "mode" "SF")])
1939090286Sobrien
1939190286Sobrien(define_insn "sse_shufps"
1939290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1939390286Sobrien        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
1939490286Sobrien		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19395117404Skan		      (match_operand:SI 3 "immediate_operand" "i")]
19396117404Skan		     UNSPEC_SHUFFLE))]
1939790286Sobrien  "TARGET_SSE"
1939890286Sobrien  ;; @@@ check operand order for intel/nonintel syntax
1939990286Sobrien  "shufps\t{%3, %2, %0|%0, %2, %3}"
19400117404Skan  [(set_attr "type" "ssecvt")
19401117404Skan   (set_attr "mode" "V4SF")])
1940290286Sobrien
1940390286Sobrien
1940490286Sobrien;; SSE arithmetic
1940590286Sobrien
1940690286Sobrien(define_insn "addv4sf3"
1940790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1940890286Sobrien        (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1940990286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1941090286Sobrien  "TARGET_SSE"
1941190286Sobrien  "addps\t{%2, %0|%0, %2}"
19412117404Skan  [(set_attr "type" "sseadd")
19413117404Skan   (set_attr "mode" "V4SF")])
1941490286Sobrien
1941590286Sobrien(define_insn "vmaddv4sf3"
1941690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1941790286Sobrien	(vec_merge:V4SF
1941890286Sobrien	 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1941990286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1942090286Sobrien	 (match_dup 1)
1942190286Sobrien	 (const_int 1)))]
1942290286Sobrien  "TARGET_SSE"
1942390286Sobrien  "addss\t{%2, %0|%0, %2}"
19424117404Skan  [(set_attr "type" "sseadd")
19425117404Skan   (set_attr "mode" "SF")])
1942690286Sobrien
1942790286Sobrien(define_insn "subv4sf3"
1942890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1942990286Sobrien        (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1943090286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1943190286Sobrien  "TARGET_SSE"
1943290286Sobrien  "subps\t{%2, %0|%0, %2}"
19433117404Skan  [(set_attr "type" "sseadd")
19434117404Skan   (set_attr "mode" "V4SF")])
1943590286Sobrien
1943690286Sobrien(define_insn "vmsubv4sf3"
1943790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1943890286Sobrien	(vec_merge:V4SF
1943990286Sobrien	 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1944090286Sobrien		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1944190286Sobrien	 (match_dup 1)
1944290286Sobrien	 (const_int 1)))]
1944390286Sobrien  "TARGET_SSE"
1944490286Sobrien  "subss\t{%2, %0|%0, %2}"
19445117404Skan  [(set_attr "type" "sseadd")
19446117404Skan   (set_attr "mode" "SF")])
1944790286Sobrien
1944890286Sobrien(define_insn "mulv4sf3"
1944990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1945090286Sobrien        (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1945190286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1945290286Sobrien  "TARGET_SSE"
1945390286Sobrien  "mulps\t{%2, %0|%0, %2}"
19454117404Skan  [(set_attr "type" "ssemul")
19455117404Skan   (set_attr "mode" "V4SF")])
1945690286Sobrien
1945790286Sobrien(define_insn "vmmulv4sf3"
1945890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1945990286Sobrien	(vec_merge:V4SF
1946090286Sobrien	 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1946190286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1946290286Sobrien	 (match_dup 1)
1946390286Sobrien	 (const_int 1)))]
1946490286Sobrien  "TARGET_SSE"
1946590286Sobrien  "mulss\t{%2, %0|%0, %2}"
19466117404Skan  [(set_attr "type" "ssemul")
19467117404Skan   (set_attr "mode" "SF")])
1946890286Sobrien
1946990286Sobrien(define_insn "divv4sf3"
1947090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1947190286Sobrien        (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1947290286Sobrien	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1947390286Sobrien  "TARGET_SSE"
1947490286Sobrien  "divps\t{%2, %0|%0, %2}"
19475117404Skan  [(set_attr "type" "ssediv")
19476117404Skan   (set_attr "mode" "V4SF")])
1947790286Sobrien
1947890286Sobrien(define_insn "vmdivv4sf3"
1947990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1948090286Sobrien	(vec_merge:V4SF
1948190286Sobrien	 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1948290286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1948390286Sobrien	 (match_dup 1)
1948490286Sobrien	 (const_int 1)))]
1948590286Sobrien  "TARGET_SSE"
1948690286Sobrien  "divss\t{%2, %0|%0, %2}"
19487117404Skan  [(set_attr "type" "ssediv")
19488117404Skan   (set_attr "mode" "SF")])
1948990286Sobrien
1949090286Sobrien
1949190286Sobrien;; SSE square root/reciprocal
1949290286Sobrien
1949390286Sobrien(define_insn "rcpv4sf2"
1949490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1949590286Sobrien        (unspec:V4SF
19496117404Skan	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
1949790286Sobrien  "TARGET_SSE"
1949890286Sobrien  "rcpps\t{%1, %0|%0, %1}"
19499117404Skan  [(set_attr "type" "sse")
19500117404Skan   (set_attr "mode" "V4SF")])
1950190286Sobrien
1950290286Sobrien(define_insn "vmrcpv4sf2"
1950390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1950490286Sobrien	(vec_merge:V4SF
19505117404Skan	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19506117404Skan		      UNSPEC_RCP)
1950790286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1950890286Sobrien	 (const_int 1)))]
1950990286Sobrien  "TARGET_SSE"
1951090286Sobrien  "rcpss\t{%1, %0|%0, %1}"
19511117404Skan  [(set_attr "type" "sse")
19512117404Skan   (set_attr "mode" "SF")])
1951390286Sobrien
1951490286Sobrien(define_insn "rsqrtv4sf2"
1951590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1951690286Sobrien        (unspec:V4SF
19517117404Skan	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
1951890286Sobrien  "TARGET_SSE"
1951990286Sobrien  "rsqrtps\t{%1, %0|%0, %1}"
19520117404Skan  [(set_attr "type" "sse")
19521117404Skan   (set_attr "mode" "V4SF")])
1952290286Sobrien
1952390286Sobrien(define_insn "vmrsqrtv4sf2"
1952490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1952590286Sobrien	(vec_merge:V4SF
19526117404Skan	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19527117404Skan		      UNSPEC_RSQRT)
1952890286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1952990286Sobrien	 (const_int 1)))]
1953090286Sobrien  "TARGET_SSE"
1953190286Sobrien  "rsqrtss\t{%1, %0|%0, %1}"
19532117404Skan  [(set_attr "type" "sse")
19533117404Skan   (set_attr "mode" "SF")])
1953490286Sobrien
1953590286Sobrien(define_insn "sqrtv4sf2"
1953690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1953790286Sobrien        (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1953890286Sobrien  "TARGET_SSE"
1953990286Sobrien  "sqrtps\t{%1, %0|%0, %1}"
19540117404Skan  [(set_attr "type" "sse")
19541117404Skan   (set_attr "mode" "V4SF")])
1954290286Sobrien
1954390286Sobrien(define_insn "vmsqrtv4sf2"
1954490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1954590286Sobrien	(vec_merge:V4SF
1954690286Sobrien	 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1954790286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1954890286Sobrien	 (const_int 1)))]
1954990286Sobrien  "TARGET_SSE"
1955090286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
19551117404Skan  [(set_attr "type" "sse")
19552117404Skan   (set_attr "mode" "SF")])
1955390286Sobrien
1955490286Sobrien;; SSE logical operations.
1955590286Sobrien
19556117404Skan;; SSE defines logical operations on floating point values.  This brings
19557117404Skan;; interesting challenge to RTL representation where logicals are only valid
19558117404Skan;; on integral types.  We deal with this by representing the floating point
19559117404Skan;; logical as logical on arguments casted to TImode as this is what hardware
19560117404Skan;; really does.  Unfortunately hardware requires the type information to be
19561132727Skan;; present and thus we must avoid subregs from being simplified and eliminated
19562117404Skan;; in later compilation phases.
19563117404Skan;;
19564117404Skan;; We have following variants from each instruction:
19565117404Skan;; sse_andsf3 - the operation taking V4SF vector operands
19566117404Skan;;              and doing TImode cast on them
19567117404Skan;; *sse_andsf3_memory - the operation taking one memory operand casted to
19568132727Skan;;                      TImode, since backend insist on eliminating casts
19569117404Skan;;                      on memory operands
19570117404Skan;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19571117404Skan;;                   We can not accept memory operand here as instruction reads
19572117404Skan;;		     whole scalar.  This is generated only post reload by GCC
19573117404Skan;;		     scalar float operations that expands to logicals (fabs)
19574117404Skan;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19575117404Skan;;		     memory operand.  Eventually combine can be able
19576132727Skan;;		     to synthesize these using splitter.
19577117404Skan;; sse2_anddf3, *sse2_anddf3_memory
19578117404Skan;;              
19579117404Skan;; 
1958090286Sobrien;; These are not called andti3 etc. because we really really don't want
1958190286Sobrien;; the compiler to widen DImode ands to TImode ands and then try to move
1958290286Sobrien;; into DImode subregs of SSE registers, and them together, and move out
1958390286Sobrien;; of DImode subregs again!
19584117404Skan;; SSE1 single precision floating point logical operation
19585117404Skan(define_expand "sse_andv4sf3"
19586146906Skan  [(set (match_operand:V4SF 0 "register_operand" "")
19587146906Skan        (and:V4SF (match_operand:V4SF 1 "register_operand" "")
19588146906Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19589117404Skan  "TARGET_SSE"
19590117404Skan  "")
1959190286Sobrien
19592117404Skan(define_insn "*sse_andv4sf3"
19593146906Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
19594146906Skan        (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19595146906Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19596117404Skan  "TARGET_SSE
19597117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19598117404Skan  "andps\t{%2, %0|%0, %2}"
19599117404Skan  [(set_attr "type" "sselog")
19600117404Skan   (set_attr "mode" "V4SF")])
1960190286Sobrien
19602117404Skan(define_expand "sse_nandv4sf3"
19603146906Skan  [(set (match_operand:V4SF 0 "register_operand" "")
19604146906Skan        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
19605146906Skan	          (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19606117404Skan  "TARGET_SSE"
19607117404Skan  "")
19608117404Skan
19609117404Skan(define_insn "*sse_nandv4sf3"
19610146906Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
19611146906Skan        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
19612146906Skan	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19613117404Skan  "TARGET_SSE"
19614117404Skan  "andnps\t{%2, %0|%0, %2}"
19615117404Skan  [(set_attr "type" "sselog")
19616117404Skan   (set_attr "mode" "V4SF")])
19617117404Skan
19618117404Skan(define_expand "sse_iorv4sf3"
19619146906Skan  [(set (match_operand:V4SF 0 "register_operand" "")
19620146906Skan        (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
19621146906Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19622117404Skan  "TARGET_SSE"
19623117404Skan  "")
19624117404Skan
19625117404Skan(define_insn "*sse_iorv4sf3"
19626146906Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
19627146906Skan        (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19628146906Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19629117404Skan  "TARGET_SSE
19630117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19631117404Skan  "orps\t{%2, %0|%0, %2}"
19632117404Skan  [(set_attr "type" "sselog")
19633117404Skan   (set_attr "mode" "V4SF")])
19634117404Skan
19635117404Skan(define_expand "sse_xorv4sf3"
19636146906Skan  [(set (match_operand:V4SF 0 "register_operand" "")
19637146906Skan        (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
19638146906Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19639146906Skan  "TARGET_SSE"
19640117404Skan  "")
19641117404Skan
19642117404Skan(define_insn "*sse_xorv4sf3"
19643146906Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
19644146906Skan        (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19645146906Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19646117404Skan  "TARGET_SSE
1964796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19648117404Skan  "xorps\t{%2, %0|%0, %2}"
19649117404Skan  [(set_attr "type" "sselog")
19650117404Skan   (set_attr "mode" "V4SF")])
1965190286Sobrien
19652117404Skan;; SSE2 double precision floating point logical operation
19653117404Skan
19654117404Skan(define_expand "sse2_andv2df3"
19655146906Skan  [(set (match_operand:V2DF 0 "register_operand" "")
19656146906Skan        (and:V2DF (match_operand:V2DF 1 "register_operand" "")
19657146906Skan	          (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1965890286Sobrien  "TARGET_SSE2"
19659117404Skan  "")
1966090286Sobrien
19661117404Skan(define_insn "*sse2_andv2df3"
19662146906Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
19663146906Skan        (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19664146906Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19665117404Skan  "TARGET_SSE2
19666117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19667117404Skan  "andpd\t{%2, %0|%0, %2}"
19668117404Skan  [(set_attr "type" "sselog")
19669117404Skan   (set_attr "mode" "V2DF")])
1967090286Sobrien
19671117404Skan(define_expand "sse2_nandv2df3"
19672146906Skan  [(set (match_operand:V2DF 0 "register_operand" "")
19673146906Skan        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
19674146906Skan	          (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1967590286Sobrien  "TARGET_SSE2"
19676117404Skan  "")
1967790286Sobrien
19678117404Skan(define_insn "*sse2_nandv2df3"
19679146906Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
19680146906Skan        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
19681146906Skan	          (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1968290286Sobrien  "TARGET_SSE2"
19683117404Skan  "andnpd\t{%2, %0|%0, %2}"
19684117404Skan  [(set_attr "type" "sselog")
19685117404Skan   (set_attr "mode" "V2DF")])
1968690286Sobrien
19687117404Skan(define_expand "sse2_iorv2df3"
19688146906Skan  [(set (match_operand:V2DF 0 "register_operand" "")
19689146906Skan        (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
19690146906Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19691117404Skan  "TARGET_SSE2"
19692117404Skan  "")
1969390286Sobrien
19694117404Skan(define_insn "*sse2_iorv2df3"
19695146906Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
19696146906Skan        (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19697146906Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19698117404Skan  "TARGET_SSE2
1969996294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19700117404Skan  "orpd\t{%2, %0|%0, %2}"
19701117404Skan  [(set_attr "type" "sselog")
19702117404Skan   (set_attr "mode" "V2DF")])
1970390286Sobrien
19704117404Skan(define_expand "sse2_xorv2df3"
19705146906Skan  [(set (match_operand:V2DF 0 "register_operand" "")
19706146906Skan        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
19707146906Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1970890286Sobrien  "TARGET_SSE2"
19709117404Skan  "")
19710117404Skan
19711117404Skan(define_insn "*sse2_xorv2df3"
19712146906Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
19713146906Skan        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19714146906Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19715117404Skan  "TARGET_SSE2
19716117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1971790286Sobrien  "xorpd\t{%2, %0|%0, %2}"
19718117404Skan  [(set_attr "type" "sselog")
19719117404Skan   (set_attr "mode" "V2DF")])
1972090286Sobrien
19721117404Skan;; SSE2 integral logicals.  These patterns must always come after floating
19722117404Skan;; point ones since we don't want compiler to use integer opcodes on floating
19723117404Skan;; point SSE values to avoid matching of subregs in the match_operand.
19724117404Skan(define_insn "*sse2_andti3"
19725117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
19726117404Skan        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19727117404Skan		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
19728117404Skan  "TARGET_SSE2
19729117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19730117404Skan  "pand\t{%2, %0|%0, %2}"
19731117404Skan  [(set_attr "type" "sselog")
19732117404Skan   (set_attr "mode" "TI")])
1973390286Sobrien
19734117404Skan(define_insn "sse2_andv2di3"
19735117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
19736117404Skan        (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19737117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19738117404Skan  "TARGET_SSE2
19739117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19740117404Skan  "pand\t{%2, %0|%0, %2}"
19741117404Skan  [(set_attr "type" "sselog")
19742117404Skan   (set_attr "mode" "TI")])
19743117404Skan
19744117404Skan(define_insn "*sse2_nandti3"
19745117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
19746117404Skan        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1974790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
19748117404Skan  "TARGET_SSE2"
19749117404Skan  "pandn\t{%2, %0|%0, %2}"
19750117404Skan  [(set_attr "type" "sselog")
19751117404Skan   (set_attr "mode" "TI")])
1975290286Sobrien
19753117404Skan(define_insn "sse2_nandv2di3"
19754117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
19755132727Skan        (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19756117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19757117404Skan  "TARGET_SSE2
19758117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19759117404Skan  "pandn\t{%2, %0|%0, %2}"
19760117404Skan  [(set_attr "type" "sselog")
19761117404Skan   (set_attr "mode" "TI")])
19762117404Skan
19763117404Skan(define_insn "*sse2_iorti3"
1976490286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
19765117404Skan        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1976690286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
19767117404Skan  "TARGET_SSE2
1976896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19769117404Skan  "por\t{%2, %0|%0, %2}"
19770117404Skan  [(set_attr "type" "sselog")
19771117404Skan   (set_attr "mode" "TI")])
1977290286Sobrien
19773117404Skan(define_insn "sse2_iorv2di3"
19774117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
19775117404Skan        (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19776117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19777117404Skan  "TARGET_SSE2
19778117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19779117404Skan  "por\t{%2, %0|%0, %2}"
19780117404Skan  [(set_attr "type" "sselog")
19781117404Skan   (set_attr "mode" "TI")])
19782117404Skan
19783117404Skan(define_insn "*sse2_xorti3"
1978490286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1978596294Sobrien        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1978690286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1978796294Sobrien  "TARGET_SSE2
1978896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1978990286Sobrien  "pxor\t{%2, %0|%0, %2}"
19790117404Skan  [(set_attr "type" "sselog")
19791117404Skan   (set_attr "mode" "TI")])
1979290286Sobrien
19793117404Skan(define_insn "sse2_xorv2di3"
19794117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
19795117404Skan        (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19796117404Skan		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19797117404Skan  "TARGET_SSE2
19798117404Skan   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19799117404Skan  "pxor\t{%2, %0|%0, %2}"
19800117404Skan  [(set_attr "type" "sselog")
19801117404Skan   (set_attr "mode" "TI")])
19802117404Skan
1980390286Sobrien;; Use xor, but don't show input operands so they aren't live before
1980490286Sobrien;; this insn.
1980590286Sobrien(define_insn "sse_clrv4sf"
1980690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
19807132727Skan	(match_operand:V4SF 1 "const0_operand" "X"))]
1980890286Sobrien  "TARGET_SSE"
19809132727Skan{
19810132727Skan  if (get_attr_mode (insn) == MODE_TI)
19811132727Skan    return "pxor\t{%0, %0|%0, %0}";
19812132727Skan  else
19813132727Skan    return "xorps\t{%0, %0|%0, %0}";
19814132727Skan}
19815117404Skan  [(set_attr "type" "sselog")
19816117404Skan   (set_attr "memory" "none")
19817132727Skan   (set (attr "mode")
19818132727Skan	(if_then_else
19819132727Skan	   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19820132727Skan			 (const_int 0))
19821132727Skan		     (ne (symbol_ref "TARGET_SSE2")
19822132727Skan			 (const_int 0)))
19823132727Skan		(eq (symbol_ref "optimize_size")
19824132727Skan		    (const_int 0)))
19825132727Skan	 (const_string "TI")
19826132727Skan	 (const_string "V4SF")))])
1982790286Sobrien
19828117404Skan;; Use xor, but don't show input operands so they aren't live before
19829117404Skan;; this insn.
19830117404Skan(define_insn "sse_clrv2df"
19831117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
19832117404Skan        (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19833117404Skan  "TARGET_SSE2"
19834117404Skan  "xorpd\t{%0, %0|%0, %0}"
19835117404Skan  [(set_attr "type" "sselog")
19836117404Skan   (set_attr "memory" "none")
19837117404Skan   (set_attr "mode" "V4SF")])
19838117404Skan
1983990286Sobrien;; SSE mask-generating compares
1984090286Sobrien
1984190286Sobrien(define_insn "maskcmpv4sf3"
1984290286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1984390286Sobrien        (match_operator:V4SI 3 "sse_comparison_operator"
1984490286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1984590286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))]
1984690286Sobrien  "TARGET_SSE"
1984790286Sobrien  "cmp%D3ps\t{%2, %0|%0, %2}"
19848117404Skan  [(set_attr "type" "ssecmp")
19849117404Skan   (set_attr "mode" "V4SF")])
1985090286Sobrien
1985190286Sobrien(define_insn "maskncmpv4sf3"
1985290286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1985390286Sobrien        (not:V4SI
1985490286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1985590286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1985690286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])))]
1985790286Sobrien  "TARGET_SSE"
1985890286Sobrien{
1985990286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1986090286Sobrien    return "cmpordps\t{%2, %0|%0, %2}";
1986190286Sobrien  else
1986290286Sobrien    return "cmpn%D3ps\t{%2, %0|%0, %2}";
1986390286Sobrien}
19864117404Skan  [(set_attr "type" "ssecmp")
19865117404Skan   (set_attr "mode" "V4SF")])
1986690286Sobrien
1986790286Sobrien(define_insn "vmmaskcmpv4sf3"
1986890286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1986990286Sobrien	(vec_merge:V4SI
1987090286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1987190286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1987290286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])
19873117404Skan	 (subreg:V4SI (match_dup 1) 0)
1987490286Sobrien	 (const_int 1)))]
1987590286Sobrien  "TARGET_SSE"
1987690286Sobrien  "cmp%D3ss\t{%2, %0|%0, %2}"
19877117404Skan  [(set_attr "type" "ssecmp")
19878117404Skan   (set_attr "mode" "SF")])
1987990286Sobrien
1988090286Sobrien(define_insn "vmmaskncmpv4sf3"
1988190286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1988290286Sobrien	(vec_merge:V4SI
1988390286Sobrien	 (not:V4SI
1988490286Sobrien	  (match_operator:V4SI 3 "sse_comparison_operator"
1988590286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1988690286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))
1988790286Sobrien	 (subreg:V4SI (match_dup 1) 0)
1988890286Sobrien	 (const_int 1)))]
1988990286Sobrien  "TARGET_SSE"
1989090286Sobrien{
1989190286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1989290286Sobrien    return "cmpordss\t{%2, %0|%0, %2}";
1989390286Sobrien  else
1989490286Sobrien    return "cmpn%D3ss\t{%2, %0|%0, %2}";
1989590286Sobrien}
19896117404Skan  [(set_attr "type" "ssecmp")
19897117404Skan   (set_attr "mode" "SF")])
1989890286Sobrien
1989990286Sobrien(define_insn "sse_comi"
1990090286Sobrien  [(set (reg:CCFP 17)
19901117404Skan        (compare:CCFP (vec_select:SF
19902117404Skan		       (match_operand:V4SF 0 "register_operand" "x")
19903117404Skan		       (parallel [(const_int 0)]))
19904117404Skan		      (vec_select:SF
19905117404Skan		       (match_operand:V4SF 1 "register_operand" "x")
19906117404Skan		       (parallel [(const_int 0)]))))]
1990790286Sobrien  "TARGET_SSE"
1990890286Sobrien  "comiss\t{%1, %0|%0, %1}"
19909132727Skan  [(set_attr "type" "ssecomi")
19910117404Skan   (set_attr "mode" "SF")])
1991190286Sobrien
1991290286Sobrien(define_insn "sse_ucomi"
1991390286Sobrien  [(set (reg:CCFPU 17)
19914117404Skan	(compare:CCFPU (vec_select:SF
19915117404Skan			(match_operand:V4SF 0 "register_operand" "x")
19916117404Skan			(parallel [(const_int 0)]))
19917117404Skan		       (vec_select:SF
19918117404Skan			(match_operand:V4SF 1 "register_operand" "x")
19919117404Skan			(parallel [(const_int 0)]))))]
1992090286Sobrien  "TARGET_SSE"
1992190286Sobrien  "ucomiss\t{%1, %0|%0, %1}"
19922132727Skan  [(set_attr "type" "ssecomi")
19923117404Skan   (set_attr "mode" "SF")])
1992490286Sobrien
1992590286Sobrien
1992690286Sobrien;; SSE unpack
1992790286Sobrien
1992890286Sobrien(define_insn "sse_unpckhps"
1992990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1993090286Sobrien	(vec_merge:V4SF
1993190286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1993290286Sobrien			  (parallel [(const_int 2)
1993390286Sobrien				     (const_int 0)
1993490286Sobrien				     (const_int 3)
1993590286Sobrien				     (const_int 1)]))
1993690286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1993790286Sobrien			  (parallel [(const_int 0)
1993890286Sobrien				     (const_int 2)
1993990286Sobrien				     (const_int 1)
1994090286Sobrien				     (const_int 3)]))
1994190286Sobrien	 (const_int 5)))]
1994290286Sobrien  "TARGET_SSE"
1994390286Sobrien  "unpckhps\t{%2, %0|%0, %2}"
19944117404Skan  [(set_attr "type" "ssecvt")
19945117404Skan   (set_attr "mode" "V4SF")])
1994690286Sobrien
1994790286Sobrien(define_insn "sse_unpcklps"
1994890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1994990286Sobrien	(vec_merge:V4SF
1995090286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1995190286Sobrien			  (parallel [(const_int 0)
1995290286Sobrien				     (const_int 2)
1995390286Sobrien				     (const_int 1)
1995490286Sobrien				     (const_int 3)]))
1995590286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1995690286Sobrien			  (parallel [(const_int 2)
1995790286Sobrien				     (const_int 0)
1995890286Sobrien				     (const_int 3)
1995990286Sobrien				     (const_int 1)]))
1996090286Sobrien	 (const_int 5)))]
1996190286Sobrien  "TARGET_SSE"
1996290286Sobrien  "unpcklps\t{%2, %0|%0, %2}"
19963117404Skan  [(set_attr "type" "ssecvt")
19964117404Skan   (set_attr "mode" "V4SF")])
1996590286Sobrien
1996690286Sobrien
1996790286Sobrien;; SSE min/max
1996890286Sobrien
1996990286Sobrien(define_insn "smaxv4sf3"
1997090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1997190286Sobrien        (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1997290286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1997390286Sobrien  "TARGET_SSE"
1997490286Sobrien  "maxps\t{%2, %0|%0, %2}"
19975117404Skan  [(set_attr "type" "sse")
19976117404Skan   (set_attr "mode" "V4SF")])
1997790286Sobrien
1997890286Sobrien(define_insn "vmsmaxv4sf3"
1997990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1998090286Sobrien	(vec_merge:V4SF
1998190286Sobrien	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1998290286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1998390286Sobrien	 (match_dup 1)
1998490286Sobrien	 (const_int 1)))]
1998590286Sobrien  "TARGET_SSE"
1998690286Sobrien  "maxss\t{%2, %0|%0, %2}"
19987117404Skan  [(set_attr "type" "sse")
19988117404Skan   (set_attr "mode" "SF")])
1998990286Sobrien
1999090286Sobrien(define_insn "sminv4sf3"
1999190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1999290286Sobrien        (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1999390286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1999490286Sobrien  "TARGET_SSE"
1999590286Sobrien  "minps\t{%2, %0|%0, %2}"
19996117404Skan  [(set_attr "type" "sse")
19997117404Skan   (set_attr "mode" "V4SF")])
1999890286Sobrien
1999990286Sobrien(define_insn "vmsminv4sf3"
2000090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
2000190286Sobrien	(vec_merge:V4SF
2000290286Sobrien	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
2000390286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
2000490286Sobrien	 (match_dup 1)
2000590286Sobrien	 (const_int 1)))]
2000690286Sobrien  "TARGET_SSE"
2000790286Sobrien  "minss\t{%2, %0|%0, %2}"
20008117404Skan  [(set_attr "type" "sse")
20009117404Skan   (set_attr "mode" "SF")])
2001090286Sobrien
2001190286Sobrien;; SSE <-> integer/MMX conversions
2001290286Sobrien
2001390286Sobrien(define_insn "cvtpi2ps"
2001490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
2001590286Sobrien	(vec_merge:V4SF
2001690286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
2001790286Sobrien	 (vec_duplicate:V4SF
2001890286Sobrien	  (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
2001990286Sobrien	 (const_int 12)))]
2002090286Sobrien  "TARGET_SSE"
2002190286Sobrien  "cvtpi2ps\t{%2, %0|%0, %2}"
20022117404Skan  [(set_attr "type" "ssecvt")
20023117404Skan   (set_attr "mode" "V4SF")])
2002490286Sobrien
2002590286Sobrien(define_insn "cvtps2pi"
2002690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2002790286Sobrien	(vec_select:V2SI
2002890286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
2002990286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
2003090286Sobrien  "TARGET_SSE"
2003190286Sobrien  "cvtps2pi\t{%1, %0|%0, %1}"
20032117404Skan  [(set_attr "type" "ssecvt")
20033117404Skan   (set_attr "mode" "V4SF")])
2003490286Sobrien
2003590286Sobrien(define_insn "cvttps2pi"
2003690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2003790286Sobrien	(vec_select:V2SI
20038117404Skan	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20039117404Skan		      UNSPEC_FIX)
2004090286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
2004190286Sobrien  "TARGET_SSE"
2004290286Sobrien  "cvttps2pi\t{%1, %0|%0, %1}"
20043117404Skan  [(set_attr "type" "ssecvt")
20044117404Skan   (set_attr "mode" "SF")])
2004590286Sobrien
2004690286Sobrien(define_insn "cvtsi2ss"
20047132727Skan  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
2004890286Sobrien	(vec_merge:V4SF
20049132727Skan	 (match_operand:V4SF 1 "register_operand" "0,0")
2005090286Sobrien	 (vec_duplicate:V4SF
20051132727Skan	  (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
2005290286Sobrien	 (const_int 14)))]
2005390286Sobrien  "TARGET_SSE"
2005490286Sobrien  "cvtsi2ss\t{%2, %0|%0, %2}"
20055132727Skan  [(set_attr "type" "sseicvt")
20056132727Skan   (set_attr "athlon_decode" "vector,double")
20057117404Skan   (set_attr "mode" "SF")])
2005890286Sobrien
20059117404Skan(define_insn "cvtsi2ssq"
20060117404Skan  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20061117404Skan	(vec_merge:V4SF
20062117404Skan	 (match_operand:V4SF 1 "register_operand" "0,0")
20063117404Skan	 (vec_duplicate:V4SF
20064117404Skan	  (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20065117404Skan	 (const_int 14)))]
20066117404Skan  "TARGET_SSE && TARGET_64BIT"
20067117404Skan  "cvtsi2ssq\t{%2, %0|%0, %2}"
20068132727Skan  [(set_attr "type" "sseicvt")
20069132727Skan   (set_attr "athlon_decode" "vector,double")
20070117404Skan   (set_attr "mode" "SF")])
20071117404Skan
2007290286Sobrien(define_insn "cvtss2si"
20073132727Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
2007490286Sobrien	(vec_select:SI
20075132727Skan	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
2007690286Sobrien	 (parallel [(const_int 0)])))]
2007790286Sobrien  "TARGET_SSE"
2007890286Sobrien  "cvtss2si\t{%1, %0|%0, %1}"
20079132727Skan  [(set_attr "type" "sseicvt")
20080132727Skan   (set_attr "athlon_decode" "double,vector")
20081132727Skan   (set_attr "mode" "SI")])
2008290286Sobrien
20083117404Skan(define_insn "cvtss2siq"
20084117404Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
20085117404Skan	(vec_select:DI
20086117404Skan	 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20087117404Skan	 (parallel [(const_int 0)])))]
20088117404Skan  "TARGET_SSE"
20089117404Skan  "cvtss2siq\t{%1, %0|%0, %1}"
20090132727Skan  [(set_attr "type" "sseicvt")
20091132727Skan   (set_attr "athlon_decode" "double,vector")
20092132727Skan   (set_attr "mode" "DI")])
20093117404Skan
2009490286Sobrien(define_insn "cvttss2si"
20095132727Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
2009690286Sobrien	(vec_select:SI
20097132727Skan	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20098117404Skan		      UNSPEC_FIX)
2009990286Sobrien	 (parallel [(const_int 0)])))]
2010090286Sobrien  "TARGET_SSE"
2010190286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
20102132727Skan  [(set_attr "type" "sseicvt")
20103132727Skan   (set_attr "mode" "SF")
20104132727Skan   (set_attr "athlon_decode" "double,vector")])
2010590286Sobrien
20106117404Skan(define_insn "cvttss2siq"
20107117404Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
20108117404Skan	(vec_select:DI
20109117404Skan	 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20110117404Skan		      UNSPEC_FIX)
20111117404Skan	 (parallel [(const_int 0)])))]
20112117404Skan  "TARGET_SSE && TARGET_64BIT"
20113117404Skan  "cvttss2siq\t{%1, %0|%0, %1}"
20114132727Skan  [(set_attr "type" "sseicvt")
20115117404Skan   (set_attr "mode" "SF")
20116132727Skan   (set_attr "athlon_decode" "double,vector")])
2011790286Sobrien
20118117404Skan
2011990286Sobrien;; MMX insns
2012090286Sobrien
2012190286Sobrien;; MMX arithmetic
2012290286Sobrien
2012390286Sobrien(define_insn "addv8qi3"
2012490286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
20125117404Skan        (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
2012690286Sobrien	           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2012790286Sobrien  "TARGET_MMX"
2012890286Sobrien  "paddb\t{%2, %0|%0, %2}"
20129117404Skan  [(set_attr "type" "mmxadd")
20130117404Skan   (set_attr "mode" "DI")])
2013190286Sobrien
2013290286Sobrien(define_insn "addv4hi3"
2013390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
20134117404Skan        (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
2013590286Sobrien	           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2013690286Sobrien  "TARGET_MMX"
2013790286Sobrien  "paddw\t{%2, %0|%0, %2}"
20138117404Skan  [(set_attr "type" "mmxadd")
20139117404Skan   (set_attr "mode" "DI")])
2014090286Sobrien
2014190286Sobrien(define_insn "addv2si3"
2014290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
20143117404Skan        (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
2014490286Sobrien	           (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
2014590286Sobrien  "TARGET_MMX"
2014690286Sobrien  "paddd\t{%2, %0|%0, %2}"
20147117404Skan  [(set_attr "type" "mmxadd")
20148117404Skan   (set_attr "mode" "DI")])
2014990286Sobrien
20150117404Skan(define_insn "mmx_adddi3"
20151117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
20152117404Skan        (unspec:DI
20153117404Skan	 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20154117404Skan		   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20155117404Skan	 UNSPEC_NOP))]
20156117404Skan  "TARGET_MMX"
20157117404Skan  "paddq\t{%2, %0|%0, %2}"
20158117404Skan  [(set_attr "type" "mmxadd")
20159117404Skan   (set_attr "mode" "DI")])
20160117404Skan
2016190286Sobrien(define_insn "ssaddv8qi3"
2016290286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
20163117404Skan        (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
2016490286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2016590286Sobrien  "TARGET_MMX"
2016690286Sobrien  "paddsb\t{%2, %0|%0, %2}"
20167117404Skan  [(set_attr "type" "mmxadd")
20168117404Skan   (set_attr "mode" "DI")])
2016990286Sobrien
2017090286Sobrien(define_insn "ssaddv4hi3"
2017190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
20172117404Skan        (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
2017390286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2017490286Sobrien  "TARGET_MMX"
2017590286Sobrien  "paddsw\t{%2, %0|%0, %2}"
20176117404Skan  [(set_attr "type" "mmxadd")
20177117404Skan   (set_attr "mode" "DI")])
2017890286Sobrien
2017990286Sobrien(define_insn "usaddv8qi3"
2018090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
20181117404Skan        (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
2018290286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2018390286Sobrien  "TARGET_MMX"
2018490286Sobrien  "paddusb\t{%2, %0|%0, %2}"
20185117404Skan  [(set_attr "type" "mmxadd")
20186117404Skan   (set_attr "mode" "DI")])
2018790286Sobrien
2018890286Sobrien(define_insn "usaddv4hi3"
2018990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
20190117404Skan        (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
2019190286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2019290286Sobrien  "TARGET_MMX"
2019390286Sobrien  "paddusw\t{%2, %0|%0, %2}"
20194117404Skan  [(set_attr "type" "mmxadd")
20195117404Skan   (set_attr "mode" "DI")])
2019690286Sobrien
2019790286Sobrien(define_insn "subv8qi3"
2019890286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2019990286Sobrien        (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
2020090286Sobrien		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2020190286Sobrien  "TARGET_MMX"
2020290286Sobrien  "psubb\t{%2, %0|%0, %2}"
20203117404Skan  [(set_attr "type" "mmxadd")
20204117404Skan   (set_attr "mode" "DI")])
2020590286Sobrien
2020690286Sobrien(define_insn "subv4hi3"
2020790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2020890286Sobrien        (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
2020990286Sobrien		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2021090286Sobrien  "TARGET_MMX"
2021190286Sobrien  "psubw\t{%2, %0|%0, %2}"
20212117404Skan  [(set_attr "type" "mmxadd")
20213117404Skan   (set_attr "mode" "DI")])
2021490286Sobrien
2021590286Sobrien(define_insn "subv2si3"
2021690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2021790286Sobrien        (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
2021890286Sobrien		    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
2021990286Sobrien  "TARGET_MMX"
2022090286Sobrien  "psubd\t{%2, %0|%0, %2}"
20221117404Skan  [(set_attr "type" "mmxadd")
20222117404Skan   (set_attr "mode" "DI")])
2022390286Sobrien
20224117404Skan(define_insn "mmx_subdi3"
20225117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
20226117404Skan        (unspec:DI
20227117404Skan	 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20228117404Skan		    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20229117404Skan	 UNSPEC_NOP))]
20230117404Skan  "TARGET_MMX"
20231117404Skan  "psubq\t{%2, %0|%0, %2}"
20232117404Skan  [(set_attr "type" "mmxadd")
20233117404Skan   (set_attr "mode" "DI")])
20234117404Skan
2023590286Sobrien(define_insn "sssubv8qi3"
2023690286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2023790286Sobrien        (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
2023890286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2023990286Sobrien  "TARGET_MMX"
2024090286Sobrien  "psubsb\t{%2, %0|%0, %2}"
20241117404Skan  [(set_attr "type" "mmxadd")
20242117404Skan   (set_attr "mode" "DI")])
2024390286Sobrien
2024490286Sobrien(define_insn "sssubv4hi3"
2024590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2024690286Sobrien        (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
2024790286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2024890286Sobrien  "TARGET_MMX"
2024990286Sobrien  "psubsw\t{%2, %0|%0, %2}"
20250117404Skan  [(set_attr "type" "mmxadd")
20251117404Skan   (set_attr "mode" "DI")])
2025290286Sobrien
2025390286Sobrien(define_insn "ussubv8qi3"
2025490286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2025590286Sobrien        (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
2025690286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2025790286Sobrien  "TARGET_MMX"
2025890286Sobrien  "psubusb\t{%2, %0|%0, %2}"
20259117404Skan  [(set_attr "type" "mmxadd")
20260117404Skan   (set_attr "mode" "DI")])
2026190286Sobrien
2026290286Sobrien(define_insn "ussubv4hi3"
2026390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2026490286Sobrien        (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
2026590286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2026690286Sobrien  "TARGET_MMX"
2026790286Sobrien  "psubusw\t{%2, %0|%0, %2}"
20268117404Skan  [(set_attr "type" "mmxadd")
20269117404Skan   (set_attr "mode" "DI")])
2027090286Sobrien
2027190286Sobrien(define_insn "mulv4hi3"
2027290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2027390286Sobrien        (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
2027490286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2027590286Sobrien  "TARGET_MMX"
2027690286Sobrien  "pmullw\t{%2, %0|%0, %2}"
20277117404Skan  [(set_attr "type" "mmxmul")
20278117404Skan   (set_attr "mode" "DI")])
2027990286Sobrien
2028090286Sobrien(define_insn "smulv4hi3_highpart"
2028190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2028290286Sobrien	(truncate:V4HI
2028390286Sobrien	 (lshiftrt:V4SI
2028490286Sobrien	  (mult:V4SI (sign_extend:V4SI
2028590286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
2028690286Sobrien		     (sign_extend:V4SI
2028790286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
2028890286Sobrien	  (const_int 16))))]
2028990286Sobrien  "TARGET_MMX"
2029090286Sobrien  "pmulhw\t{%2, %0|%0, %2}"
20291117404Skan  [(set_attr "type" "mmxmul")
20292117404Skan   (set_attr "mode" "DI")])
2029390286Sobrien
2029490286Sobrien(define_insn "umulv4hi3_highpart"
2029590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2029690286Sobrien	(truncate:V4HI
2029790286Sobrien	 (lshiftrt:V4SI
2029890286Sobrien	  (mult:V4SI (zero_extend:V4SI
2029990286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
2030090286Sobrien		     (zero_extend:V4SI
2030190286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
2030290286Sobrien	  (const_int 16))))]
2030390286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2030490286Sobrien  "pmulhuw\t{%2, %0|%0, %2}"
20305117404Skan  [(set_attr "type" "mmxmul")
20306117404Skan   (set_attr "mode" "DI")])
2030790286Sobrien
2030890286Sobrien(define_insn "mmx_pmaddwd"
2030990286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2031090286Sobrien        (plus:V2SI
2031190286Sobrien	 (mult:V2SI
2031290286Sobrien	  (sign_extend:V2SI
2031390286Sobrien	   (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
2031490286Sobrien			    (parallel [(const_int 0) (const_int 2)])))
2031590286Sobrien	  (sign_extend:V2SI
2031690286Sobrien	   (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
2031790286Sobrien			    (parallel [(const_int 0) (const_int 2)]))))
2031890286Sobrien	 (mult:V2SI
2031990286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
2032090286Sobrien					     (parallel [(const_int 1)
2032190286Sobrien							(const_int 3)])))
2032290286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
2032390286Sobrien					     (parallel [(const_int 1)
2032490286Sobrien							(const_int 3)]))))))]
2032590286Sobrien  "TARGET_MMX"
2032690286Sobrien  "pmaddwd\t{%2, %0|%0, %2}"
20327117404Skan  [(set_attr "type" "mmxmul")
20328117404Skan   (set_attr "mode" "DI")])
2032990286Sobrien
2033090286Sobrien
2033190286Sobrien;; MMX logical operations
2033290286Sobrien;; Note we don't want to declare these as regular iordi3 insns to prevent
2033390286Sobrien;; normal code that also wants to use the FPU from getting broken.
2033490286Sobrien;; The UNSPECs are there to prevent the combiner from getting overly clever.
2033590286Sobrien(define_insn "mmx_iordi3"
2033690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
2033790286Sobrien        (unspec:DI
20338117404Skan	 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20339117404Skan		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20340117404Skan	 UNSPEC_NOP))]
2034190286Sobrien  "TARGET_MMX"
2034290286Sobrien  "por\t{%2, %0|%0, %2}"
20343117404Skan  [(set_attr "type" "mmxadd")
20344117404Skan   (set_attr "mode" "DI")])
2034590286Sobrien
2034690286Sobrien(define_insn "mmx_xordi3"
2034790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
2034890286Sobrien        (unspec:DI
20349117404Skan	 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20350117404Skan		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20351117404Skan	 UNSPEC_NOP))]
2035290286Sobrien  "TARGET_MMX"
2035390286Sobrien  "pxor\t{%2, %0|%0, %2}"
20354117404Skan  [(set_attr "type" "mmxadd")
20355117404Skan   (set_attr "mode" "DI")
2035690286Sobrien   (set_attr "memory" "none")])
2035790286Sobrien
2035890286Sobrien;; Same as pxor, but don't show input operands so that we don't think
2035990286Sobrien;; they are live.
2036090286Sobrien(define_insn "mmx_clrdi"
2036190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
20362117404Skan        (unspec:DI [(const_int 0)] UNSPEC_NOP))]
2036390286Sobrien  "TARGET_MMX"
2036490286Sobrien  "pxor\t{%0, %0|%0, %0}"
20365117404Skan  [(set_attr "type" "mmxadd")
20366117404Skan   (set_attr "mode" "DI")
2036790286Sobrien   (set_attr "memory" "none")])
2036890286Sobrien
2036990286Sobrien(define_insn "mmx_anddi3"
2037090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
2037190286Sobrien        (unspec:DI
20372117404Skan	 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20373117404Skan		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20374117404Skan	 UNSPEC_NOP))]
2037590286Sobrien  "TARGET_MMX"
2037690286Sobrien  "pand\t{%2, %0|%0, %2}"
20377117404Skan  [(set_attr "type" "mmxadd")
20378117404Skan   (set_attr "mode" "DI")])
2037990286Sobrien
2038090286Sobrien(define_insn "mmx_nanddi3"
2038190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
2038290286Sobrien        (unspec:DI
2038390286Sobrien	 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20384117404Skan			  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20385117404Skan	 UNSPEC_NOP))]
2038690286Sobrien  "TARGET_MMX"
2038790286Sobrien  "pandn\t{%2, %0|%0, %2}"
20388117404Skan  [(set_attr "type" "mmxadd")
20389117404Skan   (set_attr "mode" "DI")])
2039090286Sobrien
2039190286Sobrien
2039290286Sobrien;; MMX unsigned averages/sum of absolute differences
2039390286Sobrien
2039490286Sobrien(define_insn "mmx_uavgv8qi3"
2039590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2039690286Sobrien        (ashiftrt:V8QI
2039790286Sobrien	 (plus:V8QI (plus:V8QI
2039890286Sobrien		     (match_operand:V8QI 1 "register_operand" "0")
2039990286Sobrien		     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
2040096294Sobrien		    (const_vector:V8QI [(const_int 1)
2040196294Sobrien					(const_int 1)
2040296294Sobrien					(const_int 1)
2040396294Sobrien					(const_int 1)
2040496294Sobrien					(const_int 1)
2040596294Sobrien					(const_int 1)
2040696294Sobrien					(const_int 1)
2040796294Sobrien					(const_int 1)]))
2040890286Sobrien	 (const_int 1)))]
2040990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2041090286Sobrien  "pavgb\t{%2, %0|%0, %2}"
20411117404Skan  [(set_attr "type" "mmxshft")
20412117404Skan   (set_attr "mode" "DI")])
2041390286Sobrien
2041490286Sobrien(define_insn "mmx_uavgv4hi3"
2041590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2041690286Sobrien        (ashiftrt:V4HI
2041790286Sobrien	 (plus:V4HI (plus:V4HI
2041890286Sobrien		     (match_operand:V4HI 1 "register_operand" "0")
2041990286Sobrien		     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
2042096294Sobrien		    (const_vector:V4HI [(const_int 1)
2042196294Sobrien					(const_int 1)
2042296294Sobrien					(const_int 1)
2042396294Sobrien					(const_int 1)]))
2042490286Sobrien	 (const_int 1)))]
2042590286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2042690286Sobrien  "pavgw\t{%2, %0|%0, %2}"
20427117404Skan  [(set_attr "type" "mmxshft")
20428117404Skan   (set_attr "mode" "DI")])
2042990286Sobrien
2043090286Sobrien(define_insn "mmx_psadbw"
20431117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
20432117404Skan        (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20433117404Skan		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20434117404Skan		   UNSPEC_PSADBW))]
2043590286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2043690286Sobrien  "psadbw\t{%2, %0|%0, %2}"
20437117404Skan  [(set_attr "type" "mmxshft")
20438117404Skan   (set_attr "mode" "DI")])
2043990286Sobrien
2044090286Sobrien
2044190286Sobrien;; MMX insert/extract/shuffle
2044290286Sobrien
2044390286Sobrien(define_insn "mmx_pinsrw"
2044490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2044590286Sobrien        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
2044690286Sobrien			(vec_duplicate:V4HI
2044790286Sobrien			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20448132727Skan			(match_operand:SI 3 "const_0_to_15_operand" "N")))]
2044990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2045090286Sobrien  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20451117404Skan  [(set_attr "type" "mmxcvt")
20452117404Skan   (set_attr "mode" "DI")])
2045390286Sobrien
2045490286Sobrien(define_insn "mmx_pextrw"
2045590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
2045690286Sobrien        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
2045790286Sobrien				       (parallel
20458132727Skan					[(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
2045990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2046090286Sobrien  "pextrw\t{%2, %1, %0|%0, %1, %2}"
20461117404Skan  [(set_attr "type" "mmxcvt")
20462117404Skan   (set_attr "mode" "DI")])
2046390286Sobrien
2046490286Sobrien(define_insn "mmx_pshufw"
2046590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2046690286Sobrien        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20467117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
20468117404Skan		     UNSPEC_SHUFFLE))]
2046990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2047090286Sobrien  "pshufw\t{%2, %1, %0|%0, %1, %2}"
20471117404Skan  [(set_attr "type" "mmxcvt")
20472117404Skan   (set_attr "mode" "DI")])
2047390286Sobrien
2047490286Sobrien
2047590286Sobrien;; MMX mask-generating comparisons
2047690286Sobrien
2047790286Sobrien(define_insn "eqv8qi3"
2047890286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2047990286Sobrien        (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
2048090286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2048190286Sobrien  "TARGET_MMX"
2048290286Sobrien  "pcmpeqb\t{%2, %0|%0, %2}"
20483117404Skan  [(set_attr "type" "mmxcmp")
20484117404Skan   (set_attr "mode" "DI")])
2048590286Sobrien
2048690286Sobrien(define_insn "eqv4hi3"
2048790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2048890286Sobrien        (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
2048990286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2049090286Sobrien  "TARGET_MMX"
2049190286Sobrien  "pcmpeqw\t{%2, %0|%0, %2}"
20492117404Skan  [(set_attr "type" "mmxcmp")
20493117404Skan   (set_attr "mode" "DI")])
2049490286Sobrien
2049590286Sobrien(define_insn "eqv2si3"
2049690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2049790286Sobrien        (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
2049890286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
2049990286Sobrien  "TARGET_MMX"
2050090286Sobrien  "pcmpeqd\t{%2, %0|%0, %2}"
20501117404Skan  [(set_attr "type" "mmxcmp")
20502117404Skan   (set_attr "mode" "DI")])
2050390286Sobrien
2050490286Sobrien(define_insn "gtv8qi3"
2050590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2050690286Sobrien        (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
2050790286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2050890286Sobrien  "TARGET_MMX"
2050990286Sobrien  "pcmpgtb\t{%2, %0|%0, %2}"
20510117404Skan  [(set_attr "type" "mmxcmp")
20511117404Skan   (set_attr "mode" "DI")])
2051290286Sobrien
2051390286Sobrien(define_insn "gtv4hi3"
2051490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2051590286Sobrien        (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
2051690286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2051790286Sobrien  "TARGET_MMX"
2051890286Sobrien  "pcmpgtw\t{%2, %0|%0, %2}"
20519117404Skan  [(set_attr "type" "mmxcmp")
20520117404Skan   (set_attr "mode" "DI")])
2052190286Sobrien
2052290286Sobrien(define_insn "gtv2si3"
2052390286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2052490286Sobrien        (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
2052590286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
2052690286Sobrien  "TARGET_MMX"
2052790286Sobrien  "pcmpgtd\t{%2, %0|%0, %2}"
20528117404Skan  [(set_attr "type" "mmxcmp")
20529117404Skan   (set_attr "mode" "DI")])
2053090286Sobrien
2053190286Sobrien
2053290286Sobrien;; MMX max/min insns
2053390286Sobrien
2053490286Sobrien(define_insn "umaxv8qi3"
2053590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2053690286Sobrien        (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
2053790286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2053890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2053990286Sobrien  "pmaxub\t{%2, %0|%0, %2}"
20540117404Skan  [(set_attr "type" "mmxadd")
20541117404Skan   (set_attr "mode" "DI")])
2054290286Sobrien
2054390286Sobrien(define_insn "smaxv4hi3"
2054490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2054590286Sobrien        (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
2054690286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2054790286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2054890286Sobrien  "pmaxsw\t{%2, %0|%0, %2}"
20549117404Skan  [(set_attr "type" "mmxadd")
20550117404Skan   (set_attr "mode" "DI")])
2055190286Sobrien
2055290286Sobrien(define_insn "uminv8qi3"
2055390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2055490286Sobrien        (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
2055590286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
2055690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2055790286Sobrien  "pminub\t{%2, %0|%0, %2}"
20558117404Skan  [(set_attr "type" "mmxadd")
20559117404Skan   (set_attr "mode" "DI")])
2056090286Sobrien
2056190286Sobrien(define_insn "sminv4hi3"
2056290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2056390286Sobrien        (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
2056490286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
2056590286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2056690286Sobrien  "pminsw\t{%2, %0|%0, %2}"
20567117404Skan  [(set_attr "type" "mmxadd")
20568117404Skan   (set_attr "mode" "DI")])
2056990286Sobrien
2057090286Sobrien
2057190286Sobrien;; MMX shifts
2057290286Sobrien
2057390286Sobrien(define_insn "ashrv4hi3"
2057490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2057590286Sobrien        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
2057690286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
2057790286Sobrien  "TARGET_MMX"
2057890286Sobrien  "psraw\t{%2, %0|%0, %2}"
20579117404Skan  [(set_attr "type" "mmxshft")
20580117404Skan   (set_attr "mode" "DI")])
2058190286Sobrien
2058290286Sobrien(define_insn "ashrv2si3"
2058390286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2058490286Sobrien        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
2058590286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
2058690286Sobrien  "TARGET_MMX"
2058790286Sobrien  "psrad\t{%2, %0|%0, %2}"
20588117404Skan  [(set_attr "type" "mmxshft")
20589117404Skan   (set_attr "mode" "DI")])
2059090286Sobrien
2059190286Sobrien(define_insn "lshrv4hi3"
2059290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2059390286Sobrien        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
2059490286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
2059590286Sobrien  "TARGET_MMX"
2059690286Sobrien  "psrlw\t{%2, %0|%0, %2}"
20597117404Skan  [(set_attr "type" "mmxshft")
20598117404Skan   (set_attr "mode" "DI")])
2059990286Sobrien
2060090286Sobrien(define_insn "lshrv2si3"
2060190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2060290286Sobrien        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
2060390286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
2060490286Sobrien  "TARGET_MMX"
2060590286Sobrien  "psrld\t{%2, %0|%0, %2}"
20606117404Skan  [(set_attr "type" "mmxshft")
20607117404Skan   (set_attr "mode" "DI")])
2060890286Sobrien
2060990286Sobrien;; See logical MMX insns.
2061090286Sobrien(define_insn "mmx_lshrdi3"
2061190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
2061290286Sobrien        (unspec:DI
2061390286Sobrien	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20614117404Skan		       (match_operand:DI 2 "nonmemory_operand" "yi"))]
20615117404Skan	  UNSPEC_NOP))]
2061690286Sobrien  "TARGET_MMX"
2061790286Sobrien  "psrlq\t{%2, %0|%0, %2}"
20618117404Skan  [(set_attr "type" "mmxshft")
20619117404Skan   (set_attr "mode" "DI")])
2062090286Sobrien
2062190286Sobrien(define_insn "ashlv4hi3"
2062290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2062390286Sobrien        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
2062490286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
2062590286Sobrien  "TARGET_MMX"
2062690286Sobrien  "psllw\t{%2, %0|%0, %2}"
20627117404Skan  [(set_attr "type" "mmxshft")
20628117404Skan   (set_attr "mode" "DI")])
2062990286Sobrien
2063090286Sobrien(define_insn "ashlv2si3"
2063190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2063290286Sobrien        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
2063390286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
2063490286Sobrien  "TARGET_MMX"
2063590286Sobrien  "pslld\t{%2, %0|%0, %2}"
20636117404Skan  [(set_attr "type" "mmxshft")
20637117404Skan   (set_attr "mode" "DI")])
2063890286Sobrien
2063990286Sobrien;; See logical MMX insns.
2064090286Sobrien(define_insn "mmx_ashldi3"
2064190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
2064290286Sobrien        (unspec:DI
2064390286Sobrien	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20644117404Skan		     (match_operand:DI 2 "nonmemory_operand" "yi"))]
20645117404Skan	 UNSPEC_NOP))]
2064690286Sobrien  "TARGET_MMX"
2064790286Sobrien  "psllq\t{%2, %0|%0, %2}"
20648117404Skan  [(set_attr "type" "mmxshft")
20649117404Skan   (set_attr "mode" "DI")])
2065090286Sobrien
2065190286Sobrien
2065290286Sobrien;; MMX pack/unpack insns.
2065390286Sobrien
2065490286Sobrien(define_insn "mmx_packsswb"
2065590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2065690286Sobrien	(vec_concat:V8QI
2065790286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
2065890286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
2065990286Sobrien  "TARGET_MMX"
2066090286Sobrien  "packsswb\t{%2, %0|%0, %2}"
20661117404Skan  [(set_attr "type" "mmxshft")
20662117404Skan   (set_attr "mode" "DI")])
2066390286Sobrien
2066490286Sobrien(define_insn "mmx_packssdw"
2066590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2066690286Sobrien	(vec_concat:V4HI
2066790286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
2066890286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
2066990286Sobrien  "TARGET_MMX"
2067090286Sobrien  "packssdw\t{%2, %0|%0, %2}"
20671117404Skan  [(set_attr "type" "mmxshft")
20672117404Skan   (set_attr "mode" "DI")])
2067390286Sobrien
2067490286Sobrien(define_insn "mmx_packuswb"
2067590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2067690286Sobrien	(vec_concat:V8QI
2067790286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
2067890286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
2067990286Sobrien  "TARGET_MMX"
2068090286Sobrien  "packuswb\t{%2, %0|%0, %2}"
20681117404Skan  [(set_attr "type" "mmxshft")
20682117404Skan   (set_attr "mode" "DI")])
2068390286Sobrien
2068490286Sobrien(define_insn "mmx_punpckhbw"
2068590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2068690286Sobrien	(vec_merge:V8QI
2068790286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
2068890286Sobrien			  (parallel [(const_int 4)
2068990286Sobrien				     (const_int 0)
2069090286Sobrien				     (const_int 5)
2069190286Sobrien				     (const_int 1)
2069290286Sobrien				     (const_int 6)
2069390286Sobrien				     (const_int 2)
2069490286Sobrien				     (const_int 7)
2069590286Sobrien				     (const_int 3)]))
2069690286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
2069790286Sobrien			  (parallel [(const_int 0)
2069890286Sobrien				     (const_int 4)
2069990286Sobrien				     (const_int 1)
2070090286Sobrien				     (const_int 5)
2070190286Sobrien				     (const_int 2)
2070290286Sobrien				     (const_int 6)
2070390286Sobrien				     (const_int 3)
2070490286Sobrien				     (const_int 7)]))
2070590286Sobrien	 (const_int 85)))]
2070690286Sobrien  "TARGET_MMX"
2070790286Sobrien  "punpckhbw\t{%2, %0|%0, %2}"
20708117404Skan  [(set_attr "type" "mmxcvt")
20709117404Skan   (set_attr "mode" "DI")])
2071090286Sobrien
2071190286Sobrien(define_insn "mmx_punpckhwd"
2071290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2071390286Sobrien	(vec_merge:V4HI
2071490286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
2071590286Sobrien			  (parallel [(const_int 0)
2071690286Sobrien				     (const_int 2)
2071790286Sobrien				     (const_int 1)
2071890286Sobrien				     (const_int 3)]))
2071990286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
2072090286Sobrien			  (parallel [(const_int 2)
2072190286Sobrien				     (const_int 0)
2072290286Sobrien				     (const_int 3)
2072390286Sobrien				     (const_int 1)]))
2072490286Sobrien	 (const_int 5)))]
2072590286Sobrien  "TARGET_MMX"
2072690286Sobrien  "punpckhwd\t{%2, %0|%0, %2}"
20727117404Skan  [(set_attr "type" "mmxcvt")
20728117404Skan   (set_attr "mode" "DI")])
2072990286Sobrien
2073090286Sobrien(define_insn "mmx_punpckhdq"
2073190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2073290286Sobrien	(vec_merge:V2SI
20733117404Skan	 (match_operand:V2SI 1 "register_operand" "0")
2073490286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
2073590286Sobrien			  (parallel [(const_int 1)
2073690286Sobrien				     (const_int 0)]))
2073790286Sobrien	 (const_int 1)))]
2073890286Sobrien  "TARGET_MMX"
2073990286Sobrien  "punpckhdq\t{%2, %0|%0, %2}"
20740117404Skan  [(set_attr "type" "mmxcvt")
20741117404Skan   (set_attr "mode" "DI")])
2074290286Sobrien
2074390286Sobrien(define_insn "mmx_punpcklbw"
2074490286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
2074590286Sobrien	(vec_merge:V8QI
2074690286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
2074790286Sobrien			  (parallel [(const_int 0)
2074890286Sobrien				     (const_int 4)
2074990286Sobrien				     (const_int 1)
2075090286Sobrien				     (const_int 5)
2075190286Sobrien				     (const_int 2)
2075290286Sobrien				     (const_int 6)
2075390286Sobrien				     (const_int 3)
2075490286Sobrien				     (const_int 7)]))
2075590286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
2075690286Sobrien			  (parallel [(const_int 4)
2075790286Sobrien				     (const_int 0)
2075890286Sobrien				     (const_int 5)
2075990286Sobrien				     (const_int 1)
2076090286Sobrien				     (const_int 6)
2076190286Sobrien				     (const_int 2)
2076290286Sobrien				     (const_int 7)
2076390286Sobrien				     (const_int 3)]))
2076490286Sobrien	 (const_int 85)))]
2076590286Sobrien  "TARGET_MMX"
2076690286Sobrien  "punpcklbw\t{%2, %0|%0, %2}"
20767117404Skan  [(set_attr "type" "mmxcvt")
20768117404Skan   (set_attr "mode" "DI")])
2076990286Sobrien
2077090286Sobrien(define_insn "mmx_punpcklwd"
2077190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2077290286Sobrien	(vec_merge:V4HI
2077390286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
2077490286Sobrien			  (parallel [(const_int 2)
2077590286Sobrien				     (const_int 0)
2077690286Sobrien				     (const_int 3)
2077790286Sobrien				     (const_int 1)]))
2077890286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
2077990286Sobrien			  (parallel [(const_int 0)
2078090286Sobrien				     (const_int 2)
2078190286Sobrien				     (const_int 1)
2078290286Sobrien				     (const_int 3)]))
2078390286Sobrien	 (const_int 5)))]
2078490286Sobrien  "TARGET_MMX"
2078590286Sobrien  "punpcklwd\t{%2, %0|%0, %2}"
20786117404Skan  [(set_attr "type" "mmxcvt")
20787117404Skan   (set_attr "mode" "DI")])
2078890286Sobrien
2078990286Sobrien(define_insn "mmx_punpckldq"
2079090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2079190286Sobrien	(vec_merge:V2SI
2079290286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
2079390286Sobrien			   (parallel [(const_int 1)
2079490286Sobrien				      (const_int 0)]))
20795117404Skan	 (match_operand:V2SI 2 "register_operand" "y")
2079690286Sobrien	 (const_int 1)))]
2079790286Sobrien  "TARGET_MMX"
2079890286Sobrien  "punpckldq\t{%2, %0|%0, %2}"
20799117404Skan  [(set_attr "type" "mmxcvt")
20800117404Skan   (set_attr "mode" "DI")])
2080190286Sobrien
2080290286Sobrien
2080390286Sobrien;; Miscellaneous stuff
2080490286Sobrien
2080590286Sobrien(define_insn "emms"
20806117404Skan  [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
2080790286Sobrien   (clobber (reg:XF 8))
2080890286Sobrien   (clobber (reg:XF 9))
2080990286Sobrien   (clobber (reg:XF 10))
2081090286Sobrien   (clobber (reg:XF 11))
2081190286Sobrien   (clobber (reg:XF 12))
2081290286Sobrien   (clobber (reg:XF 13))
2081390286Sobrien   (clobber (reg:XF 14))
2081490286Sobrien   (clobber (reg:XF 15))
2081590286Sobrien   (clobber (reg:DI 29))
2081690286Sobrien   (clobber (reg:DI 30))
2081790286Sobrien   (clobber (reg:DI 31))
2081890286Sobrien   (clobber (reg:DI 32))
2081990286Sobrien   (clobber (reg:DI 33))
2082090286Sobrien   (clobber (reg:DI 34))
2082190286Sobrien   (clobber (reg:DI 35))
2082290286Sobrien   (clobber (reg:DI 36))]
2082390286Sobrien  "TARGET_MMX"
2082490286Sobrien  "emms"
2082590286Sobrien  [(set_attr "type" "mmx")
2082690286Sobrien   (set_attr "memory" "unknown")])
2082790286Sobrien
2082890286Sobrien(define_insn "ldmxcsr"
20829117404Skan  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20830117404Skan		    UNSPECV_LDMXCSR)]
20831117404Skan  "TARGET_SSE"
2083290286Sobrien  "ldmxcsr\t%0"
20833117404Skan  [(set_attr "type" "sse")
2083490286Sobrien   (set_attr "memory" "load")])
2083590286Sobrien
2083690286Sobrien(define_insn "stmxcsr"
2083790286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
20838117404Skan	(unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20839117404Skan  "TARGET_SSE"
2084090286Sobrien  "stmxcsr\t%0"
20841117404Skan  [(set_attr "type" "sse")
2084290286Sobrien   (set_attr "memory" "store")])
2084390286Sobrien
2084490286Sobrien(define_expand "sfence"
2084590286Sobrien  [(set (match_dup 0)
20846117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
2084790286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2084890286Sobrien{
2084990286Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2085090286Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
2085190286Sobrien})
2085290286Sobrien
2085390286Sobrien(define_insn "*sfence_insn"
2085490286Sobrien  [(set (match_operand:BLK 0 "" "")
20855117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
2085690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
2085790286Sobrien  "sfence"
2085890286Sobrien  [(set_attr "type" "sse")
2085990286Sobrien   (set_attr "memory" "unknown")])
2086090286Sobrien
2086190286Sobrien(define_expand "sse_prologue_save"
2086290286Sobrien  [(parallel [(set (match_operand:BLK 0 "" "")
2086390286Sobrien		   (unspec:BLK [(reg:DI 21)
2086490286Sobrien				(reg:DI 22)
2086590286Sobrien				(reg:DI 23)
2086690286Sobrien				(reg:DI 24)
2086790286Sobrien				(reg:DI 25)
2086890286Sobrien				(reg:DI 26)
2086990286Sobrien				(reg:DI 27)
20870117404Skan				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
2087190286Sobrien	      (use (match_operand:DI 1 "register_operand" ""))
2087290286Sobrien	      (use (match_operand:DI 2 "immediate_operand" ""))
2087390286Sobrien	      (use (label_ref:DI (match_operand 3 "" "")))])]
2087490286Sobrien  "TARGET_64BIT"
2087590286Sobrien  "")
2087690286Sobrien
2087790286Sobrien(define_insn "*sse_prologue_save_insn"
2087890286Sobrien  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
2087990286Sobrien			  (match_operand:DI 4 "const_int_operand" "n")))
2088090286Sobrien	(unspec:BLK [(reg:DI 21)
2088190286Sobrien		     (reg:DI 22)
2088290286Sobrien		     (reg:DI 23)
2088390286Sobrien		     (reg:DI 24)
2088490286Sobrien		     (reg:DI 25)
2088590286Sobrien		     (reg:DI 26)
2088690286Sobrien		     (reg:DI 27)
20887117404Skan		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
2088890286Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
2088990286Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
2089090286Sobrien   (use (label_ref:DI (match_operand 3 "" "X")))]
2089190286Sobrien  "TARGET_64BIT
2089290286Sobrien   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
2089390286Sobrien   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
2089490286Sobrien  "*
2089590286Sobrien{
2089690286Sobrien  int i;
2089790286Sobrien  operands[0] = gen_rtx_MEM (Pmode,
2089890286Sobrien			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
2089990286Sobrien  output_asm_insn (\"jmp\\t%A1\", operands);
2090090286Sobrien  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
2090190286Sobrien    {
2090290286Sobrien      operands[4] = adjust_address (operands[0], DImode, i*16);
2090390286Sobrien      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
2090490286Sobrien      PUT_MODE (operands[4], TImode);
2090590286Sobrien      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
2090690286Sobrien        output_asm_insn (\"rex\", operands);
2090790286Sobrien      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
2090890286Sobrien    }
20909132727Skan  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2091090286Sobrien			     CODE_LABEL_NUMBER (operands[3]));
2091190286Sobrien  RET;
2091290286Sobrien}
2091356391Sobrien  "
2091490286Sobrien  [(set_attr "type" "other")
2091590286Sobrien   (set_attr "length_immediate" "0")
2091690286Sobrien   (set_attr "length_address" "0")
2091790286Sobrien   (set_attr "length" "135")
2091890286Sobrien   (set_attr "memory" "store")
2091990286Sobrien   (set_attr "modrm" "0")
2092090286Sobrien   (set_attr "mode" "DI")])
2092190286Sobrien
2092290286Sobrien;; 3Dnow! instructions
2092390286Sobrien
2092490286Sobrien(define_insn "addv2sf3"
2092590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2092690286Sobrien	(plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
2092790286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2092890286Sobrien  "TARGET_3DNOW"
2092990286Sobrien  "pfadd\\t{%2, %0|%0, %2}"
20930117404Skan  [(set_attr "type" "mmxadd")
20931117404Skan   (set_attr "mode" "V2SF")])
2093290286Sobrien
2093390286Sobrien(define_insn "subv2sf3"
2093490286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2093590286Sobrien        (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
2093690286Sobrien		    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2093790286Sobrien  "TARGET_3DNOW"
2093890286Sobrien  "pfsub\\t{%2, %0|%0, %2}"
20939117404Skan  [(set_attr "type" "mmxadd")
20940117404Skan   (set_attr "mode" "V2SF")])
2094190286Sobrien
2094290286Sobrien(define_insn "subrv2sf3"
2094390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2094490286Sobrien        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
2094590286Sobrien                    (match_operand:V2SF 1 "register_operand" "0")))]
2094690286Sobrien  "TARGET_3DNOW"
2094790286Sobrien  "pfsubr\\t{%2, %0|%0, %2}"
20948117404Skan  [(set_attr "type" "mmxadd")
20949117404Skan   (set_attr "mode" "V2SF")])
2095090286Sobrien
2095190286Sobrien(define_insn "gtv2sf3"
2095290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2095390286Sobrien	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
2095490286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2095590286Sobrien "TARGET_3DNOW"
2095690286Sobrien  "pfcmpgt\\t{%2, %0|%0, %2}"
20957117404Skan  [(set_attr "type" "mmxcmp")
20958117404Skan   (set_attr "mode" "V2SF")])
2095990286Sobrien
2096090286Sobrien(define_insn "gev2sf3"
2096190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2096290286Sobrien	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
2096390286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2096490286Sobrien  "TARGET_3DNOW"
2096590286Sobrien  "pfcmpge\\t{%2, %0|%0, %2}"
20966117404Skan  [(set_attr "type" "mmxcmp")
20967117404Skan   (set_attr "mode" "V2SF")])
2096890286Sobrien
2096990286Sobrien(define_insn "eqv2sf3"
2097090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2097190286Sobrien	(eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
2097290286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2097390286Sobrien  "TARGET_3DNOW"
2097490286Sobrien  "pfcmpeq\\t{%2, %0|%0, %2}"
20975117404Skan  [(set_attr "type" "mmxcmp")
20976117404Skan   (set_attr "mode" "V2SF")])
2097790286Sobrien
2097890286Sobrien(define_insn "pfmaxv2sf3"
2097990286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2098090286Sobrien        (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
2098190286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2098290286Sobrien  "TARGET_3DNOW"
2098390286Sobrien  "pfmax\\t{%2, %0|%0, %2}"
20984117404Skan  [(set_attr "type" "mmxadd")
20985117404Skan   (set_attr "mode" "V2SF")])
2098690286Sobrien
2098790286Sobrien(define_insn "pfminv2sf3"
2098890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2098990286Sobrien        (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
2099090286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2099190286Sobrien  "TARGET_3DNOW"
2099290286Sobrien  "pfmin\\t{%2, %0|%0, %2}"
20993117404Skan  [(set_attr "type" "mmxadd")
20994117404Skan   (set_attr "mode" "V2SF")])
2099590286Sobrien
2099690286Sobrien(define_insn "mulv2sf3"
2099790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2099890286Sobrien	(mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
2099990286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
2100090286Sobrien  "TARGET_3DNOW"
2100190286Sobrien  "pfmul\\t{%2, %0|%0, %2}"
21002117404Skan  [(set_attr "type" "mmxmul")
21003117404Skan   (set_attr "mode" "V2SF")])
2100490286Sobrien
2100590286Sobrien(define_insn "femms"
21006117404Skan  [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
2100790286Sobrien   (clobber (reg:XF 8))
2100890286Sobrien   (clobber (reg:XF 9))
2100990286Sobrien   (clobber (reg:XF 10))
2101090286Sobrien   (clobber (reg:XF 11))
2101190286Sobrien   (clobber (reg:XF 12))
2101290286Sobrien   (clobber (reg:XF 13))
2101390286Sobrien   (clobber (reg:XF 14))
2101490286Sobrien   (clobber (reg:XF 15))
2101590286Sobrien   (clobber (reg:DI 29))
2101690286Sobrien   (clobber (reg:DI 30))
2101790286Sobrien   (clobber (reg:DI 31))
2101890286Sobrien   (clobber (reg:DI 32))
2101990286Sobrien   (clobber (reg:DI 33))
2102090286Sobrien   (clobber (reg:DI 34))
2102190286Sobrien   (clobber (reg:DI 35))
2102290286Sobrien   (clobber (reg:DI 36))]
2102390286Sobrien  "TARGET_3DNOW"
2102490286Sobrien  "femms"
21025117404Skan  [(set_attr "type" "mmx")
21026117404Skan   (set_attr "memory" "none")]) 
2102790286Sobrien
2102890286Sobrien(define_insn "pf2id"
2102990286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2103090286Sobrien	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
2103190286Sobrien  "TARGET_3DNOW"
2103290286Sobrien  "pf2id\\t{%1, %0|%0, %1}"
21033117404Skan  [(set_attr "type" "mmxcvt")
21034117404Skan   (set_attr "mode" "V2SF")])
2103590286Sobrien
2103690286Sobrien(define_insn "pf2iw"
2103790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2103890286Sobrien	(sign_extend:V2SI
2103990286Sobrien	   (ss_truncate:V2HI
2104090286Sobrien	      (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
2104190286Sobrien  "TARGET_3DNOW_A"
2104290286Sobrien  "pf2iw\\t{%1, %0|%0, %1}"
21043117404Skan  [(set_attr "type" "mmxcvt")
21044117404Skan   (set_attr "mode" "V2SF")])
2104590286Sobrien
2104690286Sobrien(define_insn "pfacc"
2104790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2104890286Sobrien	(vec_concat:V2SF
2104990286Sobrien	   (plus:SF
2105090286Sobrien	      (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
2105190286Sobrien			     (parallel [(const_int  0)]))
2105290286Sobrien	      (vec_select:SF (match_dup 1)
2105390286Sobrien			     (parallel [(const_int 1)])))
2105490286Sobrien           (plus:SF
2105590286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
2105690286Sobrien			     (parallel [(const_int  0)]))
2105790286Sobrien              (vec_select:SF (match_dup 2)
2105890286Sobrien			     (parallel [(const_int 1)])))))]
2105990286Sobrien  "TARGET_3DNOW"
2106090286Sobrien  "pfacc\\t{%2, %0|%0, %2}"
21061117404Skan  [(set_attr "type" "mmxadd")
21062117404Skan   (set_attr "mode" "V2SF")])
2106390286Sobrien
2106490286Sobrien(define_insn "pfnacc"
2106590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2106690286Sobrien  	(vec_concat:V2SF
2106790286Sobrien           (minus:SF
2106890286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
2106990286Sobrien			     (parallel [(const_int 0)]))
2107090286Sobrien              (vec_select:SF (match_dup 1)
2107190286Sobrien			     (parallel [(const_int 1)])))
2107290286Sobrien           (minus:SF
2107390286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
2107490286Sobrien			     (parallel [(const_int  0)]))
2107590286Sobrien              (vec_select:SF (match_dup 2)
2107690286Sobrien			     (parallel [(const_int 1)])))))]
2107790286Sobrien  "TARGET_3DNOW_A"
2107890286Sobrien  "pfnacc\\t{%2, %0|%0, %2}"
21079117404Skan  [(set_attr "type" "mmxadd")
21080117404Skan   (set_attr "mode" "V2SF")])
2108190286Sobrien
2108290286Sobrien(define_insn "pfpnacc"
2108390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2108490286Sobrien        (vec_concat:V2SF
2108590286Sobrien           (minus:SF
2108690286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
2108790286Sobrien			     (parallel [(const_int 0)]))
2108890286Sobrien              (vec_select:SF (match_dup 1)
2108990286Sobrien			     (parallel [(const_int 1)])))
2109090286Sobrien           (plus:SF
2109190286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
2109290286Sobrien			     (parallel [(const_int 0)]))
2109390286Sobrien              (vec_select:SF (match_dup 2)
2109490286Sobrien			     (parallel [(const_int 1)])))))]
2109590286Sobrien  "TARGET_3DNOW_A"
2109690286Sobrien  "pfpnacc\\t{%2, %0|%0, %2}"
21097117404Skan  [(set_attr "type" "mmxadd")
21098117404Skan   (set_attr "mode" "V2SF")])
2109990286Sobrien
2110090286Sobrien(define_insn "pi2fw"
2110190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2110290286Sobrien	(float:V2SF
2110390286Sobrien	   (vec_concat:V2SI
2110490286Sobrien	      (sign_extend:SI
2110590286Sobrien		 (truncate:HI
2110690286Sobrien		    (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
2110790286Sobrien				   (parallel [(const_int 0)]))))
2110890286Sobrien              (sign_extend:SI
2110990286Sobrien		 (truncate:HI
2111090286Sobrien                    (vec_select:SI (match_dup 1)
2111190286Sobrien				   (parallel [(const_int  1)])))))))]
2111290286Sobrien  "TARGET_3DNOW_A"
2111390286Sobrien  "pi2fw\\t{%1, %0|%0, %1}"
21114117404Skan  [(set_attr "type" "mmxcvt")
21115117404Skan   (set_attr "mode" "V2SF")])
2111690286Sobrien
2111790286Sobrien(define_insn "floatv2si2"
2111890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2111990286Sobrien	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
2112090286Sobrien  "TARGET_3DNOW"
2112190286Sobrien  "pi2fd\\t{%1, %0|%0, %1}"
21122117404Skan  [(set_attr "type" "mmxcvt")
21123117404Skan   (set_attr "mode" "V2SF")])
2112490286Sobrien
2112590286Sobrien;; This insn is identical to pavgb in operation, but the opcode is
2112690286Sobrien;; different.  To avoid accidentally matching pavgb, use an unspec.
2112790286Sobrien
2112890286Sobrien(define_insn "pavgusb"
2112990286Sobrien [(set (match_operand:V8QI 0 "register_operand" "=y")
2113090286Sobrien       (unspec:V8QI
2113190286Sobrien          [(match_operand:V8QI 1 "register_operand" "0")
21132117404Skan           (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21133117404Skan	  UNSPEC_PAVGUSB))]
2113490286Sobrien  "TARGET_3DNOW"
2113590286Sobrien  "pavgusb\\t{%2, %0|%0, %2}"
21136117404Skan  [(set_attr "type" "mmxshft")
21137117404Skan   (set_attr "mode" "TI")])
2113890286Sobrien
21139132727Skan;; 3DNow reciprocal and sqrt
2114090286Sobrien 
2114190286Sobrien(define_insn "pfrcpv2sf2"
2114290286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
21143117404Skan        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21144117404Skan	UNSPEC_PFRCP))]
2114590286Sobrien  "TARGET_3DNOW"
2114690286Sobrien  "pfrcp\\t{%1, %0|%0, %1}"
21147117404Skan  [(set_attr "type" "mmx")
21148117404Skan   (set_attr "mode" "TI")])
2114990286Sobrien
2115090286Sobrien(define_insn "pfrcpit1v2sf3"
2115190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2115290286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21153117404Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21154117404Skan		     UNSPEC_PFRCPIT1))]
2115590286Sobrien  "TARGET_3DNOW"
2115690286Sobrien  "pfrcpit1\\t{%2, %0|%0, %2}"
21157117404Skan  [(set_attr "type" "mmx")
21158117404Skan   (set_attr "mode" "TI")])
2115990286Sobrien
2116090286Sobrien(define_insn "pfrcpit2v2sf3"
2116190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2116290286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21163117404Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21164117404Skan		     UNSPEC_PFRCPIT2))]
2116590286Sobrien  "TARGET_3DNOW"
2116690286Sobrien  "pfrcpit2\\t{%2, %0|%0, %2}"
21167117404Skan  [(set_attr "type" "mmx")
21168117404Skan   (set_attr "mode" "TI")])
2116990286Sobrien
2117090286Sobrien(define_insn "pfrsqrtv2sf2"
2117190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
21172117404Skan	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21173117404Skan		     UNSPEC_PFRSQRT))]
2117490286Sobrien  "TARGET_3DNOW"
21175117404Skan  "pfrsqrt\\t{%1, %0|%0, %1}"
21176117404Skan  [(set_attr "type" "mmx")
21177117404Skan   (set_attr "mode" "TI")])
2117890286Sobrien		
2117990286Sobrien(define_insn "pfrsqit1v2sf3"
2118090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2118190286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21182117404Skan		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21183117404Skan		     UNSPEC_PFRSQIT1))]
2118490286Sobrien  "TARGET_3DNOW"
2118590286Sobrien  "pfrsqit1\\t{%2, %0|%0, %2}"
21186117404Skan  [(set_attr "type" "mmx")
21187117404Skan   (set_attr "mode" "TI")])
2118890286Sobrien
2118990286Sobrien(define_insn "pmulhrwv4hi3"
2119090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
2119190286Sobrien	(truncate:V4HI
2119290286Sobrien	   (lshiftrt:V4SI
2119390286Sobrien	      (plus:V4SI
2119490286Sobrien	         (mult:V4SI
2119590286Sobrien	            (sign_extend:V4SI
2119690286Sobrien		       (match_operand:V4HI 1 "register_operand" "0"))
2119790286Sobrien	            (sign_extend:V4SI
2119890286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
2119996294Sobrien		 (const_vector:V4SI [(const_int 32768)
2120096294Sobrien				     (const_int 32768)
2120196294Sobrien				     (const_int 32768)
2120296294Sobrien				     (const_int 32768)]))
2120396294Sobrien	      (const_int 16))))]
2120490286Sobrien  "TARGET_3DNOW"
2120590286Sobrien  "pmulhrw\\t{%2, %0|%0, %2}"
21206117404Skan  [(set_attr "type" "mmxmul")
21207117404Skan   (set_attr "mode" "TI")])
2120890286Sobrien
2120990286Sobrien(define_insn "pswapdv2si2"
2121090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
2121190286Sobrien	(vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
2121290286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
2121390286Sobrien  "TARGET_3DNOW_A"
2121490286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
21215117404Skan  [(set_attr "type" "mmxcvt")
21216117404Skan   (set_attr "mode" "TI")])
2121790286Sobrien
2121890286Sobrien(define_insn "pswapdv2sf2"
2121990286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
2122090286Sobrien	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
2122190286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
2122290286Sobrien  "TARGET_3DNOW_A"
2122390286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
21224117404Skan  [(set_attr "type" "mmxcvt")
21225117404Skan   (set_attr "mode" "TI")])
2122690286Sobrien
2122790286Sobrien(define_expand "prefetch"
21228102802Skan  [(prefetch (match_operand 0 "address_operand" "")
2122990286Sobrien	     (match_operand:SI 1 "const_int_operand" "")
2123090286Sobrien	     (match_operand:SI 2 "const_int_operand" ""))]
2123190286Sobrien  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
2123256391Sobrien{
2123390286Sobrien  int rw = INTVAL (operands[1]);
2123490286Sobrien  int locality = INTVAL (operands[2]);
2123590286Sobrien
2123690286Sobrien  if (rw != 0 && rw != 1)
2123790286Sobrien    abort ();
2123890286Sobrien  if (locality < 0 || locality > 3)
2123990286Sobrien    abort ();
21240102802Skan  if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21241102802Skan    abort ();
2124290286Sobrien
2124390286Sobrien  /* Use 3dNOW prefetch in case we are asking for write prefetch not
2124490286Sobrien     suported by SSE counterpart or the SSE prefetch is not available
2124590286Sobrien     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
2124690286Sobrien     of locality.  */
2124790286Sobrien  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
2124890286Sobrien    operands[2] = GEN_INT (3);
2124990286Sobrien  else
2125090286Sobrien    operands[1] = const0_rtx;
2125190286Sobrien})
2125290286Sobrien
2125390286Sobrien(define_insn "*prefetch_sse"
2125490286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
2125590286Sobrien	     (const_int 0)
2125690286Sobrien	     (match_operand:SI 1 "const_int_operand" ""))]
21257102802Skan  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
2125890286Sobrien{
2125990286Sobrien  static const char * const patterns[4] = {
2126090286Sobrien   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
2126190286Sobrien  };
2126290286Sobrien
2126390286Sobrien  int locality = INTVAL (operands[1]);
2126490286Sobrien  if (locality < 0 || locality > 3)
2126590286Sobrien    abort ();
2126690286Sobrien
2126790286Sobrien  return patterns[locality];  
2126890286Sobrien}
21269102802Skan  [(set_attr "type" "sse")
21270102802Skan   (set_attr "memory" "none")])
21271102802Skan
21272102802Skan(define_insn "*prefetch_sse_rex"
21273102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
21274102802Skan	     (const_int 0)
21275102802Skan	     (match_operand:SI 1 "const_int_operand" ""))]
21276102802Skan  "TARGET_PREFETCH_SSE && TARGET_64BIT"
21277102802Skan{
21278102802Skan  static const char * const patterns[4] = {
21279102802Skan   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21280102802Skan  };
21281102802Skan
21282102802Skan  int locality = INTVAL (operands[1]);
21283102802Skan  if (locality < 0 || locality > 3)
21284102802Skan    abort ();
21285102802Skan
21286102802Skan  return patterns[locality];  
21287102802Skan}
21288117404Skan  [(set_attr "type" "sse")
21289117404Skan   (set_attr "memory" "none")])
2129090286Sobrien
2129190286Sobrien(define_insn "*prefetch_3dnow"
2129290286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
2129390286Sobrien	     (match_operand:SI 1 "const_int_operand" "n")
2129490286Sobrien	     (const_int 3))]
21295102802Skan  "TARGET_3DNOW && !TARGET_64BIT"
2129690286Sobrien{
2129790286Sobrien  if (INTVAL (operands[1]) == 0)
2129890286Sobrien    return "prefetch\t%a0";
2129990286Sobrien  else
2130090286Sobrien    return "prefetchw\t%a0";
2130190286Sobrien}
21302102802Skan  [(set_attr "type" "mmx")
21303102802Skan   (set_attr "memory" "none")])
21304102802Skan
21305102802Skan(define_insn "*prefetch_3dnow_rex"
21306102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
21307102802Skan	     (match_operand:SI 1 "const_int_operand" "n")
21308102802Skan	     (const_int 3))]
21309102802Skan  "TARGET_3DNOW && TARGET_64BIT"
21310102802Skan{
21311102802Skan  if (INTVAL (operands[1]) == 0)
21312102802Skan    return "prefetch\t%a0";
21313102802Skan  else
21314102802Skan    return "prefetchw\t%a0";
21315102802Skan}
21316117404Skan  [(set_attr "type" "mmx")
21317117404Skan   (set_attr "memory" "none")])
21318117404Skan
21319117404Skan;; SSE2 support
21320117404Skan
21321117404Skan(define_insn "addv2df3"
21322117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21323117404Skan        (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21324117404Skan	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21325117404Skan  "TARGET_SSE2"
21326117404Skan  "addpd\t{%2, %0|%0, %2}"
21327117404Skan  [(set_attr "type" "sseadd")
21328117404Skan   (set_attr "mode" "V2DF")])
21329117404Skan
21330117404Skan(define_insn "vmaddv2df3"
21331117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21332117404Skan	(vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21333117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21334117404Skan                        (match_dup 1)
21335117404Skan			(const_int 1)))]
21336117404Skan  "TARGET_SSE2"
21337117404Skan  "addsd\t{%2, %0|%0, %2}"
21338117404Skan  [(set_attr "type" "sseadd")
21339117404Skan   (set_attr "mode" "DF")])
21340117404Skan
21341117404Skan(define_insn "subv2df3"
21342117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21343117404Skan        (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21344117404Skan	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21345117404Skan  "TARGET_SSE2"
21346117404Skan  "subpd\t{%2, %0|%0, %2}"
21347117404Skan  [(set_attr "type" "sseadd")
21348117404Skan   (set_attr "mode" "V2DF")])
21349117404Skan
21350117404Skan(define_insn "vmsubv2df3"
21351117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21352117404Skan	(vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21353117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21354117404Skan                        (match_dup 1)
21355117404Skan			(const_int 1)))]
21356117404Skan  "TARGET_SSE2"
21357117404Skan  "subsd\t{%2, %0|%0, %2}"
21358117404Skan  [(set_attr "type" "sseadd")
21359117404Skan   (set_attr "mode" "DF")])
21360117404Skan
21361117404Skan(define_insn "mulv2df3"
21362117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21363117404Skan        (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21364117404Skan	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21365117404Skan  "TARGET_SSE2"
21366117404Skan  "mulpd\t{%2, %0|%0, %2}"
21367117404Skan  [(set_attr "type" "ssemul")
21368117404Skan   (set_attr "mode" "V2DF")])
21369117404Skan
21370117404Skan(define_insn "vmmulv2df3"
21371117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21372117404Skan	(vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21373117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21374117404Skan                        (match_dup 1)
21375117404Skan			(const_int 1)))]
21376117404Skan  "TARGET_SSE2"
21377117404Skan  "mulsd\t{%2, %0|%0, %2}"
21378117404Skan  [(set_attr "type" "ssemul")
21379117404Skan   (set_attr "mode" "DF")])
21380117404Skan
21381117404Skan(define_insn "divv2df3"
21382117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21383117404Skan        (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21384117404Skan	          (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21385117404Skan  "TARGET_SSE2"
21386117404Skan  "divpd\t{%2, %0|%0, %2}"
21387117404Skan  [(set_attr "type" "ssediv")
21388117404Skan   (set_attr "mode" "V2DF")])
21389117404Skan
21390117404Skan(define_insn "vmdivv2df3"
21391117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21392117404Skan	(vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21393117404Skan				  (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21394117404Skan                        (match_dup 1)
21395117404Skan			(const_int 1)))]
21396117404Skan  "TARGET_SSE2"
21397117404Skan  "divsd\t{%2, %0|%0, %2}"
21398117404Skan  [(set_attr "type" "ssediv")
21399117404Skan   (set_attr "mode" "DF")])
21400117404Skan
21401117404Skan;; SSE min/max
21402117404Skan
21403117404Skan(define_insn "smaxv2df3"
21404117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21405117404Skan        (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21406117404Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21407117404Skan  "TARGET_SSE2"
21408117404Skan  "maxpd\t{%2, %0|%0, %2}"
21409117404Skan  [(set_attr "type" "sseadd")
21410117404Skan   (set_attr "mode" "V2DF")])
21411117404Skan
21412117404Skan(define_insn "vmsmaxv2df3"
21413117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21414117404Skan	(vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21415117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21416117404Skan                        (match_dup 1)
21417117404Skan			(const_int 1)))]
21418117404Skan  "TARGET_SSE2"
21419117404Skan  "maxsd\t{%2, %0|%0, %2}"
21420117404Skan  [(set_attr "type" "sseadd")
21421117404Skan   (set_attr "mode" "DF")])
21422117404Skan
21423117404Skan(define_insn "sminv2df3"
21424117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21425117404Skan        (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21426117404Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21427117404Skan  "TARGET_SSE2"
21428117404Skan  "minpd\t{%2, %0|%0, %2}"
21429117404Skan  [(set_attr "type" "sseadd")
21430117404Skan   (set_attr "mode" "V2DF")])
21431117404Skan
21432117404Skan(define_insn "vmsminv2df3"
21433117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21434117404Skan	(vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21435117404Skan	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21436117404Skan                        (match_dup 1)
21437117404Skan			(const_int 1)))]
21438117404Skan  "TARGET_SSE2"
21439117404Skan  "minsd\t{%2, %0|%0, %2}"
21440117404Skan  [(set_attr "type" "sseadd")
21441117404Skan   (set_attr "mode" "DF")])
21442117404Skan;; SSE2 square root.  There doesn't appear to be an extension for the
21443117404Skan;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21444117404Skan
21445117404Skan(define_insn "sqrtv2df2"
21446117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21447117404Skan        (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21448117404Skan  "TARGET_SSE2"
21449117404Skan  "sqrtpd\t{%1, %0|%0, %1}"
21450117404Skan  [(set_attr "type" "sse")
21451117404Skan   (set_attr "mode" "V2DF")])
21452117404Skan
21453117404Skan(define_insn "vmsqrtv2df2"
21454117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21455117404Skan	(vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21456117404Skan                        (match_operand:V2DF 2 "register_operand" "0")
21457117404Skan			(const_int 1)))]
21458117404Skan  "TARGET_SSE2"
21459117404Skan  "sqrtsd\t{%1, %0|%0, %1}"
21460117404Skan  [(set_attr "type" "sse")
21461117404Skan   (set_attr "mode" "SF")])
21462117404Skan
21463117404Skan;; SSE mask-generating compares
21464117404Skan
21465117404Skan(define_insn "maskcmpv2df3"
21466117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21467117404Skan        (match_operator:V2DI 3 "sse_comparison_operator"
21468117404Skan			     [(match_operand:V2DF 1 "register_operand" "0")
21469117404Skan			      (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21470117404Skan  "TARGET_SSE2"
21471117404Skan  "cmp%D3pd\t{%2, %0|%0, %2}"
21472117404Skan  [(set_attr "type" "ssecmp")
21473117404Skan   (set_attr "mode" "V2DF")])
21474117404Skan
21475117404Skan(define_insn "maskncmpv2df3"
21476117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21477117404Skan        (not:V2DI
21478117404Skan	 (match_operator:V2DI 3 "sse_comparison_operator"
21479117404Skan			      [(match_operand:V2DF 1 "register_operand" "0")
21480117404Skan			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21481117404Skan  "TARGET_SSE2"
21482117404Skan{
21483117404Skan  if (GET_CODE (operands[3]) == UNORDERED)
21484117404Skan    return "cmpordps\t{%2, %0|%0, %2}";
21485117404Skan  else
21486117404Skan    return "cmpn%D3pd\t{%2, %0|%0, %2}";
21487117404Skan}
21488117404Skan  [(set_attr "type" "ssecmp")
21489117404Skan   (set_attr "mode" "V2DF")])
21490117404Skan
21491117404Skan(define_insn "vmmaskcmpv2df3"
21492117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21493117404Skan	(vec_merge:V2DI
21494117404Skan	 (match_operator:V2DI 3 "sse_comparison_operator"
21495117404Skan			      [(match_operand:V2DF 1 "register_operand" "0")
21496117404Skan			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21497117404Skan	 (subreg:V2DI (match_dup 1) 0)
21498117404Skan	 (const_int 1)))]
21499117404Skan  "TARGET_SSE2"
21500117404Skan  "cmp%D3sd\t{%2, %0|%0, %2}"
21501117404Skan  [(set_attr "type" "ssecmp")
21502117404Skan   (set_attr "mode" "DF")])
21503117404Skan
21504117404Skan(define_insn "vmmaskncmpv2df3"
21505117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21506117404Skan	(vec_merge:V2DI
21507117404Skan	 (not:V2DI
21508117404Skan	  (match_operator:V2DI 3 "sse_comparison_operator"
21509117404Skan			       [(match_operand:V2DF 1 "register_operand" "0")
21510117404Skan				(match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21511117404Skan	 (subreg:V2DI (match_dup 1) 0)
21512117404Skan	 (const_int 1)))]
21513117404Skan  "TARGET_SSE2"
21514117404Skan{
21515117404Skan  if (GET_CODE (operands[3]) == UNORDERED)
21516117404Skan    return "cmpordsd\t{%2, %0|%0, %2}";
21517117404Skan  else
21518117404Skan    return "cmpn%D3sd\t{%2, %0|%0, %2}";
21519117404Skan}
21520117404Skan  [(set_attr "type" "ssecmp")
21521117404Skan   (set_attr "mode" "DF")])
21522117404Skan
21523117404Skan(define_insn "sse2_comi"
21524117404Skan  [(set (reg:CCFP 17)
21525117404Skan        (compare:CCFP (vec_select:DF
21526117404Skan		       (match_operand:V2DF 0 "register_operand" "x")
21527117404Skan		       (parallel [(const_int 0)]))
21528117404Skan		      (vec_select:DF
21529117404Skan		       (match_operand:V2DF 1 "register_operand" "x")
21530117404Skan		       (parallel [(const_int 0)]))))]
21531117404Skan  "TARGET_SSE2"
21532117404Skan  "comisd\t{%1, %0|%0, %1}"
21533132727Skan  [(set_attr "type" "ssecomi")
21534117404Skan   (set_attr "mode" "DF")])
21535117404Skan
21536117404Skan(define_insn "sse2_ucomi"
21537117404Skan  [(set (reg:CCFPU 17)
21538117404Skan	(compare:CCFPU (vec_select:DF
21539117404Skan			 (match_operand:V2DF 0 "register_operand" "x")
21540117404Skan			 (parallel [(const_int 0)]))
21541117404Skan			(vec_select:DF
21542117404Skan			 (match_operand:V2DF 1 "register_operand" "x")
21543117404Skan			 (parallel [(const_int 0)]))))]
21544117404Skan  "TARGET_SSE2"
21545117404Skan  "ucomisd\t{%1, %0|%0, %1}"
21546132727Skan  [(set_attr "type" "ssecomi")
21547117404Skan   (set_attr "mode" "DF")])
21548117404Skan
21549117404Skan;; SSE Strange Moves.
21550117404Skan
21551117404Skan(define_insn "sse2_movmskpd"
21552117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
21553117404Skan	(unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21554117404Skan		   UNSPEC_MOVMSK))]
21555117404Skan  "TARGET_SSE2"
21556117404Skan  "movmskpd\t{%1, %0|%0, %1}"
21557117404Skan  [(set_attr "type" "ssecvt")
21558117404Skan   (set_attr "mode" "V2DF")])
21559117404Skan
21560117404Skan(define_insn "sse2_pmovmskb"
21561117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
21562117404Skan	(unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21563117404Skan		   UNSPEC_MOVMSK))]
21564117404Skan  "TARGET_SSE2"
21565117404Skan  "pmovmskb\t{%1, %0|%0, %1}"
21566117404Skan  [(set_attr "type" "ssecvt")
21567117404Skan   (set_attr "mode" "V2DF")])
21568117404Skan
21569117404Skan(define_insn "sse2_maskmovdqu"
21570117404Skan  [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21571117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21572117404Skan		       (match_operand:V16QI 2 "register_operand" "x")]
21573117404Skan		      UNSPEC_MASKMOV))]
21574117404Skan  "TARGET_SSE2"
21575117404Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
21576117404Skan  "maskmovdqu\t{%2, %1|%1, %2}"
21577117404Skan  [(set_attr "type" "ssecvt")
21578117404Skan   (set_attr "mode" "TI")])
21579117404Skan
21580117404Skan(define_insn "sse2_maskmovdqu_rex64"
21581117404Skan  [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21582117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21583117404Skan		       (match_operand:V16QI 2 "register_operand" "x")]
21584117404Skan		      UNSPEC_MASKMOV))]
21585117404Skan  "TARGET_SSE2"
21586117404Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
21587117404Skan  "maskmovdqu\t{%2, %1|%1, %2}"
21588117404Skan  [(set_attr "type" "ssecvt")
21589117404Skan   (set_attr "mode" "TI")])
21590117404Skan
21591117404Skan(define_insn "sse2_movntv2df"
21592117404Skan  [(set (match_operand:V2DF 0 "memory_operand" "=m")
21593117404Skan	(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21594117404Skan		     UNSPEC_MOVNT))]
21595117404Skan  "TARGET_SSE2"
21596117404Skan  "movntpd\t{%1, %0|%0, %1}"
21597117404Skan  [(set_attr "type" "ssecvt")
21598117404Skan   (set_attr "mode" "V2DF")])
21599117404Skan
21600117404Skan(define_insn "sse2_movntv2di"
21601117404Skan  [(set (match_operand:V2DI 0 "memory_operand" "=m")
21602117404Skan	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21603117404Skan		     UNSPEC_MOVNT))]
21604117404Skan  "TARGET_SSE2"
21605117404Skan  "movntdq\t{%1, %0|%0, %1}"
21606117404Skan  [(set_attr "type" "ssecvt")
21607117404Skan   (set_attr "mode" "TI")])
21608117404Skan
21609117404Skan(define_insn "sse2_movntsi"
21610117404Skan  [(set (match_operand:SI 0 "memory_operand" "=m")
21611117404Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21612117404Skan		   UNSPEC_MOVNT))]
21613117404Skan  "TARGET_SSE2"
21614117404Skan  "movnti\t{%1, %0|%0, %1}"
21615117404Skan  [(set_attr "type" "ssecvt")
21616117404Skan   (set_attr "mode" "V2DF")])
21617117404Skan
21618117404Skan;; SSE <-> integer/MMX conversions
21619117404Skan
21620117404Skan;; Conversions between SI and SF
21621117404Skan
21622117404Skan(define_insn "cvtdq2ps"
21623117404Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
21624117404Skan	(float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21625117404Skan  "TARGET_SSE2"
21626117404Skan  "cvtdq2ps\t{%1, %0|%0, %1}"
21627117404Skan  [(set_attr "type" "ssecvt")
21628117404Skan   (set_attr "mode" "V2DF")])
21629117404Skan
21630117404Skan(define_insn "cvtps2dq"
21631117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21632117404Skan	(fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21633117404Skan  "TARGET_SSE2"
21634117404Skan  "cvtps2dq\t{%1, %0|%0, %1}"
21635117404Skan  [(set_attr "type" "ssecvt")
21636117404Skan   (set_attr "mode" "TI")])
21637117404Skan
21638117404Skan(define_insn "cvttps2dq"
21639117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21640117404Skan	(unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21641117404Skan		     UNSPEC_FIX))]
21642117404Skan  "TARGET_SSE2"
21643117404Skan  "cvttps2dq\t{%1, %0|%0, %1}"
21644117404Skan  [(set_attr "type" "ssecvt")
21645117404Skan   (set_attr "mode" "TI")])
21646117404Skan
21647117404Skan;; Conversions between SI and DF
21648117404Skan
21649117404Skan(define_insn "cvtdq2pd"
21650117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21651117404Skan	(float:V2DF (vec_select:V2SI
21652117404Skan		     (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21653117404Skan		     (parallel
21654117404Skan		      [(const_int 0)
21655117404Skan		       (const_int 1)]))))]
21656117404Skan  "TARGET_SSE2"
21657117404Skan  "cvtdq2pd\t{%1, %0|%0, %1}"
21658117404Skan  [(set_attr "type" "ssecvt")
21659117404Skan   (set_attr "mode" "V2DF")])
21660117404Skan
21661117404Skan(define_insn "cvtpd2dq"
21662117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21663117404Skan	(vec_concat:V4SI
21664117404Skan	 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21665117404Skan	 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21666117404Skan  "TARGET_SSE2"
21667117404Skan  "cvtpd2dq\t{%1, %0|%0, %1}"
21668117404Skan  [(set_attr "type" "ssecvt")
21669117404Skan   (set_attr "mode" "TI")])
21670117404Skan
21671117404Skan(define_insn "cvttpd2dq"
21672117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21673117404Skan	(vec_concat:V4SI
21674117404Skan	 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21675117404Skan		      UNSPEC_FIX)
21676117404Skan	 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21677117404Skan  "TARGET_SSE2"
21678117404Skan  "cvttpd2dq\t{%1, %0|%0, %1}"
21679117404Skan  [(set_attr "type" "ssecvt")
21680117404Skan   (set_attr "mode" "TI")])
21681117404Skan
21682117404Skan(define_insn "cvtpd2pi"
21683117404Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
21684117404Skan	(fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21685117404Skan  "TARGET_SSE2"
21686117404Skan  "cvtpd2pi\t{%1, %0|%0, %1}"
21687117404Skan  [(set_attr "type" "ssecvt")
21688117404Skan   (set_attr "mode" "TI")])
21689117404Skan
21690117404Skan(define_insn "cvttpd2pi"
21691117404Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
21692117404Skan	(unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21693117404Skan		     UNSPEC_FIX))]
21694117404Skan  "TARGET_SSE2"
21695117404Skan  "cvttpd2pi\t{%1, %0|%0, %1}"
21696117404Skan  [(set_attr "type" "ssecvt")
21697117404Skan   (set_attr "mode" "TI")])
21698117404Skan
21699117404Skan(define_insn "cvtpi2pd"
21700117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21701117404Skan	(float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21702117404Skan  "TARGET_SSE2"
21703117404Skan  "cvtpi2pd\t{%1, %0|%0, %1}"
21704117404Skan  [(set_attr "type" "ssecvt")
21705117404Skan   (set_attr "mode" "TI")])
21706117404Skan
21707117404Skan;; Conversions between SI and DF
21708117404Skan
21709117404Skan(define_insn "cvtsd2si"
21710132727Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
21711132727Skan	(fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21712117404Skan			       (parallel [(const_int 0)]))))]
21713117404Skan  "TARGET_SSE2"
21714117404Skan  "cvtsd2si\t{%1, %0|%0, %1}"
21715132727Skan  [(set_attr "type" "sseicvt")
21716132727Skan   (set_attr "athlon_decode" "double,vector")
21717117404Skan   (set_attr "mode" "SI")])
21718117404Skan
21719117404Skan(define_insn "cvtsd2siq"
21720132727Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
21721132727Skan	(fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21722117404Skan			       (parallel [(const_int 0)]))))]
21723117404Skan  "TARGET_SSE2 && TARGET_64BIT"
21724117404Skan  "cvtsd2siq\t{%1, %0|%0, %1}"
21725132727Skan  [(set_attr "type" "sseicvt")
21726132727Skan   (set_attr "athlon_decode" "double,vector")
21727132727Skan   (set_attr "mode" "DI")])
21728117404Skan
21729117404Skan(define_insn "cvttsd2si"
21730132727Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
21731132727Skan	(unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21732117404Skan				   (parallel [(const_int 0)]))] UNSPEC_FIX))]
21733117404Skan  "TARGET_SSE2"
21734117404Skan  "cvttsd2si\t{%1, %0|%0, %1}"
21735132727Skan  [(set_attr "type" "sseicvt")
21736132727Skan   (set_attr "mode" "SI")
21737132727Skan   (set_attr "athlon_decode" "double,vector")])
21738117404Skan
21739117404Skan(define_insn "cvttsd2siq"
21740117404Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
21741117404Skan	(unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21742117404Skan				   (parallel [(const_int 0)]))] UNSPEC_FIX))]
21743117404Skan  "TARGET_SSE2 && TARGET_64BIT"
21744117404Skan  "cvttsd2siq\t{%1, %0|%0, %1}"
21745132727Skan  [(set_attr "type" "sseicvt")
21746117404Skan   (set_attr "mode" "DI")
21747132727Skan   (set_attr "athlon_decode" "double,vector")])
21748117404Skan
21749117404Skan(define_insn "cvtsi2sd"
21750132727Skan  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21751132727Skan	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21752117404Skan	 		(vec_duplicate:V2DF
21753117404Skan			  (float:DF
21754132727Skan			    (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21755117404Skan			(const_int 2)))]
21756117404Skan  "TARGET_SSE2"
21757117404Skan  "cvtsi2sd\t{%2, %0|%0, %2}"
21758132727Skan  [(set_attr "type" "sseicvt")
21759132727Skan   (set_attr "mode" "DF")
21760132727Skan   (set_attr "athlon_decode" "double,direct")])
21761117404Skan
21762117404Skan(define_insn "cvtsi2sdq"
21763117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21764117404Skan	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21765117404Skan	 		(vec_duplicate:V2DF
21766117404Skan			  (float:DF
21767117404Skan			    (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21768117404Skan			(const_int 2)))]
21769117404Skan  "TARGET_SSE2 && TARGET_64BIT"
21770117404Skan  "cvtsi2sdq\t{%2, %0|%0, %2}"
21771132727Skan  [(set_attr "type" "sseicvt")
21772117404Skan   (set_attr "mode" "DF")
21773132727Skan   (set_attr "athlon_decode" "double,direct")])
21774117404Skan
21775117404Skan;; Conversions between SF and DF
21776117404Skan
21777117404Skan(define_insn "cvtsd2ss"
21778132727Skan  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21779132727Skan	(vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21780117404Skan	 		(vec_duplicate:V4SF
21781117404Skan			  (float_truncate:V2SF
21782132727Skan			    (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21783117404Skan			(const_int 14)))]
21784117404Skan  "TARGET_SSE2"
21785117404Skan  "cvtsd2ss\t{%2, %0|%0, %2}"
21786117404Skan  [(set_attr "type" "ssecvt")
21787132727Skan   (set_attr "athlon_decode" "vector,double")
21788117404Skan   (set_attr "mode" "SF")])
21789117404Skan
21790117404Skan(define_insn "cvtss2sd"
21791117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21792117404Skan	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21793117404Skan	 		(float_extend:V2DF
21794117404Skan			  (vec_select:V2SF
21795132727Skan			    (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21796117404Skan			    (parallel [(const_int 0)
21797117404Skan				       (const_int 1)])))
21798117404Skan			(const_int 2)))]
21799117404Skan  "TARGET_SSE2"
21800117404Skan  "cvtss2sd\t{%2, %0|%0, %2}"
21801117404Skan  [(set_attr "type" "ssecvt")
21802117404Skan   (set_attr "mode" "DF")])
21803117404Skan
21804117404Skan(define_insn "cvtpd2ps"
21805117404Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
21806117404Skan	(subreg:V4SF
21807117404Skan	  (vec_concat:V4SI
21808117404Skan	    (subreg:V2SI (float_truncate:V2SF
21809117404Skan			   (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21810117404Skan	    (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21811117404Skan  "TARGET_SSE2"
21812117404Skan  "cvtpd2ps\t{%1, %0|%0, %1}"
21813117404Skan  [(set_attr "type" "ssecvt")
21814117404Skan   (set_attr "mode" "V4SF")])
21815117404Skan
21816117404Skan(define_insn "cvtps2pd"
21817117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
21818117404Skan	(float_extend:V2DF
21819117404Skan	  (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21820117404Skan			   (parallel [(const_int 0)
21821117404Skan				      (const_int 1)]))))]
21822117404Skan  "TARGET_SSE2"
21823117404Skan  "cvtps2pd\t{%1, %0|%0, %1}"
21824117404Skan  [(set_attr "type" "ssecvt")
21825117404Skan   (set_attr "mode" "V2DF")])
21826117404Skan
21827117404Skan;; SSE2 variants of MMX insns
21828117404Skan
21829117404Skan;; MMX arithmetic
21830117404Skan
21831117404Skan(define_insn "addv16qi3"
21832117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21833117404Skan        (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21834117404Skan		    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21835117404Skan  "TARGET_SSE2"
21836117404Skan  "paddb\t{%2, %0|%0, %2}"
21837117404Skan  [(set_attr "type" "sseiadd")
21838117404Skan   (set_attr "mode" "TI")])
21839117404Skan
21840117404Skan(define_insn "addv8hi3"
21841117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21842117404Skan        (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21843117404Skan	           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21844117404Skan  "TARGET_SSE2"
21845117404Skan  "paddw\t{%2, %0|%0, %2}"
21846117404Skan  [(set_attr "type" "sseiadd")
21847117404Skan   (set_attr "mode" "TI")])
21848117404Skan
21849117404Skan(define_insn "addv4si3"
21850117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21851117404Skan        (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21852117404Skan	           (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21853117404Skan  "TARGET_SSE2"
21854117404Skan  "paddd\t{%2, %0|%0, %2}"
21855117404Skan  [(set_attr "type" "sseiadd")
21856117404Skan   (set_attr "mode" "TI")])
21857117404Skan
21858117404Skan(define_insn "addv2di3"
21859117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21860117404Skan        (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21861117404Skan	           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21862117404Skan  "TARGET_SSE2"
21863117404Skan  "paddq\t{%2, %0|%0, %2}"
21864117404Skan  [(set_attr "type" "sseiadd")
21865117404Skan   (set_attr "mode" "TI")])
21866117404Skan
21867117404Skan(define_insn "ssaddv16qi3"
21868117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21869117404Skan        (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21870117404Skan		       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21871117404Skan  "TARGET_SSE2"
21872117404Skan  "paddsb\t{%2, %0|%0, %2}"
21873117404Skan  [(set_attr "type" "sseiadd")
21874117404Skan   (set_attr "mode" "TI")])
21875117404Skan
21876117404Skan(define_insn "ssaddv8hi3"
21877117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21878117404Skan        (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21879117404Skan		      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21880117404Skan  "TARGET_SSE2"
21881117404Skan  "paddsw\t{%2, %0|%0, %2}"
21882117404Skan  [(set_attr "type" "sseiadd")
21883117404Skan   (set_attr "mode" "TI")])
21884117404Skan
21885117404Skan(define_insn "usaddv16qi3"
21886117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21887117404Skan        (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21888117404Skan		       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21889117404Skan  "TARGET_SSE2"
21890117404Skan  "paddusb\t{%2, %0|%0, %2}"
21891117404Skan  [(set_attr "type" "sseiadd")
21892117404Skan   (set_attr "mode" "TI")])
21893117404Skan
21894117404Skan(define_insn "usaddv8hi3"
21895117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21896117404Skan        (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21897117404Skan		      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21898117404Skan  "TARGET_SSE2"
21899117404Skan  "paddusw\t{%2, %0|%0, %2}"
21900117404Skan  [(set_attr "type" "sseiadd")
21901117404Skan   (set_attr "mode" "TI")])
21902117404Skan
21903117404Skan(define_insn "subv16qi3"
21904117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21905117404Skan        (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21906117404Skan		     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21907117404Skan  "TARGET_SSE2"
21908117404Skan  "psubb\t{%2, %0|%0, %2}"
21909117404Skan  [(set_attr "type" "sseiadd")
21910117404Skan   (set_attr "mode" "TI")])
21911117404Skan
21912117404Skan(define_insn "subv8hi3"
21913117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21914117404Skan        (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21915117404Skan		    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21916117404Skan  "TARGET_SSE2"
21917117404Skan  "psubw\t{%2, %0|%0, %2}"
21918117404Skan  [(set_attr "type" "sseiadd")
21919117404Skan   (set_attr "mode" "TI")])
21920117404Skan
21921117404Skan(define_insn "subv4si3"
21922117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
21923117404Skan        (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21924117404Skan		    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21925117404Skan  "TARGET_SSE2"
21926117404Skan  "psubd\t{%2, %0|%0, %2}"
21927117404Skan  [(set_attr "type" "sseiadd")
21928117404Skan   (set_attr "mode" "TI")])
21929117404Skan
21930117404Skan(define_insn "subv2di3"
21931117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
21932117404Skan        (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21933117404Skan		    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21934117404Skan  "TARGET_SSE2"
21935117404Skan  "psubq\t{%2, %0|%0, %2}"
21936117404Skan  [(set_attr "type" "sseiadd")
21937117404Skan   (set_attr "mode" "TI")])
21938117404Skan
21939117404Skan(define_insn "sssubv16qi3"
21940117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21941117404Skan        (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21942117404Skan			(match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21943117404Skan  "TARGET_SSE2"
21944117404Skan  "psubsb\t{%2, %0|%0, %2}"
21945117404Skan  [(set_attr "type" "sseiadd")
21946117404Skan   (set_attr "mode" "TI")])
21947117404Skan
21948117404Skan(define_insn "sssubv8hi3"
21949117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21950117404Skan        (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21951117404Skan		       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21952117404Skan  "TARGET_SSE2"
21953117404Skan  "psubsw\t{%2, %0|%0, %2}"
21954117404Skan  [(set_attr "type" "sseiadd")
21955117404Skan   (set_attr "mode" "TI")])
21956117404Skan
21957117404Skan(define_insn "ussubv16qi3"
21958117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
21959117404Skan        (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21960117404Skan			(match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21961117404Skan  "TARGET_SSE2"
21962117404Skan  "psubusb\t{%2, %0|%0, %2}"
21963117404Skan  [(set_attr "type" "sseiadd")
21964117404Skan   (set_attr "mode" "TI")])
21965117404Skan
21966117404Skan(define_insn "ussubv8hi3"
21967117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21968117404Skan        (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21969117404Skan		       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21970117404Skan  "TARGET_SSE2"
21971117404Skan  "psubusw\t{%2, %0|%0, %2}"
21972117404Skan  [(set_attr "type" "sseiadd")
21973117404Skan   (set_attr "mode" "TI")])
21974117404Skan
21975117404Skan(define_insn "mulv8hi3"
21976117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21977117404Skan        (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21978117404Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21979117404Skan  "TARGET_SSE2"
21980117404Skan  "pmullw\t{%2, %0|%0, %2}"
21981117404Skan  [(set_attr "type" "sseimul")
21982117404Skan   (set_attr "mode" "TI")])
21983117404Skan
21984117404Skan(define_insn "smulv8hi3_highpart"
21985117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21986117404Skan	(truncate:V8HI
21987117404Skan	 (lshiftrt:V8SI
21988117404Skan	  (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21989117404Skan		     (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21990117404Skan	  (const_int 16))))]
21991117404Skan  "TARGET_SSE2"
21992117404Skan  "pmulhw\t{%2, %0|%0, %2}"
21993117404Skan  [(set_attr "type" "sseimul")
21994117404Skan   (set_attr "mode" "TI")])
21995117404Skan
21996117404Skan(define_insn "umulv8hi3_highpart"
21997117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
21998117404Skan	(truncate:V8HI
21999117404Skan	 (lshiftrt:V8SI
22000117404Skan	  (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22001117404Skan		     (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22002117404Skan	  (const_int 16))))]
22003117404Skan  "TARGET_SSE2"
22004117404Skan  "pmulhuw\t{%2, %0|%0, %2}"
22005117404Skan  [(set_attr "type" "sseimul")
22006117404Skan   (set_attr "mode" "TI")])
22007117404Skan
22008117404Skan(define_insn "sse2_umulsidi3"
22009117404Skan  [(set (match_operand:DI 0 "register_operand" "=y")
22010117404Skan        (mult:DI (zero_extend:DI (vec_select:SI
22011117404Skan				  (match_operand:V2SI 1 "register_operand" "0")
22012117404Skan				  (parallel [(const_int 0)])))
22013117404Skan		 (zero_extend:DI (vec_select:SI
22014117404Skan				  (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22015117404Skan				  (parallel [(const_int 0)])))))]
22016117404Skan  "TARGET_SSE2"
22017117404Skan  "pmuludq\t{%2, %0|%0, %2}"
22018117404Skan  [(set_attr "type" "sseimul")
22019117404Skan   (set_attr "mode" "TI")])
22020117404Skan
22021117404Skan(define_insn "sse2_umulv2siv2di3"
22022117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22023117404Skan        (mult:V2DI (zero_extend:V2DI
22024117404Skan		     (vec_select:V2SI
22025117404Skan		       (match_operand:V4SI 1 "register_operand" "0")
22026117404Skan		       (parallel [(const_int 0) (const_int 2)])))
22027117404Skan		   (zero_extend:V2DI
22028117404Skan		     (vec_select:V2SI
22029117404Skan		       (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22030117404Skan		       (parallel [(const_int 0) (const_int 2)])))))]
22031117404Skan  "TARGET_SSE2"
22032117404Skan  "pmuludq\t{%2, %0|%0, %2}"
22033117404Skan  [(set_attr "type" "sseimul")
22034117404Skan   (set_attr "mode" "TI")])
22035117404Skan
22036117404Skan(define_insn "sse2_pmaddwd"
22037117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22038117404Skan        (plus:V4SI
22039117404Skan	 (mult:V4SI
22040117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22041117404Skan					     (parallel [(const_int 0)
22042117404Skan							(const_int 2)
22043117404Skan							(const_int 4)
22044117404Skan							(const_int 6)])))
22045117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22046117404Skan					     (parallel [(const_int 0)
22047117404Skan							(const_int 2)
22048117404Skan							(const_int 4)
22049117404Skan							(const_int 6)]))))
22050117404Skan	 (mult:V4SI
22051117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22052117404Skan					     (parallel [(const_int 1)
22053117404Skan							(const_int 3)
22054117404Skan							(const_int 5)
22055117404Skan							(const_int 7)])))
22056117404Skan	  (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22057117404Skan					     (parallel [(const_int 1)
22058117404Skan							(const_int 3)
22059117404Skan							(const_int 5)
22060117404Skan							(const_int 7)]))))))]
22061117404Skan  "TARGET_SSE2"
22062117404Skan  "pmaddwd\t{%2, %0|%0, %2}"
22063117404Skan  [(set_attr "type" "sseiadd")
22064117404Skan   (set_attr "mode" "TI")])
22065117404Skan
22066117404Skan;; Same as pxor, but don't show input operands so that we don't think
22067117404Skan;; they are live.
22068117404Skan(define_insn "sse2_clrti"
22069117404Skan  [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22070117404Skan  "TARGET_SSE2"
22071132727Skan{
22072132727Skan  if (get_attr_mode (insn) == MODE_TI)
22073132727Skan    return "pxor\t%0, %0";
22074132727Skan  else
22075132727Skan    return "xorps\t%0, %0";
22076132727Skan}
22077132727Skan  [(set_attr "type" "ssemov")
22078117404Skan   (set_attr "memory" "none")
22079132727Skan   (set (attr "mode")
22080132727Skan	      (if_then_else
22081132727Skan		(ne (symbol_ref "optimize_size")
22082132727Skan		    (const_int 0))
22083132727Skan		(const_string "V4SF")
22084132727Skan		(const_string "TI")))])
22085117404Skan
22086117404Skan;; MMX unsigned averages/sum of absolute differences
22087117404Skan
22088117404Skan(define_insn "sse2_uavgv16qi3"
22089117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22090117404Skan        (ashiftrt:V16QI
22091117404Skan	 (plus:V16QI (plus:V16QI
22092117404Skan		     (match_operand:V16QI 1 "register_operand" "0")
22093117404Skan		     (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22094117404Skan		     (const_vector:V16QI [(const_int 1) (const_int 1)
22095117404Skan					  (const_int 1) (const_int 1)
22096117404Skan					  (const_int 1) (const_int 1)
22097117404Skan					  (const_int 1) (const_int 1)
22098117404Skan					  (const_int 1) (const_int 1)
22099117404Skan					  (const_int 1) (const_int 1)
22100117404Skan					  (const_int 1) (const_int 1)
22101117404Skan					  (const_int 1) (const_int 1)]))
22102117404Skan	 (const_int 1)))]
22103117404Skan  "TARGET_SSE2"
22104117404Skan  "pavgb\t{%2, %0|%0, %2}"
22105117404Skan  [(set_attr "type" "sseiadd")
22106117404Skan   (set_attr "mode" "TI")])
22107117404Skan
22108117404Skan(define_insn "sse2_uavgv8hi3"
22109117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22110117404Skan        (ashiftrt:V8HI
22111117404Skan	 (plus:V8HI (plus:V8HI
22112117404Skan		     (match_operand:V8HI 1 "register_operand" "0")
22113117404Skan		     (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22114117404Skan		    (const_vector:V8HI [(const_int 1) (const_int 1)
22115117404Skan				        (const_int 1) (const_int 1)
22116117404Skan				        (const_int 1) (const_int 1)
22117117404Skan				        (const_int 1) (const_int 1)]))
22118117404Skan	 (const_int 1)))]
22119117404Skan  "TARGET_SSE2"
22120117404Skan  "pavgw\t{%2, %0|%0, %2}"
22121117404Skan  [(set_attr "type" "sseiadd")
22122117404Skan   (set_attr "mode" "TI")])
22123117404Skan
22124117404Skan;; @@@ this isn't the right representation.
22125117404Skan(define_insn "sse2_psadbw"
22126117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22127117404Skan        (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22128117404Skan		      (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22129117404Skan		     UNSPEC_PSADBW))]
22130117404Skan  "TARGET_SSE2"
22131117404Skan  "psadbw\t{%2, %0|%0, %2}"
22132117404Skan  [(set_attr "type" "sseiadd")
22133117404Skan   (set_attr "mode" "TI")])
22134117404Skan
22135117404Skan
22136117404Skan;; MMX insert/extract/shuffle
22137117404Skan
22138117404Skan(define_insn "sse2_pinsrw"
22139117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22140117404Skan        (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22141117404Skan			(vec_duplicate:V8HI
22142117404Skan			 (truncate:HI
22143117404Skan			   (match_operand:SI 2 "nonimmediate_operand" "rm")))
22144132727Skan			(match_operand:SI 3 "const_0_to_255_operand" "N")))]
22145117404Skan  "TARGET_SSE2"
22146117404Skan  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22147117404Skan  [(set_attr "type" "ssecvt")
22148117404Skan   (set_attr "mode" "TI")])
22149117404Skan
22150117404Skan(define_insn "sse2_pextrw"
22151117404Skan  [(set (match_operand:SI 0 "register_operand" "=r")
22152117404Skan        (zero_extend:SI
22153117404Skan	  (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22154117404Skan			 (parallel
22155132727Skan			  [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22156117404Skan  "TARGET_SSE2"
22157117404Skan  "pextrw\t{%2, %1, %0|%0, %1, %2}"
22158117404Skan  [(set_attr "type" "ssecvt")
22159117404Skan   (set_attr "mode" "TI")])
22160117404Skan
22161117404Skan(define_insn "sse2_pshufd"
22162117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22163117404Skan        (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22164117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
22165117404Skan		     UNSPEC_SHUFFLE))]
22166117404Skan  "TARGET_SSE2"
22167117404Skan  "pshufd\t{%2, %1, %0|%0, %1, %2}"
22168117404Skan  [(set_attr "type" "ssecvt")
22169117404Skan   (set_attr "mode" "TI")])
22170117404Skan
22171117404Skan(define_insn "sse2_pshuflw"
22172117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22173117404Skan        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22174117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
22175117404Skan		     UNSPEC_PSHUFLW))]
22176117404Skan  "TARGET_SSE2"
22177117404Skan  "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22178117404Skan  [(set_attr "type" "ssecvt")
22179117404Skan   (set_attr "mode" "TI")])
22180117404Skan
22181117404Skan(define_insn "sse2_pshufhw"
22182117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22183117404Skan        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22184117404Skan		      (match_operand:SI 2 "immediate_operand" "i")]
22185117404Skan		     UNSPEC_PSHUFHW))]
22186117404Skan  "TARGET_SSE2"
22187117404Skan  "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22188117404Skan  [(set_attr "type" "ssecvt")
22189117404Skan   (set_attr "mode" "TI")])
22190117404Skan
22191117404Skan;; MMX mask-generating comparisons
22192117404Skan
22193117404Skan(define_insn "eqv16qi3"
22194117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22195117404Skan        (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22196117404Skan		 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22197117404Skan  "TARGET_SSE2"
22198117404Skan  "pcmpeqb\t{%2, %0|%0, %2}"
22199117404Skan  [(set_attr "type" "ssecmp")
22200117404Skan   (set_attr "mode" "TI")])
22201117404Skan
22202117404Skan(define_insn "eqv8hi3"
22203117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22204117404Skan        (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22205117404Skan		 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22206117404Skan  "TARGET_SSE2"
22207117404Skan  "pcmpeqw\t{%2, %0|%0, %2}"
22208117404Skan  [(set_attr "type" "ssecmp")
22209117404Skan   (set_attr "mode" "TI")])
22210117404Skan
22211117404Skan(define_insn "eqv4si3"
22212117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22213117404Skan        (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22214117404Skan		 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22215117404Skan  "TARGET_SSE2"
22216117404Skan  "pcmpeqd\t{%2, %0|%0, %2}"
22217117404Skan  [(set_attr "type" "ssecmp")
22218117404Skan   (set_attr "mode" "TI")])
22219117404Skan
22220117404Skan(define_insn "gtv16qi3"
22221117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22222117404Skan        (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22223117404Skan		 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22224117404Skan  "TARGET_SSE2"
22225117404Skan  "pcmpgtb\t{%2, %0|%0, %2}"
22226117404Skan  [(set_attr "type" "ssecmp")
22227117404Skan   (set_attr "mode" "TI")])
22228117404Skan
22229117404Skan(define_insn "gtv8hi3"
22230117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22231117404Skan        (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22232117404Skan		 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22233117404Skan  "TARGET_SSE2"
22234117404Skan  "pcmpgtw\t{%2, %0|%0, %2}"
22235117404Skan  [(set_attr "type" "ssecmp")
22236117404Skan   (set_attr "mode" "TI")])
22237117404Skan
22238117404Skan(define_insn "gtv4si3"
22239117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22240117404Skan        (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22241117404Skan		 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22242117404Skan  "TARGET_SSE2"
22243117404Skan  "pcmpgtd\t{%2, %0|%0, %2}"
22244117404Skan  [(set_attr "type" "ssecmp")
22245117404Skan   (set_attr "mode" "TI")])
22246117404Skan
22247117404Skan
22248117404Skan;; MMX max/min insns
22249117404Skan
22250117404Skan(define_insn "umaxv16qi3"
22251117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22252117404Skan        (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22253117404Skan		   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22254117404Skan  "TARGET_SSE2"
22255117404Skan  "pmaxub\t{%2, %0|%0, %2}"
22256117404Skan  [(set_attr "type" "sseiadd")
22257117404Skan   (set_attr "mode" "TI")])
22258117404Skan
22259117404Skan(define_insn "smaxv8hi3"
22260117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22261117404Skan        (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22262117404Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22263117404Skan  "TARGET_SSE2"
22264117404Skan  "pmaxsw\t{%2, %0|%0, %2}"
22265117404Skan  [(set_attr "type" "sseiadd")
22266117404Skan   (set_attr "mode" "TI")])
22267117404Skan
22268117404Skan(define_insn "uminv16qi3"
22269117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22270117404Skan        (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22271117404Skan		   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22272117404Skan  "TARGET_SSE2"
22273117404Skan  "pminub\t{%2, %0|%0, %2}"
22274117404Skan  [(set_attr "type" "sseiadd")
22275117404Skan   (set_attr "mode" "TI")])
22276117404Skan
22277117404Skan(define_insn "sminv8hi3"
22278117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22279117404Skan        (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22280117404Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22281117404Skan  "TARGET_SSE2"
22282117404Skan  "pminsw\t{%2, %0|%0, %2}"
22283117404Skan  [(set_attr "type" "sseiadd")
22284117404Skan   (set_attr "mode" "TI")])
22285117404Skan
22286117404Skan
22287117404Skan;; MMX shifts
22288117404Skan
22289117404Skan(define_insn "ashrv8hi3"
22290117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22291117404Skan        (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22292132727Skan		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22293117404Skan  "TARGET_SSE2"
22294117404Skan  "psraw\t{%2, %0|%0, %2}"
22295117404Skan  [(set_attr "type" "sseishft")
22296117404Skan   (set_attr "mode" "TI")])
22297117404Skan
22298117404Skan(define_insn "ashrv4si3"
22299117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22300117404Skan        (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22301132727Skan		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22302117404Skan  "TARGET_SSE2"
22303117404Skan  "psrad\t{%2, %0|%0, %2}"
22304117404Skan  [(set_attr "type" "sseishft")
22305117404Skan   (set_attr "mode" "TI")])
22306117404Skan
22307117404Skan(define_insn "lshrv8hi3"
22308117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22309117404Skan        (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22310132727Skan		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22311117404Skan  "TARGET_SSE2"
22312117404Skan  "psrlw\t{%2, %0|%0, %2}"
22313117404Skan  [(set_attr "type" "sseishft")
22314117404Skan   (set_attr "mode" "TI")])
22315117404Skan
22316117404Skan(define_insn "lshrv4si3"
22317117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22318117404Skan        (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22319132727Skan		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22320117404Skan  "TARGET_SSE2"
22321117404Skan  "psrld\t{%2, %0|%0, %2}"
22322117404Skan  [(set_attr "type" "sseishft")
22323117404Skan   (set_attr "mode" "TI")])
22324117404Skan
22325117404Skan(define_insn "lshrv2di3"
22326117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22327117404Skan        (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22328132727Skan		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22329117404Skan  "TARGET_SSE2"
22330117404Skan  "psrlq\t{%2, %0|%0, %2}"
22331117404Skan  [(set_attr "type" "sseishft")
22332117404Skan   (set_attr "mode" "TI")])
22333117404Skan
22334117404Skan(define_insn "ashlv8hi3"
22335117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22336117404Skan        (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22337132727Skan		     (match_operand:SI 2 "nonmemory_operand" "xi")))]
22338117404Skan  "TARGET_SSE2"
22339117404Skan  "psllw\t{%2, %0|%0, %2}"
22340117404Skan  [(set_attr "type" "sseishft")
22341117404Skan   (set_attr "mode" "TI")])
22342117404Skan
22343117404Skan(define_insn "ashlv4si3"
22344117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22345117404Skan        (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22346132727Skan		     (match_operand:SI 2 "nonmemory_operand" "xi")))]
22347117404Skan  "TARGET_SSE2"
22348117404Skan  "pslld\t{%2, %0|%0, %2}"
22349117404Skan  [(set_attr "type" "sseishft")
22350117404Skan   (set_attr "mode" "TI")])
22351117404Skan
22352117404Skan(define_insn "ashlv2di3"
22353117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22354117404Skan        (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22355132727Skan		     (match_operand:SI 2 "nonmemory_operand" "xi")))]
22356117404Skan  "TARGET_SSE2"
22357117404Skan  "psllq\t{%2, %0|%0, %2}"
22358117404Skan  [(set_attr "type" "sseishft")
22359117404Skan   (set_attr "mode" "TI")])
22360117404Skan
22361117404Skan(define_insn "ashrv8hi3_ti"
22362117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22363117404Skan        (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22364132727Skan		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22365117404Skan  "TARGET_SSE2"
22366117404Skan  "psraw\t{%2, %0|%0, %2}"
22367117404Skan  [(set_attr "type" "sseishft")
22368117404Skan   (set_attr "mode" "TI")])
22369117404Skan
22370117404Skan(define_insn "ashrv4si3_ti"
22371117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22372117404Skan        (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22373132727Skan		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22374117404Skan  "TARGET_SSE2"
22375117404Skan  "psrad\t{%2, %0|%0, %2}"
22376117404Skan  [(set_attr "type" "sseishft")
22377117404Skan   (set_attr "mode" "TI")])
22378117404Skan
22379117404Skan(define_insn "lshrv8hi3_ti"
22380117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22381117404Skan        (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22382132727Skan		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22383117404Skan  "TARGET_SSE2"
22384117404Skan  "psrlw\t{%2, %0|%0, %2}"
22385117404Skan  [(set_attr "type" "sseishft")
22386117404Skan   (set_attr "mode" "TI")])
22387117404Skan
22388117404Skan(define_insn "lshrv4si3_ti"
22389117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22390117404Skan        (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22391132727Skan		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22392117404Skan  "TARGET_SSE2"
22393117404Skan  "psrld\t{%2, %0|%0, %2}"
22394117404Skan  [(set_attr "type" "sseishft")
22395117404Skan   (set_attr "mode" "TI")])
22396117404Skan
22397117404Skan(define_insn "lshrv2di3_ti"
22398117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22399117404Skan        (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22400132727Skan		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22401117404Skan  "TARGET_SSE2"
22402117404Skan  "psrlq\t{%2, %0|%0, %2}"
22403117404Skan  [(set_attr "type" "sseishft")
22404117404Skan   (set_attr "mode" "TI")])
22405117404Skan
22406117404Skan(define_insn "ashlv8hi3_ti"
22407117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22408117404Skan        (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22409132727Skan		     (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22410117404Skan  "TARGET_SSE2"
22411117404Skan  "psllw\t{%2, %0|%0, %2}"
22412117404Skan  [(set_attr "type" "sseishft")
22413117404Skan   (set_attr "mode" "TI")])
22414117404Skan
22415117404Skan(define_insn "ashlv4si3_ti"
22416117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22417117404Skan        (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22418132727Skan		     (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22419117404Skan  "TARGET_SSE2"
22420117404Skan  "pslld\t{%2, %0|%0, %2}"
22421117404Skan  [(set_attr "type" "sseishft")
22422117404Skan   (set_attr "mode" "TI")])
22423117404Skan
22424117404Skan(define_insn "ashlv2di3_ti"
22425117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22426117404Skan        (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22427132727Skan		     (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22428117404Skan  "TARGET_SSE2"
22429117404Skan  "psllq\t{%2, %0|%0, %2}"
22430117404Skan  [(set_attr "type" "sseishft")
22431117404Skan   (set_attr "mode" "TI")])
22432117404Skan
22433117404Skan;; See logical MMX insns for the reason for the unspec.  Strictly speaking
22434117404Skan;; we wouldn't need here it since we never generate TImode arithmetic.
22435117404Skan
22436117404Skan;; There has to be some kind of prize for the weirdest new instruction...
22437117404Skan(define_insn "sse2_ashlti3"
22438117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
22439117404Skan        (unspec:TI
22440117404Skan	 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22441117404Skan		     (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22442117404Skan			       (const_int 8)))] UNSPEC_NOP))]
22443117404Skan  "TARGET_SSE2"
22444117404Skan  "pslldq\t{%2, %0|%0, %2}"
22445117404Skan  [(set_attr "type" "sseishft")
22446117404Skan   (set_attr "mode" "TI")])
22447117404Skan
22448117404Skan(define_insn "sse2_lshrti3"
22449117404Skan  [(set (match_operand:TI 0 "register_operand" "=x")
22450117404Skan        (unspec:TI
22451117404Skan	 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22452117404Skan		       (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22453117404Skan				(const_int 8)))] UNSPEC_NOP))]
22454117404Skan  "TARGET_SSE2"
22455117404Skan  "psrldq\t{%2, %0|%0, %2}"
22456117404Skan  [(set_attr "type" "sseishft")
22457117404Skan   (set_attr "mode" "TI")])
22458117404Skan
22459117404Skan;; SSE unpack
22460117404Skan
22461117404Skan(define_insn "sse2_unpckhpd"
22462117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22463117404Skan	(vec_concat:V2DF
22464132727Skan	 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22465132727Skan			(parallel [(const_int 1)]))
22466132727Skan	 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22467132727Skan			(parallel [(const_int 1)]))))]
22468117404Skan  "TARGET_SSE2"
22469117404Skan  "unpckhpd\t{%2, %0|%0, %2}"
22470117404Skan  [(set_attr "type" "ssecvt")
22471132727Skan   (set_attr "mode" "V2DF")])
22472117404Skan
22473117404Skan(define_insn "sse2_unpcklpd"
22474117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22475117404Skan	(vec_concat:V2DF
22476132727Skan	 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22477132727Skan			(parallel [(const_int 0)]))
22478132727Skan	 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22479132727Skan			(parallel [(const_int 0)]))))]
22480117404Skan  "TARGET_SSE2"
22481117404Skan  "unpcklpd\t{%2, %0|%0, %2}"
22482117404Skan  [(set_attr "type" "ssecvt")
22483132727Skan   (set_attr "mode" "V2DF")])
22484117404Skan
22485117404Skan;; MMX pack/unpack insns.
22486117404Skan
22487117404Skan(define_insn "sse2_packsswb"
22488117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22489117404Skan	(vec_concat:V16QI
22490117404Skan	 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22491117404Skan	 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22492117404Skan  "TARGET_SSE2"
22493117404Skan  "packsswb\t{%2, %0|%0, %2}"
22494117404Skan  [(set_attr "type" "ssecvt")
22495117404Skan   (set_attr "mode" "TI")])
22496117404Skan
22497117404Skan(define_insn "sse2_packssdw"
22498117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22499117404Skan	(vec_concat:V8HI
22500117404Skan	 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22501117404Skan	 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22502117404Skan  "TARGET_SSE2"
22503117404Skan  "packssdw\t{%2, %0|%0, %2}"
22504117404Skan  [(set_attr "type" "ssecvt")
22505117404Skan   (set_attr "mode" "TI")])
22506117404Skan
22507117404Skan(define_insn "sse2_packuswb"
22508117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22509117404Skan	(vec_concat:V16QI
22510117404Skan	 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22511117404Skan	 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22512117404Skan  "TARGET_SSE2"
22513117404Skan  "packuswb\t{%2, %0|%0, %2}"
22514117404Skan  [(set_attr "type" "ssecvt")
22515117404Skan   (set_attr "mode" "TI")])
22516117404Skan
22517117404Skan(define_insn "sse2_punpckhbw"
22518117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22519117404Skan	(vec_merge:V16QI
22520117404Skan	 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22521117404Skan			   (parallel [(const_int 8) (const_int 0)
22522117404Skan				      (const_int 9) (const_int 1)
22523117404Skan				      (const_int 10) (const_int 2)
22524117404Skan				      (const_int 11) (const_int 3)
22525117404Skan				      (const_int 12) (const_int 4)
22526117404Skan				      (const_int 13) (const_int 5)
22527117404Skan				      (const_int 14) (const_int 6)
22528117404Skan				      (const_int 15) (const_int 7)]))
22529117404Skan	 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22530117404Skan			   (parallel [(const_int 0) (const_int 8)
22531117404Skan				      (const_int 1) (const_int 9)
22532117404Skan				      (const_int 2) (const_int 10)
22533117404Skan				      (const_int 3) (const_int 11)
22534117404Skan				      (const_int 4) (const_int 12)
22535117404Skan				      (const_int 5) (const_int 13)
22536117404Skan				      (const_int 6) (const_int 14)
22537117404Skan				      (const_int 7) (const_int 15)]))
22538117404Skan	 (const_int 21845)))]
22539117404Skan  "TARGET_SSE2"
22540117404Skan  "punpckhbw\t{%2, %0|%0, %2}"
22541117404Skan  [(set_attr "type" "ssecvt")
22542117404Skan   (set_attr "mode" "TI")])
22543117404Skan
22544117404Skan(define_insn "sse2_punpckhwd"
22545117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22546117404Skan	(vec_merge:V8HI
22547117404Skan	 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22548117404Skan			  (parallel [(const_int 4) (const_int 0)
22549117404Skan				     (const_int 5) (const_int 1)
22550117404Skan				     (const_int 6) (const_int 2)
22551117404Skan				     (const_int 7) (const_int 3)]))
22552117404Skan	 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22553117404Skan			  (parallel [(const_int 0) (const_int 4)
22554117404Skan				     (const_int 1) (const_int 5)
22555117404Skan				     (const_int 2) (const_int 6)
22556117404Skan				     (const_int 3) (const_int 7)]))
22557117404Skan	 (const_int 85)))]
22558117404Skan  "TARGET_SSE2"
22559117404Skan  "punpckhwd\t{%2, %0|%0, %2}"
22560117404Skan  [(set_attr "type" "ssecvt")
22561117404Skan   (set_attr "mode" "TI")])
22562117404Skan
22563117404Skan(define_insn "sse2_punpckhdq"
22564117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22565117404Skan	(vec_merge:V4SI
22566117404Skan	 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22567117404Skan			  (parallel [(const_int 2) (const_int 0)
22568117404Skan				     (const_int 3) (const_int 1)]))
22569117404Skan	 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22570117404Skan			  (parallel [(const_int 0) (const_int 2)
22571117404Skan				     (const_int 1) (const_int 3)]))
22572117404Skan	 (const_int 5)))]
22573117404Skan  "TARGET_SSE2"
22574117404Skan  "punpckhdq\t{%2, %0|%0, %2}"
22575117404Skan  [(set_attr "type" "ssecvt")
22576117404Skan   (set_attr "mode" "TI")])
22577117404Skan
22578117404Skan(define_insn "sse2_punpcklbw"
22579117404Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22580117404Skan	(vec_merge:V16QI
22581117404Skan	 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22582117404Skan			   (parallel [(const_int 0) (const_int 8)
22583117404Skan				      (const_int 1) (const_int 9)
22584117404Skan				      (const_int 2) (const_int 10)
22585117404Skan				      (const_int 3) (const_int 11)
22586117404Skan				      (const_int 4) (const_int 12)
22587117404Skan				      (const_int 5) (const_int 13)
22588117404Skan				      (const_int 6) (const_int 14)
22589117404Skan				      (const_int 7) (const_int 15)]))
22590117404Skan	 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22591117404Skan			   (parallel [(const_int 8) (const_int 0)
22592117404Skan				      (const_int 9) (const_int 1)
22593117404Skan				      (const_int 10) (const_int 2)
22594117404Skan				      (const_int 11) (const_int 3)
22595117404Skan				      (const_int 12) (const_int 4)
22596117404Skan				      (const_int 13) (const_int 5)
22597117404Skan				      (const_int 14) (const_int 6)
22598117404Skan				      (const_int 15) (const_int 7)]))
22599117404Skan	 (const_int 21845)))]
22600117404Skan  "TARGET_SSE2"
22601117404Skan  "punpcklbw\t{%2, %0|%0, %2}"
22602117404Skan  [(set_attr "type" "ssecvt")
22603117404Skan   (set_attr "mode" "TI")])
22604117404Skan
22605117404Skan(define_insn "sse2_punpcklwd"
22606117404Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
22607117404Skan	(vec_merge:V8HI
22608117404Skan	 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22609117404Skan			  (parallel [(const_int 0) (const_int 4)
22610117404Skan				     (const_int 1) (const_int 5)
22611117404Skan				     (const_int 2) (const_int 6)
22612117404Skan				     (const_int 3) (const_int 7)]))
22613117404Skan	 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22614117404Skan			  (parallel [(const_int 4) (const_int 0)
22615117404Skan				     (const_int 5) (const_int 1)
22616117404Skan				     (const_int 6) (const_int 2)
22617117404Skan				     (const_int 7) (const_int 3)]))
22618117404Skan	 (const_int 85)))]
22619117404Skan  "TARGET_SSE2"
22620117404Skan  "punpcklwd\t{%2, %0|%0, %2}"
22621117404Skan  [(set_attr "type" "ssecvt")
22622117404Skan   (set_attr "mode" "TI")])
22623117404Skan
22624117404Skan(define_insn "sse2_punpckldq"
22625117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22626117404Skan	(vec_merge:V4SI
22627117404Skan	 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22628117404Skan			  (parallel [(const_int 0) (const_int 2)
22629117404Skan				     (const_int 1) (const_int 3)]))
22630117404Skan	 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22631117404Skan			  (parallel [(const_int 2) (const_int 0)
22632117404Skan				     (const_int 3) (const_int 1)]))
22633117404Skan	 (const_int 5)))]
22634117404Skan  "TARGET_SSE2"
22635117404Skan  "punpckldq\t{%2, %0|%0, %2}"
22636117404Skan  [(set_attr "type" "ssecvt")
22637117404Skan   (set_attr "mode" "TI")])
22638117404Skan
22639117404Skan(define_insn "sse2_punpcklqdq"
22640117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22641117404Skan	(vec_merge:V2DI
22642117404Skan	 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22643117404Skan			  (parallel [(const_int 1)
22644117404Skan				     (const_int 0)]))
22645117404Skan	 (match_operand:V2DI 1 "register_operand" "0")
22646117404Skan	 (const_int 1)))]
22647117404Skan  "TARGET_SSE2"
22648117404Skan  "punpcklqdq\t{%2, %0|%0, %2}"
22649117404Skan  [(set_attr "type" "ssecvt")
22650117404Skan   (set_attr "mode" "TI")])
22651117404Skan
22652117404Skan(define_insn "sse2_punpckhqdq"
22653117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22654117404Skan	(vec_merge:V2DI
22655117404Skan	 (match_operand:V2DI 1 "register_operand" "0")
22656117404Skan	 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22657117404Skan			  (parallel [(const_int 1)
22658117404Skan				     (const_int 0)]))
22659117404Skan	 (const_int 1)))]
22660117404Skan  "TARGET_SSE2"
22661117404Skan  "punpckhqdq\t{%2, %0|%0, %2}"
22662117404Skan  [(set_attr "type" "ssecvt")
22663117404Skan   (set_attr "mode" "TI")])
22664117404Skan
22665117404Skan;; SSE2 moves
22666117404Skan
22667117404Skan(define_insn "sse2_movapd"
22668117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22669117404Skan	(unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22670117404Skan		     UNSPEC_MOVA))]
22671117404Skan  "TARGET_SSE2
22672117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22673117404Skan  "movapd\t{%1, %0|%0, %1}"
22674117404Skan  [(set_attr "type" "ssemov")
22675117404Skan   (set_attr "mode" "V2DF")])
22676117404Skan
22677117404Skan(define_insn "sse2_movupd"
22678117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22679117404Skan	(unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22680117404Skan		     UNSPEC_MOVU))]
22681117404Skan  "TARGET_SSE2
22682117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22683117404Skan  "movupd\t{%1, %0|%0, %1}"
22684117404Skan  [(set_attr "type" "ssecvt")
22685117404Skan   (set_attr "mode" "V2DF")])
22686117404Skan
22687117404Skan(define_insn "sse2_movdqa"
22688117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22689117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22690117404Skan		       UNSPEC_MOVA))]
22691117404Skan  "TARGET_SSE2
22692117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22693117404Skan  "movdqa\t{%1, %0|%0, %1}"
22694117404Skan  [(set_attr "type" "ssemov")
22695117404Skan   (set_attr "mode" "TI")])
22696117404Skan
22697117404Skan(define_insn "sse2_movdqu"
22698117404Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22699117404Skan	(unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22700117404Skan		       UNSPEC_MOVU))]
22701117404Skan  "TARGET_SSE2
22702117404Skan   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22703117404Skan  "movdqu\t{%1, %0|%0, %1}"
22704117404Skan  [(set_attr "type" "ssecvt")
22705117404Skan   (set_attr "mode" "TI")])
22706117404Skan
22707117404Skan(define_insn "sse2_movdq2q"
22708117404Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22709117404Skan	(vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22710117404Skan		       (parallel [(const_int 0)])))]
22711117404Skan  "TARGET_SSE2 && !TARGET_64BIT"
22712117404Skan  "@
22713117404Skan   movq\t{%1, %0|%0, %1}
22714117404Skan   movdq2q\t{%1, %0|%0, %1}"
22715117404Skan  [(set_attr "type" "ssecvt")
22716117404Skan   (set_attr "mode" "TI")])
22717117404Skan
22718117404Skan(define_insn "sse2_movdq2q_rex64"
22719117404Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22720117404Skan	(vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22721117404Skan		       (parallel [(const_int 0)])))]
22722117404Skan  "TARGET_SSE2 && TARGET_64BIT"
22723117404Skan  "@
22724117404Skan   movq\t{%1, %0|%0, %1}
22725117404Skan   movdq2q\t{%1, %0|%0, %1}
22726117404Skan   movd\t{%1, %0|%0, %1}"
22727117404Skan  [(set_attr "type" "ssecvt")
22728117404Skan   (set_attr "mode" "TI")])
22729117404Skan
22730117404Skan(define_insn "sse2_movq2dq"
22731117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22732117404Skan	(vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22733117404Skan			 (const_int 0)))]
22734117404Skan  "TARGET_SSE2 && !TARGET_64BIT"
22735117404Skan  "@
22736117404Skan   movq\t{%1, %0|%0, %1}
22737117404Skan   movq2dq\t{%1, %0|%0, %1}"
22738117404Skan  [(set_attr "type" "ssecvt,ssemov")
22739117404Skan   (set_attr "mode" "TI")])
22740117404Skan
22741117404Skan(define_insn "sse2_movq2dq_rex64"
22742117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22743117404Skan	(vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22744117404Skan			 (const_int 0)))]
22745117404Skan  "TARGET_SSE2 && TARGET_64BIT"
22746117404Skan  "@
22747117404Skan   movq\t{%1, %0|%0, %1}
22748117404Skan   movq2dq\t{%1, %0|%0, %1}
22749117404Skan   movd\t{%1, %0|%0, %1}"
22750117404Skan  [(set_attr "type" "ssecvt,ssemov,ssecvt")
22751117404Skan   (set_attr "mode" "TI")])
22752117404Skan
22753117404Skan(define_insn "sse2_movq"
22754117404Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
22755117404Skan	(vec_concat:V2DI (vec_select:DI
22756117404Skan			  (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22757117404Skan			  (parallel [(const_int 0)]))
22758117404Skan			 (const_int 0)))]
22759117404Skan  "TARGET_SSE2"
22760117404Skan  "movq\t{%1, %0|%0, %1}"
22761117404Skan  [(set_attr "type" "ssemov")
22762117404Skan   (set_attr "mode" "TI")])
22763117404Skan
22764117404Skan(define_insn "sse2_loadd"
22765117404Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
22766117404Skan	(vec_merge:V4SI
22767117404Skan	 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22768117404Skan	 (const_vector:V4SI [(const_int 0)
22769117404Skan			     (const_int 0)
22770117404Skan			     (const_int 0)
22771117404Skan			     (const_int 0)])
22772117404Skan	 (const_int 1)))]
22773117404Skan  "TARGET_SSE2"
22774117404Skan  "movd\t{%1, %0|%0, %1}"
22775117404Skan  [(set_attr "type" "ssemov")
22776117404Skan   (set_attr "mode" "TI")])
22777117404Skan
22778117404Skan(define_insn "sse2_stored"
22779117404Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22780117404Skan	(vec_select:SI
22781117404Skan	 (match_operand:V4SI 1 "register_operand" "x")
22782117404Skan	 (parallel [(const_int 0)])))]
22783117404Skan  "TARGET_SSE2"
22784117404Skan  "movd\t{%1, %0|%0, %1}"
22785117404Skan  [(set_attr "type" "ssemov")
22786117404Skan   (set_attr "mode" "TI")])
22787117404Skan
22788117404Skan(define_insn "sse2_movhpd"
22789117404Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22790117404Skan	(vec_merge:V2DF
22791117404Skan	 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22792117404Skan	 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22793117404Skan	 (const_int 2)))]
22794117404Skan  "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22795117404Skan  "movhpd\t{%2, %0|%0, %2}"
22796117404Skan  [(set_attr "type" "ssecvt")
22797117404Skan   (set_attr "mode" "V2DF")])
22798117404Skan
22799117404Skan(define_expand "sse2_loadsd"
22800117404Skan  [(match_operand:V2DF 0 "register_operand" "")
22801117404Skan   (match_operand:DF 1 "memory_operand" "")]
22802117404Skan  "TARGET_SSE2"
22803117404Skan{
22804117404Skan  emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22805117404Skan			        CONST0_RTX (V2DFmode)));
22806117404Skan  DONE;
22807117404Skan})
22808117404Skan
22809117404Skan(define_insn "sse2_loadsd_1"
22810117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22811117404Skan	(vec_merge:V2DF
22812117404Skan	 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22813117404Skan	 (match_operand:V2DF 2 "const0_operand" "X")
22814117404Skan	 (const_int 1)))]
22815117404Skan  "TARGET_SSE2"
22816117404Skan  "movsd\t{%1, %0|%0, %1}"
22817117404Skan  [(set_attr "type" "ssecvt")
22818117404Skan   (set_attr "mode" "DF")])
22819117404Skan
22820117404Skan(define_insn "sse2_movsd"
22821132727Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22822117404Skan	(vec_merge:V2DF
22823132727Skan	 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22824132727Skan	 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22825117404Skan	 (const_int 1)))]
22826132727Skan  "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22827132727Skan  "@movsd\t{%2, %0|%0, %2}
22828132727Skan    movlpd\t{%2, %0|%0, %2}
22829132727Skan    movlpd\t{%2, %0|%0, %2}"
22830117404Skan  [(set_attr "type" "ssecvt")
22831132727Skan   (set_attr "mode" "DF,V2DF,V2DF")])
22832117404Skan
22833117404Skan(define_insn "sse2_storesd"
22834117404Skan  [(set (match_operand:DF 0 "memory_operand" "=m")
22835117404Skan	(vec_select:DF
22836117404Skan	 (match_operand:V2DF 1 "register_operand" "x")
22837117404Skan	 (parallel [(const_int 0)])))]
22838117404Skan  "TARGET_SSE2"
22839117404Skan  "movsd\t{%1, %0|%0, %1}"
22840117404Skan  [(set_attr "type" "ssecvt")
22841117404Skan   (set_attr "mode" "DF")])
22842117404Skan
22843117404Skan(define_insn "sse2_shufpd"
22844117404Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22845117404Skan        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22846117404Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22847117404Skan		      (match_operand:SI 3 "immediate_operand" "i")]
22848117404Skan		     UNSPEC_SHUFFLE))]
22849117404Skan  "TARGET_SSE2"
22850117404Skan  ;; @@@ check operand order for intel/nonintel syntax
22851117404Skan  "shufpd\t{%3, %2, %0|%0, %2, %3}"
22852117404Skan  [(set_attr "type" "ssecvt")
22853117404Skan   (set_attr "mode" "V2DF")])
22854117404Skan
22855117404Skan(define_insn "sse2_clflush"
22856117404Skan  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22857117404Skan		    UNSPECV_CLFLUSH)]
22858117404Skan  "TARGET_SSE2"
22859117404Skan  "clflush %0"
22860117404Skan  [(set_attr "type" "sse")
22861117404Skan   (set_attr "memory" "unknown")])
22862117404Skan
22863117404Skan(define_expand "sse2_mfence"
22864117404Skan  [(set (match_dup 0)
22865117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22866117404Skan  "TARGET_SSE2"
22867117404Skan{
22868117404Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22869117404Skan  MEM_VOLATILE_P (operands[0]) = 1;
22870117404Skan})
22871117404Skan
22872117404Skan(define_insn "*mfence_insn"
22873117404Skan  [(set (match_operand:BLK 0 "" "")
22874117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22875117404Skan  "TARGET_SSE2"
22876117404Skan  "mfence"
22877117404Skan  [(set_attr "type" "sse")
22878117404Skan   (set_attr "memory" "unknown")])
22879117404Skan
22880117404Skan(define_expand "sse2_lfence"
22881117404Skan  [(set (match_dup 0)
22882117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22883117404Skan  "TARGET_SSE2"
22884117404Skan{
22885117404Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22886117404Skan  MEM_VOLATILE_P (operands[0]) = 1;
22887117404Skan})
22888117404Skan
22889117404Skan(define_insn "*lfence_insn"
22890117404Skan  [(set (match_operand:BLK 0 "" "")
22891117404Skan	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22892117404Skan  "TARGET_SSE2"
22893117404Skan  "lfence"
22894117404Skan  [(set_attr "type" "sse")
22895117404Skan   (set_attr "memory" "unknown")])
22896122190Skan
22897132727Skan;; SSE3
22898122190Skan
22899122190Skan(define_insn "mwait"
22900122190Skan  [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22901122190Skan		     (match_operand:SI 1 "register_operand" "c")]
22902122190Skan		    UNSPECV_MWAIT)]
22903132727Skan  "TARGET_SSE3"
22904122190Skan  "mwait\t%0, %1"
22905122190Skan  [(set_attr "length" "3")])
22906122190Skan
22907122190Skan(define_insn "monitor"
22908122190Skan  [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22909122190Skan		     (match_operand:SI 1 "register_operand" "c")
22910122190Skan		     (match_operand:SI 2 "register_operand" "d")]
22911122190Skan		    UNSPECV_MONITOR)]
22912132727Skan  "TARGET_SSE3"
22913122190Skan  "monitor\t%0, %1, %2"
22914122190Skan  [(set_attr "length" "3")])
22915122190Skan
22916132727Skan;; SSE3 arithmetic
22917122190Skan
22918122190Skan(define_insn "addsubv4sf3"
22919122190Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
22920122190Skan        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22921122190Skan		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22922122190Skan		     UNSPEC_ADDSUB))]
22923132727Skan  "TARGET_SSE3"
22924122190Skan  "addsubps\t{%2, %0|%0, %2}"
22925122190Skan  [(set_attr "type" "sseadd")
22926122190Skan   (set_attr "mode" "V4SF")])
22927122190Skan
22928122190Skan(define_insn "addsubv2df3"
22929122190Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22930122190Skan        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22931122190Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22932122190Skan		     UNSPEC_ADDSUB))]
22933132727Skan  "TARGET_SSE3"
22934122190Skan  "addsubpd\t{%2, %0|%0, %2}"
22935122190Skan  [(set_attr "type" "sseadd")
22936122190Skan   (set_attr "mode" "V2DF")])
22937122190Skan
22938122190Skan(define_insn "haddv4sf3"
22939122190Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
22940122190Skan        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22941122190Skan		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22942122190Skan		     UNSPEC_HADD))]
22943132727Skan  "TARGET_SSE3"
22944122190Skan  "haddps\t{%2, %0|%0, %2}"
22945122190Skan  [(set_attr "type" "sseadd")
22946122190Skan   (set_attr "mode" "V4SF")])
22947122190Skan
22948122190Skan(define_insn "haddv2df3"
22949122190Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22950122190Skan        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22951122190Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22952122190Skan		     UNSPEC_HADD))]
22953132727Skan  "TARGET_SSE3"
22954122190Skan  "haddpd\t{%2, %0|%0, %2}"
22955122190Skan  [(set_attr "type" "sseadd")
22956122190Skan   (set_attr "mode" "V2DF")])
22957122190Skan
22958122190Skan(define_insn "hsubv4sf3"
22959122190Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
22960122190Skan        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22961122190Skan		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22962122190Skan		     UNSPEC_HSUB))]
22963132727Skan  "TARGET_SSE3"
22964122190Skan  "hsubps\t{%2, %0|%0, %2}"
22965122190Skan  [(set_attr "type" "sseadd")
22966122190Skan   (set_attr "mode" "V4SF")])
22967122190Skan
22968122190Skan(define_insn "hsubv2df3"
22969122190Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
22970122190Skan        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22971122190Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22972122190Skan		     UNSPEC_HSUB))]
22973132727Skan  "TARGET_SSE3"
22974122190Skan  "hsubpd\t{%2, %0|%0, %2}"
22975122190Skan  [(set_attr "type" "sseadd")
22976122190Skan   (set_attr "mode" "V2DF")])
22977122190Skan
22978122190Skan(define_insn "movshdup"
22979122190Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
22980122190Skan        (unspec:V4SF
22981122190Skan	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22982132727Skan  "TARGET_SSE3"
22983122190Skan  "movshdup\t{%1, %0|%0, %1}"
22984122190Skan  [(set_attr "type" "sse")
22985122190Skan   (set_attr "mode" "V4SF")])
22986122190Skan
22987122190Skan(define_insn "movsldup"
22988122190Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
22989122190Skan        (unspec:V4SF
22990122190Skan	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22991132727Skan  "TARGET_SSE3"
22992122190Skan  "movsldup\t{%1, %0|%0, %1}"
22993122190Skan  [(set_attr "type" "sse")
22994122190Skan   (set_attr "mode" "V4SF")])
22995122190Skan
22996122190Skan(define_insn "lddqu"
22997122190Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
22998122190Skan	(unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22999122190Skan		       UNSPEC_LDQQU))]
23000132727Skan  "TARGET_SSE3"
23001122190Skan  "lddqu\t{%1, %0|%0, %1}"
23002122190Skan  [(set_attr "type" "ssecvt")
23003122190Skan   (set_attr "mode" "TI")])
23004122190Skan
23005122190Skan(define_insn "loadddup"
23006122190Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
23007122190Skan	(vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23008132727Skan  "TARGET_SSE3"
23009122190Skan  "movddup\t{%1, %0|%0, %1}"
23010122190Skan  [(set_attr "type" "ssecvt")
23011122190Skan   (set_attr "mode" "DF")])
23012122190Skan
23013122190Skan(define_insn "movddup"
23014122190Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
23015122190Skan	(vec_duplicate:V2DF
23016122190Skan	 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23017122190Skan			(parallel [(const_int 0)]))))]
23018132727Skan  "TARGET_SSE3"
23019122190Skan  "movddup\t{%1, %0|%0, %1}"
23020122190Skan  [(set_attr "type" "ssecvt")
23021122190Skan   (set_attr "mode" "DF")])
23022