i386.md revision 161660
1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3;; 2001, 2002, 2003, 2004
4;; Free Software Foundation, Inc.
5;; Mostly by William Schelter.
6;; x86_64 support added by Jan Hubicka
7;;
8;; This file is part of GCC.
9;;
10;; GCC is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14;;
15;; GCC is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18;; GNU General Public License for more details.
19;;
20;; You should have received a copy of the GNU General Public License
21;; along with GCC; see the file COPYING.  If not, write to
22;; the Free Software Foundation, 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.  */
24;;
25;; The original PO technology requires these to be ordered by speed,
26;; so that assigner will pick the fastest.
27;;
28;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29;;
30;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31;; constraint letters.
32;;
33;; The special asm out single letter directives following a '%' are:
34;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35;;     operands[1].
36;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40;; 'S' Print the opcode suffix for a 32-bit float opcode.
41;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42;; 'J' Print the appropriate jump operand.
43;;
44;; 'b' Print the QImode name of the register for the indicated operand.
45;;     %b0 would print %al if operands[0] is reg 0.
46;; 'w' Likewise, print the HImode name of the register.
47;; 'k' Likewise, print the SImode name of the register.
48;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49;; 'y' Print "st(0)" instead of "st" as a register.
50
51;; UNSPEC usage:
52
53(define_constants
54  [; Relocation specifiers
55   (UNSPEC_GOT			0)
56   (UNSPEC_GOTOFF		1)
57   (UNSPEC_GOTPCREL		2)
58   (UNSPEC_GOTTPOFF		3)
59   (UNSPEC_TPOFF		4)
60   (UNSPEC_NTPOFF		5)
61   (UNSPEC_DTPOFF		6)
62   (UNSPEC_GOTNTPOFF		7)
63   (UNSPEC_INDNTPOFF		8)
64
65   ; Prologue support
66   (UNSPEC_STACK_ALLOC		11)
67   (UNSPEC_SET_GOT		12)
68   (UNSPEC_SSE_PROLOGUE_SAVE	13)
69
70   ; TLS support
71   (UNSPEC_TP			15)
72   (UNSPEC_TLS_GD		16)
73   (UNSPEC_TLS_LD_BASE		17)
74
75   ; Other random patterns
76   (UNSPEC_SCAS			20)
77   (UNSPEC_SIN			21)
78   (UNSPEC_COS			22)
79   (UNSPEC_FNSTSW		24)
80   (UNSPEC_SAHF			25)
81   (UNSPEC_FSTCW		26)
82   (UNSPEC_ADD_CARRY		27)
83   (UNSPEC_FLDCW		28)
84
85   ; For SSE/MMX support:
86   (UNSPEC_FIX			30)
87   (UNSPEC_MASKMOV		32)
88   (UNSPEC_MOVMSK		33)
89   (UNSPEC_MOVNT		34)
90   (UNSPEC_MOVA			38)
91   (UNSPEC_MOVU			39)
92   (UNSPEC_SHUFFLE		41)
93   (UNSPEC_RCP			42)
94   (UNSPEC_RSQRT		43)
95   (UNSPEC_SFENCE		44)
96   (UNSPEC_NOP			45)	; prevents combiner cleverness
97   (UNSPEC_PAVGUSB		49)
98   (UNSPEC_PFRCP		50)
99   (UNSPEC_PFRCPIT1		51)
100   (UNSPEC_PFRCPIT2		52)
101   (UNSPEC_PFRSQRT		53)
102   (UNSPEC_PFRSQIT1		54)
103   (UNSPEC_PSHUFLW		55)
104   (UNSPEC_PSHUFHW		56)
105   (UNSPEC_MFENCE		59)
106   (UNSPEC_LFENCE		60)
107   (UNSPEC_PSADBW		61)
108   (UNSPEC_ADDSUB		71)
109   (UNSPEC_HADD			72)
110   (UNSPEC_HSUB			73)
111   (UNSPEC_MOVSHDUP		74)
112   (UNSPEC_MOVSLDUP		75)
113   (UNSPEC_LDQQU		76)
114   (UNSPEC_MOVDDUP		77)
115
116   ; x87 Floating point
117   (UNSPEC_FPATAN		65)
118   (UNSPEC_FYL2X		66)
119   (UNSPEC_FSCALE		67)
120   (UNSPEC_FRNDINT		68)
121   (UNSPEC_F2XM1		69)
122
123   ; REP instruction
124   (UNSPEC_REP			75)
125  ])
126
127(define_constants
128  [(UNSPECV_BLOCKAGE		0)
129   (UNSPECV_STACK_PROBE		10)
130   (UNSPECV_EH_RETURN		13)
131   (UNSPECV_EMMS		31)
132   (UNSPECV_LDMXCSR		37)
133   (UNSPECV_STMXCSR		40)
134   (UNSPECV_FEMMS		46)
135   (UNSPECV_CLFLUSH		57)
136   (UNSPECV_ALIGN		68)
137   (UNSPECV_MONITOR		69)
138   (UNSPECV_MWAIT		70)
139  ])
140
141;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142;; from i386.c.
143
144;; In C guard expressions, put expressions which may be compile-time
145;; constants first.  This allows for better optimization.  For
146;; example, write "TARGET_64BIT && reload_completed", not
147;; "reload_completed && TARGET_64BIT".
148
149
150;; Processor type.  This attribute must exactly match the processor_type
151;; enumeration in i386.h.
152(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153  (const (symbol_ref "ix86_tune")))
154
155;; A basic instruction type.  Refinements due to arguments to be
156;; provided in other attributes.
157(define_attr "type"
158  "other,multi,
159   alu,alu1,negnot,imov,imovx,lea,
160   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161   icmp,test,ibr,setcc,icmov,
162   push,pop,call,callv,leave,
163   str,cld,
164   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165   sselog,sseiadd,sseishft,sseimul,
166   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168  (const_string "other"))
169
170;; Main data type used by the insn
171(define_attr "mode"
172  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173  (const_string "unknown"))
174
175;; The CPU unit operations uses.
176(define_attr "unit" "integer,i387,sse,mmx,unknown"
177  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178	   (const_string "i387")
179	 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181	   (const_string "sse")
182	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183	   (const_string "mmx")
184	 (eq_attr "type" "other")
185	   (const_string "unknown")]
186	 (const_string "integer")))
187
188;; The (bounding maximum) length of an instruction immediate.
189(define_attr "length_immediate" ""
190  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191	   (const_int 0)
192	 (eq_attr "unit" "i387,sse,mmx")
193	   (const_int 0)
194	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195			  imul,icmp,push,pop")
196	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197	 (eq_attr "type" "imov,test")
198	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199	 (eq_attr "type" "call")
200	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
201	     (const_int 4)
202	     (const_int 0))
203	 (eq_attr "type" "callv")
204	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
205	     (const_int 4)
206	     (const_int 0))
207	 ;; We don't know the size before shorten_branches.  Expect
208	 ;; the instruction to fit for better scheduling.
209	 (eq_attr "type" "ibr")
210	   (const_int 1)
211	 ]
212	 (symbol_ref "/* Update immediate_length and other attributes! */
213		      abort(),1")))
214
215;; The (bounding maximum) length of an instruction address.
216(define_attr "length_address" ""
217  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218	   (const_int 0)
219	 (and (eq_attr "type" "call")
220	      (match_operand 0 "constant_call_address_operand" ""))
221	     (const_int 0)
222	 (and (eq_attr "type" "callv")
223	      (match_operand 1 "constant_call_address_operand" ""))
224	     (const_int 0)
225	 ]
226	 (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228;; Set when length prefix is used.
229(define_attr "prefix_data16" ""
230  (if_then_else (ior (eq_attr "mode" "HI")
231		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232    (const_int 1)
233    (const_int 0)))
234
235;; Set when string REP prefix is used.
236(define_attr "prefix_rep" "" 
237  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238    (const_int 1)
239    (const_int 0)))
240
241;; Set when 0f opcode prefix is used.
242(define_attr "prefix_0f" ""
243  (if_then_else 
244    (ior (eq_attr "type" "imovx,setcc,icmov")
245	 (eq_attr "unit" "sse,mmx"))
246    (const_int 1)
247    (const_int 0)))
248
249;; Set when 0f opcode prefix is used.
250(define_attr "prefix_rex" ""
251  (cond [(and (eq_attr "mode" "DI")
252  	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253	   (const_int 1)
254	 (and (eq_attr "mode" "QI")
255	      (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256		  (const_int 0)))
257	   (const_int 1)
258	 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259	     (const_int 0))
260	   (const_int 1)
261	]
262	(const_int 0)))
263
264;; Set when modrm byte is used.
265(define_attr "modrm" ""
266  (cond [(eq_attr "type" "str,cld,leave")
267	   (const_int 0)
268	 (eq_attr "unit" "i387")
269	   (const_int 0)
270         (and (eq_attr "type" "incdec")
271	      (ior (match_operand:SI 1 "register_operand" "")
272		   (match_operand:HI 1 "register_operand" "")))
273	   (const_int 0)
274	 (and (eq_attr "type" "push")
275	      (not (match_operand 1 "memory_operand" "")))
276	   (const_int 0)
277	 (and (eq_attr "type" "pop")
278	      (not (match_operand 0 "memory_operand" "")))
279	   (const_int 0)
280	 (and (eq_attr "type" "imov")
281	      (and (match_operand 0 "register_operand" "")
282	           (match_operand 1 "immediate_operand" "")))
283	   (const_int 0)
284	 (and (eq_attr "type" "call")
285	      (match_operand 0 "constant_call_address_operand" ""))
286	     (const_int 0)
287	 (and (eq_attr "type" "callv")
288	      (match_operand 1 "constant_call_address_operand" ""))
289	     (const_int 0)
290	 ]
291	 (const_int 1)))
292
293;; The (bounding maximum) length of an instruction in bytes.
294;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
295;; to split it and compute proper length as for other insns.
296(define_attr "length" ""
297  (cond [(eq_attr "type" "other,multi,fistp")
298	   (const_int 16)
299	 (eq_attr "type" "fcmp")
300	   (const_int 4)
301	 (eq_attr "unit" "i387")
302	   (plus (const_int 2)
303		 (plus (attr "prefix_data16")
304		       (attr "length_address")))]
305	 (plus (plus (attr "modrm")
306		     (plus (attr "prefix_0f")
307			   (plus (attr "prefix_rex")
308				 (const_int 1))))
309	       (plus (attr "prefix_rep")
310		     (plus (attr "prefix_data16")
311			   (plus (attr "length_immediate")
312				 (attr "length_address")))))))
313
314;; The `memory' attribute is `none' if no memory is referenced, `load' or
315;; `store' if there is a simple memory reference therein, or `unknown'
316;; if the instruction is complex.
317
318(define_attr "memory" "none,load,store,both,unknown"
319  (cond [(eq_attr "type" "other,multi,str")
320	   (const_string "unknown")
321	 (eq_attr "type" "lea,fcmov,fpspc,cld")
322	   (const_string "none")
323	 (eq_attr "type" "fistp,leave")
324	   (const_string "both")
325	 (eq_attr "type" "push")
326	   (if_then_else (match_operand 1 "memory_operand" "")
327	     (const_string "both")
328	     (const_string "store"))
329	 (eq_attr "type" "pop")
330	   (if_then_else (match_operand 0 "memory_operand" "")
331	     (const_string "both")
332	     (const_string "load"))
333	 (eq_attr "type" "setcc")
334	   (if_then_else (match_operand 0 "memory_operand" "")
335	     (const_string "store")
336	     (const_string "none"))
337	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338	   (if_then_else (ior (match_operand 0 "memory_operand" "")
339			      (match_operand 1 "memory_operand" ""))
340	     (const_string "load")
341	     (const_string "none"))
342	 (eq_attr "type" "ibr")
343	   (if_then_else (match_operand 0 "memory_operand" "")
344	     (const_string "load")
345	     (const_string "none"))
346	 (eq_attr "type" "call")
347	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
348	     (const_string "none")
349	     (const_string "load"))
350	 (eq_attr "type" "callv")
351	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
352	     (const_string "none")
353	     (const_string "load"))
354	 (and (eq_attr "type" "alu1,negnot,ishift1")
355	      (match_operand 1 "memory_operand" ""))
356	   (const_string "both")
357	 (and (match_operand 0 "memory_operand" "")
358	      (match_operand 1 "memory_operand" ""))
359	   (const_string "both")
360	 (match_operand 0 "memory_operand" "")
361	   (const_string "store")
362	 (match_operand 1 "memory_operand" "")
363	   (const_string "load")
364	 (and (eq_attr "type"
365		 "!alu1,negnot,ishift1,
366		   imov,imovx,icmp,test,
367		   fmov,fcmp,fsgn,
368		   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369		   mmx,mmxmov,mmxcmp,mmxcvt")
370	      (match_operand 2 "memory_operand" ""))
371	   (const_string "load")
372	 (and (eq_attr "type" "icmov")
373	      (match_operand 3 "memory_operand" ""))
374	   (const_string "load")
375	]
376	(const_string "none")))
377
378;; Indicates if an instruction has both an immediate and a displacement.
379
380(define_attr "imm_disp" "false,true,unknown"
381  (cond [(eq_attr "type" "other,multi")
382	   (const_string "unknown")
383	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384	      (and (match_operand 0 "memory_displacement_operand" "")
385		   (match_operand 1 "immediate_operand" "")))
386	   (const_string "true")
387	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388	      (and (match_operand 0 "memory_displacement_operand" "")
389		   (match_operand 2 "immediate_operand" "")))
390	   (const_string "true")
391	]
392	(const_string "false")))
393
394;; Indicates if an FP operation has an integer source.
395
396(define_attr "fp_int_src" "false,true"
397  (const_string "false"))
398
399;; Describe a user's asm statement.
400(define_asm_attributes
401  [(set_attr "length" "128")
402   (set_attr "type" "multi")])
403
404(include "pentium.md")
405(include "ppro.md")
406(include "k6.md")
407(include "athlon.md")
408
409;; Compare instructions.
410
411;; All compare insns have expanders that save the operands away without
412;; actually generating RTL.  The bCOND or sCOND (emitted immediately
413;; after the cmp) will actually emit the cmpM.
414
415(define_expand "cmpdi"
416  [(set (reg:CC 17)
417	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418		    (match_operand:DI 1 "x86_64_general_operand" "")))]
419  ""
420{
421  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422    operands[0] = force_reg (DImode, operands[0]);
423  ix86_compare_op0 = operands[0];
424  ix86_compare_op1 = operands[1];
425  DONE;
426})
427
428(define_expand "cmpsi"
429  [(set (reg:CC 17)
430	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431		    (match_operand:SI 1 "general_operand" "")))]
432  ""
433{
434  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435    operands[0] = force_reg (SImode, operands[0]);
436  ix86_compare_op0 = operands[0];
437  ix86_compare_op1 = operands[1];
438  DONE;
439})
440
441(define_expand "cmphi"
442  [(set (reg:CC 17)
443	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444		    (match_operand:HI 1 "general_operand" "")))]
445  ""
446{
447  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448    operands[0] = force_reg (HImode, operands[0]);
449  ix86_compare_op0 = operands[0];
450  ix86_compare_op1 = operands[1];
451  DONE;
452})
453
454(define_expand "cmpqi"
455  [(set (reg:CC 17)
456	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457		    (match_operand:QI 1 "general_operand" "")))]
458  "TARGET_QIMODE_MATH"
459{
460  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461    operands[0] = force_reg (QImode, operands[0]);
462  ix86_compare_op0 = operands[0];
463  ix86_compare_op1 = operands[1];
464  DONE;
465})
466
467(define_insn "cmpdi_ccno_1_rex64"
468  [(set (reg 17)
469	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470		 (match_operand:DI 1 "const0_operand" "n,n")))]
471  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472  "@
473   test{q}\t{%0, %0|%0, %0}
474   cmp{q}\t{%1, %0|%0, %1}"
475  [(set_attr "type" "test,icmp")
476   (set_attr "length_immediate" "0,1")
477   (set_attr "mode" "DI")])
478
479(define_insn "*cmpdi_minus_1_rex64"
480  [(set (reg 17)
481	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483		 (const_int 0)))]
484  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485  "cmp{q}\t{%1, %0|%0, %1}"
486  [(set_attr "type" "icmp")
487   (set_attr "mode" "DI")])
488
489(define_expand "cmpdi_1_rex64"
490  [(set (reg:CC 17)
491	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492		    (match_operand:DI 1 "general_operand" "")))]
493  "TARGET_64BIT"
494  "")
495
496(define_insn "cmpdi_1_insn_rex64"
497  [(set (reg 17)
498	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501  "cmp{q}\t{%1, %0|%0, %1}"
502  [(set_attr "type" "icmp")
503   (set_attr "mode" "DI")])
504
505
506(define_insn "*cmpsi_ccno_1"
507  [(set (reg 17)
508	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509		 (match_operand:SI 1 "const0_operand" "n,n")))]
510  "ix86_match_ccmode (insn, CCNOmode)"
511  "@
512   test{l}\t{%0, %0|%0, %0}
513   cmp{l}\t{%1, %0|%0, %1}"
514  [(set_attr "type" "test,icmp")
515   (set_attr "length_immediate" "0,1")
516   (set_attr "mode" "SI")])
517
518(define_insn "*cmpsi_minus_1"
519  [(set (reg 17)
520	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521			   (match_operand:SI 1 "general_operand" "ri,mr"))
522		 (const_int 0)))]
523  "ix86_match_ccmode (insn, CCGOCmode)"
524  "cmp{l}\t{%1, %0|%0, %1}"
525  [(set_attr "type" "icmp")
526   (set_attr "mode" "SI")])
527
528(define_expand "cmpsi_1"
529  [(set (reg:CC 17)
530	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531		    (match_operand:SI 1 "general_operand" "ri,mr")))]
532  ""
533  "")
534
535(define_insn "*cmpsi_1_insn"
536  [(set (reg 17)
537	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538		 (match_operand:SI 1 "general_operand" "ri,mr")))]
539  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540    && ix86_match_ccmode (insn, CCmode)"
541  "cmp{l}\t{%1, %0|%0, %1}"
542  [(set_attr "type" "icmp")
543   (set_attr "mode" "SI")])
544
545(define_insn "*cmphi_ccno_1"
546  [(set (reg 17)
547	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548		 (match_operand:HI 1 "const0_operand" "n,n")))]
549  "ix86_match_ccmode (insn, CCNOmode)"
550  "@
551   test{w}\t{%0, %0|%0, %0}
552   cmp{w}\t{%1, %0|%0, %1}"
553  [(set_attr "type" "test,icmp")
554   (set_attr "length_immediate" "0,1")
555   (set_attr "mode" "HI")])
556
557(define_insn "*cmphi_minus_1"
558  [(set (reg 17)
559	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560			   (match_operand:HI 1 "general_operand" "ri,mr"))
561		 (const_int 0)))]
562  "ix86_match_ccmode (insn, CCGOCmode)"
563  "cmp{w}\t{%1, %0|%0, %1}"
564  [(set_attr "type" "icmp")
565   (set_attr "mode" "HI")])
566
567(define_insn "*cmphi_1"
568  [(set (reg 17)
569	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570		 (match_operand:HI 1 "general_operand" "ri,mr")))]
571  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572   && ix86_match_ccmode (insn, CCmode)"
573  "cmp{w}\t{%1, %0|%0, %1}"
574  [(set_attr "type" "icmp")
575   (set_attr "mode" "HI")])
576
577(define_insn "*cmpqi_ccno_1"
578  [(set (reg 17)
579	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580		 (match_operand:QI 1 "const0_operand" "n,n")))]
581  "ix86_match_ccmode (insn, CCNOmode)"
582  "@
583   test{b}\t{%0, %0|%0, %0}
584   cmp{b}\t{$0, %0|%0, 0}"
585  [(set_attr "type" "test,icmp")
586   (set_attr "length_immediate" "0,1")
587   (set_attr "mode" "QI")])
588
589(define_insn "*cmpqi_1"
590  [(set (reg 17)
591	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592		 (match_operand:QI 1 "general_operand" "qi,mq")))]
593  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594    && ix86_match_ccmode (insn, CCmode)"
595  "cmp{b}\t{%1, %0|%0, %1}"
596  [(set_attr "type" "icmp")
597   (set_attr "mode" "QI")])
598
599(define_insn "*cmpqi_minus_1"
600  [(set (reg 17)
601	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602			   (match_operand:QI 1 "general_operand" "qi,mq"))
603		 (const_int 0)))]
604  "ix86_match_ccmode (insn, CCGOCmode)"
605  "cmp{b}\t{%1, %0|%0, %1}"
606  [(set_attr "type" "icmp")
607   (set_attr "mode" "QI")])
608
609(define_insn "*cmpqi_ext_1"
610  [(set (reg 17)
611	(compare
612	  (match_operand:QI 0 "general_operand" "Qm")
613	  (subreg:QI
614	    (zero_extract:SI
615	      (match_operand 1 "ext_register_operand" "Q")
616	      (const_int 8)
617	      (const_int 8)) 0)))]
618  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619  "cmp{b}\t{%h1, %0|%0, %h1}"
620  [(set_attr "type" "icmp")
621   (set_attr "mode" "QI")])
622
623(define_insn "*cmpqi_ext_1_rex64"
624  [(set (reg 17)
625	(compare
626	  (match_operand:QI 0 "register_operand" "Q")
627	  (subreg:QI
628	    (zero_extract:SI
629	      (match_operand 1 "ext_register_operand" "Q")
630	      (const_int 8)
631	      (const_int 8)) 0)))]
632  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633  "cmp{b}\t{%h1, %0|%0, %h1}"
634  [(set_attr "type" "icmp")
635   (set_attr "mode" "QI")])
636
637(define_insn "*cmpqi_ext_2"
638  [(set (reg 17)
639	(compare
640	  (subreg:QI
641	    (zero_extract:SI
642	      (match_operand 0 "ext_register_operand" "Q")
643	      (const_int 8)
644	      (const_int 8)) 0)
645	  (match_operand:QI 1 "const0_operand" "n")))]
646  "ix86_match_ccmode (insn, CCNOmode)"
647  "test{b}\t%h0, %h0"
648  [(set_attr "type" "test")
649   (set_attr "length_immediate" "0")
650   (set_attr "mode" "QI")])
651
652(define_expand "cmpqi_ext_3"
653  [(set (reg:CC 17)
654	(compare:CC
655	  (subreg:QI
656	    (zero_extract:SI
657	      (match_operand 0 "ext_register_operand" "")
658	      (const_int 8)
659	      (const_int 8)) 0)
660	  (match_operand:QI 1 "general_operand" "")))]
661  ""
662  "")
663
664(define_insn "cmpqi_ext_3_insn"
665  [(set (reg 17)
666	(compare
667	  (subreg:QI
668	    (zero_extract:SI
669	      (match_operand 0 "ext_register_operand" "Q")
670	      (const_int 8)
671	      (const_int 8)) 0)
672	  (match_operand:QI 1 "general_operand" "Qmn")))]
673  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674  "cmp{b}\t{%1, %h0|%h0, %1}"
675  [(set_attr "type" "icmp")
676   (set_attr "mode" "QI")])
677
678(define_insn "cmpqi_ext_3_insn_rex64"
679  [(set (reg 17)
680	(compare
681	  (subreg:QI
682	    (zero_extract:SI
683	      (match_operand 0 "ext_register_operand" "Q")
684	      (const_int 8)
685	      (const_int 8)) 0)
686	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688  "cmp{b}\t{%1, %h0|%h0, %1}"
689  [(set_attr "type" "icmp")
690   (set_attr "mode" "QI")])
691
692(define_insn "*cmpqi_ext_4"
693  [(set (reg 17)
694	(compare
695	  (subreg:QI
696	    (zero_extract:SI
697	      (match_operand 0 "ext_register_operand" "Q")
698	      (const_int 8)
699	      (const_int 8)) 0)
700	  (subreg:QI
701	    (zero_extract:SI
702	      (match_operand 1 "ext_register_operand" "Q")
703	      (const_int 8)
704	      (const_int 8)) 0)))]
705  "ix86_match_ccmode (insn, CCmode)"
706  "cmp{b}\t{%h1, %h0|%h0, %h1}"
707  [(set_attr "type" "icmp")
708   (set_attr "mode" "QI")])
709
710;; These implement float point compares.
711;; %%% See if we can get away with VOIDmode operands on the actual insns,
712;; which would allow mix and match FP modes on the compares.  Which is what
713;; the old patterns did, but with many more of them.
714
715(define_expand "cmpxf"
716  [(set (reg:CC 17)
717	(compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718		    (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719  "TARGET_80387"
720{
721  ix86_compare_op0 = operands[0];
722  ix86_compare_op1 = operands[1];
723  DONE;
724})
725
726(define_expand "cmpdf"
727  [(set (reg:CC 17)
728	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
729		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
730  "TARGET_80387 || TARGET_SSE2"
731{
732  ix86_compare_op0 = operands[0];
733  ix86_compare_op1 = operands[1];
734  DONE;
735})
736
737(define_expand "cmpsf"
738  [(set (reg:CC 17)
739	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
740		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
741  "TARGET_80387 || TARGET_SSE"
742{
743  ix86_compare_op0 = operands[0];
744  ix86_compare_op1 = operands[1];
745  DONE;
746})
747
748;; FP compares, step 1:
749;; Set the FP condition codes.
750;;
751;; CCFPmode	compare with exceptions
752;; CCFPUmode	compare with no exceptions
753
754;; %%% It is an unfortunate fact that ftst has no non-popping variant,
755;; and that fp moves clobber the condition codes, and that there is
756;; currently no way to describe this fact to reg-stack.  So there are
757;; no splitters yet for this.
758
759;; %%% YIKES!  This scheme does not retain a strong connection between 
760;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
761;; work!  Only allow tos/mem with tos in op 0.
762;;
763;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
764;; things aren't as bad as they sound...
765
766(define_insn "*cmpfp_0"
767  [(set (match_operand:HI 0 "register_operand" "=a")
768	(unspec:HI
769	  [(compare:CCFP (match_operand 1 "register_operand" "f")
770		         (match_operand 2 "const0_operand" "X"))]
771	  UNSPEC_FNSTSW))]
772  "TARGET_80387
773   && FLOAT_MODE_P (GET_MODE (operands[1]))
774   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
775{
776  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
777    return "ftst\;fnstsw\t%0\;fstp\t%y0";
778  else
779    return "ftst\;fnstsw\t%0";
780}
781  [(set_attr "type" "multi")
782   (set (attr "mode")
783     (cond [(match_operand:SF 1 "" "")
784	      (const_string "SF")
785	    (match_operand:DF 1 "" "")
786	      (const_string "DF")
787	   ]
788	   (const_string "XF")))])
789
790;; We may not use "#" to split and emit these, since the REG_DEAD notes
791;; used to manage the reg stack popping would not be preserved.
792
793(define_insn "*cmpfp_2_sf"
794  [(set (reg:CCFP 18)
795	(compare:CCFP
796	  (match_operand:SF 0 "register_operand" "f")
797	  (match_operand:SF 1 "nonimmediate_operand" "fm")))]
798  "TARGET_80387"
799  "* return output_fp_compare (insn, operands, 0, 0);"
800  [(set_attr "type" "fcmp")
801   (set_attr "mode" "SF")])
802
803(define_insn "*cmpfp_2_sf_1"
804  [(set (match_operand:HI 0 "register_operand" "=a")
805	(unspec:HI
806	  [(compare:CCFP
807	     (match_operand:SF 1 "register_operand" "f")
808	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809	  UNSPEC_FNSTSW))]
810  "TARGET_80387"
811  "* return output_fp_compare (insn, operands, 2, 0);"
812  [(set_attr "type" "fcmp")
813   (set_attr "mode" "SF")])
814
815(define_insn "*cmpfp_2_df"
816  [(set (reg:CCFP 18)
817	(compare:CCFP
818	  (match_operand:DF 0 "register_operand" "f")
819	  (match_operand:DF 1 "nonimmediate_operand" "fm")))]
820  "TARGET_80387"
821  "* return output_fp_compare (insn, operands, 0, 0);"
822  [(set_attr "type" "fcmp")
823   (set_attr "mode" "DF")])
824
825(define_insn "*cmpfp_2_df_1"
826  [(set (match_operand:HI 0 "register_operand" "=a")
827	(unspec:HI
828	  [(compare:CCFP
829	     (match_operand:DF 1 "register_operand" "f")
830	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831	  UNSPEC_FNSTSW))]
832  "TARGET_80387"
833  "* return output_fp_compare (insn, operands, 2, 0);"
834  [(set_attr "type" "multi")
835   (set_attr "mode" "DF")])
836
837(define_insn "*cmpfp_2_xf"
838  [(set (reg:CCFP 18)
839	(compare:CCFP
840	  (match_operand:XF 0 "register_operand" "f")
841	  (match_operand:XF 1 "register_operand" "f")))]
842  "TARGET_80387"
843  "* return output_fp_compare (insn, operands, 0, 0);"
844  [(set_attr "type" "fcmp")
845   (set_attr "mode" "XF")])
846
847(define_insn "*cmpfp_2_xf_1"
848  [(set (match_operand:HI 0 "register_operand" "=a")
849	(unspec:HI
850	  [(compare:CCFP
851	     (match_operand:XF 1 "register_operand" "f")
852	     (match_operand:XF 2 "register_operand" "f"))]
853	  UNSPEC_FNSTSW))]
854  "TARGET_80387"
855  "* return output_fp_compare (insn, operands, 2, 0);"
856  [(set_attr "type" "multi")
857   (set_attr "mode" "XF")])
858
859(define_insn "*cmpfp_2u"
860  [(set (reg:CCFPU 18)
861	(compare:CCFPU
862	  (match_operand 0 "register_operand" "f")
863	  (match_operand 1 "register_operand" "f")))]
864  "TARGET_80387
865   && FLOAT_MODE_P (GET_MODE (operands[0]))
866   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
867  "* return output_fp_compare (insn, operands, 0, 1);"
868  [(set_attr "type" "fcmp")
869   (set (attr "mode")
870     (cond [(match_operand:SF 1 "" "")
871	      (const_string "SF")
872	    (match_operand:DF 1 "" "")
873	      (const_string "DF")
874	   ]
875	   (const_string "XF")))])
876
877(define_insn "*cmpfp_2u_1"
878  [(set (match_operand:HI 0 "register_operand" "=a")
879	(unspec:HI
880	  [(compare:CCFPU
881	     (match_operand 1 "register_operand" "f")
882	     (match_operand 2 "register_operand" "f"))]
883	  UNSPEC_FNSTSW))]
884  "TARGET_80387
885   && FLOAT_MODE_P (GET_MODE (operands[1]))
886   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887  "* return output_fp_compare (insn, operands, 2, 1);"
888  [(set_attr "type" "multi")
889   (set (attr "mode")
890     (cond [(match_operand:SF 1 "" "")
891	      (const_string "SF")
892	    (match_operand:DF 1 "" "")
893	      (const_string "DF")
894	   ]
895	   (const_string "XF")))])
896
897;; Patterns to match the SImode-in-memory ficom instructions.
898;;
899;; %%% Play games with accepting gp registers, as otherwise we have to
900;; force them to memory during rtl generation, which is no good.  We
901;; can get rid of this once we teach reload to do memory input reloads 
902;; via pushes.
903
904(define_insn "*ficom_1"
905  [(set (reg:CCFP 18)
906	(compare:CCFP
907	  (match_operand 0 "register_operand" "f,f")
908	  (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
909  "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
910   && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
911  "#")
912
913;; Split the not-really-implemented gp register case into a
914;; push-op-pop sequence.
915;;
916;; %%% This is most efficient, but am I gonna get in trouble
917;; for separating cc0_setter and cc0_user?
918
919(define_split
920  [(set (reg:CCFP 18)
921	(compare:CCFP
922	  (match_operand:SF 0 "register_operand" "")
923	  (float (match_operand:SI 1 "register_operand" ""))))]
924  "0 && TARGET_80387 && reload_completed"
925  [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
926   (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
927   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
928              (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
929  "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
930   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
931
932;; FP compares, step 2
933;; Move the fpsw to ax.
934
935(define_insn "*x86_fnstsw_1"
936  [(set (match_operand:HI 0 "register_operand" "=a")
937	(unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
938  "TARGET_80387"
939  "fnstsw\t%0"
940  [(set_attr "length" "2")
941   (set_attr "mode" "SI")
942   (set_attr "unit" "i387")
943   (set_attr "ppro_uops" "few")])
944
945;; FP compares, step 3
946;; Get ax into flags, general case.
947
948(define_insn "x86_sahf_1"
949  [(set (reg:CC 17)
950	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
951  "!TARGET_64BIT"
952  "sahf"
953  [(set_attr "length" "1")
954   (set_attr "athlon_decode" "vector")
955   (set_attr "mode" "SI")
956   (set_attr "ppro_uops" "one")])
957
958;; Pentium Pro can do steps 1 through 3 in one go.
959
960(define_insn "*cmpfp_i"
961  [(set (reg:CCFP 17)
962	(compare:CCFP (match_operand 0 "register_operand" "f")
963		      (match_operand 1 "register_operand" "f")))]
964  "TARGET_80387 && TARGET_CMOVE
965   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966   && FLOAT_MODE_P (GET_MODE (operands[0]))
967   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
968  "* return output_fp_compare (insn, operands, 1, 0);"
969  [(set_attr "type" "fcmp")
970   (set (attr "mode")
971     (cond [(match_operand:SF 1 "" "")
972	      (const_string "SF")
973	    (match_operand:DF 1 "" "")
974	      (const_string "DF")
975	   ]
976	   (const_string "XF")))
977   (set_attr "athlon_decode" "vector")])
978
979(define_insn "*cmpfp_i_sse"
980  [(set (reg:CCFP 17)
981	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
982		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
983  "TARGET_80387
984   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
985   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
986  "* return output_fp_compare (insn, operands, 1, 0);"
987  [(set_attr "type" "fcmp,ssecomi")
988   (set (attr "mode")
989     (if_then_else (match_operand:SF 1 "" "")
990        (const_string "SF")
991        (const_string "DF")))
992   (set_attr "athlon_decode" "vector")])
993
994(define_insn "*cmpfp_i_sse_only"
995  [(set (reg:CCFP 17)
996	(compare:CCFP (match_operand 0 "register_operand" "x")
997		      (match_operand 1 "nonimmediate_operand" "xm")))]
998  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1000  "* return output_fp_compare (insn, operands, 1, 0);"
1001  [(set_attr "type" "ssecomi")
1002   (set (attr "mode")
1003     (if_then_else (match_operand:SF 1 "" "")
1004        (const_string "SF")
1005        (const_string "DF")))
1006   (set_attr "athlon_decode" "vector")])
1007
1008(define_insn "*cmpfp_iu"
1009  [(set (reg:CCFPU 17)
1010	(compare:CCFPU (match_operand 0 "register_operand" "f")
1011		       (match_operand 1 "register_operand" "f")))]
1012  "TARGET_80387 && TARGET_CMOVE
1013   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1014   && FLOAT_MODE_P (GET_MODE (operands[0]))
1015   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016  "* return output_fp_compare (insn, operands, 1, 1);"
1017  [(set_attr "type" "fcmp")
1018   (set (attr "mode")
1019     (cond [(match_operand:SF 1 "" "")
1020	      (const_string "SF")
1021	    (match_operand:DF 1 "" "")
1022	      (const_string "DF")
1023	   ]
1024	   (const_string "XF")))
1025   (set_attr "athlon_decode" "vector")])
1026
1027(define_insn "*cmpfp_iu_sse"
1028  [(set (reg:CCFPU 17)
1029	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1030		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1031  "TARGET_80387
1032   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1033   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034  "* return output_fp_compare (insn, operands, 1, 1);"
1035  [(set_attr "type" "fcmp,ssecomi")
1036   (set (attr "mode")
1037     (if_then_else (match_operand:SF 1 "" "")
1038        (const_string "SF")
1039        (const_string "DF")))
1040   (set_attr "athlon_decode" "vector")])
1041
1042(define_insn "*cmpfp_iu_sse_only"
1043  [(set (reg:CCFPU 17)
1044	(compare:CCFPU (match_operand 0 "register_operand" "x")
1045		       (match_operand 1 "nonimmediate_operand" "xm")))]
1046  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048  "* return output_fp_compare (insn, operands, 1, 1);"
1049  [(set_attr "type" "ssecomi")
1050   (set (attr "mode")
1051     (if_then_else (match_operand:SF 1 "" "")
1052        (const_string "SF")
1053        (const_string "DF")))
1054   (set_attr "athlon_decode" "vector")])
1055
1056;; Move instructions.
1057
1058;; General case of fullword move.
1059
1060(define_expand "movsi"
1061  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1062	(match_operand:SI 1 "general_operand" ""))]
1063  ""
1064  "ix86_expand_move (SImode, operands); DONE;")
1065
1066;; Push/pop instructions.  They are separate since autoinc/dec is not a
1067;; general_operand.
1068;;
1069;; %%% We don't use a post-inc memory reference because x86 is not a 
1070;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1071;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1072;; targets without our curiosities, and it is just as easy to represent
1073;; this differently.
1074
1075(define_insn "*pushsi2"
1076  [(set (match_operand:SI 0 "push_operand" "=<")
1077	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1078  "!TARGET_64BIT"
1079  "push{l}\t%1"
1080  [(set_attr "type" "push")
1081   (set_attr "mode" "SI")])
1082
1083;; For 64BIT abi we always round up to 8 bytes.
1084(define_insn "*pushsi2_rex64"
1085  [(set (match_operand:SI 0 "push_operand" "=X")
1086	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1087  "TARGET_64BIT"
1088  "push{q}\t%q1"
1089  [(set_attr "type" "push")
1090   (set_attr "mode" "SI")])
1091
1092(define_insn "*pushsi2_prologue"
1093  [(set (match_operand:SI 0 "push_operand" "=<")
1094	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1095   (clobber (mem:BLK (scratch)))]
1096  "!TARGET_64BIT"
1097  "push{l}\t%1"
1098  [(set_attr "type" "push")
1099   (set_attr "mode" "SI")])
1100
1101(define_insn "*popsi1_epilogue"
1102  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103	(mem:SI (reg:SI 7)))
1104   (set (reg:SI 7)
1105	(plus:SI (reg:SI 7) (const_int 4)))
1106   (clobber (mem:BLK (scratch)))]
1107  "!TARGET_64BIT"
1108  "pop{l}\t%0"
1109  [(set_attr "type" "pop")
1110   (set_attr "mode" "SI")])
1111
1112(define_insn "popsi1"
1113  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114	(mem:SI (reg:SI 7)))
1115   (set (reg:SI 7)
1116	(plus:SI (reg:SI 7) (const_int 4)))]
1117  "!TARGET_64BIT"
1118  "pop{l}\t%0"
1119  [(set_attr "type" "pop")
1120   (set_attr "mode" "SI")])
1121
1122(define_insn "*movsi_xor"
1123  [(set (match_operand:SI 0 "register_operand" "=r")
1124	(match_operand:SI 1 "const0_operand" "i"))
1125   (clobber (reg:CC 17))]
1126  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1127  "xor{l}\t{%0, %0|%0, %0}"
1128  [(set_attr "type" "alu1")
1129   (set_attr "mode" "SI")
1130   (set_attr "length_immediate" "0")])
1131 
1132(define_insn "*movsi_or"
1133  [(set (match_operand:SI 0 "register_operand" "=r")
1134	(match_operand:SI 1 "immediate_operand" "i"))
1135   (clobber (reg:CC 17))]
1136  "reload_completed
1137   && operands[1] == constm1_rtx
1138   && (TARGET_PENTIUM || optimize_size)"
1139{
1140  operands[1] = constm1_rtx;
1141  return "or{l}\t{%1, %0|%0, %1}";
1142}
1143  [(set_attr "type" "alu1")
1144   (set_attr "mode" "SI")
1145   (set_attr "length_immediate" "1")])
1146
1147(define_insn "*movsi_1"
1148  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1149	(match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1150  "(TARGET_INTER_UNIT_MOVES || optimize_size)
1151   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1152{
1153  switch (get_attr_type (insn))
1154    {
1155    case TYPE_SSEMOV:
1156      if (get_attr_mode (insn) == MODE_TI)
1157        return "movdqa\t{%1, %0|%0, %1}";
1158      return "movd\t{%1, %0|%0, %1}";
1159
1160    case TYPE_MMXMOV:
1161      if (get_attr_mode (insn) == MODE_DI)
1162	return "movq\t{%1, %0|%0, %1}";
1163      return "movd\t{%1, %0|%0, %1}";
1164
1165    case TYPE_LEA:
1166      return "lea{l}\t{%1, %0|%0, %1}";
1167
1168    default:
1169      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1170	abort();
1171      return "mov{l}\t{%1, %0|%0, %1}";
1172    }
1173}
1174  [(set (attr "type")
1175     (cond [(eq_attr "alternative" "2,3,4")
1176	      (const_string "mmxmov")
1177	    (eq_attr "alternative" "5,6,7")
1178	      (const_string "ssemov")
1179	    (and (ne (symbol_ref "flag_pic") (const_int 0))
1180		 (match_operand:SI 1 "symbolic_operand" ""))
1181	      (const_string "lea")
1182	   ]
1183	   (const_string "imov")))
1184   (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1185
1186(define_insn "*movsi_1_nointernunit"
1187  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1188	(match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1189  "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1190   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1191{
1192  switch (get_attr_type (insn))
1193    {
1194    case TYPE_SSEMOV:
1195      if (get_attr_mode (insn) == MODE_TI)
1196        return "movdqa\t{%1, %0|%0, %1}";
1197      return "movd\t{%1, %0|%0, %1}";
1198
1199    case TYPE_MMXMOV:
1200      if (get_attr_mode (insn) == MODE_DI)
1201	return "movq\t{%1, %0|%0, %1}";
1202      return "movd\t{%1, %0|%0, %1}";
1203
1204    case TYPE_LEA:
1205      return "lea{l}\t{%1, %0|%0, %1}";
1206
1207    default:
1208      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1209	abort();
1210      return "mov{l}\t{%1, %0|%0, %1}";
1211    }
1212}
1213  [(set (attr "type")
1214     (cond [(eq_attr "alternative" "2,3,4")
1215	      (const_string "mmxmov")
1216	    (eq_attr "alternative" "5,6,7")
1217	      (const_string "ssemov")
1218	    (and (ne (symbol_ref "flag_pic") (const_int 0))
1219		 (match_operand:SI 1 "symbolic_operand" ""))
1220	      (const_string "lea")
1221	   ]
1222	   (const_string "imov")))
1223   (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1224
1225;; Stores and loads of ax to arbitrary constant address.
1226;; We fake an second form of instruction to force reload to load address
1227;; into register when rax is not available
1228(define_insn "*movabssi_1_rex64"
1229  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1230	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1231  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1232  "@
1233   movabs{l}\t{%1, %P0|%P0, %1}
1234   mov{l}\t{%1, %a0|%a0, %1}"
1235  [(set_attr "type" "imov")
1236   (set_attr "modrm" "0,*")
1237   (set_attr "length_address" "8,0")
1238   (set_attr "length_immediate" "0,*")
1239   (set_attr "memory" "store")
1240   (set_attr "mode" "SI")])
1241
1242(define_insn "*movabssi_2_rex64"
1243  [(set (match_operand:SI 0 "register_operand" "=a,r")
1244        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1245  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1246  "@
1247   movabs{l}\t{%P1, %0|%0, %P1}
1248   mov{l}\t{%a1, %0|%0, %a1}"
1249  [(set_attr "type" "imov")
1250   (set_attr "modrm" "0,*")
1251   (set_attr "length_address" "8,0")
1252   (set_attr "length_immediate" "0")
1253   (set_attr "memory" "load")
1254   (set_attr "mode" "SI")])
1255
1256(define_insn "*swapsi"
1257  [(set (match_operand:SI 0 "register_operand" "+r")
1258	(match_operand:SI 1 "register_operand" "+r"))
1259   (set (match_dup 1)
1260	(match_dup 0))]
1261  ""
1262  "xchg{l}\t%1, %0"
1263  [(set_attr "type" "imov")
1264   (set_attr "mode" "SI")
1265   (set_attr "pent_pair" "np")
1266   (set_attr "athlon_decode" "vector")
1267   (set_attr "ppro_uops" "few")])
1268
1269(define_expand "movhi"
1270  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1271        (match_operand:HI 1 "general_operand" ""))]
1272  ""
1273  "ix86_expand_move (HImode, operands); DONE;")
1274
1275(define_insn "*pushhi2"
1276  [(set (match_operand:HI 0 "push_operand" "=<,<")
1277	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1278  "!TARGET_64BIT"
1279  "@
1280   push{w}\t{|WORD PTR }%1
1281   push{w}\t%1"
1282  [(set_attr "type" "push")
1283   (set_attr "mode" "HI")])
1284
1285;; For 64BIT abi we always round up to 8 bytes.
1286(define_insn "*pushhi2_rex64"
1287  [(set (match_operand:HI 0 "push_operand" "=X")
1288	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1289  "TARGET_64BIT"
1290  "push{q}\t%q1"
1291  [(set_attr "type" "push")
1292   (set_attr "mode" "QI")])
1293
1294(define_insn "*movhi_1"
1295  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1296	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1297  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1298{
1299  switch (get_attr_type (insn))
1300    {
1301    case TYPE_IMOVX:
1302      /* movzwl is faster than movw on p2 due to partial word stalls,
1303	 though not as fast as an aligned movl.  */
1304      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1305    default:
1306      if (get_attr_mode (insn) == MODE_SI)
1307        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1308      else
1309        return "mov{w}\t{%1, %0|%0, %1}";
1310    }
1311}
1312  [(set (attr "type")
1313     (cond [(and (eq_attr "alternative" "0")
1314		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315			  (const_int 0))
1316		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1317			  (const_int 0))))
1318	      (const_string "imov")
1319	    (and (eq_attr "alternative" "1,2")
1320		 (match_operand:HI 1 "aligned_operand" ""))
1321	      (const_string "imov")
1322	    (and (ne (symbol_ref "TARGET_MOVX")
1323		     (const_int 0))
1324		 (eq_attr "alternative" "0,2"))
1325	      (const_string "imovx")
1326	   ]
1327	   (const_string "imov")))
1328    (set (attr "mode")
1329      (cond [(eq_attr "type" "imovx")
1330	       (const_string "SI")
1331	     (and (eq_attr "alternative" "1,2")
1332		  (match_operand:HI 1 "aligned_operand" ""))
1333	       (const_string "SI")
1334	     (and (eq_attr "alternative" "0")
1335		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1336			   (const_int 0))
1337		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1338			   (const_int 0))))
1339	       (const_string "SI")
1340	    ]
1341	    (const_string "HI")))])
1342
1343;; Stores and loads of ax to arbitrary constant address.
1344;; We fake an second form of instruction to force reload to load address
1345;; into register when rax is not available
1346(define_insn "*movabshi_1_rex64"
1347  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1348	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1349  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1350  "@
1351   movabs{w}\t{%1, %P0|%P0, %1}
1352   mov{w}\t{%1, %a0|%a0, %1}"
1353  [(set_attr "type" "imov")
1354   (set_attr "modrm" "0,*")
1355   (set_attr "length_address" "8,0")
1356   (set_attr "length_immediate" "0,*")
1357   (set_attr "memory" "store")
1358   (set_attr "mode" "HI")])
1359
1360(define_insn "*movabshi_2_rex64"
1361  [(set (match_operand:HI 0 "register_operand" "=a,r")
1362        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1363  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1364  "@
1365   movabs{w}\t{%P1, %0|%0, %P1}
1366   mov{w}\t{%a1, %0|%0, %a1}"
1367  [(set_attr "type" "imov")
1368   (set_attr "modrm" "0,*")
1369   (set_attr "length_address" "8,0")
1370   (set_attr "length_immediate" "0")
1371   (set_attr "memory" "load")
1372   (set_attr "mode" "HI")])
1373
1374(define_insn "*swaphi_1"
1375  [(set (match_operand:HI 0 "register_operand" "+r")
1376	(match_operand:HI 1 "register_operand" "+r"))
1377   (set (match_dup 1)
1378	(match_dup 0))]
1379  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1380  "xchg{l}\t%k1, %k0"
1381  [(set_attr "type" "imov")
1382   (set_attr "mode" "SI")
1383   (set_attr "pent_pair" "np")
1384   (set_attr "athlon_decode" "vector")
1385   (set_attr "ppro_uops" "few")])
1386
1387(define_insn "*swaphi_2"
1388  [(set (match_operand:HI 0 "register_operand" "+r")
1389	(match_operand:HI 1 "register_operand" "+r"))
1390   (set (match_dup 1)
1391	(match_dup 0))]
1392  "TARGET_PARTIAL_REG_STALL"
1393  "xchg{w}\t%1, %0"
1394  [(set_attr "type" "imov")
1395   (set_attr "mode" "HI")
1396   (set_attr "pent_pair" "np")
1397   (set_attr "athlon_decode" "vector")
1398   (set_attr "ppro_uops" "few")])
1399
1400(define_expand "movstricthi"
1401  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1402	(match_operand:HI 1 "general_operand" ""))]
1403  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1404{
1405  /* Don't generate memory->memory moves, go through a register */
1406  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1407    operands[1] = force_reg (HImode, operands[1]);
1408})
1409
1410(define_insn "*movstricthi_1"
1411  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1412	(match_operand:HI 1 "general_operand" "rn,m"))]
1413  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1414   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1415  "mov{w}\t{%1, %0|%0, %1}"
1416  [(set_attr "type" "imov")
1417   (set_attr "mode" "HI")])
1418
1419(define_insn "*movstricthi_xor"
1420  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1421	(match_operand:HI 1 "const0_operand" "i"))
1422   (clobber (reg:CC 17))]
1423  "reload_completed
1424   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1425  "xor{w}\t{%0, %0|%0, %0}"
1426  [(set_attr "type" "alu1")
1427   (set_attr "mode" "HI")
1428   (set_attr "length_immediate" "0")])
1429
1430(define_expand "movqi"
1431  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1432	(match_operand:QI 1 "general_operand" ""))]
1433  ""
1434  "ix86_expand_move (QImode, operands); DONE;")
1435
1436;; emit_push_insn when it calls move_by_pieces requires an insn to
1437;; "push a byte".  But actually we use pushw, which has the effect
1438;; of rounding the amount pushed up to a halfword.
1439
1440(define_insn "*pushqi2"
1441  [(set (match_operand:QI 0 "push_operand" "=X,X")
1442	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1443  "!TARGET_64BIT"
1444  "@
1445   push{w}\t{|word ptr }%1
1446   push{w}\t%w1"
1447  [(set_attr "type" "push")
1448   (set_attr "mode" "HI")])
1449
1450;; For 64BIT abi we always round up to 8 bytes.
1451(define_insn "*pushqi2_rex64"
1452  [(set (match_operand:QI 0 "push_operand" "=X")
1453	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454  "TARGET_64BIT"
1455  "push{q}\t%q1"
1456  [(set_attr "type" "push")
1457   (set_attr "mode" "QI")])
1458
1459;; Situation is quite tricky about when to choose full sized (SImode) move
1460;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1461;; partial register dependency machines (such as AMD Athlon), where QImode
1462;; moves issue extra dependency and for partial register stalls machines
1463;; that don't use QImode patterns (and QImode move cause stall on the next
1464;; instruction).
1465;;
1466;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467;; register stall machines with, where we use QImode instructions, since
1468;; partial register stall can be caused there.  Then we use movzx.
1469(define_insn "*movqi_1"
1470  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1472  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473{
1474  switch (get_attr_type (insn))
1475    {
1476    case TYPE_IMOVX:
1477      if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1478	abort ();
1479      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480    default:
1481      if (get_attr_mode (insn) == MODE_SI)
1482        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483      else
1484        return "mov{b}\t{%1, %0|%0, %1}";
1485    }
1486}
1487  [(set (attr "type")
1488     (cond [(and (eq_attr "alternative" "3")
1489		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1490			  (const_int 0))
1491		      (eq (symbol_ref "TARGET_QIMODE_MATH")
1492			  (const_int 0))))
1493	      (const_string "imov")
1494	    (eq_attr "alternative" "3,5")
1495	      (const_string "imovx")
1496	    (and (ne (symbol_ref "TARGET_MOVX")
1497		     (const_int 0))
1498		 (eq_attr "alternative" "2"))
1499	      (const_string "imovx")
1500	   ]
1501	   (const_string "imov")))
1502   (set (attr "mode")
1503      (cond [(eq_attr "alternative" "3,4,5")
1504	       (const_string "SI")
1505	     (eq_attr "alternative" "6")
1506	       (const_string "QI")
1507	     (eq_attr "type" "imovx")
1508	       (const_string "SI")
1509	     (and (eq_attr "type" "imov")
1510		  (and (eq_attr "alternative" "0,1,2")
1511		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1512			   (const_int 0))))
1513	       (const_string "SI")
1514	     ;; Avoid partial register stalls when not using QImode arithmetic
1515	     (and (eq_attr "type" "imov")
1516		  (and (eq_attr "alternative" "0,1,2")
1517		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518				(const_int 0))
1519			    (eq (symbol_ref "TARGET_QIMODE_MATH")
1520				(const_int 0)))))
1521	       (const_string "SI")
1522	   ]
1523	   (const_string "QI")))])
1524
1525(define_expand "reload_outqi"
1526  [(parallel [(match_operand:QI 0 "" "=m")
1527              (match_operand:QI 1 "register_operand" "r")
1528              (match_operand:QI 2 "register_operand" "=&q")])]
1529  ""
1530{
1531  rtx op0, op1, op2;
1532  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1533
1534  if (reg_overlap_mentioned_p (op2, op0))
1535    abort ();
1536  if (! q_regs_operand (op1, QImode))
1537    {
1538      emit_insn (gen_movqi (op2, op1));
1539      op1 = op2;
1540    }
1541  emit_insn (gen_movqi (op0, op1));
1542  DONE;
1543})
1544
1545(define_insn "*swapqi_1"
1546  [(set (match_operand:QI 0 "register_operand" "+r")
1547	(match_operand:QI 1 "register_operand" "+r"))
1548   (set (match_dup 1)
1549	(match_dup 0))]
1550  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551  "xchg{l}\t%k1, %k0"
1552  [(set_attr "type" "imov")
1553   (set_attr "mode" "SI")
1554   (set_attr "pent_pair" "np")
1555   (set_attr "athlon_decode" "vector")
1556   (set_attr "ppro_uops" "few")])
1557
1558(define_insn "*swapqi_2"
1559  [(set (match_operand:QI 0 "register_operand" "+q")
1560	(match_operand:QI 1 "register_operand" "+q"))
1561   (set (match_dup 1)
1562	(match_dup 0))]
1563  "TARGET_PARTIAL_REG_STALL"
1564  "xchg{b}\t%1, %0"
1565  [(set_attr "type" "imov")
1566   (set_attr "mode" "QI")
1567   (set_attr "pent_pair" "np")
1568   (set_attr "athlon_decode" "vector")
1569   (set_attr "ppro_uops" "few")])
1570
1571(define_expand "movstrictqi"
1572  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1573	(match_operand:QI 1 "general_operand" ""))]
1574  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1575{
1576  /* Don't generate memory->memory moves, go through a register.  */
1577  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1578    operands[1] = force_reg (QImode, operands[1]);
1579})
1580
1581(define_insn "*movstrictqi_1"
1582  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1583	(match_operand:QI 1 "general_operand" "*qn,m"))]
1584  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1585   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1586  "mov{b}\t{%1, %0|%0, %1}"
1587  [(set_attr "type" "imov")
1588   (set_attr "mode" "QI")])
1589
1590(define_insn "*movstrictqi_xor"
1591  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1592	(match_operand:QI 1 "const0_operand" "i"))
1593   (clobber (reg:CC 17))]
1594  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1595  "xor{b}\t{%0, %0|%0, %0}"
1596  [(set_attr "type" "alu1")
1597   (set_attr "mode" "QI")
1598   (set_attr "length_immediate" "0")])
1599
1600(define_insn "*movsi_extv_1"
1601  [(set (match_operand:SI 0 "register_operand" "=R")
1602	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1603			 (const_int 8)
1604			 (const_int 8)))]
1605  ""
1606  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1607  [(set_attr "type" "imovx")
1608   (set_attr "mode" "SI")])
1609
1610(define_insn "*movhi_extv_1"
1611  [(set (match_operand:HI 0 "register_operand" "=R")
1612	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1613			 (const_int 8)
1614			 (const_int 8)))]
1615  ""
1616  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1617  [(set_attr "type" "imovx")
1618   (set_attr "mode" "SI")])
1619
1620(define_insn "*movqi_extv_1"
1621  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1622        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1623                         (const_int 8)
1624                         (const_int 8)))]
1625  "!TARGET_64BIT"
1626{
1627  switch (get_attr_type (insn))
1628    {
1629    case TYPE_IMOVX:
1630      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1631    default:
1632      return "mov{b}\t{%h1, %0|%0, %h1}";
1633    }
1634}
1635  [(set (attr "type")
1636     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1637			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1638			     (ne (symbol_ref "TARGET_MOVX")
1639				 (const_int 0))))
1640	(const_string "imovx")
1641	(const_string "imov")))
1642   (set (attr "mode")
1643     (if_then_else (eq_attr "type" "imovx")
1644	(const_string "SI")
1645	(const_string "QI")))])
1646
1647(define_insn "*movqi_extv_1_rex64"
1648  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1649        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1650                         (const_int 8)
1651                         (const_int 8)))]
1652  "TARGET_64BIT"
1653{
1654  switch (get_attr_type (insn))
1655    {
1656    case TYPE_IMOVX:
1657      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1658    default:
1659      return "mov{b}\t{%h1, %0|%0, %h1}";
1660    }
1661}
1662  [(set (attr "type")
1663     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1664			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1665			     (ne (symbol_ref "TARGET_MOVX")
1666				 (const_int 0))))
1667	(const_string "imovx")
1668	(const_string "imov")))
1669   (set (attr "mode")
1670     (if_then_else (eq_attr "type" "imovx")
1671	(const_string "SI")
1672	(const_string "QI")))])
1673
1674;; Stores and loads of ax to arbitrary constant address.
1675;; We fake an second form of instruction to force reload to load address
1676;; into register when rax is not available
1677(define_insn "*movabsqi_1_rex64"
1678  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1679	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1680  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1681  "@
1682   movabs{b}\t{%1, %P0|%P0, %1}
1683   mov{b}\t{%1, %a0|%a0, %1}"
1684  [(set_attr "type" "imov")
1685   (set_attr "modrm" "0,*")
1686   (set_attr "length_address" "8,0")
1687   (set_attr "length_immediate" "0,*")
1688   (set_attr "memory" "store")
1689   (set_attr "mode" "QI")])
1690
1691(define_insn "*movabsqi_2_rex64"
1692  [(set (match_operand:QI 0 "register_operand" "=a,r")
1693        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1694  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1695  "@
1696   movabs{b}\t{%P1, %0|%0, %P1}
1697   mov{b}\t{%a1, %0|%0, %a1}"
1698  [(set_attr "type" "imov")
1699   (set_attr "modrm" "0,*")
1700   (set_attr "length_address" "8,0")
1701   (set_attr "length_immediate" "0")
1702   (set_attr "memory" "load")
1703   (set_attr "mode" "QI")])
1704
1705(define_insn "*movsi_extzv_1"
1706  [(set (match_operand:SI 0 "register_operand" "=R")
1707	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1708			 (const_int 8)
1709			 (const_int 8)))]
1710  ""
1711  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1712  [(set_attr "type" "imovx")
1713   (set_attr "mode" "SI")])
1714
1715(define_insn "*movqi_extzv_2"
1716  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1717        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1718				    (const_int 8)
1719				    (const_int 8)) 0))]
1720  "!TARGET_64BIT"
1721{
1722  switch (get_attr_type (insn))
1723    {
1724    case TYPE_IMOVX:
1725      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1726    default:
1727      return "mov{b}\t{%h1, %0|%0, %h1}";
1728    }
1729}
1730  [(set (attr "type")
1731     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1732			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1733			     (ne (symbol_ref "TARGET_MOVX")
1734				 (const_int 0))))
1735	(const_string "imovx")
1736	(const_string "imov")))
1737   (set (attr "mode")
1738     (if_then_else (eq_attr "type" "imovx")
1739	(const_string "SI")
1740	(const_string "QI")))])
1741
1742(define_insn "*movqi_extzv_2_rex64"
1743  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1744        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1745				    (const_int 8)
1746				    (const_int 8)) 0))]
1747  "TARGET_64BIT"
1748{
1749  switch (get_attr_type (insn))
1750    {
1751    case TYPE_IMOVX:
1752      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1753    default:
1754      return "mov{b}\t{%h1, %0|%0, %h1}";
1755    }
1756}
1757  [(set (attr "type")
1758     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1759			(ne (symbol_ref "TARGET_MOVX")
1760			    (const_int 0)))
1761	(const_string "imovx")
1762	(const_string "imov")))
1763   (set (attr "mode")
1764     (if_then_else (eq_attr "type" "imovx")
1765	(const_string "SI")
1766	(const_string "QI")))])
1767
1768(define_insn "movsi_insv_1"
1769  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770			 (const_int 8)
1771			 (const_int 8))
1772	(match_operand:SI 1 "general_operand" "Qmn"))]
1773  "!TARGET_64BIT"
1774  "mov{b}\t{%b1, %h0|%h0, %b1}"
1775  [(set_attr "type" "imov")
1776   (set_attr "mode" "QI")])
1777
1778(define_insn "movdi_insv_1_rex64"
1779  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1780			 (const_int 8)
1781			 (const_int 8))
1782	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
1783  "TARGET_64BIT"
1784  "mov{b}\t{%b1, %h0|%h0, %b1}"
1785  [(set_attr "type" "imov")
1786   (set_attr "mode" "QI")])
1787
1788(define_insn "*movqi_insv_2"
1789  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1790			 (const_int 8)
1791			 (const_int 8))
1792	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1793		     (const_int 8)))]
1794  ""
1795  "mov{b}\t{%h1, %h0|%h0, %h1}"
1796  [(set_attr "type" "imov")
1797   (set_attr "mode" "QI")])
1798
1799(define_expand "movdi"
1800  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1801	(match_operand:DI 1 "general_operand" ""))]
1802  ""
1803  "ix86_expand_move (DImode, operands); DONE;")
1804
1805(define_insn "*pushdi"
1806  [(set (match_operand:DI 0 "push_operand" "=<")
1807	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1808  "!TARGET_64BIT"
1809  "#")
1810
1811(define_insn "pushdi2_rex64"
1812  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1813	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1814  "TARGET_64BIT"
1815  "@
1816   push{q}\t%1
1817   #"
1818  [(set_attr "type" "push,multi")
1819   (set_attr "mode" "DI")])
1820
1821;; Convert impossible pushes of immediate to existing instructions.
1822;; First try to get scratch register and go through it.  In case this
1823;; fails, push sign extended lower part first and then overwrite
1824;; upper part by 32bit move.
1825(define_peephole2
1826  [(match_scratch:DI 2 "r")
1827   (set (match_operand:DI 0 "push_operand" "")
1828        (match_operand:DI 1 "immediate_operand" ""))]
1829  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1830   && !x86_64_immediate_operand (operands[1], DImode)"
1831  [(set (match_dup 2) (match_dup 1))
1832   (set (match_dup 0) (match_dup 2))]
1833  "")
1834
1835;; We need to define this as both peepholer and splitter for case
1836;; peephole2 pass is not run.
1837(define_peephole2
1838  [(set (match_operand:DI 0 "push_operand" "")
1839        (match_operand:DI 1 "immediate_operand" ""))]
1840  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1842  [(set (match_dup 0) (match_dup 1))
1843   (set (match_dup 2) (match_dup 3))]
1844  "split_di (operands + 1, 1, operands + 2, operands + 3);
1845   operands[1] = gen_lowpart (DImode, operands[2]);
1846   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1847						    GEN_INT (4)));
1848  ")
1849
1850(define_split
1851  [(set (match_operand:DI 0 "push_operand" "")
1852        (match_operand:DI 1 "immediate_operand" ""))]
1853  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1854		   ? flow2_completed : reload_completed)
1855   && !symbolic_operand (operands[1], DImode)
1856   && !x86_64_immediate_operand (operands[1], DImode)"
1857  [(set (match_dup 0) (match_dup 1))
1858   (set (match_dup 2) (match_dup 3))]
1859  "split_di (operands + 1, 1, operands + 2, operands + 3);
1860   operands[1] = gen_lowpart (DImode, operands[2]);
1861   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862						    GEN_INT (4)));
1863  ")
1864
1865(define_insn "*pushdi2_prologue_rex64"
1866  [(set (match_operand:DI 0 "push_operand" "=<")
1867	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
1868   (clobber (mem:BLK (scratch)))]
1869  "TARGET_64BIT"
1870  "push{q}\t%1"
1871  [(set_attr "type" "push")
1872   (set_attr "mode" "DI")])
1873
1874(define_insn "*popdi1_epilogue_rex64"
1875  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1876	(mem:DI (reg:DI 7)))
1877   (set (reg:DI 7)
1878	(plus:DI (reg:DI 7) (const_int 8)))
1879   (clobber (mem:BLK (scratch)))]
1880  "TARGET_64BIT"
1881  "pop{q}\t%0"
1882  [(set_attr "type" "pop")
1883   (set_attr "mode" "DI")])
1884
1885(define_insn "popdi1"
1886  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1887	(mem:DI (reg:DI 7)))
1888   (set (reg:DI 7)
1889	(plus:DI (reg:DI 7) (const_int 8)))]
1890  "TARGET_64BIT"
1891  "pop{q}\t%0"
1892  [(set_attr "type" "pop")
1893   (set_attr "mode" "DI")])
1894
1895(define_insn "*movdi_xor_rex64"
1896  [(set (match_operand:DI 0 "register_operand" "=r")
1897	(match_operand:DI 1 "const0_operand" "i"))
1898   (clobber (reg:CC 17))]
1899  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1900   && reload_completed"
1901  "xor{l}\t{%k0, %k0|%k0, %k0}"
1902  [(set_attr "type" "alu1")
1903   (set_attr "mode" "SI")
1904   (set_attr "length_immediate" "0")])
1905
1906(define_insn "*movdi_or_rex64"
1907  [(set (match_operand:DI 0 "register_operand" "=r")
1908	(match_operand:DI 1 "const_int_operand" "i"))
1909   (clobber (reg:CC 17))]
1910  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1911   && reload_completed
1912   && operands[1] == constm1_rtx"
1913{
1914  operands[1] = constm1_rtx;
1915  return "or{q}\t{%1, %0|%0, %1}";
1916}
1917  [(set_attr "type" "alu1")
1918   (set_attr "mode" "DI")
1919   (set_attr "length_immediate" "1")])
1920
1921(define_insn "*movdi_2"
1922  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1923	(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1924  "!TARGET_64BIT
1925   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1926  "@
1927   #
1928   #
1929   movq\t{%1, %0|%0, %1}
1930   movq\t{%1, %0|%0, %1}
1931   movq\t{%1, %0|%0, %1}
1932   movdqa\t{%1, %0|%0, %1}
1933   movq\t{%1, %0|%0, %1}"
1934  [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1935   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1936
1937(define_split
1938  [(set (match_operand:DI 0 "push_operand" "")
1939        (match_operand:DI 1 "general_operand" ""))]
1940  "!TARGET_64BIT && reload_completed
1941   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1942  [(const_int 0)]
1943  "ix86_split_long_move (operands); DONE;")
1944
1945;; %%% This multiword shite has got to go.
1946(define_split
1947  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1948        (match_operand:DI 1 "general_operand" ""))]
1949  "!TARGET_64BIT && reload_completed
1950   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1951   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1952  [(const_int 0)]
1953  "ix86_split_long_move (operands); DONE;")
1954
1955(define_insn "*movdi_1_rex64"
1956  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1957	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1958  "TARGET_64BIT
1959   && (TARGET_INTER_UNIT_MOVES || optimize_size)
1960   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1961{
1962  switch (get_attr_type (insn))
1963    {
1964    case TYPE_SSEMOV:
1965      if (get_attr_mode (insn) == MODE_TI)
1966	  return "movdqa\t{%1, %0|%0, %1}";
1967      /* FALLTHRU */
1968    case TYPE_MMXMOV:
1969      /* Moves from and into integer register is done using movd opcode with
1970 	 REX prefix.  */
1971      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1972	  return "movd\t{%1, %0|%0, %1}";
1973      return "movq\t{%1, %0|%0, %1}";
1974    case TYPE_MULTI:
1975      return "#";
1976    case TYPE_LEA:
1977      return "lea{q}\t{%a1, %0|%0, %a1}";
1978    default:
1979      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1980	abort ();
1981      if (get_attr_mode (insn) == MODE_SI)
1982	return "mov{l}\t{%k1, %k0|%k0, %k1}";
1983      else if (which_alternative == 2)
1984	return "movabs{q}\t{%1, %0|%0, %1}";
1985      else
1986	return "mov{q}\t{%1, %0|%0, %1}";
1987    }
1988}
1989  [(set (attr "type")
1990     (cond [(eq_attr "alternative" "5,6,7")
1991	      (const_string "mmxmov")
1992	    (eq_attr "alternative" "8,9,10")
1993	      (const_string "ssemov")
1994	    (eq_attr "alternative" "4")
1995	      (const_string "multi")
1996 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
1997		 (match_operand:DI 1 "symbolic_operand" ""))
1998	      (const_string "lea")
1999	   ]
2000	   (const_string "imov")))
2001   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2002   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2003   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2004
2005(define_insn "*movdi_1_rex64_nointerunit"
2006  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2007	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2008  "TARGET_64BIT
2009   && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2010   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2011{
2012  switch (get_attr_type (insn))
2013    {
2014    case TYPE_SSEMOV:
2015      if (get_attr_mode (insn) == MODE_TI)
2016	  return "movdqa\t{%1, %0|%0, %1}";
2017      /* FALLTHRU */
2018    case TYPE_MMXMOV:
2019      return "movq\t{%1, %0|%0, %1}";
2020    case TYPE_MULTI:
2021      return "#";
2022    case TYPE_LEA:
2023      return "lea{q}\t{%a1, %0|%0, %a1}";
2024    default:
2025      if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2026	abort ();
2027      if (get_attr_mode (insn) == MODE_SI)
2028	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2029      else if (which_alternative == 2)
2030	return "movabs{q}\t{%1, %0|%0, %1}";
2031      else
2032	return "mov{q}\t{%1, %0|%0, %1}";
2033    }
2034}
2035  [(set (attr "type")
2036     (cond [(eq_attr "alternative" "5,6,7")
2037	      (const_string "mmxmov")
2038	    (eq_attr "alternative" "8,9,10")
2039	      (const_string "ssemov")
2040	    (eq_attr "alternative" "4")
2041	      (const_string "multi")
2042 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
2043		 (match_operand:DI 1 "symbolic_operand" ""))
2044	      (const_string "lea")
2045	   ]
2046	   (const_string "imov")))
2047   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2048   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2049   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2050
2051;; Stores and loads of ax to arbitrary constant address.
2052;; We fake an second form of instruction to force reload to load address
2053;; into register when rax is not available
2054(define_insn "*movabsdi_1_rex64"
2055  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2056	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2057  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2058  "@
2059   movabs{q}\t{%1, %P0|%P0, %1}
2060   mov{q}\t{%1, %a0|%a0, %1}"
2061  [(set_attr "type" "imov")
2062   (set_attr "modrm" "0,*")
2063   (set_attr "length_address" "8,0")
2064   (set_attr "length_immediate" "0,*")
2065   (set_attr "memory" "store")
2066   (set_attr "mode" "DI")])
2067
2068(define_insn "*movabsdi_2_rex64"
2069  [(set (match_operand:DI 0 "register_operand" "=a,r")
2070        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2071  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2072  "@
2073   movabs{q}\t{%P1, %0|%0, %P1}
2074   mov{q}\t{%a1, %0|%0, %a1}"
2075  [(set_attr "type" "imov")
2076   (set_attr "modrm" "0,*")
2077   (set_attr "length_address" "8,0")
2078   (set_attr "length_immediate" "0")
2079   (set_attr "memory" "load")
2080   (set_attr "mode" "DI")])
2081
2082;; Convert impossible stores of immediate to existing instructions.
2083;; First try to get scratch register and go through it.  In case this
2084;; fails, move by 32bit parts.
2085(define_peephole2
2086  [(match_scratch:DI 2 "r")
2087   (set (match_operand:DI 0 "memory_operand" "")
2088        (match_operand:DI 1 "immediate_operand" ""))]
2089  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090   && !x86_64_immediate_operand (operands[1], DImode)"
2091  [(set (match_dup 2) (match_dup 1))
2092   (set (match_dup 0) (match_dup 2))]
2093  "")
2094
2095;; We need to define this as both peepholer and splitter for case
2096;; peephole2 pass is not run.
2097(define_peephole2
2098  [(set (match_operand:DI 0 "memory_operand" "")
2099        (match_operand:DI 1 "immediate_operand" ""))]
2100  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2101   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2102  [(set (match_dup 2) (match_dup 3))
2103   (set (match_dup 4) (match_dup 5))]
2104  "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106(define_split
2107  [(set (match_operand:DI 0 "memory_operand" "")
2108        (match_operand:DI 1 "immediate_operand" ""))]
2109  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2110		   ? flow2_completed : reload_completed)
2111   && !symbolic_operand (operands[1], DImode)
2112   && !x86_64_immediate_operand (operands[1], DImode)"
2113  [(set (match_dup 2) (match_dup 3))
2114   (set (match_dup 4) (match_dup 5))]
2115  "split_di (operands, 2, operands + 2, operands + 4);")
2116
2117(define_insn "*swapdi_rex64"
2118  [(set (match_operand:DI 0 "register_operand" "+r")
2119	(match_operand:DI 1 "register_operand" "+r"))
2120   (set (match_dup 1)
2121	(match_dup 0))]
2122  "TARGET_64BIT"
2123  "xchg{q}\t%1, %0"
2124  [(set_attr "type" "imov")
2125   (set_attr "mode" "DI")
2126   (set_attr "pent_pair" "np")
2127   (set_attr "athlon_decode" "vector")
2128   (set_attr "ppro_uops" "few")])
2129
2130(define_expand "movsf"
2131  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2132	(match_operand:SF 1 "general_operand" ""))]
2133  ""
2134  "ix86_expand_move (SFmode, operands); DONE;")
2135
2136(define_insn "*pushsf"
2137  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2138	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2139  "!TARGET_64BIT"
2140{
2141  switch (which_alternative)
2142    {
2143    case 1:
2144      return "push{l}\t%1";
2145
2146    default:
2147      /* This insn should be already split before reg-stack.  */
2148      abort ();
2149    }
2150}
2151  [(set_attr "type" "multi,push,multi")
2152   (set_attr "mode" "SF,SI,SF")])
2153
2154(define_insn "*pushsf_rex64"
2155  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2156	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2157  "TARGET_64BIT"
2158{
2159  switch (which_alternative)
2160    {
2161    case 1:
2162      return "push{q}\t%q1";
2163
2164    default:
2165      /* This insn should be already split before reg-stack.  */
2166      abort ();
2167    }
2168}
2169  [(set_attr "type" "multi,push,multi")
2170   (set_attr "mode" "SF,DI,SF")])
2171
2172(define_split
2173  [(set (match_operand:SF 0 "push_operand" "")
2174	(match_operand:SF 1 "memory_operand" ""))]
2175  "reload_completed
2176   && GET_CODE (operands[1]) == MEM
2177   && constant_pool_reference_p (operands[1])"
2178  [(set (match_dup 0)
2179	(match_dup 1))]
2180  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2181
2182
2183;; %%% Kill this when call knows how to work this out.
2184(define_split
2185  [(set (match_operand:SF 0 "push_operand" "")
2186	(match_operand:SF 1 "any_fp_register_operand" ""))]
2187  "!TARGET_64BIT"
2188  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2189   (set (mem:SF (reg:SI 7)) (match_dup 1))])
2190
2191(define_split
2192  [(set (match_operand:SF 0 "push_operand" "")
2193	(match_operand:SF 1 "any_fp_register_operand" ""))]
2194  "TARGET_64BIT"
2195  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2196   (set (mem:SF (reg:DI 7)) (match_dup 1))])
2197
2198(define_insn "*movsf_1"
2199  [(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")
2200	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2201  "(TARGET_INTER_UNIT_MOVES || optimize_size)
2202   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2203   && (reload_in_progress || reload_completed
2204       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2205       || GET_CODE (operands[1]) != CONST_DOUBLE
2206       || memory_operand (operands[0], SFmode))" 
2207{
2208  switch (which_alternative)
2209    {
2210    case 0:
2211      if (REG_P (operands[1])
2212          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2213        return "fstp\t%y0";
2214      else if (STACK_TOP_P (operands[0]))
2215        return "fld%z1\t%y1";
2216      else
2217        return "fst\t%y0";
2218
2219    case 1:
2220      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2221        return "fstp%z0\t%y0";
2222      else
2223        return "fst%z0\t%y0";
2224
2225    case 2:
2226      return standard_80387_constant_opcode (operands[1]);
2227
2228    case 3:
2229    case 4:
2230      return "mov{l}\t{%1, %0|%0, %1}";
2231    case 5:
2232      if (get_attr_mode (insn) == MODE_TI)
2233	return "pxor\t%0, %0";
2234      else
2235	return "xorps\t%0, %0";
2236    case 6:
2237      if (get_attr_mode (insn) == MODE_V4SF)
2238	return "movaps\t{%1, %0|%0, %1}";
2239      else
2240	return "movss\t{%1, %0|%0, %1}";
2241    case 7:
2242    case 8:
2243      return "movss\t{%1, %0|%0, %1}";
2244
2245    case 9:
2246    case 10:
2247      return "movd\t{%1, %0|%0, %1}";
2248
2249    case 11:
2250      return "movq\t{%1, %0|%0, %1}";
2251
2252    default:
2253      abort();
2254    }
2255}
2256  [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2257   (set (attr "mode")
2258        (cond [(eq_attr "alternative" "3,4,9,10")
2259		 (const_string "SI")
2260	       (eq_attr "alternative" "5")
2261		 (if_then_else
2262		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2263			    	 (const_int 0))
2264			     (ne (symbol_ref "TARGET_SSE2")
2265				 (const_int 0)))
2266			(eq (symbol_ref "optimize_size")
2267			    (const_int 0)))
2268		   (const_string "TI")
2269		   (const_string "V4SF"))
2270	       /* For architectures resolving dependencies on
2271		  whole SSE registers use APS move to break dependency
2272		  chains, otherwise use short move to avoid extra work. 
2273
2274		  Do the same for architectures resolving dependencies on
2275		  the parts.  While in DF mode it is better to always handle
2276		  just register parts, the SF mode is different due to lack
2277		  of instructions to load just part of the register.  It is
2278		  better to maintain the whole registers in single format
2279		  to avoid problems on using packed logical operations.  */
2280	       (eq_attr "alternative" "6")
2281		 (if_then_else
2282		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2283			    (const_int 0))
2284			(ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2285			    (const_int 0)))
2286		   (const_string "V4SF")
2287		   (const_string "SF"))
2288	       (eq_attr "alternative" "11")
2289		 (const_string "DI")]
2290	       (const_string "SF")))])
2291
2292(define_insn "*movsf_1_nointerunit"
2293  [(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")
2294	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2295  "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2296   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2297   && (reload_in_progress || reload_completed
2298       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2299       || GET_CODE (operands[1]) != CONST_DOUBLE
2300       || memory_operand (operands[0], SFmode))" 
2301{
2302  switch (which_alternative)
2303    {
2304    case 0:
2305      if (REG_P (operands[1])
2306          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2307	{
2308	  if (REGNO (operands[0]) == FIRST_STACK_REG
2309	      && TARGET_USE_FFREEP)
2310	    return "ffreep\t%y0";
2311          return "fstp\t%y0";
2312	}
2313      else if (STACK_TOP_P (operands[0]))
2314        return "fld%z1\t%y1";
2315      else
2316        return "fst\t%y0";
2317
2318    case 1:
2319      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320        return "fstp%z0\t%y0";
2321      else
2322        return "fst%z0\t%y0";
2323
2324    case 2:
2325      return standard_80387_constant_opcode (operands[1]);
2326
2327    case 3:
2328    case 4:
2329      return "mov{l}\t{%1, %0|%0, %1}";
2330    case 5:
2331      if (get_attr_mode (insn) == MODE_TI)
2332	return "pxor\t%0, %0";
2333      else
2334	return "xorps\t%0, %0";
2335    case 6:
2336      if (get_attr_mode (insn) == MODE_V4SF)
2337	return "movaps\t{%1, %0|%0, %1}";
2338      else
2339	return "movss\t{%1, %0|%0, %1}";
2340    case 7:
2341    case 8:
2342      return "movss\t{%1, %0|%0, %1}";
2343
2344    case 9:
2345    case 10:
2346      return "movd\t{%1, %0|%0, %1}";
2347
2348    case 11:
2349      return "movq\t{%1, %0|%0, %1}";
2350
2351    default:
2352      abort();
2353    }
2354}
2355  [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356   (set (attr "mode")
2357        (cond [(eq_attr "alternative" "3,4,9,10")
2358		 (const_string "SI")
2359	       (eq_attr "alternative" "5")
2360		 (if_then_else
2361		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362			    	 (const_int 0))
2363			     (ne (symbol_ref "TARGET_SSE2")
2364				 (const_int 0)))
2365			(eq (symbol_ref "optimize_size")
2366			    (const_int 0)))
2367		   (const_string "TI")
2368		   (const_string "V4SF"))
2369	       /* For architectures resolving dependencies on
2370		  whole SSE registers use APS move to break dependency
2371		  chains, otherwise use short move to avoid extra work. 
2372
2373		  Do the same for architectures resolving dependencies on
2374		  the parts.  While in DF mode it is better to always handle
2375		  just register parts, the SF mode is different due to lack
2376		  of instructions to load just part of the register.  It is
2377		  better to maintain the whole registers in single format
2378		  to avoid problems on using packed logical operations.  */
2379	       (eq_attr "alternative" "6")
2380		 (if_then_else
2381		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382			    (const_int 0))
2383			(ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2384			    (const_int 0)))
2385		   (const_string "V4SF")
2386		   (const_string "SF"))
2387	       (eq_attr "alternative" "11")
2388		 (const_string "DI")]
2389	       (const_string "SF")))])
2390
2391(define_insn "*swapsf"
2392  [(set (match_operand:SF 0 "register_operand" "+f")
2393	(match_operand:SF 1 "register_operand" "+f"))
2394   (set (match_dup 1)
2395	(match_dup 0))]
2396  "reload_completed || !TARGET_SSE"
2397{
2398  if (STACK_TOP_P (operands[0]))
2399    return "fxch\t%1";
2400  else
2401    return "fxch\t%0";
2402}
2403  [(set_attr "type" "fxch")
2404   (set_attr "mode" "SF")])
2405
2406(define_expand "movdf"
2407  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408	(match_operand:DF 1 "general_operand" ""))]
2409  ""
2410  "ix86_expand_move (DFmode, operands); DONE;")
2411
2412;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413;; Size of pushdf using integer instructions is 2+2*memory operand size
2414;; On the average, pushdf using integers can be still shorter.  Allow this
2415;; pattern for optimize_size too.
2416
2417(define_insn "*pushdf_nointeger"
2418  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2420  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421{
2422  /* This insn should be already split before reg-stack.  */
2423  abort ();
2424}
2425  [(set_attr "type" "multi")
2426   (set_attr "mode" "DF,SI,SI,DF")])
2427
2428(define_insn "*pushdf_integer"
2429  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2430	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2431  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2432{
2433  /* This insn should be already split before reg-stack.  */
2434  abort ();
2435}
2436  [(set_attr "type" "multi")
2437   (set_attr "mode" "DF,SI,DF")])
2438
2439;; %%% Kill this when call knows how to work this out.
2440(define_split
2441  [(set (match_operand:DF 0 "push_operand" "")
2442	(match_operand:DF 1 "any_fp_register_operand" ""))]
2443  "!TARGET_64BIT && reload_completed"
2444  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2445   (set (mem:DF (reg:SI 7)) (match_dup 1))]
2446  "")
2447
2448(define_split
2449  [(set (match_operand:DF 0 "push_operand" "")
2450	(match_operand:DF 1 "any_fp_register_operand" ""))]
2451  "TARGET_64BIT && reload_completed"
2452  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2453   (set (mem:DF (reg:DI 7)) (match_dup 1))]
2454  "")
2455
2456(define_split
2457  [(set (match_operand:DF 0 "push_operand" "")
2458	(match_operand:DF 1 "general_operand" ""))]
2459  "reload_completed"
2460  [(const_int 0)]
2461  "ix86_split_long_move (operands); DONE;")
2462
2463;; Moving is usually shorter when only FP registers are used. This separate
2464;; movdf pattern avoids the use of integer registers for FP operations
2465;; when optimizing for size.
2466
2467(define_insn "*movdf_nointeger"
2468  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2469	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2470  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2471   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2472   && (reload_in_progress || reload_completed
2473       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2474       || GET_CODE (operands[1]) != CONST_DOUBLE
2475       || memory_operand (operands[0], DFmode))" 
2476{
2477  switch (which_alternative)
2478    {
2479    case 0:
2480      if (REG_P (operands[1])
2481          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2482	{
2483	  if (REGNO (operands[0]) == FIRST_STACK_REG
2484	      && TARGET_USE_FFREEP)
2485	    return "ffreep\t%y0";
2486          return "fstp\t%y0";
2487	}
2488      else if (STACK_TOP_P (operands[0]))
2489        return "fld%z1\t%y1";
2490      else
2491        return "fst\t%y0";
2492
2493    case 1:
2494      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2495        return "fstp%z0\t%y0";
2496      else
2497        return "fst%z0\t%y0";
2498
2499    case 2:
2500      return standard_80387_constant_opcode (operands[1]);
2501
2502    case 3:
2503    case 4:
2504      return "#";
2505    case 5:
2506      switch (get_attr_mode (insn))
2507	{
2508	case MODE_V4SF:
2509	  return "xorps\t%0, %0";
2510	case MODE_V2DF:
2511	  return "xorpd\t%0, %0";
2512	case MODE_TI:
2513	  return "pxor\t%0, %0";
2514	default:
2515	  abort ();
2516	}
2517    case 6:
2518      switch (get_attr_mode (insn))
2519	{
2520	case MODE_V4SF:
2521	  return "movaps\t{%1, %0|%0, %1}";
2522	case MODE_V2DF:
2523	  return "movapd\t{%1, %0|%0, %1}";
2524	case MODE_DF:
2525	  return "movsd\t{%1, %0|%0, %1}";
2526	default:
2527	  abort ();
2528	}
2529    case 7:
2530      if (get_attr_mode (insn) == MODE_V2DF)
2531	return "movlpd\t{%1, %0|%0, %1}";
2532      else
2533	return "movsd\t{%1, %0|%0, %1}";
2534    case 8:
2535      return "movsd\t{%1, %0|%0, %1}";
2536
2537    default:
2538      abort();
2539    }
2540}
2541  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2542   (set (attr "mode")
2543        (cond [(eq_attr "alternative" "3,4")
2544		 (const_string "SI")
2545	       /* xorps is one byte shorter.  */
2546	       (eq_attr "alternative" "5")
2547		 (cond [(ne (symbol_ref "optimize_size")
2548			    (const_int 0))
2549			  (const_string "V4SF")
2550			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2551			    (const_int 0))
2552			  (const_string "TI")]
2553		       (const_string "V2DF"))
2554	       /* For architectures resolving dependencies on
2555		  whole SSE registers use APD move to break dependency
2556		  chains, otherwise use short move to avoid extra work.
2557
2558		  movaps encodes one byte shorter.  */
2559	       (eq_attr "alternative" "6")
2560		 (cond
2561		  [(ne (symbol_ref "optimize_size")
2562		       (const_int 0))
2563		     (const_string "V4SF")
2564		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2565		       (const_int 0))
2566		     (const_string "V2DF")]
2567		   (const_string "DF"))
2568	       /* For architectures resolving dependencies on register
2569		  parts we may avoid extra work to zero out upper part
2570		  of register.  */
2571	       (eq_attr "alternative" "7")
2572		 (if_then_else
2573		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2574		       (const_int 0))
2575		   (const_string "V2DF")
2576		   (const_string "DF"))]
2577	       (const_string "DF")))])
2578
2579(define_insn "*movdf_integer"
2580  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2581	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2582  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2583   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2584   && (reload_in_progress || reload_completed
2585       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2586       || GET_CODE (operands[1]) != CONST_DOUBLE
2587       || memory_operand (operands[0], DFmode))" 
2588{
2589  switch (which_alternative)
2590    {
2591    case 0:
2592      if (REG_P (operands[1])
2593          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2594	{
2595	  if (REGNO (operands[0]) == FIRST_STACK_REG
2596	      && TARGET_USE_FFREEP)
2597	    return "ffreep\t%y0";
2598          return "fstp\t%y0";
2599	}
2600      else if (STACK_TOP_P (operands[0]))
2601        return "fld%z1\t%y1";
2602      else
2603        return "fst\t%y0";
2604
2605    case 1:
2606      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2607        return "fstp%z0\t%y0";
2608      else
2609        return "fst%z0\t%y0";
2610
2611    case 2:
2612      return standard_80387_constant_opcode (operands[1]);
2613
2614    case 3:
2615    case 4:
2616      return "#";
2617
2618    case 5:
2619      switch (get_attr_mode (insn))
2620	{
2621	case MODE_V4SF:
2622	  return "xorps\t%0, %0";
2623	case MODE_V2DF:
2624	  return "xorpd\t%0, %0";
2625	case MODE_TI:
2626	  return "pxor\t%0, %0";
2627	default:
2628	  abort ();
2629	}
2630    case 6:
2631      switch (get_attr_mode (insn))
2632	{
2633	case MODE_V4SF:
2634	  return "movaps\t{%1, %0|%0, %1}";
2635	case MODE_V2DF:
2636	  return "movapd\t{%1, %0|%0, %1}";
2637	case MODE_DF:
2638	  return "movsd\t{%1, %0|%0, %1}";
2639	default:
2640	  abort ();
2641	}
2642    case 7:
2643      if (get_attr_mode (insn) == MODE_V2DF)
2644	return "movlpd\t{%1, %0|%0, %1}";
2645      else
2646	return "movsd\t{%1, %0|%0, %1}";
2647    case 8:
2648      return "movsd\t{%1, %0|%0, %1}";
2649
2650    default:
2651      abort();
2652    }
2653}
2654  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2655   (set (attr "mode")
2656        (cond [(eq_attr "alternative" "3,4")
2657		 (const_string "SI")
2658	       /* xorps is one byte shorter.  */
2659	       (eq_attr "alternative" "5")
2660		 (cond [(ne (symbol_ref "optimize_size")
2661			    (const_int 0))
2662			  (const_string "V4SF")
2663			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2664			    (const_int 0))
2665			  (const_string "TI")]
2666		       (const_string "V2DF"))
2667	       /* For architectures resolving dependencies on
2668		  whole SSE registers use APD move to break dependency
2669		  chains, otherwise use short move to avoid extra work.  
2670
2671		  movaps encodes one byte shorter.  */
2672	       (eq_attr "alternative" "6")
2673		 (cond
2674		  [(ne (symbol_ref "optimize_size")
2675		       (const_int 0))
2676		     (const_string "V4SF")
2677		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2678		       (const_int 0))
2679		     (const_string "V2DF")]
2680		   (const_string "DF"))
2681	       /* For architectures resolving dependencies on register
2682		  parts we may avoid extra work to zero out upper part
2683		  of register.  */
2684	       (eq_attr "alternative" "7")
2685		 (if_then_else
2686		   (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2687		       (const_int 0))
2688		   (const_string "V2DF")
2689		   (const_string "DF"))]
2690	       (const_string "DF")))])
2691
2692(define_split
2693  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2694	(match_operand:DF 1 "general_operand" ""))]
2695  "reload_completed
2696   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2697   && ! (ANY_FP_REG_P (operands[0]) || 
2698	 (GET_CODE (operands[0]) == SUBREG
2699	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2700   && ! (ANY_FP_REG_P (operands[1]) || 
2701	 (GET_CODE (operands[1]) == SUBREG
2702	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2703  [(const_int 0)]
2704  "ix86_split_long_move (operands); DONE;")
2705
2706(define_insn "*swapdf"
2707  [(set (match_operand:DF 0 "register_operand" "+f")
2708	(match_operand:DF 1 "register_operand" "+f"))
2709   (set (match_dup 1)
2710	(match_dup 0))]
2711  "reload_completed || !TARGET_SSE2"
2712{
2713  if (STACK_TOP_P (operands[0]))
2714    return "fxch\t%1";
2715  else
2716    return "fxch\t%0";
2717}
2718  [(set_attr "type" "fxch")
2719   (set_attr "mode" "DF")])
2720
2721(define_expand "movxf"
2722  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2723	(match_operand:XF 1 "general_operand" ""))]
2724  ""
2725  "ix86_expand_move (XFmode, operands); DONE;")
2726
2727;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2728;; Size of pushdf using integer instructions is 3+3*memory operand size
2729;; Pushing using integer instructions is longer except for constants
2730;; and direct memory references.
2731;; (assuming that any given constant is pushed only once, but this ought to be
2732;;  handled elsewhere).
2733
2734(define_insn "*pushxf_nointeger"
2735  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2736	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2737  "optimize_size"
2738{
2739  /* This insn should be already split before reg-stack.  */
2740  abort ();
2741}
2742  [(set_attr "type" "multi")
2743   (set_attr "mode" "XF,SI,SI")])
2744
2745(define_insn "*pushxf_integer"
2746  [(set (match_operand:XF 0 "push_operand" "=<,<")
2747	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2748  "!optimize_size"
2749{
2750  /* This insn should be already split before reg-stack.  */
2751  abort ();
2752}
2753  [(set_attr "type" "multi")
2754   (set_attr "mode" "XF,SI")])
2755
2756(define_split
2757  [(set (match_operand 0 "push_operand" "")
2758	(match_operand 1 "general_operand" ""))]
2759  "reload_completed
2760   && (GET_MODE (operands[0]) == XFmode
2761       || GET_MODE (operands[0]) == DFmode)
2762   && !ANY_FP_REG_P (operands[1])"
2763  [(const_int 0)]
2764  "ix86_split_long_move (operands); DONE;")
2765
2766(define_split
2767  [(set (match_operand:XF 0 "push_operand" "")
2768	(match_operand:XF 1 "any_fp_register_operand" ""))]
2769  "!TARGET_64BIT"
2770  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2771   (set (mem:XF (reg:SI 7)) (match_dup 1))]
2772  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774(define_split
2775  [(set (match_operand:XF 0 "push_operand" "")
2776	(match_operand:XF 1 "any_fp_register_operand" ""))]
2777  "TARGET_64BIT"
2778  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2779   (set (mem:XF (reg:DI 7)) (match_dup 1))]
2780  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2781
2782;; Do not use integer registers when optimizing for size
2783(define_insn "*movxf_nointeger"
2784  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2785	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2786  "optimize_size
2787   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2788   && (reload_in_progress || reload_completed
2789       || GET_CODE (operands[1]) != CONST_DOUBLE
2790       || memory_operand (operands[0], XFmode))" 
2791{
2792  switch (which_alternative)
2793    {
2794    case 0:
2795      if (REG_P (operands[1])
2796          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2797	{
2798	  if (REGNO (operands[0]) == FIRST_STACK_REG
2799	      && TARGET_USE_FFREEP)
2800	    return "ffreep\t%y0";
2801          return "fstp\t%y0";
2802	}
2803      else if (STACK_TOP_P (operands[0]))
2804        return "fld%z1\t%y1";
2805      else
2806        return "fst\t%y0";
2807
2808    case 1:
2809      /* There is no non-popping store to memory for XFmode.  So if
2810	 we need one, follow the store with a load.  */
2811      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2812        return "fstp%z0\t%y0\;fld%z0\t%y0";
2813      else
2814        return "fstp%z0\t%y0";
2815
2816    case 2:
2817      return standard_80387_constant_opcode (operands[1]);
2818
2819    case 3: case 4:
2820      return "#";
2821    }
2822  abort();
2823}
2824  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2825   (set_attr "mode" "XF,XF,XF,SI,SI")])
2826
2827(define_insn "*movxf_integer"
2828  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2829	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2830  "!optimize_size
2831   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2832   && (reload_in_progress || reload_completed
2833       || GET_CODE (operands[1]) != CONST_DOUBLE
2834       || memory_operand (operands[0], XFmode))" 
2835{
2836  switch (which_alternative)
2837    {
2838    case 0:
2839      if (REG_P (operands[1])
2840          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2841	{
2842	  if (REGNO (operands[0]) == FIRST_STACK_REG
2843	      && TARGET_USE_FFREEP)
2844	    return "ffreep\t%y0";
2845          return "fstp\t%y0";
2846	}
2847      else if (STACK_TOP_P (operands[0]))
2848        return "fld%z1\t%y1";
2849      else
2850        return "fst\t%y0";
2851
2852    case 1:
2853      /* There is no non-popping store to memory for XFmode.  So if
2854	 we need one, follow the store with a load.  */
2855      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2856        return "fstp%z0\t%y0\;fld%z0\t%y0";
2857      else
2858        return "fstp%z0\t%y0";
2859
2860    case 2:
2861      return standard_80387_constant_opcode (operands[1]);
2862
2863    case 3: case 4:
2864      return "#";
2865    }
2866  abort();
2867}
2868  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2869   (set_attr "mode" "XF,XF,XF,SI,SI")])
2870
2871(define_split
2872  [(set (match_operand 0 "nonimmediate_operand" "")
2873	(match_operand 1 "general_operand" ""))]
2874  "reload_completed
2875   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2876   && GET_MODE (operands[0]) == XFmode
2877   && ! (ANY_FP_REG_P (operands[0]) || 
2878	 (GET_CODE (operands[0]) == SUBREG
2879	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2880   && ! (ANY_FP_REG_P (operands[1]) || 
2881	 (GET_CODE (operands[1]) == SUBREG
2882	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2883  [(const_int 0)]
2884  "ix86_split_long_move (operands); DONE;")
2885
2886(define_split
2887  [(set (match_operand 0 "register_operand" "")
2888	(match_operand 1 "memory_operand" ""))]
2889  "reload_completed
2890   && GET_CODE (operands[1]) == MEM
2891   && (GET_MODE (operands[0]) == XFmode
2892       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2893   && constant_pool_reference_p (operands[1])"
2894  [(set (match_dup 0) (match_dup 1))]
2895{
2896  rtx c = avoid_constant_pool_reference (operands[1]);
2897  rtx r = operands[0];
2898
2899  if (GET_CODE (r) == SUBREG)
2900    r = SUBREG_REG (r);
2901
2902  if (SSE_REG_P (r))
2903    {
2904      if (!standard_sse_constant_p (c))
2905	FAIL;
2906    }
2907  else if (FP_REG_P (r))
2908    {
2909      if (!standard_80387_constant_p (c))
2910	FAIL;
2911    }
2912  else if (MMX_REG_P (r))
2913    FAIL;
2914
2915  operands[1] = c;
2916})
2917
2918(define_insn "swapxf"
2919  [(set (match_operand:XF 0 "register_operand" "+f")
2920	(match_operand:XF 1 "register_operand" "+f"))
2921   (set (match_dup 1)
2922	(match_dup 0))]
2923  ""
2924{
2925  if (STACK_TOP_P (operands[0]))
2926    return "fxch\t%1";
2927  else
2928    return "fxch\t%0";
2929}
2930  [(set_attr "type" "fxch")
2931   (set_attr "mode" "XF")])
2932
2933;; Zero extension instructions
2934
2935(define_expand "zero_extendhisi2"
2936  [(set (match_operand:SI 0 "register_operand" "")
2937     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2938  ""
2939{
2940  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2941    {
2942      operands[1] = force_reg (HImode, operands[1]);
2943      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2944      DONE;
2945    }
2946})
2947
2948(define_insn "zero_extendhisi2_and"
2949  [(set (match_operand:SI 0 "register_operand" "=r")
2950     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2951   (clobber (reg:CC 17))]
2952  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2953  "#"
2954  [(set_attr "type" "alu1")
2955   (set_attr "mode" "SI")])
2956
2957(define_split
2958  [(set (match_operand:SI 0 "register_operand" "")
2959	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2960   (clobber (reg:CC 17))]
2961  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2962  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2963	      (clobber (reg:CC 17))])]
2964  "")
2965
2966(define_insn "*zero_extendhisi2_movzwl"
2967  [(set (match_operand:SI 0 "register_operand" "=r")
2968     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2969  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2970  "movz{wl|x}\t{%1, %0|%0, %1}"
2971  [(set_attr "type" "imovx")
2972   (set_attr "mode" "SI")])
2973
2974(define_expand "zero_extendqihi2"
2975  [(parallel
2976    [(set (match_operand:HI 0 "register_operand" "")
2977       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2978     (clobber (reg:CC 17))])]
2979  ""
2980  "")
2981
2982(define_insn "*zero_extendqihi2_and"
2983  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2984     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2985   (clobber (reg:CC 17))]
2986  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2987  "#"
2988  [(set_attr "type" "alu1")
2989   (set_attr "mode" "HI")])
2990
2991(define_insn "*zero_extendqihi2_movzbw_and"
2992  [(set (match_operand:HI 0 "register_operand" "=r,r")
2993     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2994   (clobber (reg:CC 17))]
2995  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2996  "#"
2997  [(set_attr "type" "imovx,alu1")
2998   (set_attr "mode" "HI")])
2999
3000(define_insn "*zero_extendqihi2_movzbw"
3001  [(set (match_operand:HI 0 "register_operand" "=r")
3002     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3003  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3004  "movz{bw|x}\t{%1, %0|%0, %1}"
3005  [(set_attr "type" "imovx")
3006   (set_attr "mode" "HI")])
3007
3008;; For the movzbw case strip only the clobber
3009(define_split
3010  [(set (match_operand:HI 0 "register_operand" "")
3011	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012   (clobber (reg:CC 17))]
3013  "reload_completed 
3014   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3015   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3016  [(set (match_operand:HI 0 "register_operand" "")
3017	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3018
3019;; When source and destination does not overlap, clear destination
3020;; first and then do the movb
3021(define_split
3022  [(set (match_operand:HI 0 "register_operand" "")
3023	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3024   (clobber (reg:CC 17))]
3025  "reload_completed
3026   && ANY_QI_REG_P (operands[0])
3027   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3028   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3029  [(set (match_dup 0) (const_int 0))
3030   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3031  "operands[2] = gen_lowpart (QImode, operands[0]);")
3032
3033;; Rest is handled by single and.
3034(define_split
3035  [(set (match_operand:HI 0 "register_operand" "")
3036	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3037   (clobber (reg:CC 17))]
3038  "reload_completed
3039   && true_regnum (operands[0]) == true_regnum (operands[1])"
3040  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3041	      (clobber (reg:CC 17))])]
3042  "")
3043
3044(define_expand "zero_extendqisi2"
3045  [(parallel
3046    [(set (match_operand:SI 0 "register_operand" "")
3047       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3048     (clobber (reg:CC 17))])]
3049  ""
3050  "")
3051
3052(define_insn "*zero_extendqisi2_and"
3053  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3054     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3055   (clobber (reg:CC 17))]
3056  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3057  "#"
3058  [(set_attr "type" "alu1")
3059   (set_attr "mode" "SI")])
3060
3061(define_insn "*zero_extendqisi2_movzbw_and"
3062  [(set (match_operand:SI 0 "register_operand" "=r,r")
3063     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3064   (clobber (reg:CC 17))]
3065  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3066  "#"
3067  [(set_attr "type" "imovx,alu1")
3068   (set_attr "mode" "SI")])
3069
3070(define_insn "*zero_extendqisi2_movzbw"
3071  [(set (match_operand:SI 0 "register_operand" "=r")
3072     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3073  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3074  "movz{bl|x}\t{%1, %0|%0, %1}"
3075  [(set_attr "type" "imovx")
3076   (set_attr "mode" "SI")])
3077
3078;; For the movzbl case strip only the clobber
3079(define_split
3080  [(set (match_operand:SI 0 "register_operand" "")
3081	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3082   (clobber (reg:CC 17))]
3083  "reload_completed 
3084   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3085   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3086  [(set (match_dup 0)
3087	(zero_extend:SI (match_dup 1)))])
3088
3089;; When source and destination does not overlap, clear destination
3090;; first and then do the movb
3091(define_split
3092  [(set (match_operand:SI 0 "register_operand" "")
3093	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3094   (clobber (reg:CC 17))]
3095  "reload_completed
3096   && ANY_QI_REG_P (operands[0])
3097   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3098   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3099   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3100  [(set (match_dup 0) (const_int 0))
3101   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3102  "operands[2] = gen_lowpart (QImode, operands[0]);")
3103
3104;; Rest is handled by single and.
3105(define_split
3106  [(set (match_operand:SI 0 "register_operand" "")
3107	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3108   (clobber (reg:CC 17))]
3109  "reload_completed
3110   && true_regnum (operands[0]) == true_regnum (operands[1])"
3111  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3112	      (clobber (reg:CC 17))])]
3113  "")
3114
3115;; %%% Kill me once multi-word ops are sane.
3116(define_expand "zero_extendsidi2"
3117  [(set (match_operand:DI 0 "register_operand" "=r")
3118     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3119  ""
3120  "if (!TARGET_64BIT)
3121     {
3122       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3123       DONE;
3124     }
3125  ")
3126
3127(define_insn "zero_extendsidi2_32"
3128  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3129	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3130   (clobber (reg:CC 17))]
3131  "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3132  "@
3133   #
3134   #
3135   #
3136   movd\t{%1, %0|%0, %1}
3137   movd\t{%1, %0|%0, %1}"
3138  [(set_attr "mode" "SI,SI,SI,DI,TI")
3139   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3140
3141(define_insn "*zero_extendsidi2_32_1"
3142  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3143	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3144   (clobber (reg:CC 17))]
3145  "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3146  "@
3147   #
3148   #
3149   #
3150   movd\t{%1, %0|%0, %1}
3151   movd\t{%1, %0|%0, %1}"
3152  [(set_attr "mode" "SI,SI,SI,DI,TI")
3153   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3154
3155(define_insn "zero_extendsidi2_rex64"
3156  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3157     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3158  "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3159  "@
3160   mov\t{%k1, %k0|%k0, %k1}
3161   #
3162   movd\t{%1, %0|%0, %1}
3163   movd\t{%1, %0|%0, %1}"
3164  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3165   (set_attr "mode" "SI,DI,DI,TI")])
3166
3167(define_insn "*zero_extendsidi2_rex64_1"
3168  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3169     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3170  "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3171  "@
3172   mov\t{%k1, %k0|%k0, %k1}
3173   #
3174   movd\t{%1, %0|%0, %1}
3175   movd\t{%1, %0|%0, %1}"
3176  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3177   (set_attr "mode" "SI,DI,SI,SI")])
3178
3179(define_split
3180  [(set (match_operand:DI 0 "memory_operand" "")
3181     (zero_extend:DI (match_dup 0)))]
3182  "TARGET_64BIT"
3183  [(set (match_dup 4) (const_int 0))]
3184  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3185
3186(define_split 
3187  [(set (match_operand:DI 0 "register_operand" "")
3188	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3189   (clobber (reg:CC 17))]
3190  "!TARGET_64BIT && reload_completed
3191   && true_regnum (operands[0]) == true_regnum (operands[1])"
3192  [(set (match_dup 4) (const_int 0))]
3193  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195(define_split 
3196  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3197	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3198   (clobber (reg:CC 17))]
3199  "!TARGET_64BIT && reload_completed
3200   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3201  [(set (match_dup 3) (match_dup 1))
3202   (set (match_dup 4) (const_int 0))]
3203  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204
3205(define_insn "zero_extendhidi2"
3206  [(set (match_operand:DI 0 "register_operand" "=r,r")
3207     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3208  "TARGET_64BIT"
3209  "@
3210   movz{wl|x}\t{%1, %k0|%k0, %1} 
3211   movz{wq|x}\t{%1, %0|%0, %1}"
3212  [(set_attr "type" "imovx")
3213   (set_attr "mode" "SI,DI")])
3214
3215(define_insn "zero_extendqidi2"
3216  [(set (match_operand:DI 0 "register_operand" "=r,r")
3217     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3218  "TARGET_64BIT"
3219  "@
3220   movz{bl|x}\t{%1, %k0|%k0, %1} 
3221   movz{bq|x}\t{%1, %0|%0, %1}"
3222  [(set_attr "type" "imovx")
3223   (set_attr "mode" "SI,DI")])
3224
3225;; Sign extension instructions
3226
3227(define_expand "extendsidi2"
3228  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3229		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3230	      (clobber (reg:CC 17))
3231	      (clobber (match_scratch:SI 2 ""))])]
3232  ""
3233{
3234  if (TARGET_64BIT)
3235    {
3236      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3237      DONE;
3238    }
3239})
3240
3241(define_insn "*extendsidi2_1"
3242  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3243	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3244   (clobber (reg:CC 17))
3245   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3246  "!TARGET_64BIT"
3247  "#")
3248
3249(define_insn "extendsidi2_rex64"
3250  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3251	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3252  "TARGET_64BIT"
3253  "@
3254   {cltq|cdqe}
3255   movs{lq|x}\t{%1,%0|%0, %1}"
3256  [(set_attr "type" "imovx")
3257   (set_attr "mode" "DI")
3258   (set_attr "prefix_0f" "0")
3259   (set_attr "modrm" "0,1")])
3260
3261(define_insn "extendhidi2"
3262  [(set (match_operand:DI 0 "register_operand" "=r")
3263	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3264  "TARGET_64BIT"
3265  "movs{wq|x}\t{%1,%0|%0, %1}"
3266  [(set_attr "type" "imovx")
3267   (set_attr "mode" "DI")])
3268
3269(define_insn "extendqidi2"
3270  [(set (match_operand:DI 0 "register_operand" "=r")
3271	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3272  "TARGET_64BIT"
3273  "movs{bq|x}\t{%1,%0|%0, %1}"
3274   [(set_attr "type" "imovx")
3275    (set_attr "mode" "DI")])
3276
3277;; Extend to memory case when source register does die.
3278(define_split 
3279  [(set (match_operand:DI 0 "memory_operand" "")
3280	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3281   (clobber (reg:CC 17))
3282   (clobber (match_operand:SI 2 "register_operand" ""))]
3283  "(reload_completed
3284    && dead_or_set_p (insn, operands[1])
3285    && !reg_mentioned_p (operands[1], operands[0]))"
3286  [(set (match_dup 3) (match_dup 1))
3287   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3288	      (clobber (reg:CC 17))])
3289   (set (match_dup 4) (match_dup 1))]
3290  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291
3292;; Extend to memory case when source register does not die.
3293(define_split 
3294  [(set (match_operand:DI 0 "memory_operand" "")
3295	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3296   (clobber (reg:CC 17))
3297   (clobber (match_operand:SI 2 "register_operand" ""))]
3298  "reload_completed"
3299  [(const_int 0)]
3300{
3301  split_di (&operands[0], 1, &operands[3], &operands[4]);
3302
3303  emit_move_insn (operands[3], operands[1]);
3304
3305  /* Generate a cltd if possible and doing so it profitable.  */
3306  if (true_regnum (operands[1]) == 0
3307      && true_regnum (operands[2]) == 1
3308      && (optimize_size || TARGET_USE_CLTD))
3309    {
3310      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3311    }
3312  else
3313    {
3314      emit_move_insn (operands[2], operands[1]);
3315      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3316    }
3317  emit_move_insn (operands[4], operands[2]);
3318  DONE;
3319})
3320
3321;; Extend to register case.  Optimize case where source and destination
3322;; registers match and cases where we can use cltd.
3323(define_split 
3324  [(set (match_operand:DI 0 "register_operand" "")
3325	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3326   (clobber (reg:CC 17))
3327   (clobber (match_scratch:SI 2 ""))]
3328  "reload_completed"
3329  [(const_int 0)]
3330{
3331  split_di (&operands[0], 1, &operands[3], &operands[4]);
3332
3333  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3334    emit_move_insn (operands[3], operands[1]);
3335
3336  /* Generate a cltd if possible and doing so it profitable.  */
3337  if (true_regnum (operands[3]) == 0
3338      && (optimize_size || TARGET_USE_CLTD))
3339    {
3340      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3341      DONE;
3342    }
3343
3344  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3345    emit_move_insn (operands[4], operands[1]);
3346
3347  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3348  DONE;
3349})
3350
3351(define_insn "extendhisi2"
3352  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3353	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3354  ""
3355{
3356  switch (get_attr_prefix_0f (insn))
3357    {
3358    case 0:
3359      return "{cwtl|cwde}";
3360    default:
3361      return "movs{wl|x}\t{%1,%0|%0, %1}";
3362    }
3363}
3364  [(set_attr "type" "imovx")
3365   (set_attr "mode" "SI")
3366   (set (attr "prefix_0f")
3367     ;; movsx is short decodable while cwtl is vector decoded.
3368     (if_then_else (and (eq_attr "cpu" "!k6")
3369			(eq_attr "alternative" "0"))
3370	(const_string "0")
3371	(const_string "1")))
3372   (set (attr "modrm")
3373     (if_then_else (eq_attr "prefix_0f" "0")
3374	(const_string "0")
3375	(const_string "1")))])
3376
3377(define_insn "*extendhisi2_zext"
3378  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3379	(zero_extend:DI
3380	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3381  "TARGET_64BIT"
3382{
3383  switch (get_attr_prefix_0f (insn))
3384    {
3385    case 0:
3386      return "{cwtl|cwde}";
3387    default:
3388      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3389    }
3390}
3391  [(set_attr "type" "imovx")
3392   (set_attr "mode" "SI")
3393   (set (attr "prefix_0f")
3394     ;; movsx is short decodable while cwtl is vector decoded.
3395     (if_then_else (and (eq_attr "cpu" "!k6")
3396			(eq_attr "alternative" "0"))
3397	(const_string "0")
3398	(const_string "1")))
3399   (set (attr "modrm")
3400     (if_then_else (eq_attr "prefix_0f" "0")
3401	(const_string "0")
3402	(const_string "1")))])
3403
3404(define_insn "extendqihi2"
3405  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3406	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3407  ""
3408{
3409  switch (get_attr_prefix_0f (insn))
3410    {
3411    case 0:
3412      return "{cbtw|cbw}";
3413    default:
3414      return "movs{bw|x}\t{%1,%0|%0, %1}";
3415    }
3416}
3417  [(set_attr "type" "imovx")
3418   (set_attr "mode" "HI")
3419   (set (attr "prefix_0f")
3420     ;; movsx is short decodable while cwtl is vector decoded.
3421     (if_then_else (and (eq_attr "cpu" "!k6")
3422			(eq_attr "alternative" "0"))
3423	(const_string "0")
3424	(const_string "1")))
3425   (set (attr "modrm")
3426     (if_then_else (eq_attr "prefix_0f" "0")
3427	(const_string "0")
3428	(const_string "1")))])
3429
3430(define_insn "extendqisi2"
3431  [(set (match_operand:SI 0 "register_operand" "=r")
3432	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3433  ""
3434  "movs{bl|x}\t{%1,%0|%0, %1}"
3435   [(set_attr "type" "imovx")
3436    (set_attr "mode" "SI")])
3437
3438(define_insn "*extendqisi2_zext"
3439  [(set (match_operand:DI 0 "register_operand" "=r")
3440	(zero_extend:DI
3441	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3442  "TARGET_64BIT"
3443  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3444   [(set_attr "type" "imovx")
3445    (set_attr "mode" "SI")])
3446
3447;; Conversions between float and double.
3448
3449;; These are all no-ops in the model used for the 80387.  So just
3450;; emit moves.
3451
3452;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3453(define_insn "*dummy_extendsfdf2"
3454  [(set (match_operand:DF 0 "push_operand" "=<")
3455	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3456  "0"
3457  "#")
3458
3459(define_split
3460  [(set (match_operand:DF 0 "push_operand" "")
3461	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3462  "!TARGET_64BIT"
3463  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3464   (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3465
3466(define_split
3467  [(set (match_operand:DF 0 "push_operand" "")
3468	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469  "TARGET_64BIT"
3470  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3471   (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3472
3473(define_insn "*dummy_extendsfxf2"
3474  [(set (match_operand:XF 0 "push_operand" "=<")
3475	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3476  "0"
3477  "#")
3478
3479(define_split
3480  [(set (match_operand:XF 0 "push_operand" "")
3481	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482  ""
3483  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3484   (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3485  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3486
3487(define_split
3488  [(set (match_operand:XF 0 "push_operand" "")
3489	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3490  "TARGET_64BIT"
3491  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3492   (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3493  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494
3495(define_split
3496  [(set (match_operand:XF 0 "push_operand" "")
3497	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498  ""
3499  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3500   (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3501  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502
3503(define_split
3504  [(set (match_operand:XF 0 "push_operand" "")
3505	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3506  "TARGET_64BIT"
3507  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3508   (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3509  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510
3511(define_expand "extendsfdf2"
3512  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3513        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3514  "TARGET_80387 || TARGET_SSE2"
3515{
3516  /* ??? Needed for compress_float_constant since all fp constants
3517     are LEGITIMATE_CONSTANT_P.  */
3518  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3519    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3520  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3521    operands[1] = force_reg (SFmode, operands[1]);
3522})
3523
3524(define_insn "*extendsfdf2_1"
3525  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3526        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3527  "(TARGET_80387 || TARGET_SSE2)
3528   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3529{
3530  switch (which_alternative)
3531    {
3532    case 0:
3533      if (REG_P (operands[1])
3534          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3535        return "fstp\t%y0";
3536      else if (STACK_TOP_P (operands[0]))
3537        return "fld%z1\t%y1";
3538      else
3539        return "fst\t%y0";
3540
3541    case 1:
3542      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3543        return "fstp%z0\t%y0";
3544
3545      else
3546        return "fst%z0\t%y0";
3547    case 2:
3548      return "cvtss2sd\t{%1, %0|%0, %1}";
3549
3550    default:
3551      abort ();
3552    }
3553}
3554  [(set_attr "type" "fmov,fmov,ssecvt")
3555   (set_attr "mode" "SF,XF,DF")])
3556
3557(define_insn "*extendsfdf2_1_sse_only"
3558  [(set (match_operand:DF 0 "register_operand" "=Y")
3559        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3560  "!TARGET_80387 && TARGET_SSE2
3561   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3562  "cvtss2sd\t{%1, %0|%0, %1}"
3563  [(set_attr "type" "ssecvt")
3564   (set_attr "mode" "DF")])
3565
3566(define_expand "extendsfxf2"
3567  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3568        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3569  "TARGET_80387"
3570{
3571  /* ??? Needed for compress_float_constant since all fp constants
3572     are LEGITIMATE_CONSTANT_P.  */
3573  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3574    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3575  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3576    operands[1] = force_reg (SFmode, operands[1]);
3577})
3578
3579(define_insn "*extendsfxf2_1"
3580  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3581        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3582  "TARGET_80387
3583   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3584{
3585  switch (which_alternative)
3586    {
3587    case 0:
3588      if (REG_P (operands[1])
3589          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590        return "fstp\t%y0";
3591      else if (STACK_TOP_P (operands[0]))
3592        return "fld%z1\t%y1";
3593      else
3594        return "fst\t%y0";
3595
3596    case 1:
3597      /* There is no non-popping store to memory for XFmode.  So if
3598	 we need one, follow the store with a load.  */
3599      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3600        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3601      else
3602        return "fstp%z0\t%y0";
3603
3604    default:
3605      abort ();
3606    }
3607}
3608  [(set_attr "type" "fmov")
3609   (set_attr "mode" "SF,XF")])
3610
3611(define_expand "extenddfxf2"
3612  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3613        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3614  "TARGET_80387"
3615{
3616  /* ??? Needed for compress_float_constant since all fp constants
3617     are LEGITIMATE_CONSTANT_P.  */
3618  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3619    operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3620  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3621    operands[1] = force_reg (DFmode, operands[1]);
3622})
3623
3624(define_insn "*extenddfxf2_1"
3625  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3626        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3627  "TARGET_80387
3628   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3629{
3630  switch (which_alternative)
3631    {
3632    case 0:
3633      if (REG_P (operands[1])
3634          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635        return "fstp\t%y0";
3636      else if (STACK_TOP_P (operands[0]))
3637        return "fld%z1\t%y1";
3638      else
3639        return "fst\t%y0";
3640
3641    case 1:
3642      /* There is no non-popping store to memory for XFmode.  So if
3643	 we need one, follow the store with a load.  */
3644      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3645        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3646      else
3647        return "fstp%z0\t%y0";
3648
3649    default:
3650      abort ();
3651    }
3652}
3653  [(set_attr "type" "fmov")
3654   (set_attr "mode" "DF,XF")])
3655
3656;; %%% This seems bad bad news.
3657;; This cannot output into an f-reg because there is no way to be sure
3658;; of truncating in that case.  Otherwise this is just like a simple move
3659;; insn.  So we pretend we can output to a reg in order to get better
3660;; register preferencing, but we really use a stack slot.
3661
3662(define_expand "truncdfsf2"
3663  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3664		   (float_truncate:SF
3665		    (match_operand:DF 1 "register_operand" "")))
3666	      (clobber (match_dup 2))])]
3667  "TARGET_80387 || TARGET_SSE2"
3668  "
3669   if (TARGET_80387)
3670     operands[2] = assign_386_stack_local (SFmode, 0);
3671   else
3672     {
3673	emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3674	DONE;
3675     }
3676")
3677
3678(define_insn "*truncdfsf2_1"
3679  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3680	(float_truncate:SF
3681	 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3682   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3683  "TARGET_80387 && !TARGET_SSE2"
3684{
3685  switch (which_alternative)
3686    {
3687    case 0:
3688      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689	return "fstp%z0\t%y0";
3690      else
3691	return "fst%z0\t%y0";
3692    default:
3693      abort ();
3694    }
3695}
3696  [(set_attr "type" "fmov,multi,multi,multi")
3697   (set_attr "mode" "SF,SF,SF,SF")])
3698
3699(define_insn "*truncdfsf2_1_sse"
3700  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3701	(float_truncate:SF
3702	 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3703   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3704  "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3705{
3706  switch (which_alternative)
3707    {
3708    case 0:
3709      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3710	return "fstp%z0\t%y0";
3711      else
3712	return "fst%z0\t%y0";
3713    case 4:
3714      return "#";
3715    default:
3716      abort ();
3717    }
3718}
3719  [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3720   (set_attr "mode" "SF,SF,SF,SF,DF")])
3721
3722(define_insn "*truncdfsf2_1_sse_nooverlap"
3723  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3724	(float_truncate:SF
3725	 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3726   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3727  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3728{
3729  switch (which_alternative)
3730    {
3731    case 0:
3732      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3733	return "fstp%z0\t%y0";
3734      else
3735	return "fst%z0\t%y0";
3736    case 4:
3737      return "#";
3738    default:
3739      abort ();
3740    }
3741}
3742  [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3743   (set_attr "mode" "SF,SF,SF,SF,DF")])
3744
3745(define_insn "*truncdfsf2_2"
3746  [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3747	(float_truncate:SF
3748	 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3749  "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3750   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3751{
3752  switch (which_alternative)
3753    {
3754    case 0:
3755    case 1:
3756      return "cvtsd2ss\t{%1, %0|%0, %1}";
3757    case 2:
3758      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759	return "fstp%z0\t%y0";
3760      else
3761	return "fst%z0\t%y0";
3762    default:
3763      abort ();
3764    }
3765}
3766  [(set_attr "type" "ssecvt,ssecvt,fmov")
3767   (set_attr "athlon_decode" "vector,double,*")
3768   (set_attr "mode" "SF,SF,SF")])
3769
3770(define_insn "*truncdfsf2_2_nooverlap"
3771  [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3772	(float_truncate:SF
3773	 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3774  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3775   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3776{
3777  switch (which_alternative)
3778    {
3779    case 0:
3780      return "#";
3781    case 1:
3782      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783	return "fstp%z0\t%y0";
3784      else
3785	return "fst%z0\t%y0";
3786    default:
3787      abort ();
3788    }
3789}
3790  [(set_attr "type" "ssecvt,fmov")
3791   (set_attr "mode" "DF,SF")])
3792
3793(define_insn "*truncdfsf2_3"
3794  [(set (match_operand:SF 0 "memory_operand" "=m")
3795	(float_truncate:SF
3796	 (match_operand:DF 1 "register_operand" "f")))]
3797  "TARGET_80387"
3798{
3799  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3800    return "fstp%z0\t%y0";
3801  else
3802    return "fst%z0\t%y0";
3803}
3804  [(set_attr "type" "fmov")
3805   (set_attr "mode" "SF")])
3806
3807(define_insn "truncdfsf2_sse_only"
3808  [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3809	(float_truncate:SF
3810	 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3811  "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3812  "cvtsd2ss\t{%1, %0|%0, %1}"
3813  [(set_attr "type" "ssecvt")
3814   (set_attr "athlon_decode" "vector,double")
3815   (set_attr "mode" "SF")])
3816
3817(define_insn "*truncdfsf2_sse_only_nooverlap"
3818  [(set (match_operand:SF 0 "register_operand" "=&Y")
3819	(float_truncate:SF
3820	 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3821  "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3822  "#"
3823  [(set_attr "type" "ssecvt")
3824   (set_attr "mode" "DF")])
3825
3826(define_split
3827  [(set (match_operand:SF 0 "memory_operand" "")
3828	(float_truncate:SF
3829	 (match_operand:DF 1 "register_operand" "")))
3830   (clobber (match_operand:SF 2 "memory_operand" ""))]
3831  "TARGET_80387"
3832  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3833  "")
3834
3835; Avoid possible reformatting penalty on the destination by first
3836; zeroing it out
3837(define_split
3838  [(set (match_operand:SF 0 "register_operand" "")
3839	(float_truncate:SF
3840	 (match_operand:DF 1 "nonimmediate_operand" "")))
3841   (clobber (match_operand 2 "" ""))]
3842  "TARGET_80387 && reload_completed
3843   && SSE_REG_P (operands[0])
3844   && !STACK_REG_P (operands[1])"
3845  [(const_int 0)]
3846{
3847  rtx src, dest;
3848  if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3849    emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3850  else
3851    {
3852      dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3853      src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3854      /* simplify_gen_subreg refuses to widen memory references.  */
3855      if (GET_CODE (src) == SUBREG)
3856	alter_subreg (&src);
3857      if (reg_overlap_mentioned_p (operands[0], operands[1]))
3858	abort ();
3859      emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3860      emit_insn (gen_cvtsd2ss (dest, dest, src));
3861    }
3862  DONE;
3863})
3864
3865(define_split
3866  [(set (match_operand:SF 0 "register_operand" "")
3867	(float_truncate:SF
3868	 (match_operand:DF 1 "nonimmediate_operand" "")))]
3869  "TARGET_80387 && reload_completed
3870   && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3871  [(const_int 0)]
3872{
3873  rtx src, dest;
3874  dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3875  src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3876  /* simplify_gen_subreg refuses to widen memory references.  */
3877  if (GET_CODE (src) == SUBREG)
3878    alter_subreg (&src);
3879  if (reg_overlap_mentioned_p (operands[0], operands[1]))
3880    abort ();
3881  emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3882  emit_insn (gen_cvtsd2ss (dest, dest, src));
3883  DONE;
3884})
3885
3886(define_split
3887  [(set (match_operand:SF 0 "register_operand" "")
3888	(float_truncate:SF
3889	 (match_operand:DF 1 "fp_register_operand" "")))
3890   (clobber (match_operand:SF 2 "memory_operand" ""))]
3891  "TARGET_80387 && reload_completed"
3892  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3893   (set (match_dup 0) (match_dup 2))]
3894  "")
3895
3896(define_expand "truncxfsf2"
3897  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3898		   (float_truncate:SF
3899		    (match_operand:XF 1 "register_operand" "")))
3900	      (clobber (match_dup 2))])]
3901  "TARGET_80387"
3902  "operands[2] = assign_386_stack_local (SFmode, 0);")
3903
3904(define_insn "*truncxfsf2_1"
3905  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3906	(float_truncate:SF
3907	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3908   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3909  "TARGET_80387"
3910{
3911  switch (which_alternative)
3912    {
3913    case 0:
3914      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3915	return "fstp%z0\t%y0";
3916      else
3917	return "fst%z0\t%y0";
3918    default:
3919      abort();
3920    }
3921}
3922  [(set_attr "type" "fmov,multi,multi,multi")
3923   (set_attr "mode" "SF")])
3924
3925(define_insn "*truncxfsf2_2"
3926  [(set (match_operand:SF 0 "memory_operand" "=m")
3927	(float_truncate:SF
3928	 (match_operand:XF 1 "register_operand" "f")))]
3929  "TARGET_80387"
3930{
3931  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3932    return "fstp%z0\t%y0";
3933  else
3934    return "fst%z0\t%y0";
3935}
3936  [(set_attr "type" "fmov")
3937   (set_attr "mode" "SF")])
3938
3939(define_split
3940  [(set (match_operand:SF 0 "memory_operand" "")
3941	(float_truncate:SF
3942	 (match_operand:XF 1 "register_operand" "")))
3943   (clobber (match_operand:SF 2 "memory_operand" ""))]
3944  "TARGET_80387"
3945  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3946  "")
3947
3948(define_split
3949  [(set (match_operand:SF 0 "register_operand" "")
3950	(float_truncate:SF
3951	 (match_operand:XF 1 "register_operand" "")))
3952   (clobber (match_operand:SF 2 "memory_operand" ""))]
3953  "TARGET_80387 && reload_completed"
3954  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955   (set (match_dup 0) (match_dup 2))]
3956  "")
3957
3958(define_expand "truncxfdf2"
3959  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3960		   (float_truncate:DF
3961		    (match_operand:XF 1 "register_operand" "")))
3962	      (clobber (match_dup 2))])]
3963  "TARGET_80387"
3964  "operands[2] = assign_386_stack_local (DFmode, 0);")
3965
3966(define_insn "*truncxfdf2_1"
3967  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3968	(float_truncate:DF
3969	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971  "TARGET_80387"
3972{
3973  switch (which_alternative)
3974    {
3975    case 0:
3976      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977	return "fstp%z0\t%y0";
3978      else
3979	return "fst%z0\t%y0";
3980    default:
3981      abort();
3982    }
3983  abort ();
3984}
3985  [(set_attr "type" "fmov,multi,multi,multi")
3986   (set_attr "mode" "DF")])
3987
3988(define_insn "*truncxfdf2_2"
3989  [(set (match_operand:DF 0 "memory_operand" "=m")
3990	(float_truncate:DF
3991	  (match_operand:XF 1 "register_operand" "f")))]
3992  "TARGET_80387"
3993{
3994  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995    return "fstp%z0\t%y0";
3996  else
3997    return "fst%z0\t%y0";
3998}
3999  [(set_attr "type" "fmov")
4000   (set_attr "mode" "DF")])
4001
4002(define_split
4003  [(set (match_operand:DF 0 "memory_operand" "")
4004	(float_truncate:DF
4005	 (match_operand:XF 1 "register_operand" "")))
4006   (clobber (match_operand:DF 2 "memory_operand" ""))]
4007  "TARGET_80387"
4008  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4009  "")
4010
4011(define_split
4012  [(set (match_operand:DF 0 "register_operand" "")
4013	(float_truncate:DF
4014	 (match_operand:XF 1 "register_operand" "")))
4015   (clobber (match_operand:DF 2 "memory_operand" ""))]
4016  "TARGET_80387 && reload_completed"
4017  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4018   (set (match_dup 0) (match_dup 2))]
4019  "")
4020
4021
4022;; %%% Break up all these bad boys.
4023
4024;; Signed conversion to DImode.
4025
4026(define_expand "fix_truncxfdi2"
4027  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028        (fix:DI (match_operand:XF 1 "register_operand" "")))]
4029  "TARGET_80387"
4030  "")
4031
4032(define_expand "fix_truncdfdi2"
4033  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4034        (fix:DI (match_operand:DF 1 "register_operand" "")))]
4035  "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4036{
4037  if (TARGET_64BIT && TARGET_SSE2)
4038   {
4039     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4040     emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4041     if (out != operands[0])
4042	emit_move_insn (operands[0], out);
4043     DONE;
4044   }
4045})
4046
4047(define_expand "fix_truncsfdi2"
4048  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4049	(fix:DI (match_operand:SF 1 "register_operand" "")))]
4050  "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4051{
4052  if (TARGET_SSE && TARGET_64BIT)
4053   {
4054     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4055     emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4056     if (out != operands[0])
4057	emit_move_insn (operands[0], out);
4058     DONE;
4059   }
4060})
4061
4062;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4063;; of the machinery.
4064(define_insn_and_split "*fix_truncdi_1"
4065  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4066	(fix:DI (match_operand 1 "register_operand" "f,f")))]
4067  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4068   && !reload_completed && !reload_in_progress
4069   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4070  "#"
4071  "&& 1"
4072  [(const_int 0)]
4073{
4074  ix86_optimize_mode_switching = 1;
4075  operands[2] = assign_386_stack_local (HImode, 1);
4076  operands[3] = assign_386_stack_local (HImode, 2);
4077  if (memory_operand (operands[0], VOIDmode))
4078    emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4079				       operands[2], operands[3]));
4080  else
4081    {
4082      operands[4] = assign_386_stack_local (DImode, 0);
4083      emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4084					   operands[2], operands[3],
4085					   operands[4]));
4086    }
4087  DONE;
4088}
4089  [(set_attr "type" "fistp")
4090   (set_attr "mode" "DI")])
4091
4092(define_insn "fix_truncdi_nomemory"
4093  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4094	(fix:DI (match_operand 1 "register_operand" "f,f")))
4095   (use (match_operand:HI 2 "memory_operand" "m,m"))
4096   (use (match_operand:HI 3 "memory_operand" "m,m"))
4097   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4098   (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4099  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4100   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4101  "#"
4102  [(set_attr "type" "fistp")
4103   (set_attr "mode" "DI")])
4104
4105(define_insn "fix_truncdi_memory"
4106  [(set (match_operand:DI 0 "memory_operand" "=m")
4107	(fix:DI (match_operand 1 "register_operand" "f")))
4108   (use (match_operand:HI 2 "memory_operand" "m"))
4109   (use (match_operand:HI 3 "memory_operand" "m"))
4110   (clobber (match_scratch:DF 4 "=&1f"))]
4111  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4112   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4113  "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4114  [(set_attr "type" "fistp")
4115   (set_attr "mode" "DI")])
4116
4117(define_split 
4118  [(set (match_operand:DI 0 "register_operand" "")
4119	(fix:DI (match_operand 1 "register_operand" "")))
4120   (use (match_operand:HI 2 "memory_operand" ""))
4121   (use (match_operand:HI 3 "memory_operand" ""))
4122   (clobber (match_operand:DI 4 "memory_operand" ""))
4123   (clobber (match_scratch 5 ""))]
4124  "reload_completed"
4125  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4126	      (use (match_dup 2))
4127	      (use (match_dup 3))
4128	      (clobber (match_dup 5))])
4129   (set (match_dup 0) (match_dup 4))]
4130  "")
4131
4132(define_split 
4133  [(set (match_operand:DI 0 "memory_operand" "")
4134	(fix:DI (match_operand 1 "register_operand" "")))
4135   (use (match_operand:HI 2 "memory_operand" ""))
4136   (use (match_operand:HI 3 "memory_operand" ""))
4137   (clobber (match_operand:DI 4 "memory_operand" ""))
4138   (clobber (match_scratch 5 ""))]
4139  "reload_completed"
4140  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4141	      (use (match_dup 2))
4142	      (use (match_dup 3))
4143	      (clobber (match_dup 5))])]
4144  "")
4145
4146;; When SSE available, it is always faster to use it!
4147(define_insn "fix_truncsfdi_sse"
4148  [(set (match_operand:DI 0 "register_operand" "=r,r")
4149	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4150  "TARGET_64BIT && TARGET_SSE"
4151  "cvttss2si{q}\t{%1, %0|%0, %1}"
4152  [(set_attr "type" "sseicvt")
4153   (set_attr "mode" "SF")
4154   (set_attr "athlon_decode" "double,vector")])
4155
4156;; Avoid vector decoded form of the instruction.
4157(define_peephole2
4158  [(match_scratch:SF 2 "x")
4159   (set (match_operand:DI 0 "register_operand" "")
4160	(fix:DI (match_operand:SF 1 "memory_operand" "")))]
4161  "TARGET_K8 && !optimize_size"
4162  [(set (match_dup 2) (match_dup 1))
4163   (set (match_dup 0) (fix:DI (match_dup 2)))]
4164  "")
4165
4166(define_insn "fix_truncdfdi_sse"
4167  [(set (match_operand:DI 0 "register_operand" "=r,r")
4168	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4169  "TARGET_64BIT && TARGET_SSE2"
4170  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4171  [(set_attr "type" "sseicvt,sseicvt")
4172   (set_attr "mode" "DF")
4173   (set_attr "athlon_decode" "double,vector")])
4174
4175;; Avoid vector decoded form of the instruction.
4176(define_peephole2
4177  [(match_scratch:DF 2 "Y")
4178   (set (match_operand:DI 0 "register_operand" "")
4179	(fix:DI (match_operand:DF 1 "memory_operand" "")))]
4180  "TARGET_K8 && !optimize_size"
4181  [(set (match_dup 2) (match_dup 1))
4182   (set (match_dup 0) (fix:DI (match_dup 2)))]
4183  "")
4184
4185;; Signed conversion to SImode.
4186
4187(define_expand "fix_truncxfsi2"
4188  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4189	(fix:SI (match_operand:XF 1 "register_operand" "")))]
4190  "TARGET_80387"
4191  "")
4192
4193(define_expand "fix_truncdfsi2"
4194  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4195	(fix:SI (match_operand:DF 1 "register_operand" "")))]
4196  "TARGET_80387 || TARGET_SSE2"
4197{
4198  if (TARGET_SSE2)
4199   {
4200     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4201     emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4202     if (out != operands[0])
4203	emit_move_insn (operands[0], out);
4204     DONE;
4205   }
4206})
4207
4208(define_expand "fix_truncsfsi2"
4209  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4210	(fix:SI (match_operand:SF 1 "register_operand" "")))]
4211  "TARGET_80387 || TARGET_SSE"
4212{
4213  if (TARGET_SSE)
4214   {
4215     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4216     emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4217     if (out != operands[0])
4218	emit_move_insn (operands[0], out);
4219     DONE;
4220   }
4221})
4222
4223;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4224;; of the machinery.
4225(define_insn_and_split "*fix_truncsi_1"
4226  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4227	(fix:SI (match_operand 1 "register_operand" "f,f")))]
4228  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4229   && !reload_completed && !reload_in_progress
4230   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4231  "#"
4232  "&& 1"
4233  [(const_int 0)]
4234{
4235  ix86_optimize_mode_switching = 1;
4236  operands[2] = assign_386_stack_local (HImode, 1);
4237  operands[3] = assign_386_stack_local (HImode, 2);
4238  if (memory_operand (operands[0], VOIDmode))
4239    emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4240				       operands[2], operands[3]));
4241  else
4242    {
4243      operands[4] = assign_386_stack_local (SImode, 0);
4244      emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4245					   operands[2], operands[3],
4246					   operands[4]));
4247    }
4248  DONE;
4249}
4250  [(set_attr "type" "fistp")
4251   (set_attr "mode" "SI")])
4252
4253(define_insn "fix_truncsi_nomemory"
4254  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4255	(fix:SI (match_operand 1 "register_operand" "f,f")))
4256   (use (match_operand:HI 2 "memory_operand" "m,m"))
4257   (use (match_operand:HI 3 "memory_operand" "m,m"))
4258   (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4259  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4260   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4261  "#"
4262  [(set_attr "type" "fistp")
4263   (set_attr "mode" "SI")])
4264
4265(define_insn "fix_truncsi_memory"
4266  [(set (match_operand:SI 0 "memory_operand" "=m")
4267	(fix:SI (match_operand 1 "register_operand" "f")))
4268   (use (match_operand:HI 2 "memory_operand" "m"))
4269   (use (match_operand:HI 3 "memory_operand" "m"))]
4270  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4271   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4272  "* return output_fix_trunc (insn, operands);"
4273  [(set_attr "type" "fistp")
4274   (set_attr "mode" "SI")])
4275
4276;; When SSE available, it is always faster to use it!
4277(define_insn "fix_truncsfsi_sse"
4278  [(set (match_operand:SI 0 "register_operand" "=r,r")
4279	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4280  "TARGET_SSE"
4281  "cvttss2si\t{%1, %0|%0, %1}"
4282  [(set_attr "type" "sseicvt")
4283   (set_attr "mode" "DF")
4284   (set_attr "athlon_decode" "double,vector")])
4285
4286;; Avoid vector decoded form of the instruction.
4287(define_peephole2
4288  [(match_scratch:SF 2 "x")
4289   (set (match_operand:SI 0 "register_operand" "")
4290	(fix:SI (match_operand:SF 1 "memory_operand" "")))]
4291  "TARGET_K8 && !optimize_size"
4292  [(set (match_dup 2) (match_dup 1))
4293   (set (match_dup 0) (fix:SI (match_dup 2)))]
4294  "")
4295
4296(define_insn "fix_truncdfsi_sse"
4297  [(set (match_operand:SI 0 "register_operand" "=r,r")
4298	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4299  "TARGET_SSE2"
4300  "cvttsd2si\t{%1, %0|%0, %1}"
4301  [(set_attr "type" "sseicvt")
4302   (set_attr "mode" "DF")
4303   (set_attr "athlon_decode" "double,vector")])
4304
4305;; Avoid vector decoded form of the instruction.
4306(define_peephole2
4307  [(match_scratch:DF 2 "Y")
4308   (set (match_operand:SI 0 "register_operand" "")
4309	(fix:SI (match_operand:DF 1 "memory_operand" "")))]
4310  "TARGET_K8 && !optimize_size"
4311  [(set (match_dup 2) (match_dup 1))
4312   (set (match_dup 0) (fix:SI (match_dup 2)))]
4313  "")
4314
4315(define_split 
4316  [(set (match_operand:SI 0 "register_operand" "")
4317	(fix:SI (match_operand 1 "register_operand" "")))
4318   (use (match_operand:HI 2 "memory_operand" ""))
4319   (use (match_operand:HI 3 "memory_operand" ""))
4320   (clobber (match_operand:SI 4 "memory_operand" ""))]
4321  "reload_completed"
4322  [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4323	      (use (match_dup 2))
4324	      (use (match_dup 3))])
4325   (set (match_dup 0) (match_dup 4))]
4326  "")
4327
4328(define_split 
4329  [(set (match_operand:SI 0 "memory_operand" "")
4330	(fix:SI (match_operand 1 "register_operand" "")))
4331   (use (match_operand:HI 2 "memory_operand" ""))
4332   (use (match_operand:HI 3 "memory_operand" ""))
4333   (clobber (match_operand:SI 4 "memory_operand" ""))]
4334  "reload_completed"
4335  [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4336	      (use (match_dup 2))
4337	      (use (match_dup 3))])]
4338  "")
4339
4340;; Signed conversion to HImode.
4341
4342(define_expand "fix_truncxfhi2"
4343  [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344        (fix:HI (match_operand:XF 1 "register_operand" "")))]
4345  "TARGET_80387"
4346  "")
4347
4348(define_expand "fix_truncdfhi2"
4349  [(set (match_operand:HI 0 "nonimmediate_operand" "")
4350	(fix:HI (match_operand:DF 1 "register_operand" "")))]
4351  "TARGET_80387 && !TARGET_SSE2"
4352  "")
4353
4354(define_expand "fix_truncsfhi2"
4355  [(set (match_operand:HI 0 "nonimmediate_operand" "")
4356	(fix:HI (match_operand:SF 1 "register_operand" "")))]
4357  "TARGET_80387 && !TARGET_SSE"
4358  "")
4359
4360;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4361;; of the machinery.
4362(define_insn_and_split "*fix_trunchi_1"
4363  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4364	(fix:HI (match_operand 1 "register_operand" "f,f")))]
4365  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4366   && !reload_completed && !reload_in_progress
4367   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4368  "#"
4369  ""
4370  [(const_int 0)]
4371{
4372  ix86_optimize_mode_switching = 1;
4373  operands[2] = assign_386_stack_local (HImode, 1);
4374  operands[3] = assign_386_stack_local (HImode, 2);
4375  if (memory_operand (operands[0], VOIDmode))
4376    emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4377				       operands[2], operands[3]));
4378  else
4379    {
4380      operands[4] = assign_386_stack_local (HImode, 0);
4381      emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4382					   operands[2], operands[3],
4383					   operands[4]));
4384    }
4385  DONE;
4386}
4387  [(set_attr "type" "fistp")
4388   (set_attr "mode" "HI")])
4389
4390(define_insn "fix_trunchi_nomemory"
4391  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4392	(fix:HI (match_operand 1 "register_operand" "f,f")))
4393   (use (match_operand:HI 2 "memory_operand" "m,m"))
4394   (use (match_operand:HI 3 "memory_operand" "m,m"))
4395   (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4396  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4397   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4398  "#"
4399  [(set_attr "type" "fistp")
4400   (set_attr "mode" "HI")])
4401
4402(define_insn "fix_trunchi_memory"
4403  [(set (match_operand:HI 0 "memory_operand" "=m")
4404	(fix:HI (match_operand 1 "register_operand" "f")))
4405   (use (match_operand:HI 2 "memory_operand" "m"))
4406   (use (match_operand:HI 3 "memory_operand" "m"))]
4407  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4408   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4409  "* return output_fix_trunc (insn, operands);"
4410  [(set_attr "type" "fistp")
4411   (set_attr "mode" "HI")])
4412
4413(define_split 
4414  [(set (match_operand:HI 0 "memory_operand" "")
4415	(fix:HI (match_operand 1 "register_operand" "")))
4416   (use (match_operand:HI 2 "memory_operand" ""))
4417   (use (match_operand:HI 3 "memory_operand" ""))
4418   (clobber (match_operand:HI 4 "memory_operand" ""))]
4419  "reload_completed"
4420  [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4421	      (use (match_dup 2))
4422	      (use (match_dup 3))])]
4423  "")
4424
4425(define_split 
4426  [(set (match_operand:HI 0 "register_operand" "")
4427	(fix:HI (match_operand 1 "register_operand" "")))
4428   (use (match_operand:HI 2 "memory_operand" ""))
4429   (use (match_operand:HI 3 "memory_operand" ""))
4430   (clobber (match_operand:HI 4 "memory_operand" ""))]
4431  "reload_completed"
4432  [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4433	      (use (match_dup 2))
4434	      (use (match_dup 3))
4435	      (clobber (match_dup 4))])
4436   (set (match_dup 0) (match_dup 4))]
4437  "")
4438
4439;; %% Not used yet.
4440(define_insn "x86_fnstcw_1"
4441  [(set (match_operand:HI 0 "memory_operand" "=m")
4442	(unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4443  "TARGET_80387"
4444  "fnstcw\t%0"
4445  [(set_attr "length" "2")
4446   (set_attr "mode" "HI")
4447   (set_attr "unit" "i387")
4448   (set_attr "ppro_uops" "few")])
4449
4450(define_insn "x86_fldcw_1"
4451  [(set (reg:HI 18)
4452	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4453  "TARGET_80387"
4454  "fldcw\t%0"
4455  [(set_attr "length" "2")
4456   (set_attr "mode" "HI")
4457   (set_attr "unit" "i387")
4458   (set_attr "athlon_decode" "vector")
4459   (set_attr "ppro_uops" "few")])
4460
4461;; Conversion between fixed point and floating point.
4462
4463;; Even though we only accept memory inputs, the backend _really_
4464;; wants to be able to do this between registers.
4465
4466(define_expand "floathisf2"
4467  [(set (match_operand:SF 0 "register_operand" "")
4468	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4469  "TARGET_SSE || TARGET_80387"
4470{
4471  if (TARGET_SSE && TARGET_SSE_MATH)
4472    {
4473      emit_insn (gen_floatsisf2 (operands[0],
4474				 convert_to_mode (SImode, operands[1], 0)));
4475      DONE;
4476    }
4477})
4478
4479(define_insn "*floathisf2_1"
4480  [(set (match_operand:SF 0 "register_operand" "=f,f")
4481	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4482  "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4483  "@
4484   fild%z1\t%1
4485   #"
4486  [(set_attr "type" "fmov,multi")
4487   (set_attr "mode" "SF")
4488   (set_attr "fp_int_src" "true")])
4489
4490(define_expand "floatsisf2"
4491  [(set (match_operand:SF 0 "register_operand" "")
4492	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4493  "TARGET_SSE || TARGET_80387"
4494  "")
4495
4496(define_insn "*floatsisf2_i387"
4497  [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4498	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4499  "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4500  "@
4501   fild%z1\t%1
4502   #
4503   cvtsi2ss\t{%1, %0|%0, %1}
4504   cvtsi2ss\t{%1, %0|%0, %1}"
4505  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4506   (set_attr "mode" "SF")
4507   (set_attr "athlon_decode" "*,*,vector,double")
4508   (set_attr "fp_int_src" "true")])
4509
4510(define_insn "*floatsisf2_sse"
4511  [(set (match_operand:SF 0 "register_operand" "=x,x")
4512	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4513  "TARGET_SSE"
4514  "cvtsi2ss\t{%1, %0|%0, %1}"
4515  [(set_attr "type" "sseicvt")
4516   (set_attr "mode" "SF")
4517   (set_attr "athlon_decode" "vector,double")
4518   (set_attr "fp_int_src" "true")])
4519
4520; Avoid possible reformatting penalty on the destination by first
4521; zeroing it out
4522(define_split
4523  [(set (match_operand:SF 0 "register_operand" "")
4524	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525  "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4526   && SSE_REG_P (operands[0])"
4527  [(const_int 0)]
4528{
4529  rtx dest;
4530  dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4531  emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4532  emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4533  DONE;
4534})
4535
4536(define_expand "floatdisf2"
4537  [(set (match_operand:SF 0 "register_operand" "")
4538	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4539  "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4540  "")
4541
4542(define_insn "*floatdisf2_i387_only"
4543  [(set (match_operand:SF 0 "register_operand" "=f,?f")
4544	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4545  "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4546  "@
4547   fild%z1\t%1
4548   #"
4549  [(set_attr "type" "fmov,multi")
4550   (set_attr "mode" "SF")
4551   (set_attr "fp_int_src" "true")])
4552
4553(define_insn "*floatdisf2_i387"
4554  [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4555	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4556  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4557  "@
4558   fild%z1\t%1
4559   #
4560   cvtsi2ss{q}\t{%1, %0|%0, %1}
4561   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4563   (set_attr "mode" "SF")
4564   (set_attr "athlon_decode" "*,*,vector,double")
4565   (set_attr "fp_int_src" "true")])
4566
4567(define_insn "*floatdisf2_sse"
4568  [(set (match_operand:SF 0 "register_operand" "=x,x")
4569	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4570  "TARGET_64BIT && TARGET_SSE"
4571  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4572  [(set_attr "type" "sseicvt")
4573   (set_attr "mode" "SF")
4574   (set_attr "athlon_decode" "vector,double")
4575   (set_attr "fp_int_src" "true")])
4576
4577; Avoid possible reformatting penalty on the destination by first
4578; zeroing it out
4579(define_split
4580  [(set (match_operand:SF 0 "register_operand" "")
4581	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4582  "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4583   && SSE_REG_P (operands[0])"
4584  [(const_int 0)]
4585{
4586  rtx dest;
4587  dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4588  emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4589  emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4590  DONE;
4591})
4592
4593(define_expand "floathidf2"
4594  [(set (match_operand:DF 0 "register_operand" "")
4595	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4596  "TARGET_SSE2 || TARGET_80387"
4597{
4598  if (TARGET_SSE && TARGET_SSE_MATH)
4599    {
4600      emit_insn (gen_floatsidf2 (operands[0],
4601				 convert_to_mode (SImode, operands[1], 0)));
4602      DONE;
4603    }
4604})
4605
4606(define_insn "*floathidf2_1"
4607  [(set (match_operand:DF 0 "register_operand" "=f,f")
4608	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4609  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4610  "@
4611   fild%z1\t%1
4612   #"
4613  [(set_attr "type" "fmov,multi")
4614   (set_attr "mode" "DF")
4615   (set_attr "fp_int_src" "true")])
4616
4617(define_expand "floatsidf2"
4618  [(set (match_operand:DF 0 "register_operand" "")
4619	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4620  "TARGET_80387 || TARGET_SSE2"
4621  "")
4622
4623(define_insn "*floatsidf2_i387"
4624  [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4625	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4626  "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4627  "@
4628   fild%z1\t%1
4629   #
4630   cvtsi2sd\t{%1, %0|%0, %1}
4631   cvtsi2sd\t{%1, %0|%0, %1}"
4632  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4633   (set_attr "mode" "DF")
4634   (set_attr "athlon_decode" "*,*,double,direct")
4635   (set_attr "fp_int_src" "true")])
4636
4637(define_insn "*floatsidf2_sse"
4638  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4639	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4640  "TARGET_SSE2"
4641  "cvtsi2sd\t{%1, %0|%0, %1}"
4642  [(set_attr "type" "sseicvt")
4643   (set_attr "mode" "DF")
4644   (set_attr "athlon_decode" "double,direct")
4645   (set_attr "fp_int_src" "true")])
4646
4647(define_expand "floatdidf2"
4648  [(set (match_operand:DF 0 "register_operand" "")
4649	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4650  "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4651  "")
4652
4653(define_insn "*floatdidf2_i387_only"
4654  [(set (match_operand:DF 0 "register_operand" "=f,?f")
4655	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4656  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4657  "@
4658   fild%z1\t%1
4659   #"
4660  [(set_attr "type" "fmov,multi")
4661   (set_attr "mode" "DF")
4662   (set_attr "fp_int_src" "true")])
4663
4664(define_insn "*floatdidf2_i387"
4665  [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4666	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4667  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4668  "@
4669   fild%z1\t%1
4670   #
4671   cvtsi2sd{q}\t{%1, %0|%0, %1}
4672   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4674   (set_attr "mode" "DF")
4675   (set_attr "athlon_decode" "*,*,double,direct")
4676   (set_attr "fp_int_src" "true")])
4677
4678(define_insn "*floatdidf2_sse"
4679  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4680	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4681  "TARGET_SSE2"
4682  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4683  [(set_attr "type" "sseicvt")
4684   (set_attr "mode" "DF")
4685   (set_attr "athlon_decode" "double,direct")
4686   (set_attr "fp_int_src" "true")])
4687
4688(define_insn "floathixf2"
4689  [(set (match_operand:XF 0 "register_operand" "=f,f")
4690	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4691  "TARGET_80387"
4692  "@
4693   fild%z1\t%1
4694   #"
4695  [(set_attr "type" "fmov,multi")
4696   (set_attr "mode" "XF")
4697   (set_attr "fp_int_src" "true")])
4698
4699(define_insn "floatsixf2"
4700  [(set (match_operand:XF 0 "register_operand" "=f,f")
4701	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4702  "TARGET_80387"
4703  "@
4704   fild%z1\t%1
4705   #"
4706  [(set_attr "type" "fmov,multi")
4707   (set_attr "mode" "XF")
4708   (set_attr "fp_int_src" "true")])
4709
4710(define_insn "floatdixf2"
4711  [(set (match_operand:XF 0 "register_operand" "=f,f")
4712	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4713  "TARGET_80387"
4714  "@
4715   fild%z1\t%1
4716   #"
4717  [(set_attr "type" "fmov,multi")
4718   (set_attr "mode" "XF")
4719   (set_attr "fp_int_src" "true")])
4720
4721;; %%% Kill these when reload knows how to do it.
4722(define_split
4723  [(set (match_operand 0 "fp_register_operand" "")
4724	(float (match_operand 1 "register_operand" "")))]
4725  "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4726  [(const_int 0)]
4727{
4728  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4729  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4730  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4731  ix86_free_from_memory (GET_MODE (operands[1]));
4732  DONE;
4733})
4734
4735(define_expand "floatunssisf2"
4736  [(use (match_operand:SF 0 "register_operand" ""))
4737   (use (match_operand:SI 1 "register_operand" ""))]
4738  "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4739  "x86_emit_floatuns (operands); DONE;")
4740
4741(define_expand "floatunsdisf2"
4742  [(use (match_operand:SF 0 "register_operand" ""))
4743   (use (match_operand:DI 1 "register_operand" ""))]
4744  "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4745  "x86_emit_floatuns (operands); DONE;")
4746
4747(define_expand "floatunsdidf2"
4748  [(use (match_operand:DF 0 "register_operand" ""))
4749   (use (match_operand:DI 1 "register_operand" ""))]
4750  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4751  "x86_emit_floatuns (operands); DONE;")
4752
4753;; SSE extract/set expanders
4754
4755(define_expand "vec_setv2df"
4756  [(match_operand:V2DF 0 "register_operand" "")
4757   (match_operand:DF 1 "register_operand" "")
4758   (match_operand 2 "const_int_operand" "")]
4759  "TARGET_SSE2"
4760{
4761  switch (INTVAL (operands[2]))
4762    {
4763    case 0:
4764      emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765				 simplify_gen_subreg (V2DFmode, operands[1],
4766						      DFmode, 0)));
4767      break;
4768    case 1:
4769      {
4770	rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771
4772	emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773      }
4774      break;
4775    default:
4776      abort ();
4777    }
4778  DONE;
4779})
4780
4781(define_expand "vec_extractv2df"
4782  [(match_operand:DF 0 "register_operand" "")
4783   (match_operand:V2DF 1 "register_operand" "")
4784   (match_operand 2 "const_int_operand" "")]
4785  "TARGET_SSE2"
4786{
4787  switch (INTVAL (operands[2]))
4788    {
4789    case 0:
4790      emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791      break;
4792    case 1:
4793      {
4794	rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795
4796	emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797      }
4798      break;
4799    default:
4800      abort ();
4801    }
4802  DONE;
4803})
4804
4805(define_expand "vec_initv2df"
4806  [(match_operand:V2DF 0 "register_operand" "")
4807   (match_operand 1 "" "")]
4808  "TARGET_SSE2"
4809{
4810  ix86_expand_vector_init (operands[0], operands[1]);
4811  DONE;
4812})
4813
4814(define_expand "vec_setv4sf"
4815  [(match_operand:V4SF 0 "register_operand" "")
4816   (match_operand:SF 1 "register_operand" "")
4817   (match_operand 2 "const_int_operand" "")]
4818  "TARGET_SSE"
4819{
4820  switch (INTVAL (operands[2]))
4821    {
4822    case 0:
4823      emit_insn (gen_sse_movss (operands[0], operands[0],
4824				simplify_gen_subreg (V4SFmode, operands[1],
4825						     SFmode, 0)));
4826      break;
4827    case 1:
4828      {
4829	rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830	rtx tmp = gen_reg_rtx (V4SFmode);
4831 
4832        emit_move_insn (tmp, operands[0]);
4833	emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834	emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835        emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836                                   GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837      }
4838    case 2:
4839      {
4840        rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4841        rtx tmp = gen_reg_rtx (V4SFmode);
4842
4843        emit_move_insn (tmp, operands[0]);
4844        emit_insn (gen_sse_movss (tmp, tmp, op1));
4845        emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4846                                   GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4847      }
4848      break;
4849    case 3:
4850      {
4851        rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4852        rtx tmp = gen_reg_rtx (V4SFmode);
4853
4854        emit_move_insn (tmp, operands[0]);
4855        emit_insn (gen_sse_movss (tmp, tmp, op1));
4856        emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4857                                   GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4858      }
4859      break;
4860    default:
4861      abort ();
4862    }
4863  DONE;
4864})
4865
4866(define_expand "vec_extractv4sf"
4867  [(match_operand:SF 0 "register_operand" "")
4868   (match_operand:V4SF 1 "register_operand" "")
4869   (match_operand 2 "const_int_operand" "")]
4870  "TARGET_SSE"
4871{
4872  switch (INTVAL (operands[2]))
4873    {
4874    case 0:
4875      emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4876      break;
4877    case 1:
4878      {
4879	rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4880	rtx tmp = gen_reg_rtx (V4SFmode);
4881 
4882        emit_move_insn (tmp, operands[1]);
4883        emit_insn (gen_sse_shufps (op0, tmp, tmp,
4884                                   GEN_INT (1)));
4885      }
4886    case 2:
4887      {
4888	rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4889	rtx tmp = gen_reg_rtx (V4SFmode);
4890 
4891        emit_move_insn (tmp, operands[1]);
4892        emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4893      }
4894    case 3:
4895      {
4896	rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4897	rtx tmp = gen_reg_rtx (V4SFmode);
4898 
4899        emit_move_insn (tmp, operands[1]);
4900        emit_insn (gen_sse_shufps (op0, tmp, tmp,
4901                                   GEN_INT (3)));
4902      }
4903    default:
4904      abort ();
4905    }
4906  DONE;
4907})
4908
4909(define_expand "vec_initv4sf"
4910  [(match_operand:V4SF 0 "register_operand" "")
4911   (match_operand 1 "" "")]
4912  "TARGET_SSE"
4913{
4914  ix86_expand_vector_init (operands[0], operands[1]);
4915  DONE;
4916})
4917
4918;; Add instructions
4919
4920;; %%% splits for addsidi3
4921;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4922;	(plus:DI (match_operand:DI 1 "general_operand" "")
4923;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4924
4925(define_expand "adddi3"
4926  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4927	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4928		 (match_operand:DI 2 "x86_64_general_operand" "")))
4929   (clobber (reg:CC 17))]
4930  ""
4931  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4932
4933(define_insn "*adddi3_1"
4934  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4935	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4936		 (match_operand:DI 2 "general_operand" "roiF,riF")))
4937   (clobber (reg:CC 17))]
4938  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4939  "#")
4940
4941(define_split
4942  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4943	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4944		 (match_operand:DI 2 "general_operand" "")))
4945   (clobber (reg:CC 17))]
4946  "!TARGET_64BIT && reload_completed"
4947  [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4948					  UNSPEC_ADD_CARRY))
4949	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4950   (parallel [(set (match_dup 3)
4951		   (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4952				     (match_dup 4))
4953			    (match_dup 5)))
4954	      (clobber (reg:CC 17))])]
4955  "split_di (operands+0, 1, operands+0, operands+3);
4956   split_di (operands+1, 1, operands+1, operands+4);
4957   split_di (operands+2, 1, operands+2, operands+5);")
4958
4959(define_insn "adddi3_carry_rex64"
4960  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4961	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4962			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4963		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4964   (clobber (reg:CC 17))]
4965  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4966  "adc{q}\t{%2, %0|%0, %2}"
4967  [(set_attr "type" "alu")
4968   (set_attr "pent_pair" "pu")
4969   (set_attr "mode" "DI")
4970   (set_attr "ppro_uops" "few")])
4971
4972(define_insn "*adddi3_cc_rex64"
4973  [(set (reg:CC 17)
4974	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4975		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4976		   UNSPEC_ADD_CARRY))
4977   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4978	(plus:DI (match_dup 1) (match_dup 2)))]
4979  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4980  "add{q}\t{%2, %0|%0, %2}"
4981  [(set_attr "type" "alu")
4982   (set_attr "mode" "DI")])
4983
4984(define_insn "addqi3_carry"
4985  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4986	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4987			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4988		   (match_operand:QI 2 "general_operand" "qi,qm")))
4989   (clobber (reg:CC 17))]
4990  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4991  "adc{b}\t{%2, %0|%0, %2}"
4992  [(set_attr "type" "alu")
4993   (set_attr "pent_pair" "pu")
4994   (set_attr "mode" "QI")
4995   (set_attr "ppro_uops" "few")])
4996
4997(define_insn "addhi3_carry"
4998  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4999	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5000			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5001		   (match_operand:HI 2 "general_operand" "ri,rm")))
5002   (clobber (reg:CC 17))]
5003  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5004  "adc{w}\t{%2, %0|%0, %2}"
5005  [(set_attr "type" "alu")
5006   (set_attr "pent_pair" "pu")
5007   (set_attr "mode" "HI")
5008   (set_attr "ppro_uops" "few")])
5009
5010(define_insn "addsi3_carry"
5011  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5012	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5013			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5014		   (match_operand:SI 2 "general_operand" "ri,rm")))
5015   (clobber (reg:CC 17))]
5016  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5017  "adc{l}\t{%2, %0|%0, %2}"
5018  [(set_attr "type" "alu")
5019   (set_attr "pent_pair" "pu")
5020   (set_attr "mode" "SI")
5021   (set_attr "ppro_uops" "few")])
5022
5023(define_insn "*addsi3_carry_zext"
5024  [(set (match_operand:DI 0 "register_operand" "=r")
5025	  (zero_extend:DI 
5026	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5027			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
5028		     (match_operand:SI 2 "general_operand" "rim"))))
5029   (clobber (reg:CC 17))]
5030  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5031  "adc{l}\t{%2, %k0|%k0, %2}"
5032  [(set_attr "type" "alu")
5033   (set_attr "pent_pair" "pu")
5034   (set_attr "mode" "SI")
5035   (set_attr "ppro_uops" "few")])
5036
5037(define_insn "*addsi3_cc"
5038  [(set (reg:CC 17)
5039	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5040		    (match_operand:SI 2 "general_operand" "ri,rm")]
5041		   UNSPEC_ADD_CARRY))
5042   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5043	(plus:SI (match_dup 1) (match_dup 2)))]
5044  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5045  "add{l}\t{%2, %0|%0, %2}"
5046  [(set_attr "type" "alu")
5047   (set_attr "mode" "SI")])
5048
5049(define_insn "addqi3_cc"
5050  [(set (reg:CC 17)
5051	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5052		    (match_operand:QI 2 "general_operand" "qi,qm")]
5053		   UNSPEC_ADD_CARRY))
5054   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5055	(plus:QI (match_dup 1) (match_dup 2)))]
5056  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5057  "add{b}\t{%2, %0|%0, %2}"
5058  [(set_attr "type" "alu")
5059   (set_attr "mode" "QI")])
5060
5061(define_expand "addsi3"
5062  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5063		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5064			    (match_operand:SI 2 "general_operand" "")))
5065	      (clobber (reg:CC 17))])]
5066  ""
5067  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5068
5069(define_insn "*lea_1"
5070  [(set (match_operand:SI 0 "register_operand" "=r")
5071	(match_operand:SI 1 "no_seg_address_operand" "p"))]
5072  "!TARGET_64BIT"
5073  "lea{l}\t{%a1, %0|%0, %a1}"
5074  [(set_attr "type" "lea")
5075   (set_attr "mode" "SI")])
5076
5077(define_insn "*lea_1_rex64"
5078  [(set (match_operand:SI 0 "register_operand" "=r")
5079	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5080  "TARGET_64BIT"
5081  "lea{l}\t{%a1, %0|%0, %a1}"
5082  [(set_attr "type" "lea")
5083   (set_attr "mode" "SI")])
5084
5085(define_insn "*lea_1_zext"
5086  [(set (match_operand:DI 0 "register_operand" "=r")
5087	(zero_extend:DI
5088	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5089  "TARGET_64BIT"
5090  "lea{l}\t{%a1, %k0|%k0, %a1}"
5091  [(set_attr "type" "lea")
5092   (set_attr "mode" "SI")])
5093
5094(define_insn "*lea_2_rex64"
5095  [(set (match_operand:DI 0 "register_operand" "=r")
5096	(match_operand:DI 1 "no_seg_address_operand" "p"))]
5097  "TARGET_64BIT"
5098  "lea{q}\t{%a1, %0|%0, %a1}"
5099  [(set_attr "type" "lea")
5100   (set_attr "mode" "DI")])
5101
5102;; The lea patterns for non-Pmodes needs to be matched by several
5103;; insns converted to real lea by splitters.
5104
5105(define_insn_and_split "*lea_general_1"
5106  [(set (match_operand 0 "register_operand" "=r")
5107	(plus (plus (match_operand 1 "index_register_operand" "r")
5108		    (match_operand 2 "register_operand" "r"))
5109	      (match_operand 3 "immediate_operand" "i")))]
5110  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5111    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5112   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5113   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5114   && GET_MODE (operands[0]) == GET_MODE (operands[2])
5115   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5116       || GET_MODE (operands[3]) == VOIDmode)"
5117  "#"
5118  "&& reload_completed"
5119  [(const_int 0)]
5120{
5121  rtx pat;
5122  operands[0] = gen_lowpart (SImode, operands[0]);
5123  operands[1] = gen_lowpart (Pmode, operands[1]);
5124  operands[2] = gen_lowpart (Pmode, operands[2]);
5125  operands[3] = gen_lowpart (Pmode, operands[3]);
5126  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5127  		      operands[3]);
5128  if (Pmode != SImode)
5129    pat = gen_rtx_SUBREG (SImode, pat, 0);
5130  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5131  DONE;
5132}
5133  [(set_attr "type" "lea")
5134   (set_attr "mode" "SI")])
5135
5136(define_insn_and_split "*lea_general_1_zext"
5137  [(set (match_operand:DI 0 "register_operand" "=r")
5138	(zero_extend:DI
5139	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5140			    (match_operand:SI 2 "register_operand" "r"))
5141		   (match_operand:SI 3 "immediate_operand" "i"))))]
5142  "TARGET_64BIT"
5143  "#"
5144  "&& reload_completed"
5145  [(set (match_dup 0)
5146	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5147						     (match_dup 2))
5148					    (match_dup 3)) 0)))]
5149{
5150  operands[1] = gen_lowpart (Pmode, operands[1]);
5151  operands[2] = gen_lowpart (Pmode, operands[2]);
5152  operands[3] = gen_lowpart (Pmode, operands[3]);
5153}
5154  [(set_attr "type" "lea")
5155   (set_attr "mode" "SI")])
5156
5157(define_insn_and_split "*lea_general_2"
5158  [(set (match_operand 0 "register_operand" "=r")
5159	(plus (mult (match_operand 1 "index_register_operand" "r")
5160		    (match_operand 2 "const248_operand" "i"))
5161	      (match_operand 3 "nonmemory_operand" "ri")))]
5162  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5163    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5164   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5165   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5166   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5167       || GET_MODE (operands[3]) == VOIDmode)"
5168  "#"
5169  "&& reload_completed"
5170  [(const_int 0)]
5171{
5172  rtx pat;
5173  operands[0] = gen_lowpart (SImode, operands[0]);
5174  operands[1] = gen_lowpart (Pmode, operands[1]);
5175  operands[3] = gen_lowpart (Pmode, operands[3]);
5176  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5177  		      operands[3]);
5178  if (Pmode != SImode)
5179    pat = gen_rtx_SUBREG (SImode, pat, 0);
5180  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5181  DONE;
5182}
5183  [(set_attr "type" "lea")
5184   (set_attr "mode" "SI")])
5185
5186(define_insn_and_split "*lea_general_2_zext"
5187  [(set (match_operand:DI 0 "register_operand" "=r")
5188	(zero_extend:DI
5189	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5190			    (match_operand:SI 2 "const248_operand" "n"))
5191		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5192  "TARGET_64BIT"
5193  "#"
5194  "&& reload_completed"
5195  [(set (match_dup 0)
5196	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5197						     (match_dup 2))
5198					    (match_dup 3)) 0)))]
5199{
5200  operands[1] = gen_lowpart (Pmode, operands[1]);
5201  operands[3] = gen_lowpart (Pmode, operands[3]);
5202}
5203  [(set_attr "type" "lea")
5204   (set_attr "mode" "SI")])
5205
5206(define_insn_and_split "*lea_general_3"
5207  [(set (match_operand 0 "register_operand" "=r")
5208	(plus (plus (mult (match_operand 1 "index_register_operand" "r")
5209			  (match_operand 2 "const248_operand" "i"))
5210		    (match_operand 3 "register_operand" "r"))
5211	      (match_operand 4 "immediate_operand" "i")))]
5212  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5213    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5214   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5215   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5216   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5217  "#"
5218  "&& reload_completed"
5219  [(const_int 0)]
5220{
5221  rtx pat;
5222  operands[0] = gen_lowpart (SImode, operands[0]);
5223  operands[1] = gen_lowpart (Pmode, operands[1]);
5224  operands[3] = gen_lowpart (Pmode, operands[3]);
5225  operands[4] = gen_lowpart (Pmode, operands[4]);
5226  pat = gen_rtx_PLUS (Pmode,
5227  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5228		      					 operands[2]),
5229				    operands[3]),
5230  		      operands[4]);
5231  if (Pmode != SImode)
5232    pat = gen_rtx_SUBREG (SImode, pat, 0);
5233  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5234  DONE;
5235}
5236  [(set_attr "type" "lea")
5237   (set_attr "mode" "SI")])
5238
5239(define_insn_and_split "*lea_general_3_zext"
5240  [(set (match_operand:DI 0 "register_operand" "=r")
5241	(zero_extend:DI
5242	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5243				     (match_operand:SI 2 "const248_operand" "n"))
5244			    (match_operand:SI 3 "register_operand" "r"))
5245		   (match_operand:SI 4 "immediate_operand" "i"))))]
5246  "TARGET_64BIT"
5247  "#"
5248  "&& reload_completed"
5249  [(set (match_dup 0)
5250	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5251							      (match_dup 2))
5252						     (match_dup 3))
5253					    (match_dup 4)) 0)))]
5254{
5255  operands[1] = gen_lowpart (Pmode, operands[1]);
5256  operands[3] = gen_lowpart (Pmode, operands[3]);
5257  operands[4] = gen_lowpart (Pmode, operands[4]);
5258}
5259  [(set_attr "type" "lea")
5260   (set_attr "mode" "SI")])
5261
5262(define_insn "*adddi_1_rex64"
5263  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5264	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5265		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5266   (clobber (reg:CC 17))]
5267  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5268{
5269  switch (get_attr_type (insn))
5270    {
5271    case TYPE_LEA:
5272      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5273      return "lea{q}\t{%a2, %0|%0, %a2}";
5274
5275    case TYPE_INCDEC:
5276      if (! rtx_equal_p (operands[0], operands[1]))
5277	abort ();
5278      if (operands[2] == const1_rtx)
5279        return "inc{q}\t%0";
5280      else if (operands[2] == constm1_rtx)
5281        return "dec{q}\t%0";
5282      else
5283	abort ();
5284
5285    default:
5286      if (! rtx_equal_p (operands[0], operands[1]))
5287	abort ();
5288
5289      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5290	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5291      if (GET_CODE (operands[2]) == CONST_INT
5292	  /* Avoid overflows.  */
5293	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5294          && (INTVAL (operands[2]) == 128
5295	      || (INTVAL (operands[2]) < 0
5296		  && INTVAL (operands[2]) != -128)))
5297        {
5298          operands[2] = GEN_INT (-INTVAL (operands[2]));
5299          return "sub{q}\t{%2, %0|%0, %2}";
5300        }
5301      return "add{q}\t{%2, %0|%0, %2}";
5302    }
5303}
5304  [(set (attr "type")
5305     (cond [(eq_attr "alternative" "2")
5306	      (const_string "lea")
5307	    ; Current assemblers are broken and do not allow @GOTOFF in
5308	    ; ought but a memory context.
5309	    (match_operand:DI 2 "pic_symbolic_operand" "")
5310	      (const_string "lea")
5311	    (match_operand:DI 2 "incdec_operand" "")
5312	      (const_string "incdec")
5313	   ]
5314	   (const_string "alu")))
5315   (set_attr "mode" "DI")])
5316
5317;; Convert lea to the lea pattern to avoid flags dependency.
5318(define_split
5319  [(set (match_operand:DI 0 "register_operand" "")
5320	(plus:DI (match_operand:DI 1 "register_operand" "")
5321		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5322   (clobber (reg:CC 17))]
5323  "TARGET_64BIT && reload_completed
5324   && true_regnum (operands[0]) != true_regnum (operands[1])"
5325  [(set (match_dup 0)
5326	(plus:DI (match_dup 1)
5327		 (match_dup 2)))]
5328  "")
5329
5330(define_insn "*adddi_2_rex64"
5331  [(set (reg 17)
5332	(compare
5333	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5334		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5335	  (const_int 0)))			
5336   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5337	(plus:DI (match_dup 1) (match_dup 2)))]
5338  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5339   && ix86_binary_operator_ok (PLUS, DImode, operands)
5340   /* Current assemblers are broken and do not allow @GOTOFF in
5341      ought but a memory context.  */
5342   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5343{
5344  switch (get_attr_type (insn))
5345    {
5346    case TYPE_INCDEC:
5347      if (! rtx_equal_p (operands[0], operands[1]))
5348	abort ();
5349      if (operands[2] == const1_rtx)
5350        return "inc{q}\t%0";
5351      else if (operands[2] == constm1_rtx)
5352        return "dec{q}\t%0";
5353      else
5354	abort ();
5355
5356    default:
5357      if (! rtx_equal_p (operands[0], operands[1]))
5358	abort ();
5359      /* ???? We ought to handle there the 32bit case too
5360	 - do we need new constraint?  */
5361      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5363      if (GET_CODE (operands[2]) == CONST_INT
5364	  /* Avoid overflows.  */
5365	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366          && (INTVAL (operands[2]) == 128
5367	      || (INTVAL (operands[2]) < 0
5368		  && INTVAL (operands[2]) != -128)))
5369        {
5370          operands[2] = GEN_INT (-INTVAL (operands[2]));
5371          return "sub{q}\t{%2, %0|%0, %2}";
5372        }
5373      return "add{q}\t{%2, %0|%0, %2}";
5374    }
5375}
5376  [(set (attr "type")
5377     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378	(const_string "incdec")
5379	(const_string "alu")))
5380   (set_attr "mode" "DI")])
5381
5382(define_insn "*adddi_3_rex64"
5383  [(set (reg 17)
5384	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5386   (clobber (match_scratch:DI 0 "=r"))]
5387  "TARGET_64BIT
5388   && ix86_match_ccmode (insn, CCZmode)
5389   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390   /* Current assemblers are broken and do not allow @GOTOFF in
5391      ought but a memory context.  */
5392   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5393{
5394  switch (get_attr_type (insn))
5395    {
5396    case TYPE_INCDEC:
5397      if (! rtx_equal_p (operands[0], operands[1]))
5398	abort ();
5399      if (operands[2] == const1_rtx)
5400        return "inc{q}\t%0";
5401      else if (operands[2] == constm1_rtx)
5402        return "dec{q}\t%0";
5403      else
5404	abort ();
5405
5406    default:
5407      if (! rtx_equal_p (operands[0], operands[1]))
5408	abort ();
5409      /* ???? We ought to handle there the 32bit case too
5410	 - do we need new constraint?  */
5411      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5413      if (GET_CODE (operands[2]) == CONST_INT
5414	  /* Avoid overflows.  */
5415	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416          && (INTVAL (operands[2]) == 128
5417	      || (INTVAL (operands[2]) < 0
5418		  && INTVAL (operands[2]) != -128)))
5419        {
5420          operands[2] = GEN_INT (-INTVAL (operands[2]));
5421          return "sub{q}\t{%2, %0|%0, %2}";
5422        }
5423      return "add{q}\t{%2, %0|%0, %2}";
5424    }
5425}
5426  [(set (attr "type")
5427     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428	(const_string "incdec")
5429	(const_string "alu")))
5430   (set_attr "mode" "DI")])
5431
5432; For comparisons against 1, -1 and 128, we may generate better code
5433; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5434; is matched then.  We can't accept general immediate, because for
5435; case of overflows,  the result is messed up.
5436; This pattern also don't hold of 0x8000000000000000, since the value overflows
5437; when negated.
5438; Also carry flag is reversed compared to cmp, so this conversion is valid
5439; only for comparisons not depending on it.
5440(define_insn "*adddi_4_rex64"
5441  [(set (reg 17)
5442	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5443		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5444   (clobber (match_scratch:DI 0 "=rm"))]
5445  "TARGET_64BIT
5446   &&  ix86_match_ccmode (insn, CCGCmode)"
5447{
5448  switch (get_attr_type (insn))
5449    {
5450    case TYPE_INCDEC:
5451      if (operands[2] == constm1_rtx)
5452        return "inc{q}\t%0";
5453      else if (operands[2] == const1_rtx)
5454        return "dec{q}\t%0";
5455      else
5456	abort();
5457
5458    default:
5459      if (! rtx_equal_p (operands[0], operands[1]))
5460	abort ();
5461      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5463      if ((INTVAL (operands[2]) == -128
5464	   || (INTVAL (operands[2]) > 0
5465	       && INTVAL (operands[2]) != 128))
5466	  /* Avoid overflows.  */
5467	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5468	return "sub{q}\t{%2, %0|%0, %2}";
5469      operands[2] = GEN_INT (-INTVAL (operands[2]));
5470      return "add{q}\t{%2, %0|%0, %2}";
5471    }
5472}
5473  [(set (attr "type")
5474     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5475	(const_string "incdec")
5476	(const_string "alu")))
5477   (set_attr "mode" "DI")])
5478
5479(define_insn "*adddi_5_rex64"
5480  [(set (reg 17)
5481	(compare
5482	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5483		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5484	  (const_int 0)))			
5485   (clobber (match_scratch:DI 0 "=r"))]
5486  "TARGET_64BIT
5487   && ix86_match_ccmode (insn, CCGOCmode)
5488   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5489   /* Current assemblers are broken and do not allow @GOTOFF in
5490      ought but a memory context.  */
5491   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5492{
5493  switch (get_attr_type (insn))
5494    {
5495    case TYPE_INCDEC:
5496      if (! rtx_equal_p (operands[0], operands[1]))
5497	abort ();
5498      if (operands[2] == const1_rtx)
5499        return "inc{q}\t%0";
5500      else if (operands[2] == constm1_rtx)
5501        return "dec{q}\t%0";
5502      else
5503	abort();
5504
5505    default:
5506      if (! rtx_equal_p (operands[0], operands[1]))
5507	abort ();
5508      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5509	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5510      if (GET_CODE (operands[2]) == CONST_INT
5511	  /* Avoid overflows.  */
5512	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5513          && (INTVAL (operands[2]) == 128
5514	      || (INTVAL (operands[2]) < 0
5515		  && INTVAL (operands[2]) != -128)))
5516        {
5517          operands[2] = GEN_INT (-INTVAL (operands[2]));
5518          return "sub{q}\t{%2, %0|%0, %2}";
5519        }
5520      return "add{q}\t{%2, %0|%0, %2}";
5521    }
5522}
5523  [(set (attr "type")
5524     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5525	(const_string "incdec")
5526	(const_string "alu")))
5527   (set_attr "mode" "DI")])
5528
5529
5530(define_insn "*addsi_1"
5531  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5532	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5533		 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5534   (clobber (reg:CC 17))]
5535  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5536{
5537  switch (get_attr_type (insn))
5538    {
5539    case TYPE_LEA:
5540      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5541      return "lea{l}\t{%a2, %0|%0, %a2}";
5542
5543    case TYPE_INCDEC:
5544      if (! rtx_equal_p (operands[0], operands[1]))
5545	abort ();
5546      if (operands[2] == const1_rtx)
5547        return "inc{l}\t%0";
5548      else if (operands[2] == constm1_rtx)
5549        return "dec{l}\t%0";
5550      else
5551	abort();
5552
5553    default:
5554      if (! rtx_equal_p (operands[0], operands[1]))
5555	abort ();
5556
5557      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5558	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5559      if (GET_CODE (operands[2]) == CONST_INT
5560          && (INTVAL (operands[2]) == 128
5561	      || (INTVAL (operands[2]) < 0
5562		  && INTVAL (operands[2]) != -128)))
5563        {
5564          operands[2] = GEN_INT (-INTVAL (operands[2]));
5565          return "sub{l}\t{%2, %0|%0, %2}";
5566        }
5567      return "add{l}\t{%2, %0|%0, %2}";
5568    }
5569}
5570  [(set (attr "type")
5571     (cond [(eq_attr "alternative" "2")
5572	      (const_string "lea")
5573	    ; Current assemblers are broken and do not allow @GOTOFF in
5574	    ; ought but a memory context.
5575	    (match_operand:SI 2 "pic_symbolic_operand" "")
5576	      (const_string "lea")
5577	    (match_operand:SI 2 "incdec_operand" "")
5578	      (const_string "incdec")
5579	   ]
5580	   (const_string "alu")))
5581   (set_attr "mode" "SI")])
5582
5583;; Convert lea to the lea pattern to avoid flags dependency.
5584(define_split
5585  [(set (match_operand 0 "register_operand" "")
5586	(plus (match_operand 1 "register_operand" "")
5587              (match_operand 2 "nonmemory_operand" "")))
5588   (clobber (reg:CC 17))]
5589  "reload_completed
5590   && true_regnum (operands[0]) != true_regnum (operands[1])"
5591  [(const_int 0)]
5592{
5593  rtx pat;
5594  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5595     may confuse gen_lowpart.  */
5596  if (GET_MODE (operands[0]) != Pmode)
5597    {
5598      operands[1] = gen_lowpart (Pmode, operands[1]);
5599      operands[2] = gen_lowpart (Pmode, operands[2]);
5600    }
5601  operands[0] = gen_lowpart (SImode, operands[0]);
5602  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5603  if (Pmode != SImode)
5604    pat = gen_rtx_SUBREG (SImode, pat, 0);
5605  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5606  DONE;
5607})
5608
5609;; It may seem that nonimmediate operand is proper one for operand 1.
5610;; The addsi_1 pattern allows nonimmediate operand at that place and
5611;; we take care in ix86_binary_operator_ok to not allow two memory
5612;; operands so proper swapping will be done in reload.  This allow
5613;; patterns constructed from addsi_1 to match.
5614(define_insn "addsi_1_zext"
5615  [(set (match_operand:DI 0 "register_operand" "=r,r")
5616	(zero_extend:DI
5617	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5618		   (match_operand:SI 2 "general_operand" "rmni,rni"))))
5619   (clobber (reg:CC 17))]
5620  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5621{
5622  switch (get_attr_type (insn))
5623    {
5624    case TYPE_LEA:
5625      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5626      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5627
5628    case TYPE_INCDEC:
5629      if (operands[2] == const1_rtx)
5630        return "inc{l}\t%k0";
5631      else if (operands[2] == constm1_rtx)
5632        return "dec{l}\t%k0";
5633      else
5634	abort();
5635
5636    default:
5637      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5639      if (GET_CODE (operands[2]) == CONST_INT
5640          && (INTVAL (operands[2]) == 128
5641	      || (INTVAL (operands[2]) < 0
5642		  && INTVAL (operands[2]) != -128)))
5643        {
5644          operands[2] = GEN_INT (-INTVAL (operands[2]));
5645          return "sub{l}\t{%2, %k0|%k0, %2}";
5646        }
5647      return "add{l}\t{%2, %k0|%k0, %2}";
5648    }
5649}
5650  [(set (attr "type")
5651     (cond [(eq_attr "alternative" "1")
5652	      (const_string "lea")
5653	    ; Current assemblers are broken and do not allow @GOTOFF in
5654	    ; ought but a memory context.
5655	    (match_operand:SI 2 "pic_symbolic_operand" "")
5656	      (const_string "lea")
5657	    (match_operand:SI 2 "incdec_operand" "")
5658	      (const_string "incdec")
5659	   ]
5660	   (const_string "alu")))
5661   (set_attr "mode" "SI")])
5662
5663;; Convert lea to the lea pattern to avoid flags dependency.
5664(define_split
5665  [(set (match_operand:DI 0 "register_operand" "")
5666	(zero_extend:DI
5667	  (plus:SI (match_operand:SI 1 "register_operand" "")
5668		   (match_operand:SI 2 "nonmemory_operand" ""))))
5669   (clobber (reg:CC 17))]
5670  "TARGET_64BIT && reload_completed
5671   && true_regnum (operands[0]) != true_regnum (operands[1])"
5672  [(set (match_dup 0)
5673	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5674{
5675  operands[1] = gen_lowpart (Pmode, operands[1]);
5676  operands[2] = gen_lowpart (Pmode, operands[2]);
5677})
5678
5679(define_insn "*addsi_2"
5680  [(set (reg 17)
5681	(compare
5682	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5683		   (match_operand:SI 2 "general_operand" "rmni,rni"))
5684	  (const_int 0)))			
5685   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5686	(plus:SI (match_dup 1) (match_dup 2)))]
5687  "ix86_match_ccmode (insn, CCGOCmode)
5688   && ix86_binary_operator_ok (PLUS, SImode, operands)
5689   /* Current assemblers are broken and do not allow @GOTOFF in
5690      ought but a memory context.  */
5691   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5692{
5693  switch (get_attr_type (insn))
5694    {
5695    case TYPE_INCDEC:
5696      if (! rtx_equal_p (operands[0], operands[1]))
5697	abort ();
5698      if (operands[2] == const1_rtx)
5699        return "inc{l}\t%0";
5700      else if (operands[2] == constm1_rtx)
5701        return "dec{l}\t%0";
5702      else
5703	abort();
5704
5705    default:
5706      if (! rtx_equal_p (operands[0], operands[1]))
5707	abort ();
5708      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5709	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5710      if (GET_CODE (operands[2]) == CONST_INT
5711          && (INTVAL (operands[2]) == 128
5712	      || (INTVAL (operands[2]) < 0
5713		  && INTVAL (operands[2]) != -128)))
5714        {
5715          operands[2] = GEN_INT (-INTVAL (operands[2]));
5716          return "sub{l}\t{%2, %0|%0, %2}";
5717        }
5718      return "add{l}\t{%2, %0|%0, %2}";
5719    }
5720}
5721  [(set (attr "type")
5722     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723	(const_string "incdec")
5724	(const_string "alu")))
5725   (set_attr "mode" "SI")])
5726
5727;; See comment for addsi_1_zext why we do use nonimmediate_operand
5728(define_insn "*addsi_2_zext"
5729  [(set (reg 17)
5730	(compare
5731	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732		   (match_operand:SI 2 "general_operand" "rmni"))
5733	  (const_int 0)))			
5734   (set (match_operand:DI 0 "register_operand" "=r")
5735	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5736  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5737   && ix86_binary_operator_ok (PLUS, SImode, operands)
5738   /* Current assemblers are broken and do not allow @GOTOFF in
5739      ought but a memory context.  */
5740   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741{
5742  switch (get_attr_type (insn))
5743    {
5744    case TYPE_INCDEC:
5745      if (operands[2] == const1_rtx)
5746        return "inc{l}\t%k0";
5747      else if (operands[2] == constm1_rtx)
5748        return "dec{l}\t%k0";
5749      else
5750	abort();
5751
5752    default:
5753      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5755      if (GET_CODE (operands[2]) == CONST_INT
5756          && (INTVAL (operands[2]) == 128
5757	      || (INTVAL (operands[2]) < 0
5758		  && INTVAL (operands[2]) != -128)))
5759        {
5760          operands[2] = GEN_INT (-INTVAL (operands[2]));
5761          return "sub{l}\t{%2, %k0|%k0, %2}";
5762        }
5763      return "add{l}\t{%2, %k0|%k0, %2}";
5764    }
5765}
5766  [(set (attr "type")
5767     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768	(const_string "incdec")
5769	(const_string "alu")))
5770   (set_attr "mode" "SI")])
5771
5772(define_insn "*addsi_3"
5773  [(set (reg 17)
5774	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5775		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5776   (clobber (match_scratch:SI 0 "=r"))]
5777  "ix86_match_ccmode (insn, CCZmode)
5778   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5779   /* Current assemblers are broken and do not allow @GOTOFF in
5780      ought but a memory context.  */
5781   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5782{
5783  switch (get_attr_type (insn))
5784    {
5785    case TYPE_INCDEC:
5786      if (! rtx_equal_p (operands[0], operands[1]))
5787	abort ();
5788      if (operands[2] == const1_rtx)
5789        return "inc{l}\t%0";
5790      else if (operands[2] == constm1_rtx)
5791        return "dec{l}\t%0";
5792      else
5793	abort();
5794
5795    default:
5796      if (! rtx_equal_p (operands[0], operands[1]))
5797	abort ();
5798      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5800      if (GET_CODE (operands[2]) == CONST_INT
5801          && (INTVAL (operands[2]) == 128
5802	      || (INTVAL (operands[2]) < 0
5803		  && INTVAL (operands[2]) != -128)))
5804        {
5805          operands[2] = GEN_INT (-INTVAL (operands[2]));
5806          return "sub{l}\t{%2, %0|%0, %2}";
5807        }
5808      return "add{l}\t{%2, %0|%0, %2}";
5809    }
5810}
5811  [(set (attr "type")
5812     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813	(const_string "incdec")
5814	(const_string "alu")))
5815   (set_attr "mode" "SI")])
5816
5817;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818(define_insn "*addsi_3_zext"
5819  [(set (reg 17)
5820	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5821		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5822   (set (match_operand:DI 0 "register_operand" "=r")
5823	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5824  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5825   && ix86_binary_operator_ok (PLUS, SImode, operands)
5826   /* Current assemblers are broken and do not allow @GOTOFF in
5827      ought but a memory context.  */
5828   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5829{
5830  switch (get_attr_type (insn))
5831    {
5832    case TYPE_INCDEC:
5833      if (operands[2] == const1_rtx)
5834        return "inc{l}\t%k0";
5835      else if (operands[2] == constm1_rtx)
5836        return "dec{l}\t%k0";
5837      else
5838	abort();
5839
5840    default:
5841      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843      if (GET_CODE (operands[2]) == CONST_INT
5844          && (INTVAL (operands[2]) == 128
5845	      || (INTVAL (operands[2]) < 0
5846		  && INTVAL (operands[2]) != -128)))
5847        {
5848          operands[2] = GEN_INT (-INTVAL (operands[2]));
5849          return "sub{l}\t{%2, %k0|%k0, %2}";
5850        }
5851      return "add{l}\t{%2, %k0|%k0, %2}";
5852    }
5853}
5854  [(set (attr "type")
5855     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5856	(const_string "incdec")
5857	(const_string "alu")))
5858   (set_attr "mode" "SI")])
5859
5860; For comparisons against 1, -1 and 128, we may generate better code
5861; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5862; is matched then.  We can't accept general immediate, because for
5863; case of overflows,  the result is messed up.
5864; This pattern also don't hold of 0x80000000, since the value overflows
5865; when negated.
5866; Also carry flag is reversed compared to cmp, so this conversion is valid
5867; only for comparisons not depending on it.
5868(define_insn "*addsi_4"
5869  [(set (reg 17)
5870	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
5871		 (match_operand:SI 2 "const_int_operand" "n")))
5872   (clobber (match_scratch:SI 0 "=rm"))]
5873  "ix86_match_ccmode (insn, CCGCmode)
5874   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5875{
5876  switch (get_attr_type (insn))
5877    {
5878    case TYPE_INCDEC:
5879      if (operands[2] == constm1_rtx)
5880        return "inc{l}\t%0";
5881      else if (operands[2] == const1_rtx)
5882        return "dec{l}\t%0";
5883      else
5884	abort();
5885
5886    default:
5887      if (! rtx_equal_p (operands[0], operands[1]))
5888	abort ();
5889      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5890	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5891      if ((INTVAL (operands[2]) == -128
5892	   || (INTVAL (operands[2]) > 0
5893	       && INTVAL (operands[2]) != 128)))
5894	return "sub{l}\t{%2, %0|%0, %2}";
5895      operands[2] = GEN_INT (-INTVAL (operands[2]));
5896      return "add{l}\t{%2, %0|%0, %2}";
5897    }
5898}
5899  [(set (attr "type")
5900     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901	(const_string "incdec")
5902	(const_string "alu")))
5903   (set_attr "mode" "SI")])
5904
5905(define_insn "*addsi_5"
5906  [(set (reg 17)
5907	(compare
5908	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5909		   (match_operand:SI 2 "general_operand" "rmni"))
5910	  (const_int 0)))			
5911   (clobber (match_scratch:SI 0 "=r"))]
5912  "ix86_match_ccmode (insn, CCGOCmode)
5913   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5914   /* Current assemblers are broken and do not allow @GOTOFF in
5915      ought but a memory context.  */
5916   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5917{
5918  switch (get_attr_type (insn))
5919    {
5920    case TYPE_INCDEC:
5921      if (! rtx_equal_p (operands[0], operands[1]))
5922	abort ();
5923      if (operands[2] == const1_rtx)
5924        return "inc{l}\t%0";
5925      else if (operands[2] == constm1_rtx)
5926        return "dec{l}\t%0";
5927      else
5928	abort();
5929
5930    default:
5931      if (! rtx_equal_p (operands[0], operands[1]))
5932	abort ();
5933      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5935      if (GET_CODE (operands[2]) == CONST_INT
5936          && (INTVAL (operands[2]) == 128
5937	      || (INTVAL (operands[2]) < 0
5938		  && INTVAL (operands[2]) != -128)))
5939        {
5940          operands[2] = GEN_INT (-INTVAL (operands[2]));
5941          return "sub{l}\t{%2, %0|%0, %2}";
5942        }
5943      return "add{l}\t{%2, %0|%0, %2}";
5944    }
5945}
5946  [(set (attr "type")
5947     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948	(const_string "incdec")
5949	(const_string "alu")))
5950   (set_attr "mode" "SI")])
5951
5952(define_expand "addhi3"
5953  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5955			    (match_operand:HI 2 "general_operand" "")))
5956	      (clobber (reg:CC 17))])]
5957  "TARGET_HIMODE_MATH"
5958  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5959
5960;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5961;; type optimizations enabled by define-splits.  This is not important
5962;; for PII, and in fact harmful because of partial register stalls.
5963
5964(define_insn "*addhi_1_lea"
5965  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5966	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5967		 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5968   (clobber (reg:CC 17))]
5969  "!TARGET_PARTIAL_REG_STALL
5970   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5971{
5972  switch (get_attr_type (insn))
5973    {
5974    case TYPE_LEA:
5975      return "#";
5976    case TYPE_INCDEC:
5977      if (operands[2] == const1_rtx)
5978	return "inc{w}\t%0";
5979      else if (operands[2] == constm1_rtx)
5980	return "dec{w}\t%0";
5981      abort();
5982
5983    default:
5984      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5985	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5986      if (GET_CODE (operands[2]) == CONST_INT
5987          && (INTVAL (operands[2]) == 128
5988	      || (INTVAL (operands[2]) < 0
5989		  && INTVAL (operands[2]) != -128)))
5990	{
5991	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5992	  return "sub{w}\t{%2, %0|%0, %2}";
5993	}
5994      return "add{w}\t{%2, %0|%0, %2}";
5995    }
5996}
5997  [(set (attr "type")
5998     (if_then_else (eq_attr "alternative" "2")
5999	(const_string "lea")
6000	(if_then_else (match_operand:HI 2 "incdec_operand" "")
6001	   (const_string "incdec")
6002	   (const_string "alu"))))
6003   (set_attr "mode" "HI,HI,SI")])
6004
6005(define_insn "*addhi_1"
6006  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6007	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6008		 (match_operand:HI 2 "general_operand" "ri,rm")))
6009   (clobber (reg:CC 17))]
6010  "TARGET_PARTIAL_REG_STALL
6011   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6012{
6013  switch (get_attr_type (insn))
6014    {
6015    case TYPE_INCDEC:
6016      if (operands[2] == const1_rtx)
6017	return "inc{w}\t%0";
6018      else if (operands[2] == constm1_rtx)
6019	return "dec{w}\t%0";
6020      abort();
6021
6022    default:
6023      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6025      if (GET_CODE (operands[2]) == CONST_INT
6026          && (INTVAL (operands[2]) == 128
6027	      || (INTVAL (operands[2]) < 0
6028		  && INTVAL (operands[2]) != -128)))
6029	{
6030	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6031	  return "sub{w}\t{%2, %0|%0, %2}";
6032	}
6033      return "add{w}\t{%2, %0|%0, %2}";
6034    }
6035}
6036  [(set (attr "type")
6037     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6038	(const_string "incdec")
6039	(const_string "alu")))
6040   (set_attr "mode" "HI")])
6041
6042(define_insn "*addhi_2"
6043  [(set (reg 17)
6044	(compare
6045	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046		   (match_operand:HI 2 "general_operand" "rmni,rni"))
6047	  (const_int 0)))			
6048   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6049	(plus:HI (match_dup 1) (match_dup 2)))]
6050  "ix86_match_ccmode (insn, CCGOCmode)
6051   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052{
6053  switch (get_attr_type (insn))
6054    {
6055    case TYPE_INCDEC:
6056      if (operands[2] == const1_rtx)
6057	return "inc{w}\t%0";
6058      else if (operands[2] == constm1_rtx)
6059	return "dec{w}\t%0";
6060      abort();
6061
6062    default:
6063      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6065      if (GET_CODE (operands[2]) == CONST_INT
6066          && (INTVAL (operands[2]) == 128
6067	      || (INTVAL (operands[2]) < 0
6068		  && INTVAL (operands[2]) != -128)))
6069	{
6070	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6071	  return "sub{w}\t{%2, %0|%0, %2}";
6072	}
6073      return "add{w}\t{%2, %0|%0, %2}";
6074    }
6075}
6076  [(set (attr "type")
6077     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078	(const_string "incdec")
6079	(const_string "alu")))
6080   (set_attr "mode" "HI")])
6081
6082(define_insn "*addhi_3"
6083  [(set (reg 17)
6084	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6085		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6086   (clobber (match_scratch:HI 0 "=r"))]
6087  "ix86_match_ccmode (insn, CCZmode)
6088   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089{
6090  switch (get_attr_type (insn))
6091    {
6092    case TYPE_INCDEC:
6093      if (operands[2] == const1_rtx)
6094	return "inc{w}\t%0";
6095      else if (operands[2] == constm1_rtx)
6096	return "dec{w}\t%0";
6097      abort();
6098
6099    default:
6100      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102      if (GET_CODE (operands[2]) == CONST_INT
6103          && (INTVAL (operands[2]) == 128
6104	      || (INTVAL (operands[2]) < 0
6105		  && INTVAL (operands[2]) != -128)))
6106	{
6107	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6108	  return "sub{w}\t{%2, %0|%0, %2}";
6109	}
6110      return "add{w}\t{%2, %0|%0, %2}";
6111    }
6112}
6113  [(set (attr "type")
6114     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6115	(const_string "incdec")
6116	(const_string "alu")))
6117   (set_attr "mode" "HI")])
6118
6119; See comments above addsi_3_imm for details.
6120(define_insn "*addhi_4"
6121  [(set (reg 17)
6122	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
6123		 (match_operand:HI 2 "const_int_operand" "n")))
6124   (clobber (match_scratch:HI 0 "=rm"))]
6125  "ix86_match_ccmode (insn, CCGCmode)
6126   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6127{
6128  switch (get_attr_type (insn))
6129    {
6130    case TYPE_INCDEC:
6131      if (operands[2] == constm1_rtx)
6132        return "inc{w}\t%0";
6133      else if (operands[2] == const1_rtx)
6134        return "dec{w}\t%0";
6135      else
6136	abort();
6137
6138    default:
6139      if (! rtx_equal_p (operands[0], operands[1]))
6140	abort ();
6141      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6143      if ((INTVAL (operands[2]) == -128
6144	   || (INTVAL (operands[2]) > 0
6145	       && INTVAL (operands[2]) != 128)))
6146	return "sub{w}\t{%2, %0|%0, %2}";
6147      operands[2] = GEN_INT (-INTVAL (operands[2]));
6148      return "add{w}\t{%2, %0|%0, %2}";
6149    }
6150}
6151  [(set (attr "type")
6152     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153	(const_string "incdec")
6154	(const_string "alu")))
6155   (set_attr "mode" "SI")])
6156
6157
6158(define_insn "*addhi_5"
6159  [(set (reg 17)
6160	(compare
6161	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6162		   (match_operand:HI 2 "general_operand" "rmni"))
6163	  (const_int 0)))			
6164   (clobber (match_scratch:HI 0 "=r"))]
6165  "ix86_match_ccmode (insn, CCGOCmode)
6166   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6167{
6168  switch (get_attr_type (insn))
6169    {
6170    case TYPE_INCDEC:
6171      if (operands[2] == const1_rtx)
6172	return "inc{w}\t%0";
6173      else if (operands[2] == constm1_rtx)
6174	return "dec{w}\t%0";
6175      abort();
6176
6177    default:
6178      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6179	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6180      if (GET_CODE (operands[2]) == CONST_INT
6181          && (INTVAL (operands[2]) == 128
6182	      || (INTVAL (operands[2]) < 0
6183		  && INTVAL (operands[2]) != -128)))
6184	{
6185	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6186	  return "sub{w}\t{%2, %0|%0, %2}";
6187	}
6188      return "add{w}\t{%2, %0|%0, %2}";
6189    }
6190}
6191  [(set (attr "type")
6192     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193	(const_string "incdec")
6194	(const_string "alu")))
6195   (set_attr "mode" "HI")])
6196
6197(define_expand "addqi3"
6198  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6199		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6200			    (match_operand:QI 2 "general_operand" "")))
6201	      (clobber (reg:CC 17))])]
6202  "TARGET_QIMODE_MATH"
6203  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6204
6205;; %%% Potential partial reg stall on alternative 2.  What to do?
6206(define_insn "*addqi_1_lea"
6207  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6208	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6209		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6210   (clobber (reg:CC 17))]
6211  "!TARGET_PARTIAL_REG_STALL
6212   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6213{
6214  int widen = (which_alternative == 2);
6215  switch (get_attr_type (insn))
6216    {
6217    case TYPE_LEA:
6218      return "#";
6219    case TYPE_INCDEC:
6220      if (operands[2] == const1_rtx)
6221	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222      else if (operands[2] == constm1_rtx)
6223	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6224      abort();
6225
6226    default:
6227      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6229      if (GET_CODE (operands[2]) == CONST_INT
6230          && (INTVAL (operands[2]) == 128
6231	      || (INTVAL (operands[2]) < 0
6232		  && INTVAL (operands[2]) != -128)))
6233	{
6234	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6235	  if (widen)
6236	    return "sub{l}\t{%2, %k0|%k0, %2}";
6237	  else
6238	    return "sub{b}\t{%2, %0|%0, %2}";
6239	}
6240      if (widen)
6241        return "add{l}\t{%k2, %k0|%k0, %k2}";
6242      else
6243        return "add{b}\t{%2, %0|%0, %2}";
6244    }
6245}
6246  [(set (attr "type")
6247     (if_then_else (eq_attr "alternative" "3")
6248	(const_string "lea")
6249	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6250	   (const_string "incdec")
6251	   (const_string "alu"))))
6252   (set_attr "mode" "QI,QI,SI,SI")])
6253
6254(define_insn "*addqi_1"
6255  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6256	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6257		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6258   (clobber (reg:CC 17))]
6259  "TARGET_PARTIAL_REG_STALL
6260   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261{
6262  int widen = (which_alternative == 2);
6263  switch (get_attr_type (insn))
6264    {
6265    case TYPE_INCDEC:
6266      if (operands[2] == const1_rtx)
6267	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268      else if (operands[2] == constm1_rtx)
6269	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6270      abort();
6271
6272    default:
6273      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6274	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6275      if (GET_CODE (operands[2]) == CONST_INT
6276          && (INTVAL (operands[2]) == 128
6277	      || (INTVAL (operands[2]) < 0
6278		  && INTVAL (operands[2]) != -128)))
6279	{
6280	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6281	  if (widen)
6282	    return "sub{l}\t{%2, %k0|%k0, %2}";
6283	  else
6284	    return "sub{b}\t{%2, %0|%0, %2}";
6285	}
6286      if (widen)
6287        return "add{l}\t{%k2, %k0|%k0, %k2}";
6288      else
6289        return "add{b}\t{%2, %0|%0, %2}";
6290    }
6291}
6292  [(set (attr "type")
6293     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294	(const_string "incdec")
6295	(const_string "alu")))
6296   (set_attr "mode" "QI,QI,SI")])
6297
6298(define_insn "*addqi_1_slp"
6299  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6300	(plus:QI (match_dup 0)
6301		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6302   (clobber (reg:CC 17))]
6303  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6304   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6305{
6306  switch (get_attr_type (insn))
6307    {
6308    case TYPE_INCDEC:
6309      if (operands[1] == const1_rtx)
6310	return "inc{b}\t%0";
6311      else if (operands[1] == constm1_rtx)
6312	return "dec{b}\t%0";
6313      abort();
6314
6315    default:
6316      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6317      if (GET_CODE (operands[1]) == CONST_INT
6318	  && INTVAL (operands[1]) < 0)
6319	{
6320	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6321	  return "sub{b}\t{%1, %0|%0, %1}";
6322	}
6323      return "add{b}\t{%1, %0|%0, %1}";
6324    }
6325}
6326  [(set (attr "type")
6327     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6328	(const_string "incdec")
6329	(const_string "alu1")))
6330   (set (attr "memory")
6331     (if_then_else (match_operand 1 "memory_operand" "")
6332        (const_string "load")
6333        (const_string "none")))
6334   (set_attr "mode" "QI")])
6335
6336(define_insn "*addqi_2"
6337  [(set (reg 17)
6338	(compare
6339	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6340		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6341	  (const_int 0)))
6342   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6343	(plus:QI (match_dup 1) (match_dup 2)))]
6344  "ix86_match_ccmode (insn, CCGOCmode)
6345   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6346{
6347  switch (get_attr_type (insn))
6348    {
6349    case TYPE_INCDEC:
6350      if (operands[2] == const1_rtx)
6351	return "inc{b}\t%0";
6352      else if (operands[2] == constm1_rtx
6353	       || (GET_CODE (operands[2]) == CONST_INT
6354		   && INTVAL (operands[2]) == 255))
6355	return "dec{b}\t%0";
6356      abort();
6357
6358    default:
6359      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6360      if (GET_CODE (operands[2]) == CONST_INT
6361          && INTVAL (operands[2]) < 0)
6362	{
6363	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6364	  return "sub{b}\t{%2, %0|%0, %2}";
6365	}
6366      return "add{b}\t{%2, %0|%0, %2}";
6367    }
6368}
6369  [(set (attr "type")
6370     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371	(const_string "incdec")
6372	(const_string "alu")))
6373   (set_attr "mode" "QI")])
6374
6375(define_insn "*addqi_3"
6376  [(set (reg 17)
6377	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6378		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6379   (clobber (match_scratch:QI 0 "=q"))]
6380  "ix86_match_ccmode (insn, CCZmode)
6381   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6382{
6383  switch (get_attr_type (insn))
6384    {
6385    case TYPE_INCDEC:
6386      if (operands[2] == const1_rtx)
6387	return "inc{b}\t%0";
6388      else if (operands[2] == constm1_rtx
6389	       || (GET_CODE (operands[2]) == CONST_INT
6390		   && INTVAL (operands[2]) == 255))
6391	return "dec{b}\t%0";
6392      abort();
6393
6394    default:
6395      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6396      if (GET_CODE (operands[2]) == CONST_INT
6397          && INTVAL (operands[2]) < 0)
6398	{
6399	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6400	  return "sub{b}\t{%2, %0|%0, %2}";
6401	}
6402      return "add{b}\t{%2, %0|%0, %2}";
6403    }
6404}
6405  [(set (attr "type")
6406     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407	(const_string "incdec")
6408	(const_string "alu")))
6409   (set_attr "mode" "QI")])
6410
6411; See comments above addsi_3_imm for details.
6412(define_insn "*addqi_4"
6413  [(set (reg 17)
6414	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6415		 (match_operand:QI 2 "const_int_operand" "n")))
6416   (clobber (match_scratch:QI 0 "=qm"))]
6417  "ix86_match_ccmode (insn, CCGCmode)
6418   && (INTVAL (operands[2]) & 0xff) != 0x80"
6419{
6420  switch (get_attr_type (insn))
6421    {
6422    case TYPE_INCDEC:
6423      if (operands[2] == constm1_rtx
6424	  || (GET_CODE (operands[2]) == CONST_INT
6425	      && INTVAL (operands[2]) == 255))
6426        return "inc{b}\t%0";
6427      else if (operands[2] == const1_rtx)
6428        return "dec{b}\t%0";
6429      else
6430	abort();
6431
6432    default:
6433      if (! rtx_equal_p (operands[0], operands[1]))
6434	abort ();
6435      if (INTVAL (operands[2]) < 0)
6436        {
6437          operands[2] = GEN_INT (-INTVAL (operands[2]));
6438          return "add{b}\t{%2, %0|%0, %2}";
6439        }
6440      return "sub{b}\t{%2, %0|%0, %2}";
6441    }
6442}
6443  [(set (attr "type")
6444     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6445	(const_string "incdec")
6446	(const_string "alu")))
6447   (set_attr "mode" "QI")])
6448
6449
6450(define_insn "*addqi_5"
6451  [(set (reg 17)
6452	(compare
6453	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6454		   (match_operand:QI 2 "general_operand" "qmni"))
6455	  (const_int 0)))
6456   (clobber (match_scratch:QI 0 "=q"))]
6457  "ix86_match_ccmode (insn, CCGOCmode)
6458   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6459{
6460  switch (get_attr_type (insn))
6461    {
6462    case TYPE_INCDEC:
6463      if (operands[2] == const1_rtx)
6464	return "inc{b}\t%0";
6465      else if (operands[2] == constm1_rtx
6466	       || (GET_CODE (operands[2]) == CONST_INT
6467		   && INTVAL (operands[2]) == 255))
6468	return "dec{b}\t%0";
6469      abort();
6470
6471    default:
6472      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6473      if (GET_CODE (operands[2]) == CONST_INT
6474          && INTVAL (operands[2]) < 0)
6475	{
6476	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6477	  return "sub{b}\t{%2, %0|%0, %2}";
6478	}
6479      return "add{b}\t{%2, %0|%0, %2}";
6480    }
6481}
6482  [(set (attr "type")
6483     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6484	(const_string "incdec")
6485	(const_string "alu")))
6486   (set_attr "mode" "QI")])
6487
6488
6489(define_insn "addqi_ext_1"
6490  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6491			 (const_int 8)
6492			 (const_int 8))
6493	(plus:SI
6494	  (zero_extract:SI
6495	    (match_operand 1 "ext_register_operand" "0")
6496	    (const_int 8)
6497	    (const_int 8))
6498	  (match_operand:QI 2 "general_operand" "Qmn")))
6499   (clobber (reg:CC 17))]
6500  "!TARGET_64BIT"
6501{
6502  switch (get_attr_type (insn))
6503    {
6504    case TYPE_INCDEC:
6505      if (operands[2] == const1_rtx)
6506	return "inc{b}\t%h0";
6507      else if (operands[2] == constm1_rtx
6508	       || (GET_CODE (operands[2]) == CONST_INT
6509		   && INTVAL (operands[2]) == 255))
6510	return "dec{b}\t%h0";
6511      abort();
6512
6513    default:
6514      return "add{b}\t{%2, %h0|%h0, %2}";
6515    }
6516}
6517  [(set (attr "type")
6518     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6519	(const_string "incdec")
6520	(const_string "alu")))
6521   (set_attr "mode" "QI")])
6522
6523(define_insn "*addqi_ext_1_rex64"
6524  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6525			 (const_int 8)
6526			 (const_int 8))
6527	(plus:SI
6528	  (zero_extract:SI
6529	    (match_operand 1 "ext_register_operand" "0")
6530	    (const_int 8)
6531	    (const_int 8))
6532	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6533   (clobber (reg:CC 17))]
6534  "TARGET_64BIT"
6535{
6536  switch (get_attr_type (insn))
6537    {
6538    case TYPE_INCDEC:
6539      if (operands[2] == const1_rtx)
6540	return "inc{b}\t%h0";
6541      else if (operands[2] == constm1_rtx
6542	       || (GET_CODE (operands[2]) == CONST_INT
6543		   && INTVAL (operands[2]) == 255))
6544	return "dec{b}\t%h0";
6545      abort();
6546
6547    default:
6548      return "add{b}\t{%2, %h0|%h0, %2}";
6549    }
6550}
6551  [(set (attr "type")
6552     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6553	(const_string "incdec")
6554	(const_string "alu")))
6555   (set_attr "mode" "QI")])
6556
6557(define_insn "*addqi_ext_2"
6558  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6559			 (const_int 8)
6560			 (const_int 8))
6561	(plus:SI
6562	  (zero_extract:SI
6563	    (match_operand 1 "ext_register_operand" "%0")
6564	    (const_int 8)
6565	    (const_int 8))
6566	  (zero_extract:SI
6567	    (match_operand 2 "ext_register_operand" "Q")
6568	    (const_int 8)
6569	    (const_int 8))))
6570   (clobber (reg:CC 17))]
6571  ""
6572  "add{b}\t{%h2, %h0|%h0, %h2}"
6573  [(set_attr "type" "alu")
6574   (set_attr "mode" "QI")])
6575
6576;; The patterns that match these are at the end of this file.
6577
6578(define_expand "addxf3"
6579  [(set (match_operand:XF 0 "register_operand" "")
6580	(plus:XF (match_operand:XF 1 "register_operand" "")
6581		 (match_operand:XF 2 "register_operand" "")))]
6582  "TARGET_80387"
6583  "")
6584
6585(define_expand "adddf3"
6586  [(set (match_operand:DF 0 "register_operand" "")
6587	(plus:DF (match_operand:DF 1 "register_operand" "")
6588		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6589  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6590  "")
6591
6592(define_expand "addsf3"
6593  [(set (match_operand:SF 0 "register_operand" "")
6594	(plus:SF (match_operand:SF 1 "register_operand" "")
6595		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6596  "TARGET_80387 || TARGET_SSE_MATH"
6597  "")
6598
6599;; Subtract instructions
6600
6601;; %%% splits for subsidi3
6602
6603(define_expand "subdi3"
6604  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6605		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6606			     (match_operand:DI 2 "x86_64_general_operand" "")))
6607	      (clobber (reg:CC 17))])]
6608  ""
6609  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6610
6611(define_insn "*subdi3_1"
6612  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6613	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6614		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6615   (clobber (reg:CC 17))]
6616  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6617  "#")
6618
6619(define_split
6620  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6621	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6622		  (match_operand:DI 2 "general_operand" "")))
6623   (clobber (reg:CC 17))]
6624  "!TARGET_64BIT && reload_completed"
6625  [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6626	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6627   (parallel [(set (match_dup 3)
6628		   (minus:SI (match_dup 4)
6629			     (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6630				      (match_dup 5))))
6631	      (clobber (reg:CC 17))])]
6632  "split_di (operands+0, 1, operands+0, operands+3);
6633   split_di (operands+1, 1, operands+1, operands+4);
6634   split_di (operands+2, 1, operands+2, operands+5);")
6635
6636(define_insn "subdi3_carry_rex64"
6637  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6638	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6639	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6640	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6641   (clobber (reg:CC 17))]
6642  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6643  "sbb{q}\t{%2, %0|%0, %2}"
6644  [(set_attr "type" "alu")
6645   (set_attr "pent_pair" "pu")
6646   (set_attr "ppro_uops" "few")
6647   (set_attr "mode" "DI")])
6648
6649(define_insn "*subdi_1_rex64"
6650  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6651	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6652		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6653   (clobber (reg:CC 17))]
6654  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6655  "sub{q}\t{%2, %0|%0, %2}"
6656  [(set_attr "type" "alu")
6657   (set_attr "mode" "DI")])
6658
6659(define_insn "*subdi_2_rex64"
6660  [(set (reg 17)
6661	(compare
6662	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6663		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6664	  (const_int 0)))
6665   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6666	(minus:DI (match_dup 1) (match_dup 2)))]
6667  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6668   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6669  "sub{q}\t{%2, %0|%0, %2}"
6670  [(set_attr "type" "alu")
6671   (set_attr "mode" "DI")])
6672
6673(define_insn "*subdi_3_rex63"
6674  [(set (reg 17)
6675	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6676		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6677   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6678	(minus:DI (match_dup 1) (match_dup 2)))]
6679  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6680   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6681  "sub{q}\t{%2, %0|%0, %2}"
6682  [(set_attr "type" "alu")
6683   (set_attr "mode" "DI")])
6684
6685(define_insn "subqi3_carry"
6686  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6687	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6688	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6689	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6690   (clobber (reg:CC 17))]
6691  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6692  "sbb{b}\t{%2, %0|%0, %2}"
6693  [(set_attr "type" "alu")
6694   (set_attr "pent_pair" "pu")
6695   (set_attr "ppro_uops" "few")
6696   (set_attr "mode" "QI")])
6697
6698(define_insn "subhi3_carry"
6699  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6700	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6701	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6702	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6703   (clobber (reg:CC 17))]
6704  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6705  "sbb{w}\t{%2, %0|%0, %2}"
6706  [(set_attr "type" "alu")
6707   (set_attr "pent_pair" "pu")
6708   (set_attr "ppro_uops" "few")
6709   (set_attr "mode" "HI")])
6710
6711(define_insn "subsi3_carry"
6712  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6715	       (match_operand:SI 2 "general_operand" "ri,rm"))))
6716   (clobber (reg:CC 17))]
6717  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6718  "sbb{l}\t{%2, %0|%0, %2}"
6719  [(set_attr "type" "alu")
6720   (set_attr "pent_pair" "pu")
6721   (set_attr "ppro_uops" "few")
6722   (set_attr "mode" "SI")])
6723
6724(define_insn "subsi3_carry_zext"
6725  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6726	  (zero_extend:DI
6727	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6728	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6729		 (match_operand:SI 2 "general_operand" "ri,rm")))))
6730   (clobber (reg:CC 17))]
6731  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732  "sbb{l}\t{%2, %k0|%k0, %2}"
6733  [(set_attr "type" "alu")
6734   (set_attr "pent_pair" "pu")
6735   (set_attr "ppro_uops" "few")
6736   (set_attr "mode" "SI")])
6737
6738(define_expand "subsi3"
6739  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6740		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6741			     (match_operand:SI 2 "general_operand" "")))
6742	      (clobber (reg:CC 17))])]
6743  ""
6744  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6745
6746(define_insn "*subsi_1"
6747  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6749		  (match_operand:SI 2 "general_operand" "ri,rm")))
6750   (clobber (reg:CC 17))]
6751  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6752  "sub{l}\t{%2, %0|%0, %2}"
6753  [(set_attr "type" "alu")
6754   (set_attr "mode" "SI")])
6755
6756(define_insn "*subsi_1_zext"
6757  [(set (match_operand:DI 0 "register_operand" "=r")
6758	(zero_extend:DI
6759	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6760		    (match_operand:SI 2 "general_operand" "rim"))))
6761   (clobber (reg:CC 17))]
6762  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763  "sub{l}\t{%2, %k0|%k0, %2}"
6764  [(set_attr "type" "alu")
6765   (set_attr "mode" "SI")])
6766
6767(define_insn "*subsi_2"
6768  [(set (reg 17)
6769	(compare
6770	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6771		    (match_operand:SI 2 "general_operand" "ri,rm"))
6772	  (const_int 0)))
6773   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6774	(minus:SI (match_dup 1) (match_dup 2)))]
6775  "ix86_match_ccmode (insn, CCGOCmode)
6776   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777  "sub{l}\t{%2, %0|%0, %2}"
6778  [(set_attr "type" "alu")
6779   (set_attr "mode" "SI")])
6780
6781(define_insn "*subsi_2_zext"
6782  [(set (reg 17)
6783	(compare
6784	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6785		    (match_operand:SI 2 "general_operand" "rim"))
6786	  (const_int 0)))
6787   (set (match_operand:DI 0 "register_operand" "=r")
6788	(zero_extend:DI
6789	  (minus:SI (match_dup 1)
6790		    (match_dup 2))))]
6791  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6792   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793  "sub{l}\t{%2, %k0|%k0, %2}"
6794  [(set_attr "type" "alu")
6795   (set_attr "mode" "SI")])
6796
6797(define_insn "*subsi_3"
6798  [(set (reg 17)
6799	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800		 (match_operand:SI 2 "general_operand" "ri,rm")))
6801   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6802	(minus:SI (match_dup 1) (match_dup 2)))]
6803  "ix86_match_ccmode (insn, CCmode)
6804   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805  "sub{l}\t{%2, %0|%0, %2}"
6806  [(set_attr "type" "alu")
6807   (set_attr "mode" "SI")])
6808
6809(define_insn "*subsi_3_zext"
6810  [(set (reg 17)
6811	(compare (match_operand:SI 1 "register_operand" "0")
6812		 (match_operand:SI 2 "general_operand" "rim")))
6813   (set (match_operand:DI 0 "register_operand" "=r")
6814	(zero_extend:DI
6815	  (minus:SI (match_dup 1)
6816		    (match_dup 2))))]
6817  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6818   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6819  "sub{q}\t{%2, %0|%0, %2}"
6820  [(set_attr "type" "alu")
6821   (set_attr "mode" "DI")])
6822
6823(define_expand "subhi3"
6824  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6825		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6826			     (match_operand:HI 2 "general_operand" "")))
6827	      (clobber (reg:CC 17))])]
6828  "TARGET_HIMODE_MATH"
6829  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6830
6831(define_insn "*subhi_1"
6832  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6834		  (match_operand:HI 2 "general_operand" "ri,rm")))
6835   (clobber (reg:CC 17))]
6836  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6837  "sub{w}\t{%2, %0|%0, %2}"
6838  [(set_attr "type" "alu")
6839   (set_attr "mode" "HI")])
6840
6841(define_insn "*subhi_2"
6842  [(set (reg 17)
6843	(compare
6844	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6845		    (match_operand:HI 2 "general_operand" "ri,rm"))
6846	  (const_int 0)))
6847   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6848	(minus:HI (match_dup 1) (match_dup 2)))]
6849  "ix86_match_ccmode (insn, CCGOCmode)
6850   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6851  "sub{w}\t{%2, %0|%0, %2}"
6852  [(set_attr "type" "alu")
6853   (set_attr "mode" "HI")])
6854
6855(define_insn "*subhi_3"
6856  [(set (reg 17)
6857	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6858		 (match_operand:HI 2 "general_operand" "ri,rm")))
6859   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6860	(minus:HI (match_dup 1) (match_dup 2)))]
6861  "ix86_match_ccmode (insn, CCmode)
6862   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6863  "sub{w}\t{%2, %0|%0, %2}"
6864  [(set_attr "type" "alu")
6865   (set_attr "mode" "HI")])
6866
6867(define_expand "subqi3"
6868  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6869		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6870			     (match_operand:QI 2 "general_operand" "")))
6871	      (clobber (reg:CC 17))])]
6872  "TARGET_QIMODE_MATH"
6873  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6874
6875(define_insn "*subqi_1"
6876  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6877	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878		  (match_operand:QI 2 "general_operand" "qn,qmn")))
6879   (clobber (reg:CC 17))]
6880  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6881  "sub{b}\t{%2, %0|%0, %2}"
6882  [(set_attr "type" "alu")
6883   (set_attr "mode" "QI")])
6884
6885(define_insn "*subqi_1_slp"
6886  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6887	(minus:QI (match_dup 0)
6888		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6889   (clobber (reg:CC 17))]
6890  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6891   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6892  "sub{b}\t{%1, %0|%0, %1}"
6893  [(set_attr "type" "alu1")
6894   (set_attr "mode" "QI")])
6895
6896(define_insn "*subqi_2"
6897  [(set (reg 17)
6898	(compare
6899	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6900		    (match_operand:QI 2 "general_operand" "qi,qm"))
6901	  (const_int 0)))
6902   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6903	(minus:HI (match_dup 1) (match_dup 2)))]
6904  "ix86_match_ccmode (insn, CCGOCmode)
6905   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6906  "sub{b}\t{%2, %0|%0, %2}"
6907  [(set_attr "type" "alu")
6908   (set_attr "mode" "QI")])
6909
6910(define_insn "*subqi_3"
6911  [(set (reg 17)
6912	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6913		 (match_operand:QI 2 "general_operand" "qi,qm")))
6914   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6915	(minus:HI (match_dup 1) (match_dup 2)))]
6916  "ix86_match_ccmode (insn, CCmode)
6917   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6918  "sub{b}\t{%2, %0|%0, %2}"
6919  [(set_attr "type" "alu")
6920   (set_attr "mode" "QI")])
6921
6922;; The patterns that match these are at the end of this file.
6923
6924(define_expand "subxf3"
6925  [(set (match_operand:XF 0 "register_operand" "")
6926	(minus:XF (match_operand:XF 1 "register_operand" "")
6927		  (match_operand:XF 2 "register_operand" "")))]
6928  "TARGET_80387"
6929  "")
6930
6931(define_expand "subdf3"
6932  [(set (match_operand:DF 0 "register_operand" "")
6933	(minus:DF (match_operand:DF 1 "register_operand" "")
6934		  (match_operand:DF 2 "nonimmediate_operand" "")))]
6935  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6936  "")
6937
6938(define_expand "subsf3"
6939  [(set (match_operand:SF 0 "register_operand" "")
6940	(minus:SF (match_operand:SF 1 "register_operand" "")
6941		  (match_operand:SF 2 "nonimmediate_operand" "")))]
6942  "TARGET_80387 || TARGET_SSE_MATH"
6943  "")
6944
6945;; Multiply instructions
6946
6947(define_expand "muldi3"
6948  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949		   (mult:DI (match_operand:DI 1 "register_operand" "")
6950			    (match_operand:DI 2 "x86_64_general_operand" "")))
6951	      (clobber (reg:CC 17))])]
6952  "TARGET_64BIT"
6953  "")
6954
6955(define_insn "*muldi3_1_rex64"
6956  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959   (clobber (reg:CC 17))]
6960  "TARGET_64BIT
6961   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6962  "@
6963   imul{q}\t{%2, %1, %0|%0, %1, %2}
6964   imul{q}\t{%2, %1, %0|%0, %1, %2}
6965   imul{q}\t{%2, %0|%0, %2}"
6966  [(set_attr "type" "imul")
6967   (set_attr "prefix_0f" "0,0,1")
6968   (set (attr "athlon_decode")
6969	(cond [(eq_attr "cpu" "athlon")
6970		  (const_string "vector")
6971	       (eq_attr "alternative" "1")
6972		  (const_string "vector")
6973	       (and (eq_attr "alternative" "2")
6974		    (match_operand 1 "memory_operand" ""))
6975		  (const_string "vector")]
6976	      (const_string "direct")))
6977   (set_attr "mode" "DI")])
6978
6979(define_expand "mulsi3"
6980  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6981		   (mult:SI (match_operand:SI 1 "register_operand" "")
6982			    (match_operand:SI 2 "general_operand" "")))
6983	      (clobber (reg:CC 17))])]
6984  ""
6985  "")
6986
6987(define_insn "*mulsi3_1"
6988  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6989	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6990		 (match_operand:SI 2 "general_operand" "K,i,mr")))
6991   (clobber (reg:CC 17))]
6992  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6993  "@
6994   imul{l}\t{%2, %1, %0|%0, %1, %2}
6995   imul{l}\t{%2, %1, %0|%0, %1, %2}
6996   imul{l}\t{%2, %0|%0, %2}"
6997  [(set_attr "type" "imul")
6998   (set_attr "prefix_0f" "0,0,1")
6999   (set (attr "athlon_decode")
7000	(cond [(eq_attr "cpu" "athlon")
7001		  (const_string "vector")
7002	       (eq_attr "alternative" "1")
7003		  (const_string "vector")
7004	       (and (eq_attr "alternative" "2")
7005		    (match_operand 1 "memory_operand" ""))
7006		  (const_string "vector")]
7007	      (const_string "direct")))
7008   (set_attr "mode" "SI")])
7009
7010(define_insn "*mulsi3_1_zext"
7011  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7012	(zero_extend:DI
7013	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7014		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
7015   (clobber (reg:CC 17))]
7016  "TARGET_64BIT
7017   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018  "@
7019   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7020   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7021   imul{l}\t{%2, %k0|%k0, %2}"
7022  [(set_attr "type" "imul")
7023   (set_attr "prefix_0f" "0,0,1")
7024   (set (attr "athlon_decode")
7025	(cond [(eq_attr "cpu" "athlon")
7026		  (const_string "vector")
7027	       (eq_attr "alternative" "1")
7028		  (const_string "vector")
7029	       (and (eq_attr "alternative" "2")
7030		    (match_operand 1 "memory_operand" ""))
7031		  (const_string "vector")]
7032	      (const_string "direct")))
7033   (set_attr "mode" "SI")])
7034
7035(define_expand "mulhi3"
7036  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7037		   (mult:HI (match_operand:HI 1 "register_operand" "")
7038			    (match_operand:HI 2 "general_operand" "")))
7039	      (clobber (reg:CC 17))])]
7040  "TARGET_HIMODE_MATH"
7041  "")
7042
7043(define_insn "*mulhi3_1"
7044  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7045	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7046		 (match_operand:HI 2 "general_operand" "K,i,mr")))
7047   (clobber (reg:CC 17))]
7048  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7049  "@
7050   imul{w}\t{%2, %1, %0|%0, %1, %2}
7051   imul{w}\t{%2, %1, %0|%0, %1, %2}
7052   imul{w}\t{%2, %0|%0, %2}"
7053  [(set_attr "type" "imul")
7054   (set_attr "prefix_0f" "0,0,1")
7055   (set (attr "athlon_decode")
7056	(cond [(eq_attr "cpu" "athlon")
7057		  (const_string "vector")
7058	       (eq_attr "alternative" "1,2")
7059		  (const_string "vector")]
7060	      (const_string "direct")))
7061   (set_attr "mode" "HI")])
7062
7063(define_expand "mulqi3"
7064  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7065		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7066			    (match_operand:QI 2 "register_operand" "")))
7067	      (clobber (reg:CC 17))])]
7068  "TARGET_QIMODE_MATH"
7069  "")
7070
7071(define_insn "*mulqi3_1"
7072  [(set (match_operand:QI 0 "register_operand" "=a")
7073	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7074		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7075   (clobber (reg:CC 17))]
7076  "TARGET_QIMODE_MATH
7077   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7078  "mul{b}\t%2"
7079  [(set_attr "type" "imul")
7080   (set_attr "length_immediate" "0")
7081   (set (attr "athlon_decode")
7082     (if_then_else (eq_attr "cpu" "athlon")
7083        (const_string "vector")
7084        (const_string "direct")))
7085   (set_attr "mode" "QI")])
7086
7087(define_expand "umulqihi3"
7088  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089		   (mult:HI (zero_extend:HI
7090			      (match_operand:QI 1 "nonimmediate_operand" ""))
7091			    (zero_extend:HI
7092			      (match_operand:QI 2 "register_operand" ""))))
7093	      (clobber (reg:CC 17))])]
7094  "TARGET_QIMODE_MATH"
7095  "")
7096
7097(define_insn "*umulqihi3_1"
7098  [(set (match_operand:HI 0 "register_operand" "=a")
7099	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7100		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7101   (clobber (reg:CC 17))]
7102  "TARGET_QIMODE_MATH
7103   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104  "mul{b}\t%2"
7105  [(set_attr "type" "imul")
7106   (set_attr "length_immediate" "0")
7107   (set (attr "athlon_decode")
7108     (if_then_else (eq_attr "cpu" "athlon")
7109        (const_string "vector")
7110        (const_string "direct")))
7111   (set_attr "mode" "QI")])
7112
7113(define_expand "mulqihi3"
7114  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7115		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7116			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7117	      (clobber (reg:CC 17))])]
7118  "TARGET_QIMODE_MATH"
7119  "")
7120
7121(define_insn "*mulqihi3_insn"
7122  [(set (match_operand:HI 0 "register_operand" "=a")
7123	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7124		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7125   (clobber (reg:CC 17))]
7126  "TARGET_QIMODE_MATH
7127   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7128  "imul{b}\t%2"
7129  [(set_attr "type" "imul")
7130   (set_attr "length_immediate" "0")
7131   (set (attr "athlon_decode")
7132     (if_then_else (eq_attr "cpu" "athlon")
7133        (const_string "vector")
7134        (const_string "direct")))
7135   (set_attr "mode" "QI")])
7136
7137(define_expand "umulditi3"
7138  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7139		   (mult:TI (zero_extend:TI
7140			      (match_operand:DI 1 "nonimmediate_operand" ""))
7141			    (zero_extend:TI
7142			      (match_operand:DI 2 "register_operand" ""))))
7143	      (clobber (reg:CC 17))])]
7144  "TARGET_64BIT"
7145  "")
7146
7147(define_insn "*umulditi3_insn"
7148  [(set (match_operand:TI 0 "register_operand" "=A")
7149	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7150		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7151   (clobber (reg:CC 17))]
7152  "TARGET_64BIT
7153   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154  "mul{q}\t%2"
7155  [(set_attr "type" "imul")
7156   (set_attr "ppro_uops" "few")
7157   (set_attr "length_immediate" "0")
7158   (set (attr "athlon_decode")
7159     (if_then_else (eq_attr "cpu" "athlon")
7160        (const_string "vector")
7161        (const_string "double")))
7162   (set_attr "mode" "DI")])
7163
7164;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7165(define_expand "umulsidi3"
7166  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7167		   (mult:DI (zero_extend:DI
7168			      (match_operand:SI 1 "nonimmediate_operand" ""))
7169			    (zero_extend:DI
7170			      (match_operand:SI 2 "register_operand" ""))))
7171	      (clobber (reg:CC 17))])]
7172  "!TARGET_64BIT"
7173  "")
7174
7175(define_insn "*umulsidi3_insn"
7176  [(set (match_operand:DI 0 "register_operand" "=A")
7177	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7178		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7179   (clobber (reg:CC 17))]
7180  "!TARGET_64BIT
7181   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7182  "mul{l}\t%2"
7183  [(set_attr "type" "imul")
7184   (set_attr "ppro_uops" "few")
7185   (set_attr "length_immediate" "0")
7186   (set (attr "athlon_decode")
7187     (if_then_else (eq_attr "cpu" "athlon")
7188        (const_string "vector")
7189        (const_string "double")))
7190   (set_attr "mode" "SI")])
7191
7192(define_expand "mulditi3"
7193  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7194		   (mult:TI (sign_extend:TI
7195			      (match_operand:DI 1 "nonimmediate_operand" ""))
7196			    (sign_extend:TI
7197			      (match_operand:DI 2 "register_operand" ""))))
7198	      (clobber (reg:CC 17))])]
7199  "TARGET_64BIT"
7200  "")
7201
7202(define_insn "*mulditi3_insn"
7203  [(set (match_operand:TI 0 "register_operand" "=A")
7204	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7205		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7206   (clobber (reg:CC 17))]
7207  "TARGET_64BIT
7208   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7209  "imul{q}\t%2"
7210  [(set_attr "type" "imul")
7211   (set_attr "length_immediate" "0")
7212   (set (attr "athlon_decode")
7213     (if_then_else (eq_attr "cpu" "athlon")
7214        (const_string "vector")
7215        (const_string "double")))
7216   (set_attr "mode" "DI")])
7217
7218(define_expand "mulsidi3"
7219  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7220		   (mult:DI (sign_extend:DI
7221			      (match_operand:SI 1 "nonimmediate_operand" ""))
7222			    (sign_extend:DI
7223			      (match_operand:SI 2 "register_operand" ""))))
7224	      (clobber (reg:CC 17))])]
7225  "!TARGET_64BIT"
7226  "")
7227
7228(define_insn "*mulsidi3_insn"
7229  [(set (match_operand:DI 0 "register_operand" "=A")
7230	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7231		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7232   (clobber (reg:CC 17))]
7233  "!TARGET_64BIT
7234   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235  "imul{l}\t%2"
7236  [(set_attr "type" "imul")
7237   (set_attr "length_immediate" "0")
7238   (set (attr "athlon_decode")
7239     (if_then_else (eq_attr "cpu" "athlon")
7240        (const_string "vector")
7241        (const_string "double")))
7242   (set_attr "mode" "SI")])
7243
7244(define_expand "umuldi3_highpart"
7245  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7246		   (truncate:DI
7247		     (lshiftrt:TI
7248		       (mult:TI (zero_extend:TI
7249				  (match_operand:DI 1 "nonimmediate_operand" ""))
7250				(zero_extend:TI
7251				  (match_operand:DI 2 "register_operand" "")))
7252		       (const_int 64))))
7253	      (clobber (match_scratch:DI 3 ""))
7254	      (clobber (reg:CC 17))])]
7255  "TARGET_64BIT"
7256  "")
7257
7258(define_insn "*umuldi3_highpart_rex64"
7259  [(set (match_operand:DI 0 "register_operand" "=d")
7260	(truncate:DI
7261	  (lshiftrt:TI
7262	    (mult:TI (zero_extend:TI
7263		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7264		     (zero_extend:TI
7265		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7266	    (const_int 64))))
7267   (clobber (match_scratch:DI 3 "=1"))
7268   (clobber (reg:CC 17))]
7269  "TARGET_64BIT
7270   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7271  "mul{q}\t%2"
7272  [(set_attr "type" "imul")
7273   (set_attr "ppro_uops" "few")
7274   (set_attr "length_immediate" "0")
7275   (set (attr "athlon_decode")
7276     (if_then_else (eq_attr "cpu" "athlon")
7277        (const_string "vector")
7278        (const_string "double")))
7279   (set_attr "mode" "DI")])
7280
7281(define_expand "umulsi3_highpart"
7282  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7283		   (truncate:SI
7284		     (lshiftrt:DI
7285		       (mult:DI (zero_extend:DI
7286				  (match_operand:SI 1 "nonimmediate_operand" ""))
7287				(zero_extend:DI
7288				  (match_operand:SI 2 "register_operand" "")))
7289		       (const_int 32))))
7290	      (clobber (match_scratch:SI 3 ""))
7291	      (clobber (reg:CC 17))])]
7292  ""
7293  "")
7294
7295(define_insn "*umulsi3_highpart_insn"
7296  [(set (match_operand:SI 0 "register_operand" "=d")
7297	(truncate:SI
7298	  (lshiftrt:DI
7299	    (mult:DI (zero_extend:DI
7300		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7301		     (zero_extend:DI
7302		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7303	    (const_int 32))))
7304   (clobber (match_scratch:SI 3 "=1"))
7305   (clobber (reg:CC 17))]
7306  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7307  "mul{l}\t%2"
7308  [(set_attr "type" "imul")
7309   (set_attr "ppro_uops" "few")
7310   (set_attr "length_immediate" "0")
7311   (set (attr "athlon_decode")
7312     (if_then_else (eq_attr "cpu" "athlon")
7313        (const_string "vector")
7314        (const_string "double")))
7315   (set_attr "mode" "SI")])
7316
7317(define_insn "*umulsi3_highpart_zext"
7318  [(set (match_operand:DI 0 "register_operand" "=d")
7319	(zero_extend:DI (truncate:SI
7320	  (lshiftrt:DI
7321	    (mult:DI (zero_extend:DI
7322		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7323		     (zero_extend:DI
7324		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7325	    (const_int 32)))))
7326   (clobber (match_scratch:SI 3 "=1"))
7327   (clobber (reg:CC 17))]
7328  "TARGET_64BIT
7329   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7330  "mul{l}\t%2"
7331  [(set_attr "type" "imul")
7332   (set_attr "ppro_uops" "few")
7333   (set_attr "length_immediate" "0")
7334   (set (attr "athlon_decode")
7335     (if_then_else (eq_attr "cpu" "athlon")
7336        (const_string "vector")
7337        (const_string "double")))
7338   (set_attr "mode" "SI")])
7339
7340(define_expand "smuldi3_highpart"
7341  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7342		   (truncate:DI
7343		     (lshiftrt:TI
7344		       (mult:TI (sign_extend:TI
7345				  (match_operand:DI 1 "nonimmediate_operand" ""))
7346				(sign_extend:TI
7347				  (match_operand:DI 2 "register_operand" "")))
7348		       (const_int 64))))
7349	      (clobber (match_scratch:DI 3 ""))
7350	      (clobber (reg:CC 17))])]
7351  "TARGET_64BIT"
7352  "")
7353
7354(define_insn "*smuldi3_highpart_rex64"
7355  [(set (match_operand:DI 0 "register_operand" "=d")
7356	(truncate:DI
7357	  (lshiftrt:TI
7358	    (mult:TI (sign_extend:TI
7359		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7360		     (sign_extend:TI
7361		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7362	    (const_int 64))))
7363   (clobber (match_scratch:DI 3 "=1"))
7364   (clobber (reg:CC 17))]
7365  "TARGET_64BIT
7366   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7367  "imul{q}\t%2"
7368  [(set_attr "type" "imul")
7369   (set_attr "ppro_uops" "few")
7370   (set (attr "athlon_decode")
7371     (if_then_else (eq_attr "cpu" "athlon")
7372        (const_string "vector")
7373        (const_string "double")))
7374   (set_attr "mode" "DI")])
7375
7376(define_expand "smulsi3_highpart"
7377  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7378		   (truncate:SI
7379		     (lshiftrt:DI
7380		       (mult:DI (sign_extend:DI
7381				  (match_operand:SI 1 "nonimmediate_operand" ""))
7382				(sign_extend:DI
7383				  (match_operand:SI 2 "register_operand" "")))
7384		       (const_int 32))))
7385	      (clobber (match_scratch:SI 3 ""))
7386	      (clobber (reg:CC 17))])]
7387  ""
7388  "")
7389
7390(define_insn "*smulsi3_highpart_insn"
7391  [(set (match_operand:SI 0 "register_operand" "=d")
7392	(truncate:SI
7393	  (lshiftrt:DI
7394	    (mult:DI (sign_extend:DI
7395		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7396		     (sign_extend:DI
7397		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7398	    (const_int 32))))
7399   (clobber (match_scratch:SI 3 "=1"))
7400   (clobber (reg:CC 17))]
7401  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7402  "imul{l}\t%2"
7403  [(set_attr "type" "imul")
7404   (set_attr "ppro_uops" "few")
7405   (set (attr "athlon_decode")
7406     (if_then_else (eq_attr "cpu" "athlon")
7407        (const_string "vector")
7408        (const_string "double")))
7409   (set_attr "mode" "SI")])
7410
7411(define_insn "*smulsi3_highpart_zext"
7412  [(set (match_operand:DI 0 "register_operand" "=d")
7413	(zero_extend:DI (truncate:SI
7414	  (lshiftrt:DI
7415	    (mult:DI (sign_extend:DI
7416		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7417		     (sign_extend:DI
7418		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7419	    (const_int 32)))))
7420   (clobber (match_scratch:SI 3 "=1"))
7421   (clobber (reg:CC 17))]
7422  "TARGET_64BIT
7423   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7424  "imul{l}\t%2"
7425  [(set_attr "type" "imul")
7426   (set_attr "ppro_uops" "few")
7427   (set (attr "athlon_decode")
7428     (if_then_else (eq_attr "cpu" "athlon")
7429        (const_string "vector")
7430        (const_string "double")))
7431   (set_attr "mode" "SI")])
7432
7433;; The patterns that match these are at the end of this file.
7434
7435(define_expand "mulxf3"
7436  [(set (match_operand:XF 0 "register_operand" "")
7437	(mult:XF (match_operand:XF 1 "register_operand" "")
7438		 (match_operand:XF 2 "register_operand" "")))]
7439  "TARGET_80387"
7440  "")
7441
7442(define_expand "muldf3"
7443  [(set (match_operand:DF 0 "register_operand" "")
7444	(mult:DF (match_operand:DF 1 "register_operand" "")
7445		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7446  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7447  "")
7448
7449(define_expand "mulsf3"
7450  [(set (match_operand:SF 0 "register_operand" "")
7451	(mult:SF (match_operand:SF 1 "register_operand" "")
7452		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7453  "TARGET_80387 || TARGET_SSE_MATH"
7454  "")
7455
7456;; Divide instructions
7457
7458(define_insn "divqi3"
7459  [(set (match_operand:QI 0 "register_operand" "=a")
7460	(div:QI (match_operand:HI 1 "register_operand" "0")
7461		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7462   (clobber (reg:CC 17))]
7463  "TARGET_QIMODE_MATH"
7464  "idiv{b}\t%2"
7465  [(set_attr "type" "idiv")
7466   (set_attr "mode" "QI")
7467   (set_attr "ppro_uops" "few")])
7468
7469(define_insn "udivqi3"
7470  [(set (match_operand:QI 0 "register_operand" "=a")
7471	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7472		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7473   (clobber (reg:CC 17))]
7474  "TARGET_QIMODE_MATH"
7475  "div{b}\t%2"
7476  [(set_attr "type" "idiv")
7477   (set_attr "mode" "QI")
7478   (set_attr "ppro_uops" "few")])
7479
7480;; The patterns that match these are at the end of this file.
7481
7482(define_expand "divxf3"
7483  [(set (match_operand:XF 0 "register_operand" "")
7484	(div:XF (match_operand:XF 1 "register_operand" "")
7485		(match_operand:XF 2 "register_operand" "")))]
7486  "TARGET_80387"
7487  "")
7488
7489(define_expand "divdf3"
7490  [(set (match_operand:DF 0 "register_operand" "")
7491 	(div:DF (match_operand:DF 1 "register_operand" "")
7492 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7493   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7494   "")
7495 
7496(define_expand "divsf3"
7497  [(set (match_operand:SF 0 "register_operand" "")
7498	(div:SF (match_operand:SF 1 "register_operand" "")
7499		(match_operand:SF 2 "nonimmediate_operand" "")))]
7500  "TARGET_80387 || TARGET_SSE_MATH"
7501  "")
7502
7503;; Remainder instructions.
7504
7505(define_expand "divmoddi4"
7506  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7507		   (div:DI (match_operand:DI 1 "register_operand" "")
7508			   (match_operand:DI 2 "nonimmediate_operand" "")))
7509	      (set (match_operand:DI 3 "register_operand" "")
7510		   (mod:DI (match_dup 1) (match_dup 2)))
7511	      (clobber (reg:CC 17))])]
7512  "TARGET_64BIT"
7513  "")
7514
7515;; Allow to come the parameter in eax or edx to avoid extra moves.
7516;; Penalize eax case slightly because it results in worse scheduling
7517;; of code.
7518(define_insn "*divmoddi4_nocltd_rex64"
7519  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7520	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7521		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7522   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7523	(mod:DI (match_dup 2) (match_dup 3)))
7524   (clobber (reg:CC 17))]
7525  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7526  "#"
7527  [(set_attr "type" "multi")])
7528
7529(define_insn "*divmoddi4_cltd_rex64"
7530  [(set (match_operand:DI 0 "register_operand" "=a")
7531	(div:DI (match_operand:DI 2 "register_operand" "a")
7532		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7533   (set (match_operand:DI 1 "register_operand" "=&d")
7534	(mod:DI (match_dup 2) (match_dup 3)))
7535   (clobber (reg:CC 17))]
7536  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7537  "#"
7538  [(set_attr "type" "multi")])
7539
7540(define_insn "*divmoddi_noext_rex64"
7541  [(set (match_operand:DI 0 "register_operand" "=a")
7542	(div:DI (match_operand:DI 1 "register_operand" "0")
7543		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7544   (set (match_operand:DI 3 "register_operand" "=d")
7545	(mod:DI (match_dup 1) (match_dup 2)))
7546   (use (match_operand:DI 4 "register_operand" "3"))
7547   (clobber (reg:CC 17))]
7548  "TARGET_64BIT"
7549  "idiv{q}\t%2"
7550  [(set_attr "type" "idiv")
7551   (set_attr "mode" "DI")
7552   (set_attr "ppro_uops" "few")])
7553
7554(define_split
7555  [(set (match_operand:DI 0 "register_operand" "")
7556	(div:DI (match_operand:DI 1 "register_operand" "")
7557		(match_operand:DI 2 "nonimmediate_operand" "")))
7558   (set (match_operand:DI 3 "register_operand" "")
7559	(mod:DI (match_dup 1) (match_dup 2)))
7560   (clobber (reg:CC 17))]
7561  "TARGET_64BIT && reload_completed"
7562  [(parallel [(set (match_dup 3)
7563		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7564	      (clobber (reg:CC 17))])
7565   (parallel [(set (match_dup 0)
7566	           (div:DI (reg:DI 0) (match_dup 2)))
7567	      (set (match_dup 3)
7568		   (mod:DI (reg:DI 0) (match_dup 2)))
7569	      (use (match_dup 3))
7570	      (clobber (reg:CC 17))])]
7571{
7572  /* Avoid use of cltd in favor of a mov+shift.  */
7573  if (!TARGET_USE_CLTD && !optimize_size)
7574    {
7575      if (true_regnum (operands[1]))
7576        emit_move_insn (operands[0], operands[1]);
7577      else
7578	emit_move_insn (operands[3], operands[1]);
7579      operands[4] = operands[3];
7580    }
7581  else
7582    {
7583      if (true_regnum (operands[1]))
7584	abort();
7585      operands[4] = operands[1];
7586    }
7587})
7588
7589
7590(define_expand "divmodsi4"
7591  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7592		   (div:SI (match_operand:SI 1 "register_operand" "")
7593			   (match_operand:SI 2 "nonimmediate_operand" "")))
7594	      (set (match_operand:SI 3 "register_operand" "")
7595		   (mod:SI (match_dup 1) (match_dup 2)))
7596	      (clobber (reg:CC 17))])]
7597  ""
7598  "")
7599
7600;; Allow to come the parameter in eax or edx to avoid extra moves.
7601;; Penalize eax case slightly because it results in worse scheduling
7602;; of code.
7603(define_insn "*divmodsi4_nocltd"
7604  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7605	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7606		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7607   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7608	(mod:SI (match_dup 2) (match_dup 3)))
7609   (clobber (reg:CC 17))]
7610  "!optimize_size && !TARGET_USE_CLTD"
7611  "#"
7612  [(set_attr "type" "multi")])
7613
7614(define_insn "*divmodsi4_cltd"
7615  [(set (match_operand:SI 0 "register_operand" "=a")
7616	(div:SI (match_operand:SI 2 "register_operand" "a")
7617		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7618   (set (match_operand:SI 1 "register_operand" "=&d")
7619	(mod:SI (match_dup 2) (match_dup 3)))
7620   (clobber (reg:CC 17))]
7621  "optimize_size || TARGET_USE_CLTD"
7622  "#"
7623  [(set_attr "type" "multi")])
7624
7625(define_insn "*divmodsi_noext"
7626  [(set (match_operand:SI 0 "register_operand" "=a")
7627	(div:SI (match_operand:SI 1 "register_operand" "0")
7628		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7629   (set (match_operand:SI 3 "register_operand" "=d")
7630	(mod:SI (match_dup 1) (match_dup 2)))
7631   (use (match_operand:SI 4 "register_operand" "3"))
7632   (clobber (reg:CC 17))]
7633  ""
7634  "idiv{l}\t%2"
7635  [(set_attr "type" "idiv")
7636   (set_attr "mode" "SI")
7637   (set_attr "ppro_uops" "few")])
7638
7639(define_split
7640  [(set (match_operand:SI 0 "register_operand" "")
7641	(div:SI (match_operand:SI 1 "register_operand" "")
7642		(match_operand:SI 2 "nonimmediate_operand" "")))
7643   (set (match_operand:SI 3 "register_operand" "")
7644	(mod:SI (match_dup 1) (match_dup 2)))
7645   (clobber (reg:CC 17))]
7646  "reload_completed"
7647  [(parallel [(set (match_dup 3)
7648		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7649	      (clobber (reg:CC 17))])
7650   (parallel [(set (match_dup 0)
7651	           (div:SI (reg:SI 0) (match_dup 2)))
7652	      (set (match_dup 3)
7653		   (mod:SI (reg:SI 0) (match_dup 2)))
7654	      (use (match_dup 3))
7655	      (clobber (reg:CC 17))])]
7656{
7657  /* Avoid use of cltd in favor of a mov+shift.  */
7658  if (!TARGET_USE_CLTD && !optimize_size)
7659    {
7660      if (true_regnum (operands[1]))
7661        emit_move_insn (operands[0], operands[1]);
7662      else
7663	emit_move_insn (operands[3], operands[1]);
7664      operands[4] = operands[3];
7665    }
7666  else
7667    {
7668      if (true_regnum (operands[1]))
7669	abort();
7670      operands[4] = operands[1];
7671    }
7672})
7673;; %%% Split me.
7674(define_insn "divmodhi4"
7675  [(set (match_operand:HI 0 "register_operand" "=a")
7676	(div:HI (match_operand:HI 1 "register_operand" "0")
7677		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7678   (set (match_operand:HI 3 "register_operand" "=&d")
7679	(mod:HI (match_dup 1) (match_dup 2)))
7680   (clobber (reg:CC 17))]
7681  "TARGET_HIMODE_MATH"
7682  "cwtd\;idiv{w}\t%2"
7683  [(set_attr "type" "multi")
7684   (set_attr "length_immediate" "0")
7685   (set_attr "mode" "SI")])
7686
7687(define_insn "udivmoddi4"
7688  [(set (match_operand:DI 0 "register_operand" "=a")
7689	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7690		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691   (set (match_operand:DI 3 "register_operand" "=&d")
7692	(umod:DI (match_dup 1) (match_dup 2)))
7693   (clobber (reg:CC 17))]
7694  "TARGET_64BIT"
7695  "xor{q}\t%3, %3\;div{q}\t%2"
7696  [(set_attr "type" "multi")
7697   (set_attr "length_immediate" "0")
7698   (set_attr "mode" "DI")])
7699
7700(define_insn "*udivmoddi4_noext"
7701  [(set (match_operand:DI 0 "register_operand" "=a")
7702	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7703		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7704   (set (match_operand:DI 3 "register_operand" "=d")
7705	(umod:DI (match_dup 1) (match_dup 2)))
7706   (use (match_dup 3))
7707   (clobber (reg:CC 17))]
7708  "TARGET_64BIT"
7709  "div{q}\t%2"
7710  [(set_attr "type" "idiv")
7711   (set_attr "ppro_uops" "few")
7712   (set_attr "mode" "DI")])
7713
7714(define_split
7715  [(set (match_operand:DI 0 "register_operand" "")
7716	(udiv:DI (match_operand:DI 1 "register_operand" "")
7717		 (match_operand:DI 2 "nonimmediate_operand" "")))
7718   (set (match_operand:DI 3 "register_operand" "")
7719	(umod:DI (match_dup 1) (match_dup 2)))
7720   (clobber (reg:CC 17))]
7721  "TARGET_64BIT && reload_completed"
7722  [(set (match_dup 3) (const_int 0))
7723   (parallel [(set (match_dup 0)
7724		   (udiv:DI (match_dup 1) (match_dup 2)))
7725	      (set (match_dup 3)
7726		   (umod:DI (match_dup 1) (match_dup 2)))
7727	      (use (match_dup 3))
7728	      (clobber (reg:CC 17))])]
7729  "")
7730
7731(define_insn "udivmodsi4"
7732  [(set (match_operand:SI 0 "register_operand" "=a")
7733	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7734		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7735   (set (match_operand:SI 3 "register_operand" "=&d")
7736	(umod:SI (match_dup 1) (match_dup 2)))
7737   (clobber (reg:CC 17))]
7738  ""
7739  "xor{l}\t%3, %3\;div{l}\t%2"
7740  [(set_attr "type" "multi")
7741   (set_attr "length_immediate" "0")
7742   (set_attr "mode" "SI")])
7743
7744(define_insn "*udivmodsi4_noext"
7745  [(set (match_operand:SI 0 "register_operand" "=a")
7746	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7747		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7748   (set (match_operand:SI 3 "register_operand" "=d")
7749	(umod:SI (match_dup 1) (match_dup 2)))
7750   (use (match_dup 3))
7751   (clobber (reg:CC 17))]
7752  ""
7753  "div{l}\t%2"
7754  [(set_attr "type" "idiv")
7755   (set_attr "ppro_uops" "few")
7756   (set_attr "mode" "SI")])
7757
7758(define_split
7759  [(set (match_operand:SI 0 "register_operand" "")
7760	(udiv:SI (match_operand:SI 1 "register_operand" "")
7761		 (match_operand:SI 2 "nonimmediate_operand" "")))
7762   (set (match_operand:SI 3 "register_operand" "")
7763	(umod:SI (match_dup 1) (match_dup 2)))
7764   (clobber (reg:CC 17))]
7765  "reload_completed"
7766  [(set (match_dup 3) (const_int 0))
7767   (parallel [(set (match_dup 0)
7768		   (udiv:SI (match_dup 1) (match_dup 2)))
7769	      (set (match_dup 3)
7770		   (umod:SI (match_dup 1) (match_dup 2)))
7771	      (use (match_dup 3))
7772	      (clobber (reg:CC 17))])]
7773  "")
7774
7775(define_expand "udivmodhi4"
7776  [(set (match_dup 4) (const_int 0))
7777   (parallel [(set (match_operand:HI 0 "register_operand" "")
7778		   (udiv:HI (match_operand:HI 1 "register_operand" "")
7779		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
7780	      (set (match_operand:HI 3 "register_operand" "")
7781	   	   (umod:HI (match_dup 1) (match_dup 2)))
7782	      (use (match_dup 4))
7783	      (clobber (reg:CC 17))])]
7784  "TARGET_HIMODE_MATH"
7785  "operands[4] = gen_reg_rtx (HImode);")
7786
7787(define_insn "*udivmodhi_noext"
7788  [(set (match_operand:HI 0 "register_operand" "=a")
7789	(udiv:HI (match_operand:HI 1 "register_operand" "0")
7790		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7791   (set (match_operand:HI 3 "register_operand" "=d")
7792	(umod:HI (match_dup 1) (match_dup 2)))
7793   (use (match_operand:HI 4 "register_operand" "3"))
7794   (clobber (reg:CC 17))]
7795  ""
7796  "div{w}\t%2"
7797  [(set_attr "type" "idiv")
7798   (set_attr "mode" "HI")
7799   (set_attr "ppro_uops" "few")])
7800
7801;; We can not use div/idiv for double division, because it causes
7802;; "division by zero" on the overflow and that's not what we expect
7803;; from truncate.  Because true (non truncating) double division is
7804;; never generated, we can't create this insn anyway.
7805;
7806;(define_insn ""
7807;  [(set (match_operand:SI 0 "register_operand" "=a")
7808;	(truncate:SI
7809;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7810;		   (zero_extend:DI
7811;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7812;   (set (match_operand:SI 3 "register_operand" "=d")
7813;	(truncate:SI
7814;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7815;   (clobber (reg:CC 17))]
7816;  ""
7817;  "div{l}\t{%2, %0|%0, %2}"
7818;  [(set_attr "type" "idiv")
7819;   (set_attr "ppro_uops" "few")])
7820
7821;;- Logical AND instructions
7822
7823;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7824;; Note that this excludes ah.
7825
7826(define_insn "*testdi_1_rex64"
7827  [(set (reg 17)
7828	(compare
7829	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7830		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7831	  (const_int 0)))]
7832  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7833   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7834  "@
7835   test{l}\t{%k1, %k0|%k0, %k1} 
7836   test{l}\t{%k1, %k0|%k0, %k1} 
7837   test{q}\t{%1, %0|%0, %1} 
7838   test{q}\t{%1, %0|%0, %1} 
7839   test{q}\t{%1, %0|%0, %1}"
7840  [(set_attr "type" "test")
7841   (set_attr "modrm" "0,1,0,1,1")
7842   (set_attr "mode" "SI,SI,DI,DI,DI")
7843   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7844
7845(define_insn "testsi_1"
7846  [(set (reg 17)
7847	(compare
7848	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7849		  (match_operand:SI 1 "general_operand" "in,in,rin"))
7850	  (const_int 0)))]
7851  "ix86_match_ccmode (insn, CCNOmode)
7852   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7853  "test{l}\t{%1, %0|%0, %1}"
7854  [(set_attr "type" "test")
7855   (set_attr "modrm" "0,1,1")
7856   (set_attr "mode" "SI")
7857   (set_attr "pent_pair" "uv,np,uv")])
7858
7859(define_expand "testsi_ccno_1"
7860  [(set (reg:CCNO 17)
7861	(compare:CCNO
7862	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7863		  (match_operand:SI 1 "nonmemory_operand" ""))
7864	  (const_int 0)))]
7865  ""
7866  "")
7867
7868(define_insn "*testhi_1"
7869  [(set (reg 17)
7870        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7871			 (match_operand:HI 1 "general_operand" "n,n,rn"))
7872		 (const_int 0)))]
7873  "ix86_match_ccmode (insn, CCNOmode)
7874   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7875  "test{w}\t{%1, %0|%0, %1}"
7876  [(set_attr "type" "test")
7877   (set_attr "modrm" "0,1,1")
7878   (set_attr "mode" "HI")
7879   (set_attr "pent_pair" "uv,np,uv")])
7880
7881(define_expand "testqi_ccz_1"
7882  [(set (reg:CCZ 17)
7883        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7884			     (match_operand:QI 1 "nonmemory_operand" ""))
7885		 (const_int 0)))]
7886  ""
7887  "")
7888
7889(define_insn "*testqi_1_maybe_si"
7890  [(set (reg 17)
7891        (compare
7892	  (and:QI
7893	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7894	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7895	  (const_int 0)))]
7896  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897   && ix86_match_ccmode (insn,
7898			 GET_CODE (operands[1]) == CONST_INT
7899			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7900{
7901  if (which_alternative == 3)
7902    {
7903      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7904	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7905      return "test{l}\t{%1, %k0|%k0, %1}";
7906    }
7907  return "test{b}\t{%1, %0|%0, %1}";
7908}
7909  [(set_attr "type" "test")
7910   (set_attr "modrm" "0,1,1,1")
7911   (set_attr "mode" "QI,QI,QI,SI")
7912   (set_attr "pent_pair" "uv,np,uv,np")])
7913
7914(define_insn "*testqi_1"
7915  [(set (reg 17)
7916        (compare
7917	  (and:QI
7918	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7919	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7920	  (const_int 0)))]
7921  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7922   && ix86_match_ccmode (insn, CCNOmode)"
7923  "test{b}\t{%1, %0|%0, %1}"
7924  [(set_attr "type" "test")
7925   (set_attr "modrm" "0,1,1")
7926   (set_attr "mode" "QI")
7927   (set_attr "pent_pair" "uv,np,uv")])
7928
7929(define_expand "testqi_ext_ccno_0"
7930  [(set (reg:CCNO 17)
7931	(compare:CCNO
7932	  (and:SI
7933	    (zero_extract:SI
7934	      (match_operand 0 "ext_register_operand" "")
7935	      (const_int 8)
7936	      (const_int 8))
7937	    (match_operand 1 "const_int_operand" ""))
7938	  (const_int 0)))]
7939  ""
7940  "")
7941
7942(define_insn "*testqi_ext_0"
7943  [(set (reg 17)
7944	(compare
7945	  (and:SI
7946	    (zero_extract:SI
7947	      (match_operand 0 "ext_register_operand" "Q")
7948	      (const_int 8)
7949	      (const_int 8))
7950	    (match_operand 1 "const_int_operand" "n"))
7951	  (const_int 0)))]
7952  "ix86_match_ccmode (insn, CCNOmode)"
7953  "test{b}\t{%1, %h0|%h0, %1}"
7954  [(set_attr "type" "test")
7955   (set_attr "mode" "QI")
7956   (set_attr "length_immediate" "1")
7957   (set_attr "pent_pair" "np")])
7958
7959(define_insn "*testqi_ext_1"
7960  [(set (reg 17)
7961	(compare
7962	  (and:SI
7963	    (zero_extract:SI
7964	      (match_operand 0 "ext_register_operand" "Q")
7965	      (const_int 8)
7966	      (const_int 8))
7967	    (zero_extend:SI
7968	      (match_operand:QI 1 "general_operand" "Qm")))
7969	  (const_int 0)))]
7970  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7971   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7972  "test{b}\t{%1, %h0|%h0, %1}"
7973  [(set_attr "type" "test")
7974   (set_attr "mode" "QI")])
7975
7976(define_insn "*testqi_ext_1_rex64"
7977  [(set (reg 17)
7978	(compare
7979	  (and:SI
7980	    (zero_extract:SI
7981	      (match_operand 0 "ext_register_operand" "Q")
7982	      (const_int 8)
7983	      (const_int 8))
7984	    (zero_extend:SI
7985	      (match_operand:QI 1 "register_operand" "Q")))
7986	  (const_int 0)))]
7987  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7988  "test{b}\t{%1, %h0|%h0, %1}"
7989  [(set_attr "type" "test")
7990   (set_attr "mode" "QI")])
7991
7992(define_insn "*testqi_ext_2"
7993  [(set (reg 17)
7994	(compare
7995	  (and:SI
7996	    (zero_extract:SI
7997	      (match_operand 0 "ext_register_operand" "Q")
7998	      (const_int 8)
7999	      (const_int 8))
8000	    (zero_extract:SI
8001	      (match_operand 1 "ext_register_operand" "Q")
8002	      (const_int 8)
8003	      (const_int 8)))
8004	  (const_int 0)))]
8005  "ix86_match_ccmode (insn, CCNOmode)"
8006  "test{b}\t{%h1, %h0|%h0, %h1}"
8007  [(set_attr "type" "test")
8008   (set_attr "mode" "QI")])
8009
8010;; Combine likes to form bit extractions for some tests.  Humor it.
8011(define_insn "*testqi_ext_3"
8012  [(set (reg 17)
8013        (compare (zero_extract:SI
8014		   (match_operand 0 "nonimmediate_operand" "rm")
8015		   (match_operand:SI 1 "const_int_operand" "")
8016		   (match_operand:SI 2 "const_int_operand" ""))
8017		 (const_int 0)))]
8018  "ix86_match_ccmode (insn, CCNOmode)
8019   && (GET_MODE (operands[0]) == SImode
8020       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8021       || GET_MODE (operands[0]) == HImode
8022       || GET_MODE (operands[0]) == QImode)"
8023  "#")
8024
8025(define_insn "*testqi_ext_3_rex64"
8026  [(set (reg 17)
8027        (compare (zero_extract:DI
8028		   (match_operand 0 "nonimmediate_operand" "rm")
8029		   (match_operand:DI 1 "const_int_operand" "")
8030		   (match_operand:DI 2 "const_int_operand" ""))
8031		 (const_int 0)))]
8032  "TARGET_64BIT
8033   && ix86_match_ccmode (insn, CCNOmode)
8034   /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8035   && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8036   /* Ensure that resulting mask is zero or sign extended operand.  */
8037   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8038       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8039	   && INTVAL (operands[1]) > 32))
8040   && (GET_MODE (operands[0]) == SImode
8041       || GET_MODE (operands[0]) == DImode
8042       || GET_MODE (operands[0]) == HImode
8043       || GET_MODE (operands[0]) == QImode)"
8044  "#")
8045
8046(define_split
8047  [(set (match_operand 0 "flags_reg_operand" "")
8048        (match_operator 1 "compare_operator"
8049	  [(zero_extract
8050	     (match_operand 2 "nonimmediate_operand" "")
8051	     (match_operand 3 "const_int_operand" "")
8052	     (match_operand 4 "const_int_operand" ""))
8053	   (const_int 0)]))]
8054  "ix86_match_ccmode (insn, CCNOmode)"
8055  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8056{
8057  rtx val = operands[2];
8058  HOST_WIDE_INT len = INTVAL (operands[3]);
8059  HOST_WIDE_INT pos = INTVAL (operands[4]);
8060  HOST_WIDE_INT mask;
8061  enum machine_mode mode, submode;
8062
8063  mode = GET_MODE (val);
8064  if (GET_CODE (val) == MEM)
8065    {
8066      /* ??? Combine likes to put non-volatile mem extractions in QImode
8067	 no matter the size of the test.  So find a mode that works.  */
8068      if (! MEM_VOLATILE_P (val))
8069	{
8070	  mode = smallest_mode_for_size (pos + len, MODE_INT);
8071	  val = adjust_address (val, mode, 0);
8072	}
8073    }
8074  else if (GET_CODE (val) == SUBREG
8075	   && (submode = GET_MODE (SUBREG_REG (val)),
8076	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8077	   && pos + len <= GET_MODE_BITSIZE (submode))
8078    {
8079      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8080      mode = submode;
8081      val = SUBREG_REG (val);
8082    }
8083  else if (mode == HImode && pos + len <= 8)
8084    {
8085      /* Small HImode tests can be converted to QImode.  */
8086      mode = QImode;
8087      val = gen_lowpart (QImode, val);
8088    }
8089
8090  mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8091  mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8092
8093  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8094})
8095
8096;; Convert HImode/SImode test instructions with immediate to QImode ones.
8097;; i386 does not allow to encode test with 8bit sign extended immediate, so
8098;; this is relatively important trick.
8099;; Do the conversion only post-reload to avoid limiting of the register class
8100;; to QI regs.
8101(define_split
8102  [(set (match_operand 0 "flags_reg_operand" "")
8103	(match_operator 1 "compare_operator"
8104	  [(and (match_operand 2 "register_operand" "")
8105	        (match_operand 3 "const_int_operand" ""))
8106	   (const_int 0)]))]
8107   "reload_completed
8108    && QI_REG_P (operands[2])
8109    && GET_MODE (operands[2]) != QImode
8110    && ((ix86_match_ccmode (insn, CCZmode)
8111    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8112	|| (ix86_match_ccmode (insn, CCNOmode)
8113	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8114  [(set (match_dup 0)
8115	(match_op_dup 1
8116	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8117		   (match_dup 3))
8118	   (const_int 0)]))]
8119  "operands[2] = gen_lowpart (SImode, operands[2]);
8120   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8121
8122(define_split
8123  [(set (match_operand 0 "flags_reg_operand" "")
8124	(match_operator 1 "compare_operator"
8125	  [(and (match_operand 2 "nonimmediate_operand" "")
8126	        (match_operand 3 "const_int_operand" ""))
8127	   (const_int 0)]))]
8128   "reload_completed
8129    && GET_MODE (operands[2]) != QImode
8130    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8131    && ((ix86_match_ccmode (insn, CCZmode)
8132	 && !(INTVAL (operands[3]) & ~255))
8133	|| (ix86_match_ccmode (insn, CCNOmode)
8134	    && !(INTVAL (operands[3]) & ~127)))"
8135  [(set (match_dup 0)
8136	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8137			 (const_int 0)]))]
8138  "operands[2] = gen_lowpart (QImode, operands[2]);
8139   operands[3] = gen_lowpart (QImode, operands[3]);")
8140
8141
8142;; %%% This used to optimize known byte-wide and operations to memory,
8143;; and sometimes to QImode registers.  If this is considered useful,
8144;; it should be done with splitters.
8145
8146(define_expand "anddi3"
8147  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8148	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8149		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8150   (clobber (reg:CC 17))]
8151  "TARGET_64BIT"
8152  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8153
8154(define_insn "*anddi_1_rex64"
8155  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8156	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8157		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8158   (clobber (reg:CC 17))]
8159  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8160{
8161  switch (get_attr_type (insn))
8162    {
8163    case TYPE_IMOVX:
8164      {
8165	enum machine_mode mode;
8166
8167	if (GET_CODE (operands[2]) != CONST_INT)
8168	  abort ();
8169        if (INTVAL (operands[2]) == 0xff)
8170	  mode = QImode;
8171	else if (INTVAL (operands[2]) == 0xffff)
8172	  mode = HImode;
8173	else
8174	  abort ();
8175	
8176	operands[1] = gen_lowpart (mode, operands[1]);
8177	if (mode == QImode)
8178	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8179	else
8180	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8181      }
8182
8183    default:
8184      if (! rtx_equal_p (operands[0], operands[1]))
8185	abort ();
8186      if (get_attr_mode (insn) == MODE_SI)
8187	return "and{l}\t{%k2, %k0|%k0, %k2}";
8188      else
8189	return "and{q}\t{%2, %0|%0, %2}";
8190    }
8191}
8192  [(set_attr "type" "alu,alu,alu,imovx")
8193   (set_attr "length_immediate" "*,*,*,0")
8194   (set_attr "mode" "SI,DI,DI,DI")])
8195
8196(define_insn "*anddi_2"
8197  [(set (reg 17)
8198	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8199			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8200		 (const_int 0)))
8201   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8202	(and:DI (match_dup 1) (match_dup 2)))]
8203  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204   && ix86_binary_operator_ok (AND, DImode, operands)"
8205  "@
8206   and{l}\t{%k2, %k0|%k0, %k2} 
8207   and{q}\t{%2, %0|%0, %2} 
8208   and{q}\t{%2, %0|%0, %2}"
8209  [(set_attr "type" "alu")
8210   (set_attr "mode" "SI,DI,DI")])
8211
8212(define_expand "andsi3"
8213  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8214	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8215		(match_operand:SI 2 "general_operand" "")))
8216   (clobber (reg:CC 17))]
8217  ""
8218  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8219
8220(define_insn "*andsi_1"
8221  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8222	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8223		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8224   (clobber (reg:CC 17))]
8225  "ix86_binary_operator_ok (AND, SImode, operands)"
8226{
8227  switch (get_attr_type (insn))
8228    {
8229    case TYPE_IMOVX:
8230      {
8231	enum machine_mode mode;
8232
8233	if (GET_CODE (operands[2]) != CONST_INT)
8234	  abort ();
8235        if (INTVAL (operands[2]) == 0xff)
8236	  mode = QImode;
8237	else if (INTVAL (operands[2]) == 0xffff)
8238	  mode = HImode;
8239	else
8240	  abort ();
8241	
8242	operands[1] = gen_lowpart (mode, operands[1]);
8243	if (mode == QImode)
8244	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8245	else
8246	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8247      }
8248
8249    default:
8250      if (! rtx_equal_p (operands[0], operands[1]))
8251	abort ();
8252      return "and{l}\t{%2, %0|%0, %2}";
8253    }
8254}
8255  [(set_attr "type" "alu,alu,imovx")
8256   (set_attr "length_immediate" "*,*,0")
8257   (set_attr "mode" "SI")])
8258
8259(define_split
8260  [(set (match_operand 0 "register_operand" "")
8261	(and (match_dup 0)
8262	     (const_int -65536)))
8263   (clobber (reg:CC 17))]
8264  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8265  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8266  "operands[1] = gen_lowpart (HImode, operands[0]);")
8267
8268(define_split
8269  [(set (match_operand 0 "ext_register_operand" "")
8270	(and (match_dup 0)
8271	     (const_int -256)))
8272   (clobber (reg:CC 17))]
8273  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8274  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8275  "operands[1] = gen_lowpart (QImode, operands[0]);")
8276
8277(define_split
8278  [(set (match_operand 0 "ext_register_operand" "")
8279	(and (match_dup 0)
8280	     (const_int -65281)))
8281   (clobber (reg:CC 17))]
8282  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8283  [(parallel [(set (zero_extract:SI (match_dup 0)
8284				    (const_int 8)
8285				    (const_int 8))
8286		   (xor:SI 
8287		     (zero_extract:SI (match_dup 0)
8288				      (const_int 8)
8289				      (const_int 8))
8290		     (zero_extract:SI (match_dup 0)
8291				      (const_int 8)
8292				      (const_int 8))))
8293	      (clobber (reg:CC 17))])]
8294  "operands[0] = gen_lowpart (SImode, operands[0]);")
8295
8296;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297(define_insn "*andsi_1_zext"
8298  [(set (match_operand:DI 0 "register_operand" "=r")
8299	(zero_extend:DI
8300	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8301		  (match_operand:SI 2 "general_operand" "rim"))))
8302   (clobber (reg:CC 17))]
8303  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8304  "and{l}\t{%2, %k0|%k0, %2}"
8305  [(set_attr "type" "alu")
8306   (set_attr "mode" "SI")])
8307
8308(define_insn "*andsi_2"
8309  [(set (reg 17)
8310	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8311			 (match_operand:SI 2 "general_operand" "rim,ri"))
8312		 (const_int 0)))
8313   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8314	(and:SI (match_dup 1) (match_dup 2)))]
8315  "ix86_match_ccmode (insn, CCNOmode)
8316   && ix86_binary_operator_ok (AND, SImode, operands)"
8317  "and{l}\t{%2, %0|%0, %2}"
8318  [(set_attr "type" "alu")
8319   (set_attr "mode" "SI")])
8320
8321;; See comment for addsi_1_zext why we do use nonimmediate_operand
8322(define_insn "*andsi_2_zext"
8323  [(set (reg 17)
8324	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8325			 (match_operand:SI 2 "general_operand" "rim"))
8326		 (const_int 0)))
8327   (set (match_operand:DI 0 "register_operand" "=r")
8328	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8329  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8330   && ix86_binary_operator_ok (AND, SImode, operands)"
8331  "and{l}\t{%2, %k0|%k0, %2}"
8332  [(set_attr "type" "alu")
8333   (set_attr "mode" "SI")])
8334
8335(define_expand "andhi3"
8336  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8337	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8338		(match_operand:HI 2 "general_operand" "")))
8339   (clobber (reg:CC 17))]
8340  "TARGET_HIMODE_MATH"
8341  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8342
8343(define_insn "*andhi_1"
8344  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8345	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8346		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8347   (clobber (reg:CC 17))]
8348  "ix86_binary_operator_ok (AND, HImode, operands)"
8349{
8350  switch (get_attr_type (insn))
8351    {
8352    case TYPE_IMOVX:
8353      if (GET_CODE (operands[2]) != CONST_INT)
8354	abort ();
8355      if (INTVAL (operands[2]) == 0xff)
8356	return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8357      abort ();
8358
8359    default:
8360      if (! rtx_equal_p (operands[0], operands[1]))
8361	abort ();
8362
8363      return "and{w}\t{%2, %0|%0, %2}";
8364    }
8365}
8366  [(set_attr "type" "alu,alu,imovx")
8367   (set_attr "length_immediate" "*,*,0")
8368   (set_attr "mode" "HI,HI,SI")])
8369
8370(define_insn "*andhi_2"
8371  [(set (reg 17)
8372	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8373			 (match_operand:HI 2 "general_operand" "rim,ri"))
8374		 (const_int 0)))
8375   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8376	(and:HI (match_dup 1) (match_dup 2)))]
8377  "ix86_match_ccmode (insn, CCNOmode)
8378   && ix86_binary_operator_ok (AND, HImode, operands)"
8379  "and{w}\t{%2, %0|%0, %2}"
8380  [(set_attr "type" "alu")
8381   (set_attr "mode" "HI")])
8382
8383(define_expand "andqi3"
8384  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8385	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8386		(match_operand:QI 2 "general_operand" "")))
8387   (clobber (reg:CC 17))]
8388  "TARGET_QIMODE_MATH"
8389  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8390
8391;; %%% Potential partial reg stall on alternative 2.  What to do?
8392(define_insn "*andqi_1"
8393  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8394	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8396   (clobber (reg:CC 17))]
8397  "ix86_binary_operator_ok (AND, QImode, operands)"
8398  "@
8399   and{b}\t{%2, %0|%0, %2}
8400   and{b}\t{%2, %0|%0, %2}
8401   and{l}\t{%k2, %k0|%k0, %k2}"
8402  [(set_attr "type" "alu")
8403   (set_attr "mode" "QI,QI,SI")])
8404
8405(define_insn "*andqi_1_slp"
8406  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8407	(and:QI (match_dup 0)
8408		(match_operand:QI 1 "general_operand" "qi,qmi")))
8409   (clobber (reg:CC 17))]
8410  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8411   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8412  "and{b}\t{%1, %0|%0, %1}"
8413  [(set_attr "type" "alu1")
8414   (set_attr "mode" "QI")])
8415
8416(define_insn "*andqi_2_maybe_si"
8417  [(set (reg 17)
8418	(compare (and:QI
8419		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8420		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8421		 (const_int 0)))
8422   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8423	(and:QI (match_dup 1) (match_dup 2)))]
8424  "ix86_binary_operator_ok (AND, QImode, operands)
8425   && ix86_match_ccmode (insn,
8426			 GET_CODE (operands[2]) == CONST_INT
8427			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8428{
8429  if (which_alternative == 2)
8430    {
8431      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8432        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8433      return "and{l}\t{%2, %k0|%k0, %2}";
8434    }
8435  return "and{b}\t{%2, %0|%0, %2}";
8436}
8437  [(set_attr "type" "alu")
8438   (set_attr "mode" "QI,QI,SI")])
8439
8440(define_insn "*andqi_2"
8441  [(set (reg 17)
8442	(compare (and:QI
8443		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8444		   (match_operand:QI 2 "general_operand" "qim,qi"))
8445		 (const_int 0)))
8446   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8447	(and:QI (match_dup 1) (match_dup 2)))]
8448  "ix86_match_ccmode (insn, CCNOmode)
8449   && ix86_binary_operator_ok (AND, QImode, operands)"
8450  "and{b}\t{%2, %0|%0, %2}"
8451  [(set_attr "type" "alu")
8452   (set_attr "mode" "QI")])
8453
8454(define_insn "*andqi_2_slp"
8455  [(set (reg 17)
8456	(compare (and:QI
8457		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8458		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8459		 (const_int 0)))
8460   (set (strict_low_part (match_dup 0))
8461	(and:QI (match_dup 0) (match_dup 1)))]
8462  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8463   && ix86_match_ccmode (insn, CCNOmode)
8464   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8465  "and{b}\t{%1, %0|%0, %1}"
8466  [(set_attr "type" "alu1")
8467   (set_attr "mode" "QI")])
8468
8469;; ??? A bug in recog prevents it from recognizing a const_int as an
8470;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8471;; for a QImode operand, which of course failed.
8472
8473(define_insn "andqi_ext_0"
8474  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475			 (const_int 8)
8476			 (const_int 8))
8477	(and:SI 
8478	  (zero_extract:SI
8479	    (match_operand 1 "ext_register_operand" "0")
8480	    (const_int 8)
8481	    (const_int 8))
8482	  (match_operand 2 "const_int_operand" "n")))
8483   (clobber (reg:CC 17))]
8484  ""
8485  "and{b}\t{%2, %h0|%h0, %2}"
8486  [(set_attr "type" "alu")
8487   (set_attr "length_immediate" "1")
8488   (set_attr "mode" "QI")])
8489
8490;; Generated by peephole translating test to and.  This shows up
8491;; often in fp comparisons.
8492
8493(define_insn "*andqi_ext_0_cc"
8494  [(set (reg 17)
8495	(compare
8496	  (and:SI
8497	    (zero_extract:SI
8498	      (match_operand 1 "ext_register_operand" "0")
8499	      (const_int 8)
8500	      (const_int 8))
8501	    (match_operand 2 "const_int_operand" "n"))
8502	  (const_int 0)))
8503   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504			 (const_int 8)
8505			 (const_int 8))
8506	(and:SI 
8507	  (zero_extract:SI
8508	    (match_dup 1)
8509	    (const_int 8)
8510	    (const_int 8))
8511	  (match_dup 2)))]
8512  "ix86_match_ccmode (insn, CCNOmode)"
8513  "and{b}\t{%2, %h0|%h0, %2}"
8514  [(set_attr "type" "alu")
8515   (set_attr "length_immediate" "1")
8516   (set_attr "mode" "QI")])
8517
8518(define_insn "*andqi_ext_1"
8519  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8520			 (const_int 8)
8521			 (const_int 8))
8522	(and:SI 
8523	  (zero_extract:SI
8524	    (match_operand 1 "ext_register_operand" "0")
8525	    (const_int 8)
8526	    (const_int 8))
8527	  (zero_extend:SI
8528	    (match_operand:QI 2 "general_operand" "Qm"))))
8529   (clobber (reg:CC 17))]
8530  "!TARGET_64BIT"
8531  "and{b}\t{%2, %h0|%h0, %2}"
8532  [(set_attr "type" "alu")
8533   (set_attr "length_immediate" "0")
8534   (set_attr "mode" "QI")])
8535
8536(define_insn "*andqi_ext_1_rex64"
8537  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8538			 (const_int 8)
8539			 (const_int 8))
8540	(and:SI 
8541	  (zero_extract:SI
8542	    (match_operand 1 "ext_register_operand" "0")
8543	    (const_int 8)
8544	    (const_int 8))
8545	  (zero_extend:SI
8546	    (match_operand 2 "ext_register_operand" "Q"))))
8547   (clobber (reg:CC 17))]
8548  "TARGET_64BIT"
8549  "and{b}\t{%2, %h0|%h0, %2}"
8550  [(set_attr "type" "alu")
8551   (set_attr "length_immediate" "0")
8552   (set_attr "mode" "QI")])
8553
8554(define_insn "*andqi_ext_2"
8555  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8556			 (const_int 8)
8557			 (const_int 8))
8558	(and:SI
8559	  (zero_extract:SI
8560	    (match_operand 1 "ext_register_operand" "%0")
8561	    (const_int 8)
8562	    (const_int 8))
8563	  (zero_extract:SI
8564	    (match_operand 2 "ext_register_operand" "Q")
8565	    (const_int 8)
8566	    (const_int 8))))
8567   (clobber (reg:CC 17))]
8568  ""
8569  "and{b}\t{%h2, %h0|%h0, %h2}"
8570  [(set_attr "type" "alu")
8571   (set_attr "length_immediate" "0")
8572   (set_attr "mode" "QI")])
8573
8574;; Convert wide AND instructions with immediate operand to shorter QImode
8575;; equivalents when possible.
8576;; Don't do the splitting with memory operands, since it introduces risk
8577;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8578;; for size, but that can (should?) be handled by generic code instead.
8579(define_split
8580  [(set (match_operand 0 "register_operand" "")
8581	(and (match_operand 1 "register_operand" "")
8582	     (match_operand 2 "const_int_operand" "")))
8583   (clobber (reg:CC 17))]
8584   "reload_completed
8585    && QI_REG_P (operands[0])
8586    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8587    && !(~INTVAL (operands[2]) & ~(255 << 8))
8588    && GET_MODE (operands[0]) != QImode"
8589  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8590		   (and:SI (zero_extract:SI (match_dup 1)
8591					    (const_int 8) (const_int 8))
8592			   (match_dup 2)))
8593	      (clobber (reg:CC 17))])]
8594  "operands[0] = gen_lowpart (SImode, operands[0]);
8595   operands[1] = gen_lowpart (SImode, operands[1]);
8596   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8597
8598;; Since AND can be encoded with sign extended immediate, this is only
8599;; profitable when 7th bit is not set.
8600(define_split
8601  [(set (match_operand 0 "register_operand" "")
8602	(and (match_operand 1 "general_operand" "")
8603	     (match_operand 2 "const_int_operand" "")))
8604   (clobber (reg:CC 17))]
8605   "reload_completed
8606    && ANY_QI_REG_P (operands[0])
8607    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8608    && !(~INTVAL (operands[2]) & ~255)
8609    && !(INTVAL (operands[2]) & 128)
8610    && GET_MODE (operands[0]) != QImode"
8611  [(parallel [(set (strict_low_part (match_dup 0))
8612		   (and:QI (match_dup 1)
8613			   (match_dup 2)))
8614	      (clobber (reg:CC 17))])]
8615  "operands[0] = gen_lowpart (QImode, operands[0]);
8616   operands[1] = gen_lowpart (QImode, operands[1]);
8617   operands[2] = gen_lowpart (QImode, operands[2]);")
8618
8619;; Logical inclusive OR instructions
8620
8621;; %%% This used to optimize known byte-wide and operations to memory.
8622;; If this is considered useful, it should be done with splitters.
8623
8624(define_expand "iordi3"
8625  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8626	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8627		(match_operand:DI 2 "x86_64_general_operand" "")))
8628   (clobber (reg:CC 17))]
8629  "TARGET_64BIT"
8630  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8631
8632(define_insn "*iordi_1_rex64"
8633  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8634	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8635		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8636   (clobber (reg:CC 17))]
8637  "TARGET_64BIT
8638   && ix86_binary_operator_ok (IOR, DImode, operands)"
8639  "or{q}\t{%2, %0|%0, %2}"
8640  [(set_attr "type" "alu")
8641   (set_attr "mode" "DI")])
8642
8643(define_insn "*iordi_2_rex64"
8644  [(set (reg 17)
8645	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8646			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8647		 (const_int 0)))
8648   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8649	(ior:DI (match_dup 1) (match_dup 2)))]
8650  "TARGET_64BIT
8651   && ix86_match_ccmode (insn, CCNOmode)
8652   && ix86_binary_operator_ok (IOR, DImode, operands)"
8653  "or{q}\t{%2, %0|%0, %2}"
8654  [(set_attr "type" "alu")
8655   (set_attr "mode" "DI")])
8656
8657(define_insn "*iordi_3_rex64"
8658  [(set (reg 17)
8659	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8660			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8661		 (const_int 0)))
8662   (clobber (match_scratch:DI 0 "=r"))]
8663  "TARGET_64BIT
8664   && ix86_match_ccmode (insn, CCNOmode)
8665   && ix86_binary_operator_ok (IOR, DImode, operands)"
8666  "or{q}\t{%2, %0|%0, %2}"
8667  [(set_attr "type" "alu")
8668   (set_attr "mode" "DI")])
8669
8670
8671(define_expand "iorsi3"
8672  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8673	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8674		(match_operand:SI 2 "general_operand" "")))
8675   (clobber (reg:CC 17))]
8676  ""
8677  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8678
8679(define_insn "*iorsi_1"
8680  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8681	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8682		(match_operand:SI 2 "general_operand" "ri,rmi")))
8683   (clobber (reg:CC 17))]
8684  "ix86_binary_operator_ok (IOR, SImode, operands)"
8685  "or{l}\t{%2, %0|%0, %2}"
8686  [(set_attr "type" "alu")
8687   (set_attr "mode" "SI")])
8688
8689;; See comment for addsi_1_zext why we do use nonimmediate_operand
8690(define_insn "*iorsi_1_zext"
8691  [(set (match_operand:DI 0 "register_operand" "=rm")
8692	(zero_extend:DI
8693	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8694		  (match_operand:SI 2 "general_operand" "rim"))))
8695   (clobber (reg:CC 17))]
8696  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8697  "or{l}\t{%2, %k0|%k0, %2}"
8698  [(set_attr "type" "alu")
8699   (set_attr "mode" "SI")])
8700
8701(define_insn "*iorsi_1_zext_imm"
8702  [(set (match_operand:DI 0 "register_operand" "=rm")
8703	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8704		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8705   (clobber (reg:CC 17))]
8706  "TARGET_64BIT"
8707  "or{l}\t{%2, %k0|%k0, %2}"
8708  [(set_attr "type" "alu")
8709   (set_attr "mode" "SI")])
8710
8711(define_insn "*iorsi_2"
8712  [(set (reg 17)
8713	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8714			 (match_operand:SI 2 "general_operand" "rim,ri"))
8715		 (const_int 0)))
8716   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8717	(ior:SI (match_dup 1) (match_dup 2)))]
8718  "ix86_match_ccmode (insn, CCNOmode)
8719   && ix86_binary_operator_ok (IOR, SImode, operands)"
8720  "or{l}\t{%2, %0|%0, %2}"
8721  [(set_attr "type" "alu")
8722   (set_attr "mode" "SI")])
8723
8724;; See comment for addsi_1_zext why we do use nonimmediate_operand
8725;; ??? Special case for immediate operand is missing - it is tricky.
8726(define_insn "*iorsi_2_zext"
8727  [(set (reg 17)
8728	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8729			 (match_operand:SI 2 "general_operand" "rim"))
8730		 (const_int 0)))
8731   (set (match_operand:DI 0 "register_operand" "=r")
8732	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8733  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8734   && ix86_binary_operator_ok (IOR, SImode, operands)"
8735  "or{l}\t{%2, %k0|%k0, %2}"
8736  [(set_attr "type" "alu")
8737   (set_attr "mode" "SI")])
8738
8739(define_insn "*iorsi_2_zext_imm"
8740  [(set (reg 17)
8741	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8742			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8743		 (const_int 0)))
8744   (set (match_operand:DI 0 "register_operand" "=r")
8745	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8746  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8747   && ix86_binary_operator_ok (IOR, SImode, operands)"
8748  "or{l}\t{%2, %k0|%k0, %2}"
8749  [(set_attr "type" "alu")
8750   (set_attr "mode" "SI")])
8751
8752(define_insn "*iorsi_3"
8753  [(set (reg 17)
8754	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8755			 (match_operand:SI 2 "general_operand" "rim"))
8756		 (const_int 0)))
8757   (clobber (match_scratch:SI 0 "=r"))]
8758  "ix86_match_ccmode (insn, CCNOmode)
8759   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760  "or{l}\t{%2, %0|%0, %2}"
8761  [(set_attr "type" "alu")
8762   (set_attr "mode" "SI")])
8763
8764(define_expand "iorhi3"
8765  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8766	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8767		(match_operand:HI 2 "general_operand" "")))
8768   (clobber (reg:CC 17))]
8769  "TARGET_HIMODE_MATH"
8770  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8771
8772(define_insn "*iorhi_1"
8773  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8774	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8775		(match_operand:HI 2 "general_operand" "rmi,ri")))
8776   (clobber (reg:CC 17))]
8777  "ix86_binary_operator_ok (IOR, HImode, operands)"
8778  "or{w}\t{%2, %0|%0, %2}"
8779  [(set_attr "type" "alu")
8780   (set_attr "mode" "HI")])
8781
8782(define_insn "*iorhi_2"
8783  [(set (reg 17)
8784	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8785			 (match_operand:HI 2 "general_operand" "rim,ri"))
8786		 (const_int 0)))
8787   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8788	(ior:HI (match_dup 1) (match_dup 2)))]
8789  "ix86_match_ccmode (insn, CCNOmode)
8790   && ix86_binary_operator_ok (IOR, HImode, operands)"
8791  "or{w}\t{%2, %0|%0, %2}"
8792  [(set_attr "type" "alu")
8793   (set_attr "mode" "HI")])
8794
8795(define_insn "*iorhi_3"
8796  [(set (reg 17)
8797	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8798			 (match_operand:HI 2 "general_operand" "rim"))
8799		 (const_int 0)))
8800   (clobber (match_scratch:HI 0 "=r"))]
8801  "ix86_match_ccmode (insn, CCNOmode)
8802   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8803  "or{w}\t{%2, %0|%0, %2}"
8804  [(set_attr "type" "alu")
8805   (set_attr "mode" "HI")])
8806
8807(define_expand "iorqi3"
8808  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8809	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8810		(match_operand:QI 2 "general_operand" "")))
8811   (clobber (reg:CC 17))]
8812  "TARGET_QIMODE_MATH"
8813  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8814
8815;; %%% Potential partial reg stall on alternative 2.  What to do?
8816(define_insn "*iorqi_1"
8817  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8818	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8819		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8820   (clobber (reg:CC 17))]
8821  "ix86_binary_operator_ok (IOR, QImode, operands)"
8822  "@
8823   or{b}\t{%2, %0|%0, %2}
8824   or{b}\t{%2, %0|%0, %2}
8825   or{l}\t{%k2, %k0|%k0, %k2}"
8826  [(set_attr "type" "alu")
8827   (set_attr "mode" "QI,QI,SI")])
8828
8829(define_insn "*iorqi_1_slp"
8830  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8831	(ior:QI (match_dup 0)
8832		(match_operand:QI 1 "general_operand" "qmi,qi")))
8833   (clobber (reg:CC 17))]
8834  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8835   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8836  "or{b}\t{%1, %0|%0, %1}"
8837  [(set_attr "type" "alu1")
8838   (set_attr "mode" "QI")])
8839
8840(define_insn "*iorqi_2"
8841  [(set (reg 17)
8842	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8843			 (match_operand:QI 2 "general_operand" "qim,qi"))
8844		 (const_int 0)))
8845   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8846	(ior:QI (match_dup 1) (match_dup 2)))]
8847  "ix86_match_ccmode (insn, CCNOmode)
8848   && ix86_binary_operator_ok (IOR, QImode, operands)"
8849  "or{b}\t{%2, %0|%0, %2}"
8850  [(set_attr "type" "alu")
8851   (set_attr "mode" "QI")])
8852
8853(define_insn "*iorqi_2_slp"
8854  [(set (reg 17)
8855	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8856			 (match_operand:QI 1 "general_operand" "qim,qi"))
8857		 (const_int 0)))
8858   (set (strict_low_part (match_dup 0))
8859	(ior:QI (match_dup 0) (match_dup 1)))]
8860  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8861   && ix86_match_ccmode (insn, CCNOmode)
8862   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8863  "or{b}\t{%1, %0|%0, %1}"
8864  [(set_attr "type" "alu1")
8865   (set_attr "mode" "QI")])
8866
8867(define_insn "*iorqi_3"
8868  [(set (reg 17)
8869	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8870			 (match_operand:QI 2 "general_operand" "qim"))
8871		 (const_int 0)))
8872   (clobber (match_scratch:QI 0 "=q"))]
8873  "ix86_match_ccmode (insn, CCNOmode)
8874   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8875  "or{b}\t{%2, %0|%0, %2}"
8876  [(set_attr "type" "alu")
8877   (set_attr "mode" "QI")])
8878
8879(define_insn "iorqi_ext_0"
8880  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8881			 (const_int 8)
8882			 (const_int 8))
8883	(ior:SI 
8884	  (zero_extract:SI
8885	    (match_operand 1 "ext_register_operand" "0")
8886	    (const_int 8)
8887	    (const_int 8))
8888	  (match_operand 2 "const_int_operand" "n")))
8889   (clobber (reg:CC 17))]
8890  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8891  "or{b}\t{%2, %h0|%h0, %2}"
8892  [(set_attr "type" "alu")
8893   (set_attr "length_immediate" "1")
8894   (set_attr "mode" "QI")])
8895
8896(define_insn "*iorqi_ext_1"
8897  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8898			 (const_int 8)
8899			 (const_int 8))
8900	(ior:SI 
8901	  (zero_extract:SI
8902	    (match_operand 1 "ext_register_operand" "0")
8903	    (const_int 8)
8904	    (const_int 8))
8905	  (zero_extend:SI
8906	    (match_operand:QI 2 "general_operand" "Qm"))))
8907   (clobber (reg:CC 17))]
8908  "!TARGET_64BIT
8909   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910  "or{b}\t{%2, %h0|%h0, %2}"
8911  [(set_attr "type" "alu")
8912   (set_attr "length_immediate" "0")
8913   (set_attr "mode" "QI")])
8914
8915(define_insn "*iorqi_ext_1_rex64"
8916  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8917			 (const_int 8)
8918			 (const_int 8))
8919	(ior:SI 
8920	  (zero_extract:SI
8921	    (match_operand 1 "ext_register_operand" "0")
8922	    (const_int 8)
8923	    (const_int 8))
8924	  (zero_extend:SI
8925	    (match_operand 2 "ext_register_operand" "Q"))))
8926   (clobber (reg:CC 17))]
8927  "TARGET_64BIT
8928   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8929  "or{b}\t{%2, %h0|%h0, %2}"
8930  [(set_attr "type" "alu")
8931   (set_attr "length_immediate" "0")
8932   (set_attr "mode" "QI")])
8933
8934(define_insn "*iorqi_ext_2"
8935  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8936			 (const_int 8)
8937			 (const_int 8))
8938	(ior:SI 
8939	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8940	  		   (const_int 8)
8941			   (const_int 8))
8942	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8943	  		   (const_int 8)
8944			   (const_int 8))))
8945   (clobber (reg:CC 17))]
8946  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8947  "ior{b}\t{%h2, %h0|%h0, %h2}"
8948  [(set_attr "type" "alu")
8949   (set_attr "length_immediate" "0")
8950   (set_attr "mode" "QI")])
8951
8952(define_split
8953  [(set (match_operand 0 "register_operand" "")
8954	(ior (match_operand 1 "register_operand" "")
8955	     (match_operand 2 "const_int_operand" "")))
8956   (clobber (reg:CC 17))]
8957   "reload_completed
8958    && QI_REG_P (operands[0])
8959    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8960    && !(INTVAL (operands[2]) & ~(255 << 8))
8961    && GET_MODE (operands[0]) != QImode"
8962  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8963		   (ior:SI (zero_extract:SI (match_dup 1)
8964					    (const_int 8) (const_int 8))
8965			   (match_dup 2)))
8966	      (clobber (reg:CC 17))])]
8967  "operands[0] = gen_lowpart (SImode, operands[0]);
8968   operands[1] = gen_lowpart (SImode, operands[1]);
8969   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8970
8971;; Since OR can be encoded with sign extended immediate, this is only
8972;; profitable when 7th bit is set.
8973(define_split
8974  [(set (match_operand 0 "register_operand" "")
8975	(ior (match_operand 1 "general_operand" "")
8976	     (match_operand 2 "const_int_operand" "")))
8977   (clobber (reg:CC 17))]
8978   "reload_completed
8979    && ANY_QI_REG_P (operands[0])
8980    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8981    && !(INTVAL (operands[2]) & ~255)
8982    && (INTVAL (operands[2]) & 128)
8983    && GET_MODE (operands[0]) != QImode"
8984  [(parallel [(set (strict_low_part (match_dup 0))
8985		   (ior:QI (match_dup 1)
8986			   (match_dup 2)))
8987	      (clobber (reg:CC 17))])]
8988  "operands[0] = gen_lowpart (QImode, operands[0]);
8989   operands[1] = gen_lowpart (QImode, operands[1]);
8990   operands[2] = gen_lowpart (QImode, operands[2]);")
8991
8992;; Logical XOR instructions
8993
8994;; %%% This used to optimize known byte-wide and operations to memory.
8995;; If this is considered useful, it should be done with splitters.
8996
8997(define_expand "xordi3"
8998  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8999	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9000		(match_operand:DI 2 "x86_64_general_operand" "")))
9001   (clobber (reg:CC 17))]
9002  "TARGET_64BIT"
9003  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9004
9005(define_insn "*xordi_1_rex64"
9006  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9007	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9008		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9009   (clobber (reg:CC 17))]
9010  "TARGET_64BIT
9011   && ix86_binary_operator_ok (XOR, DImode, operands)"
9012  "@
9013   xor{q}\t{%2, %0|%0, %2} 
9014   xor{q}\t{%2, %0|%0, %2}"
9015  [(set_attr "type" "alu")
9016   (set_attr "mode" "DI,DI")])
9017
9018(define_insn "*xordi_2_rex64"
9019  [(set (reg 17)
9020	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9021			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9022		 (const_int 0)))
9023   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9024	(xor:DI (match_dup 1) (match_dup 2)))]
9025  "TARGET_64BIT
9026   && ix86_match_ccmode (insn, CCNOmode)
9027   && ix86_binary_operator_ok (XOR, DImode, operands)"
9028  "@
9029   xor{q}\t{%2, %0|%0, %2} 
9030   xor{q}\t{%2, %0|%0, %2}"
9031  [(set_attr "type" "alu")
9032   (set_attr "mode" "DI,DI")])
9033
9034(define_insn "*xordi_3_rex64"
9035  [(set (reg 17)
9036	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9037			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9038		 (const_int 0)))
9039   (clobber (match_scratch:DI 0 "=r"))]
9040  "TARGET_64BIT
9041   && ix86_match_ccmode (insn, CCNOmode)
9042   && ix86_binary_operator_ok (XOR, DImode, operands)"
9043  "xor{q}\t{%2, %0|%0, %2}"
9044  [(set_attr "type" "alu")
9045   (set_attr "mode" "DI")])
9046
9047(define_expand "xorsi3"
9048  [(set (match_operand:SI 0 "nonimmediate_operand" "")
9049	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9050		(match_operand:SI 2 "general_operand" "")))
9051   (clobber (reg:CC 17))]
9052  ""
9053  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9054
9055(define_insn "*xorsi_1"
9056  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9057	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9058		(match_operand:SI 2 "general_operand" "ri,rm")))
9059   (clobber (reg:CC 17))]
9060  "ix86_binary_operator_ok (XOR, SImode, operands)"
9061  "xor{l}\t{%2, %0|%0, %2}"
9062  [(set_attr "type" "alu")
9063   (set_attr "mode" "SI")])
9064
9065;; See comment for addsi_1_zext why we do use nonimmediate_operand
9066;; Add speccase for immediates
9067(define_insn "*xorsi_1_zext"
9068  [(set (match_operand:DI 0 "register_operand" "=r")
9069	(zero_extend:DI
9070	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9071		  (match_operand:SI 2 "general_operand" "rim"))))
9072   (clobber (reg:CC 17))]
9073  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9074  "xor{l}\t{%2, %k0|%k0, %2}"
9075  [(set_attr "type" "alu")
9076   (set_attr "mode" "SI")])
9077
9078(define_insn "*xorsi_1_zext_imm"
9079  [(set (match_operand:DI 0 "register_operand" "=r")
9080	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9081		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9082   (clobber (reg:CC 17))]
9083  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9084  "xor{l}\t{%2, %k0|%k0, %2}"
9085  [(set_attr "type" "alu")
9086   (set_attr "mode" "SI")])
9087
9088(define_insn "*xorsi_2"
9089  [(set (reg 17)
9090	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9091			 (match_operand:SI 2 "general_operand" "rim,ri"))
9092		 (const_int 0)))
9093   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9094	(xor:SI (match_dup 1) (match_dup 2)))]
9095  "ix86_match_ccmode (insn, CCNOmode)
9096   && ix86_binary_operator_ok (XOR, SImode, operands)"
9097  "xor{l}\t{%2, %0|%0, %2}"
9098  [(set_attr "type" "alu")
9099   (set_attr "mode" "SI")])
9100
9101;; See comment for addsi_1_zext why we do use nonimmediate_operand
9102;; ??? Special case for immediate operand is missing - it is tricky.
9103(define_insn "*xorsi_2_zext"
9104  [(set (reg 17)
9105	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9106			 (match_operand:SI 2 "general_operand" "rim"))
9107		 (const_int 0)))
9108   (set (match_operand:DI 0 "register_operand" "=r")
9109	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9110  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9111   && ix86_binary_operator_ok (XOR, SImode, operands)"
9112  "xor{l}\t{%2, %k0|%k0, %2}"
9113  [(set_attr "type" "alu")
9114   (set_attr "mode" "SI")])
9115
9116(define_insn "*xorsi_2_zext_imm"
9117  [(set (reg 17)
9118	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9119			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9120		 (const_int 0)))
9121   (set (match_operand:DI 0 "register_operand" "=r")
9122	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9123  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9124   && ix86_binary_operator_ok (XOR, SImode, operands)"
9125  "xor{l}\t{%2, %k0|%k0, %2}"
9126  [(set_attr "type" "alu")
9127   (set_attr "mode" "SI")])
9128
9129(define_insn "*xorsi_3"
9130  [(set (reg 17)
9131	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9132			 (match_operand:SI 2 "general_operand" "rim"))
9133		 (const_int 0)))
9134   (clobber (match_scratch:SI 0 "=r"))]
9135  "ix86_match_ccmode (insn, CCNOmode)
9136   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9137  "xor{l}\t{%2, %0|%0, %2}"
9138  [(set_attr "type" "alu")
9139   (set_attr "mode" "SI")])
9140
9141(define_expand "xorhi3"
9142  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9143	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9144		(match_operand:HI 2 "general_operand" "")))
9145   (clobber (reg:CC 17))]
9146  "TARGET_HIMODE_MATH"
9147  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9148
9149(define_insn "*xorhi_1"
9150  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9151	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9152		(match_operand:HI 2 "general_operand" "rmi,ri")))
9153   (clobber (reg:CC 17))]
9154  "ix86_binary_operator_ok (XOR, HImode, operands)"
9155  "xor{w}\t{%2, %0|%0, %2}"
9156  [(set_attr "type" "alu")
9157   (set_attr "mode" "HI")])
9158
9159(define_insn "*xorhi_2"
9160  [(set (reg 17)
9161	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9162			 (match_operand:HI 2 "general_operand" "rim,ri"))
9163		 (const_int 0)))
9164   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9165	(xor:HI (match_dup 1) (match_dup 2)))]
9166  "ix86_match_ccmode (insn, CCNOmode)
9167   && ix86_binary_operator_ok (XOR, HImode, operands)"
9168  "xor{w}\t{%2, %0|%0, %2}"
9169  [(set_attr "type" "alu")
9170   (set_attr "mode" "HI")])
9171
9172(define_insn "*xorhi_3"
9173  [(set (reg 17)
9174	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9175			 (match_operand:HI 2 "general_operand" "rim"))
9176		 (const_int 0)))
9177   (clobber (match_scratch:HI 0 "=r"))]
9178  "ix86_match_ccmode (insn, CCNOmode)
9179   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9180  "xor{w}\t{%2, %0|%0, %2}"
9181  [(set_attr "type" "alu")
9182   (set_attr "mode" "HI")])
9183
9184(define_expand "xorqi3"
9185  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9186	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9187		(match_operand:QI 2 "general_operand" "")))
9188   (clobber (reg:CC 17))]
9189  "TARGET_QIMODE_MATH"
9190  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9191
9192;; %%% Potential partial reg stall on alternative 2.  What to do?
9193(define_insn "*xorqi_1"
9194  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9195	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9196		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9197   (clobber (reg:CC 17))]
9198  "ix86_binary_operator_ok (XOR, QImode, operands)"
9199  "@
9200   xor{b}\t{%2, %0|%0, %2}
9201   xor{b}\t{%2, %0|%0, %2}
9202   xor{l}\t{%k2, %k0|%k0, %k2}"
9203  [(set_attr "type" "alu")
9204   (set_attr "mode" "QI,QI,SI")])
9205
9206(define_insn "*xorqi_1_slp"
9207  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9208	(xor:QI (match_dup 0)
9209		(match_operand:QI 1 "general_operand" "qi,qmi")))
9210   (clobber (reg:CC 17))]
9211  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9213  "xor{b}\t{%1, %0|%0, %1}"
9214  [(set_attr "type" "alu1")
9215   (set_attr "mode" "QI")])
9216
9217(define_insn "xorqi_ext_0"
9218  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9219			 (const_int 8)
9220			 (const_int 8))
9221	(xor:SI 
9222	  (zero_extract:SI
9223	    (match_operand 1 "ext_register_operand" "0")
9224	    (const_int 8)
9225	    (const_int 8))
9226	  (match_operand 2 "const_int_operand" "n")))
9227   (clobber (reg:CC 17))]
9228  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9229  "xor{b}\t{%2, %h0|%h0, %2}"
9230  [(set_attr "type" "alu")
9231   (set_attr "length_immediate" "1")
9232   (set_attr "mode" "QI")])
9233
9234(define_insn "*xorqi_ext_1"
9235  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9236			 (const_int 8)
9237			 (const_int 8))
9238	(xor:SI 
9239	  (zero_extract:SI
9240	    (match_operand 1 "ext_register_operand" "0")
9241	    (const_int 8)
9242	    (const_int 8))
9243	  (zero_extend:SI
9244	    (match_operand:QI 2 "general_operand" "Qm"))))
9245   (clobber (reg:CC 17))]
9246  "!TARGET_64BIT
9247   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248  "xor{b}\t{%2, %h0|%h0, %2}"
9249  [(set_attr "type" "alu")
9250   (set_attr "length_immediate" "0")
9251   (set_attr "mode" "QI")])
9252
9253(define_insn "*xorqi_ext_1_rex64"
9254  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9255			 (const_int 8)
9256			 (const_int 8))
9257	(xor:SI 
9258	  (zero_extract:SI
9259	    (match_operand 1 "ext_register_operand" "0")
9260	    (const_int 8)
9261	    (const_int 8))
9262	  (zero_extend:SI
9263	    (match_operand 2 "ext_register_operand" "Q"))))
9264   (clobber (reg:CC 17))]
9265  "TARGET_64BIT
9266   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9267  "xor{b}\t{%2, %h0|%h0, %2}"
9268  [(set_attr "type" "alu")
9269   (set_attr "length_immediate" "0")
9270   (set_attr "mode" "QI")])
9271
9272(define_insn "*xorqi_ext_2"
9273  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274			 (const_int 8)
9275			 (const_int 8))
9276	(xor:SI 
9277	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9278	  		   (const_int 8)
9279			   (const_int 8))
9280	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9281	  		   (const_int 8)
9282			   (const_int 8))))
9283   (clobber (reg:CC 17))]
9284  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9285  "xor{b}\t{%h2, %h0|%h0, %h2}"
9286  [(set_attr "type" "alu")
9287   (set_attr "length_immediate" "0")
9288   (set_attr "mode" "QI")])
9289
9290(define_insn "*xorqi_cc_1"
9291  [(set (reg 17)
9292	(compare
9293	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9294		  (match_operand:QI 2 "general_operand" "qim,qi"))
9295	  (const_int 0)))
9296   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9297	(xor:QI (match_dup 1) (match_dup 2)))]
9298  "ix86_match_ccmode (insn, CCNOmode)
9299   && ix86_binary_operator_ok (XOR, QImode, operands)"
9300  "xor{b}\t{%2, %0|%0, %2}"
9301  [(set_attr "type" "alu")
9302   (set_attr "mode" "QI")])
9303
9304(define_insn "*xorqi_2_slp"
9305  [(set (reg 17)
9306	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9307			 (match_operand:QI 1 "general_operand" "qim,qi"))
9308		 (const_int 0)))
9309   (set (strict_low_part (match_dup 0))
9310	(xor:QI (match_dup 0) (match_dup 1)))]
9311  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9312   && ix86_match_ccmode (insn, CCNOmode)
9313   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9314  "xor{b}\t{%1, %0|%0, %1}"
9315  [(set_attr "type" "alu1")
9316   (set_attr "mode" "QI")])
9317
9318(define_insn "*xorqi_cc_2"
9319  [(set (reg 17)
9320	(compare
9321	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9322		  (match_operand:QI 2 "general_operand" "qim"))
9323	  (const_int 0)))
9324   (clobber (match_scratch:QI 0 "=q"))]
9325  "ix86_match_ccmode (insn, CCNOmode)
9326   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9327  "xor{b}\t{%2, %0|%0, %2}"
9328  [(set_attr "type" "alu")
9329   (set_attr "mode" "QI")])
9330
9331(define_insn "*xorqi_cc_ext_1"
9332  [(set (reg 17)
9333	(compare
9334	  (xor:SI
9335	    (zero_extract:SI
9336	      (match_operand 1 "ext_register_operand" "0")
9337	      (const_int 8)
9338	      (const_int 8))
9339	    (match_operand:QI 2 "general_operand" "qmn"))
9340	  (const_int 0)))
9341   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9342			 (const_int 8)
9343			 (const_int 8))
9344	(xor:SI 
9345	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9346	  (match_dup 2)))]
9347  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9348  "xor{b}\t{%2, %h0|%h0, %2}"
9349  [(set_attr "type" "alu")
9350   (set_attr "mode" "QI")])
9351
9352(define_insn "*xorqi_cc_ext_1_rex64"
9353  [(set (reg 17)
9354	(compare
9355	  (xor:SI
9356	    (zero_extract:SI
9357	      (match_operand 1 "ext_register_operand" "0")
9358	      (const_int 8)
9359	      (const_int 8))
9360	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9361	  (const_int 0)))
9362   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9363			 (const_int 8)
9364			 (const_int 8))
9365	(xor:SI 
9366	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9367	  (match_dup 2)))]
9368  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9369  "xor{b}\t{%2, %h0|%h0, %2}"
9370  [(set_attr "type" "alu")
9371   (set_attr "mode" "QI")])
9372
9373(define_expand "xorqi_cc_ext_1"
9374  [(parallel [
9375     (set (reg:CCNO 17)
9376	  (compare:CCNO
9377	    (xor:SI
9378	      (zero_extract:SI
9379		(match_operand 1 "ext_register_operand" "")
9380		(const_int 8)
9381		(const_int 8))
9382	      (match_operand:QI 2 "general_operand" ""))
9383	    (const_int 0)))
9384     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9385			   (const_int 8)
9386			   (const_int 8))
9387	  (xor:SI 
9388	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9389	    (match_dup 2)))])]
9390  ""
9391  "")
9392
9393(define_split
9394  [(set (match_operand 0 "register_operand" "")
9395	(xor (match_operand 1 "register_operand" "")
9396	     (match_operand 2 "const_int_operand" "")))
9397   (clobber (reg:CC 17))]
9398   "reload_completed
9399    && QI_REG_P (operands[0])
9400    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9401    && !(INTVAL (operands[2]) & ~(255 << 8))
9402    && GET_MODE (operands[0]) != QImode"
9403  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9404		   (xor:SI (zero_extract:SI (match_dup 1)
9405					    (const_int 8) (const_int 8))
9406			   (match_dup 2)))
9407	      (clobber (reg:CC 17))])]
9408  "operands[0] = gen_lowpart (SImode, operands[0]);
9409   operands[1] = gen_lowpart (SImode, operands[1]);
9410   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9411
9412;; Since XOR can be encoded with sign extended immediate, this is only
9413;; profitable when 7th bit is set.
9414(define_split
9415  [(set (match_operand 0 "register_operand" "")
9416	(xor (match_operand 1 "general_operand" "")
9417	     (match_operand 2 "const_int_operand" "")))
9418   (clobber (reg:CC 17))]
9419   "reload_completed
9420    && ANY_QI_REG_P (operands[0])
9421    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9422    && !(INTVAL (operands[2]) & ~255)
9423    && (INTVAL (operands[2]) & 128)
9424    && GET_MODE (operands[0]) != QImode"
9425  [(parallel [(set (strict_low_part (match_dup 0))
9426		   (xor:QI (match_dup 1)
9427			   (match_dup 2)))
9428	      (clobber (reg:CC 17))])]
9429  "operands[0] = gen_lowpart (QImode, operands[0]);
9430   operands[1] = gen_lowpart (QImode, operands[1]);
9431   operands[2] = gen_lowpart (QImode, operands[2]);")
9432
9433;; Negation instructions
9434
9435(define_expand "negdi2"
9436  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9437		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9438	      (clobber (reg:CC 17))])]
9439  ""
9440  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9441
9442(define_insn "*negdi2_1"
9443  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9444	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9445   (clobber (reg:CC 17))]
9446  "!TARGET_64BIT
9447   && ix86_unary_operator_ok (NEG, DImode, operands)"
9448  "#")
9449
9450(define_split
9451  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9452	(neg:DI (match_operand:DI 1 "general_operand" "")))
9453   (clobber (reg:CC 17))]
9454  "!TARGET_64BIT && reload_completed"
9455  [(parallel
9456    [(set (reg:CCZ 17)
9457	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9458     (set (match_dup 0) (neg:SI (match_dup 2)))])
9459   (parallel
9460    [(set (match_dup 1)
9461	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9462			    (match_dup 3))
9463		   (const_int 0)))
9464     (clobber (reg:CC 17))])
9465   (parallel
9466    [(set (match_dup 1)
9467	  (neg:SI (match_dup 1)))
9468     (clobber (reg:CC 17))])]
9469  "split_di (operands+1, 1, operands+2, operands+3);
9470   split_di (operands+0, 1, operands+0, operands+1);")
9471
9472(define_insn "*negdi2_1_rex64"
9473  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9474	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9475   (clobber (reg:CC 17))]
9476  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9477  "neg{q}\t%0"
9478  [(set_attr "type" "negnot")
9479   (set_attr "mode" "DI")])
9480
9481;; The problem with neg is that it does not perform (compare x 0),
9482;; it really performs (compare 0 x), which leaves us with the zero
9483;; flag being the only useful item.
9484
9485(define_insn "*negdi2_cmpz_rex64"
9486  [(set (reg:CCZ 17)
9487	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9488		     (const_int 0)))
9489   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9490	(neg:DI (match_dup 1)))]
9491  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9492  "neg{q}\t%0"
9493  [(set_attr "type" "negnot")
9494   (set_attr "mode" "DI")])
9495
9496
9497(define_expand "negsi2"
9498  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9499		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9500	      (clobber (reg:CC 17))])]
9501  ""
9502  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9503
9504(define_insn "*negsi2_1"
9505  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9506	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9507   (clobber (reg:CC 17))]
9508  "ix86_unary_operator_ok (NEG, SImode, operands)"
9509  "neg{l}\t%0"
9510  [(set_attr "type" "negnot")
9511   (set_attr "mode" "SI")])
9512
9513;; Combine is quite creative about this pattern.
9514(define_insn "*negsi2_1_zext"
9515  [(set (match_operand:DI 0 "register_operand" "=r")
9516	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9517					(const_int 32)))
9518		     (const_int 32)))
9519   (clobber (reg:CC 17))]
9520  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9521  "neg{l}\t%k0"
9522  [(set_attr "type" "negnot")
9523   (set_attr "mode" "SI")])
9524
9525;; The problem with neg is that it does not perform (compare x 0),
9526;; it really performs (compare 0 x), which leaves us with the zero
9527;; flag being the only useful item.
9528
9529(define_insn "*negsi2_cmpz"
9530  [(set (reg:CCZ 17)
9531	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9532		     (const_int 0)))
9533   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9534	(neg:SI (match_dup 1)))]
9535  "ix86_unary_operator_ok (NEG, SImode, operands)"
9536  "neg{l}\t%0"
9537  [(set_attr "type" "negnot")
9538   (set_attr "mode" "SI")])
9539
9540(define_insn "*negsi2_cmpz_zext"
9541  [(set (reg:CCZ 17)
9542	(compare:CCZ (lshiftrt:DI
9543		       (neg:DI (ashift:DI
9544				 (match_operand:DI 1 "register_operand" "0")
9545				 (const_int 32)))
9546		       (const_int 32))
9547		     (const_int 0)))
9548   (set (match_operand:DI 0 "register_operand" "=r")
9549	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9550					(const_int 32)))
9551		     (const_int 32)))]
9552  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9553  "neg{l}\t%k0"
9554  [(set_attr "type" "negnot")
9555   (set_attr "mode" "SI")])
9556
9557(define_expand "neghi2"
9558  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9559		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9560	      (clobber (reg:CC 17))])]
9561  "TARGET_HIMODE_MATH"
9562  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9563
9564(define_insn "*neghi2_1"
9565  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9566	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9567   (clobber (reg:CC 17))]
9568  "ix86_unary_operator_ok (NEG, HImode, operands)"
9569  "neg{w}\t%0"
9570  [(set_attr "type" "negnot")
9571   (set_attr "mode" "HI")])
9572
9573(define_insn "*neghi2_cmpz"
9574  [(set (reg:CCZ 17)
9575	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9576		     (const_int 0)))
9577   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9578	(neg:HI (match_dup 1)))]
9579  "ix86_unary_operator_ok (NEG, HImode, operands)"
9580  "neg{w}\t%0"
9581  [(set_attr "type" "negnot")
9582   (set_attr "mode" "HI")])
9583
9584(define_expand "negqi2"
9585  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9586		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9587	      (clobber (reg:CC 17))])]
9588  "TARGET_QIMODE_MATH"
9589  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9590
9591(define_insn "*negqi2_1"
9592  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9593	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9594   (clobber (reg:CC 17))]
9595  "ix86_unary_operator_ok (NEG, QImode, operands)"
9596  "neg{b}\t%0"
9597  [(set_attr "type" "negnot")
9598   (set_attr "mode" "QI")])
9599
9600(define_insn "*negqi2_cmpz"
9601  [(set (reg:CCZ 17)
9602	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9603		     (const_int 0)))
9604   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9605	(neg:QI (match_dup 1)))]
9606  "ix86_unary_operator_ok (NEG, QImode, operands)"
9607  "neg{b}\t%0"
9608  [(set_attr "type" "negnot")
9609   (set_attr "mode" "QI")])
9610
9611;; Changing of sign for FP values is doable using integer unit too.
9612
9613(define_expand "negsf2"
9614  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9616	      (clobber (reg:CC 17))])]
9617  "TARGET_80387 || TARGET_SSE_MATH"
9618  "if (TARGET_SSE_MATH)
9619     {
9620       /* In case operand is in memory,  we will not use SSE.  */
9621       if (memory_operand (operands[0], VOIDmode)
9622	   && rtx_equal_p (operands[0], operands[1]))
9623	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9624       else
9625	{
9626	  /* Using SSE is tricky, since we need bitwise negation of -0
9627	     in register.  */
9628	  rtx reg = gen_reg_rtx (SFmode);
9629	  rtx dest = operands[0];
9630	  rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9631
9632	  operands[1] = force_reg (SFmode, operands[1]);
9633	  operands[0] = force_reg (SFmode, operands[0]);
9634	  reg = force_reg (V4SFmode,
9635			   gen_rtx_CONST_VECTOR (V4SFmode,
9636			     gen_rtvec (4, imm, CONST0_RTX (SFmode),
9637					CONST0_RTX (SFmode),
9638					CONST0_RTX (SFmode))));
9639	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9640	  if (dest != operands[0])
9641	    emit_move_insn (dest, operands[0]);
9642	}
9643       DONE;
9644     }
9645   ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9646
9647(define_insn "negsf2_memory"
9648  [(set (match_operand:SF 0 "memory_operand" "=m")
9649	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
9650   (clobber (reg:CC 17))]
9651  "ix86_unary_operator_ok (NEG, SFmode, operands)"
9652  "#")
9653
9654(define_insn "negsf2_ifs"
9655  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9656	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9657   (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9658   (clobber (reg:CC 17))]
9659  "TARGET_SSE
9660   && (reload_in_progress || reload_completed
9661       || (register_operand (operands[0], VOIDmode)
9662	   && register_operand (operands[1], VOIDmode)))"
9663  "#")
9664
9665(define_split
9666  [(set (match_operand:SF 0 "memory_operand" "")
9667	(neg:SF (match_operand:SF 1 "memory_operand" "")))
9668   (use (match_operand:SF 2 "" ""))
9669   (clobber (reg:CC 17))]
9670  ""
9671  [(parallel [(set (match_dup 0)
9672		   (neg:SF (match_dup 1)))
9673	      (clobber (reg:CC 17))])])
9674
9675(define_split
9676  [(set (match_operand:SF 0 "register_operand" "")
9677	(neg:SF (match_operand:SF 1 "register_operand" "")))
9678   (use (match_operand:V4SF 2 "" ""))
9679   (clobber (reg:CC 17))]
9680  "reload_completed && !SSE_REG_P (operands[0])"
9681  [(parallel [(set (match_dup 0)
9682		   (neg:SF (match_dup 1)))
9683	      (clobber (reg:CC 17))])])
9684
9685(define_split
9686  [(set (match_operand:SF 0 "register_operand" "")
9687	(neg:SF (match_operand:SF 1 "register_operand" "")))
9688   (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9689   (clobber (reg:CC 17))]
9690  "reload_completed && SSE_REG_P (operands[0])"
9691  [(set (match_dup 0)
9692	(xor:V4SF (match_dup 1)
9693		  (match_dup 2)))]
9694{
9695  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9696  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9697  if (operands_match_p (operands[0], operands[2]))
9698    {
9699      rtx tmp;
9700      tmp = operands[1];
9701      operands[1] = operands[2];
9702      operands[2] = tmp;
9703    }
9704})
9705
9706
9707;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9708;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9709;; to itself.
9710(define_insn "*negsf2_if"
9711  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9712	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9713   (clobber (reg:CC 17))]
9714  "TARGET_80387
9715   && ix86_unary_operator_ok (NEG, SFmode, operands)"
9716  "#")
9717
9718(define_split
9719  [(set (match_operand:SF 0 "fp_register_operand" "")
9720	(neg:SF (match_operand:SF 1 "register_operand" "")))
9721   (clobber (reg:CC 17))]
9722  "TARGET_80387 && reload_completed"
9723  [(set (match_dup 0)
9724	(neg:SF (match_dup 1)))]
9725  "")
9726
9727(define_split
9728  [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9729	(neg:SF (match_operand:SF 1 "register_operand" "")))
9730   (clobber (reg:CC 17))]
9731  "TARGET_80387 && reload_completed"
9732  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9733	      (clobber (reg:CC 17))])]
9734  "operands[1] = gen_int_mode (0x80000000, SImode);
9735   operands[0] = gen_lowpart (SImode, operands[0]);")
9736
9737(define_split
9738  [(set (match_operand 0 "memory_operand" "")
9739	(neg (match_operand 1 "memory_operand" "")))
9740   (clobber (reg:CC 17))]
9741  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9742  [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9743	      (clobber (reg:CC 17))])]
9744{
9745  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9746
9747  if (GET_MODE (operands[1]) == XFmode)
9748    size = 10;
9749  operands[0] = adjust_address (operands[0], QImode, size - 1);
9750  operands[1] = gen_int_mode (0x80, QImode);
9751})
9752
9753(define_expand "negdf2"
9754  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9755		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9756	      (clobber (reg:CC 17))])]
9757  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9758  "if (TARGET_SSE2 && TARGET_SSE_MATH)
9759     {
9760       /* In case operand is in memory,  we will not use SSE.  */
9761       if (memory_operand (operands[0], VOIDmode)
9762	   && rtx_equal_p (operands[0], operands[1]))
9763	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9764       else
9765	{
9766	  /* Using SSE is tricky, since we need bitwise negation of -0
9767	     in register.  */
9768	  rtx reg;
9769#if HOST_BITS_PER_WIDE_INT >= 64
9770	  rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9771#else
9772	  rtx imm = immed_double_const (0, 0x80000000, DImode);
9773#endif
9774	  rtx dest = operands[0];
9775
9776	  operands[1] = force_reg (DFmode, operands[1]);
9777	  operands[0] = force_reg (DFmode, operands[0]);
9778	  imm = gen_lowpart (DFmode, imm);
9779	  reg = force_reg (V2DFmode,
9780			   gen_rtx_CONST_VECTOR (V2DFmode,
9781			     gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9782	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9783	  if (dest != operands[0])
9784	    emit_move_insn (dest, operands[0]);
9785	}
9786       DONE;
9787     }
9788   ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9789
9790(define_insn "negdf2_memory"
9791  [(set (match_operand:DF 0 "memory_operand" "=m")
9792	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
9793   (clobber (reg:CC 17))]
9794  "ix86_unary_operator_ok (NEG, DFmode, operands)"
9795  "#")
9796
9797(define_insn "negdf2_ifs"
9798  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9799	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9800   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9801   (clobber (reg:CC 17))]
9802  "!TARGET_64BIT && TARGET_SSE2
9803   && (reload_in_progress || reload_completed
9804       || (register_operand (operands[0], VOIDmode)
9805	   && register_operand (operands[1], VOIDmode)))"
9806  "#")
9807
9808(define_insn "*negdf2_ifs_rex64"
9809  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9810	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9811   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9812   (clobber (reg:CC 17))]
9813  "TARGET_64BIT && TARGET_SSE2
9814   && (reload_in_progress || reload_completed
9815       || (register_operand (operands[0], VOIDmode)
9816	   && register_operand (operands[1], VOIDmode)))"
9817  "#")
9818
9819(define_split
9820  [(set (match_operand:DF 0 "memory_operand" "")
9821	(neg:DF (match_operand:DF 1 "memory_operand" "")))
9822   (use (match_operand:V2DF 2 "" ""))
9823   (clobber (reg:CC 17))]
9824  ""
9825  [(parallel [(set (match_dup 0)
9826		   (neg:DF (match_dup 1)))
9827	      (clobber (reg:CC 17))])])
9828
9829(define_split
9830  [(set (match_operand:DF 0 "register_operand" "")
9831	(neg:DF (match_operand:DF 1 "register_operand" "")))
9832   (use (match_operand:V2DF 2 "" ""))
9833   (clobber (reg:CC 17))]
9834  "reload_completed && !SSE_REG_P (operands[0])
9835   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9836  [(parallel [(set (match_dup 0)
9837		   (neg:DF (match_dup 1)))
9838	      (clobber (reg:CC 17))])])
9839
9840(define_split
9841  [(set (match_operand:DF 0 "register_operand" "")
9842	(neg:DF (match_operand:DF 1 "register_operand" "")))
9843   (use (match_operand:V2DF 2 "" ""))
9844   (clobber (reg:CC 17))]
9845  "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9846  [(parallel [(set (match_dup 0)
9847		   (xor:DI (match_dup 1) (match_dup 2)))
9848	      (clobber (reg:CC 17))])]
9849   "operands[0] = gen_lowpart (DImode, operands[0]);
9850    operands[1] = gen_lowpart (DImode, operands[1]);
9851    operands[2] = gen_lowpart (DImode, operands[2]);")
9852
9853(define_split
9854  [(set (match_operand:DF 0 "register_operand" "")
9855	(neg:DF (match_operand:DF 1 "register_operand" "")))
9856   (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9857   (clobber (reg:CC 17))]
9858  "reload_completed && SSE_REG_P (operands[0])"
9859  [(set (match_dup 0)
9860	(xor:V2DF (match_dup 1)
9861		  (match_dup 2)))]
9862{
9863  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9864  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9865  /* Avoid possible reformatting on the operands.  */
9866  if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9867    emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9868  if (operands_match_p (operands[0], operands[2]))
9869    {
9870      rtx tmp;
9871      tmp = operands[1];
9872      operands[1] = operands[2];
9873      operands[2] = tmp;
9874    }
9875})
9876
9877;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9878;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9879;; to itself.
9880(define_insn "*negdf2_if"
9881  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9882	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9883   (clobber (reg:CC 17))]
9884  "!TARGET_64BIT && TARGET_80387
9885   && ix86_unary_operator_ok (NEG, DFmode, operands)"
9886  "#")
9887
9888;; FIXME: We should to allow integer registers here.  Problem is that
9889;; we need another scratch register to get constant from.
9890;; Forcing constant to mem if no register available in peep2 should be
9891;; safe even for PIC mode, because of RIP relative addressing.
9892(define_insn "*negdf2_if_rex64"
9893  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9894	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9895   (clobber (reg:CC 17))]
9896  "TARGET_64BIT && TARGET_80387
9897   && ix86_unary_operator_ok (NEG, DFmode, operands)"
9898  "#")
9899
9900(define_split
9901  [(set (match_operand:DF 0 "fp_register_operand" "")
9902	(neg:DF (match_operand:DF 1 "register_operand" "")))
9903   (clobber (reg:CC 17))]
9904  "TARGET_80387 && reload_completed"
9905  [(set (match_dup 0)
9906	(neg:DF (match_dup 1)))]
9907  "")
9908
9909(define_split
9910  [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9911	(neg:DF (match_operand:DF 1 "register_operand" "")))
9912   (clobber (reg:CC 17))]
9913  "!TARGET_64BIT && TARGET_80387 && reload_completed"
9914  [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9915	      (clobber (reg:CC 17))])]
9916  "operands[4] = gen_int_mode (0x80000000, SImode);
9917   split_di (operands+0, 1, operands+2, operands+3);")
9918
9919(define_expand "negxf2"
9920  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9921		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9922	      (clobber (reg:CC 17))])]
9923  "TARGET_80387"
9924  "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9925
9926;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9927;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9928;; to itself.
9929(define_insn "*negxf2_if"
9930  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9931	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9932   (clobber (reg:CC 17))]
9933  "TARGET_80387
9934   && ix86_unary_operator_ok (NEG, XFmode, operands)"
9935  "#")
9936
9937(define_split
9938  [(set (match_operand:XF 0 "fp_register_operand" "")
9939	(neg:XF (match_operand:XF 1 "register_operand" "")))
9940   (clobber (reg:CC 17))]
9941  "TARGET_80387 && reload_completed"
9942  [(set (match_dup 0)
9943	(neg:XF (match_dup 1)))]
9944  "")
9945
9946(define_split
9947  [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9948	(neg:XF (match_operand:XF 1 "register_operand" "")))
9949   (clobber (reg:CC 17))]
9950  "TARGET_80387 && reload_completed"
9951  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9952	      (clobber (reg:CC 17))])]
9953  "operands[1] = GEN_INT (0x8000);
9954   operands[0] = gen_rtx_REG (SImode,
9955			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9956
9957;; Conditionalize these after reload. If they matches before reload, we 
9958;; lose the clobber and ability to use integer instructions.
9959
9960(define_insn "*negsf2_1"
9961  [(set (match_operand:SF 0 "register_operand" "=f")
9962	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963  "TARGET_80387 && reload_completed"
9964  "fchs"
9965  [(set_attr "type" "fsgn")
9966   (set_attr "mode" "SF")
9967   (set_attr "ppro_uops" "few")])
9968
9969(define_insn "*negdf2_1"
9970  [(set (match_operand:DF 0 "register_operand" "=f")
9971	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
9972  "TARGET_80387 && reload_completed"
9973  "fchs"
9974  [(set_attr "type" "fsgn")
9975   (set_attr "mode" "DF")
9976   (set_attr "ppro_uops" "few")])
9977
9978(define_insn "*negextendsfdf2"
9979  [(set (match_operand:DF 0 "register_operand" "=f")
9980	(neg:DF (float_extend:DF
9981		  (match_operand:SF 1 "register_operand" "0"))))]
9982  "TARGET_80387"
9983  "fchs"
9984  [(set_attr "type" "fsgn")
9985   (set_attr "mode" "DF")
9986   (set_attr "ppro_uops" "few")])
9987
9988(define_insn "*negxf2_1"
9989  [(set (match_operand:XF 0 "register_operand" "=f")
9990	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
9991  "TARGET_80387 && reload_completed"
9992  "fchs"
9993  [(set_attr "type" "fsgn")
9994   (set_attr "mode" "XF")
9995   (set_attr "ppro_uops" "few")])
9996
9997(define_insn "*negextenddfxf2"
9998  [(set (match_operand:XF 0 "register_operand" "=f")
9999	(neg:XF (float_extend:XF
10000		  (match_operand:DF 1 "register_operand" "0"))))]
10001  "TARGET_80387"
10002  "fchs"
10003  [(set_attr "type" "fsgn")
10004   (set_attr "mode" "XF")
10005   (set_attr "ppro_uops" "few")])
10006
10007(define_insn "*negextendsfxf2"
10008  [(set (match_operand:XF 0 "register_operand" "=f")
10009	(neg:XF (float_extend:XF
10010		  (match_operand:SF 1 "register_operand" "0"))))]
10011  "TARGET_80387"
10012  "fchs"
10013  [(set_attr "type" "fsgn")
10014   (set_attr "mode" "XF")
10015   (set_attr "ppro_uops" "few")])
10016
10017;; Absolute value instructions
10018
10019(define_expand "abssf2"
10020  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10021		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10022	      (clobber (reg:CC 17))])]
10023  "TARGET_80387 || TARGET_SSE_MATH"
10024  "if (TARGET_SSE_MATH)
10025     {
10026       /* In case operand is in memory,  we will not use SSE.  */
10027       if (memory_operand (operands[0], VOIDmode)
10028	   && rtx_equal_p (operands[0], operands[1]))
10029	 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10030       else
10031	{
10032	  /* Using SSE is tricky, since we need bitwise negation of -0
10033	     in register.  */
10034	  rtx reg = gen_reg_rtx (V4SFmode);
10035	  rtx dest = operands[0];
10036	  rtx imm;
10037
10038	  operands[1] = force_reg (SFmode, operands[1]);
10039	  operands[0] = force_reg (SFmode, operands[0]);
10040	  imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10041	  reg = force_reg (V4SFmode,
10042			   gen_rtx_CONST_VECTOR (V4SFmode,
10043			   gen_rtvec (4, imm, CONST0_RTX (SFmode),
10044				      CONST0_RTX (SFmode),
10045				      CONST0_RTX (SFmode))));
10046	  emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10047	  if (dest != operands[0])
10048	    emit_move_insn (dest, operands[0]);
10049	}
10050       DONE;
10051     }
10052   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10053
10054(define_insn "abssf2_memory"
10055  [(set (match_operand:SF 0 "memory_operand" "=m")
10056	(abs:SF (match_operand:SF 1 "memory_operand" "0")))
10057   (clobber (reg:CC 17))]
10058  "ix86_unary_operator_ok (ABS, SFmode, operands)"
10059  "#")
10060
10061(define_insn "abssf2_ifs"
10062  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10063	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10064   (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10065   (clobber (reg:CC 17))]
10066  "TARGET_SSE
10067   && (reload_in_progress || reload_completed
10068       || (register_operand (operands[0], VOIDmode)
10069	    && register_operand (operands[1], VOIDmode)))"
10070  "#")
10071
10072(define_split
10073  [(set (match_operand:SF 0 "memory_operand" "")
10074	(abs:SF (match_operand:SF 1 "memory_operand" "")))
10075   (use (match_operand:V4SF 2 "" ""))
10076   (clobber (reg:CC 17))]
10077  ""
10078  [(parallel [(set (match_dup 0)
10079		   (abs:SF (match_dup 1)))
10080	      (clobber (reg:CC 17))])])
10081
10082(define_split
10083  [(set (match_operand:SF 0 "register_operand" "")
10084	(abs:SF (match_operand:SF 1 "register_operand" "")))
10085   (use (match_operand:V4SF 2 "" ""))
10086   (clobber (reg:CC 17))]
10087  "reload_completed && !SSE_REG_P (operands[0])"
10088  [(parallel [(set (match_dup 0)
10089		   (abs:SF (match_dup 1)))
10090	      (clobber (reg:CC 17))])])
10091
10092(define_split
10093  [(set (match_operand:SF 0 "register_operand" "")
10094	(abs:SF (match_operand:SF 1 "register_operand" "")))
10095   (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10096   (clobber (reg:CC 17))]
10097  "reload_completed && SSE_REG_P (operands[0])"
10098  [(set (match_dup 0)
10099	(and:V4SF (match_dup 1)
10100		  (match_dup 2)))]
10101{
10102  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10103  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10104  if (operands_match_p (operands[0], operands[2]))
10105    {
10106      rtx tmp;
10107      tmp = operands[1];
10108      operands[1] = operands[2];
10109      operands[2] = tmp;
10110    }
10111})
10112
10113;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10114;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10115;; to itself.
10116(define_insn "*abssf2_if"
10117  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10118	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10119   (clobber (reg:CC 17))]
10120  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
10121  "#")
10122
10123(define_split
10124  [(set (match_operand:SF 0 "fp_register_operand" "")
10125	(abs:SF (match_operand:SF 1 "register_operand" "")))
10126   (clobber (reg:CC 17))]
10127  "TARGET_80387 && reload_completed"
10128  [(set (match_dup 0)
10129	(abs:SF (match_dup 1)))]
10130  "")
10131
10132(define_split
10133  [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10134	(abs:SF (match_operand:SF 1 "register_operand" "")))
10135   (clobber (reg:CC 17))]
10136  "TARGET_80387 && reload_completed"
10137  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10138	      (clobber (reg:CC 17))])]
10139  "operands[1] = gen_int_mode (~0x80000000, SImode);
10140   operands[0] = gen_lowpart (SImode, operands[0]);")
10141
10142(define_split
10143  [(set (match_operand 0 "memory_operand" "")
10144	(abs (match_operand 1 "memory_operand" "")))
10145   (clobber (reg:CC 17))]
10146  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10147  [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10148	      (clobber (reg:CC 17))])]
10149{
10150  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10151
10152  if (GET_MODE (operands[1]) == XFmode)
10153    size = 10;
10154  operands[0] = adjust_address (operands[0], QImode, size - 1);
10155  operands[1] = gen_int_mode (~0x80, QImode);
10156})
10157
10158(define_expand "absdf2"
10159  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10160		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10161	      (clobber (reg:CC 17))])]
10162  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10163  "if (TARGET_SSE2 && TARGET_SSE_MATH)
10164     {
10165       /* In case operand is in memory,  we will not use SSE.  */
10166       if (memory_operand (operands[0], VOIDmode)
10167	   && rtx_equal_p (operands[0], operands[1]))
10168	 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10169       else
10170	{
10171	  /* Using SSE is tricky, since we need bitwise negation of -0
10172	     in register.  */
10173	  rtx reg = gen_reg_rtx (V2DFmode);
10174#if HOST_BITS_PER_WIDE_INT >= 64
10175	  rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10176#else
10177	  rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10178#endif
10179	  rtx dest = operands[0];
10180
10181	  operands[1] = force_reg (DFmode, operands[1]);
10182	  operands[0] = force_reg (DFmode, operands[0]);
10183
10184	  /* Produce LONG_DOUBLE with the proper immediate argument.  */
10185	  imm = gen_lowpart (DFmode, imm);
10186	  reg = force_reg (V2DFmode,
10187			   gen_rtx_CONST_VECTOR (V2DFmode,
10188			   gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10189	  emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10190	  if (dest != operands[0])
10191	    emit_move_insn (dest, operands[0]);
10192	}
10193       DONE;
10194     }
10195   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10196
10197(define_insn "absdf2_memory"
10198  [(set (match_operand:DF 0 "memory_operand" "=m")
10199	(abs:DF (match_operand:DF 1 "memory_operand" "0")))
10200   (clobber (reg:CC 17))]
10201  "ix86_unary_operator_ok (ABS, DFmode, operands)"
10202  "#")
10203
10204(define_insn "absdf2_ifs"
10205  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10206	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10207   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10208   (clobber (reg:CC 17))]
10209  "!TARGET_64BIT && TARGET_SSE2
10210   && (reload_in_progress || reload_completed
10211       || (register_operand (operands[0], VOIDmode)
10212	   && register_operand (operands[1], VOIDmode)))"
10213  "#")
10214
10215(define_insn "*absdf2_ifs_rex64"
10216  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10217	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10218   (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10219   (clobber (reg:CC 17))]
10220  "TARGET_64BIT && TARGET_SSE2
10221   && (reload_in_progress || reload_completed
10222       || (register_operand (operands[0], VOIDmode)
10223	   && register_operand (operands[1], VOIDmode)))"
10224  "#")
10225
10226(define_split
10227  [(set (match_operand:DF 0 "memory_operand" "")
10228	(abs:DF (match_operand:DF 1 "memory_operand" "")))
10229   (use (match_operand:V2DF 2 "" ""))
10230   (clobber (reg:CC 17))]
10231  ""
10232  [(parallel [(set (match_dup 0)
10233		   (abs:DF (match_dup 1)))
10234	      (clobber (reg:CC 17))])])
10235
10236(define_split
10237  [(set (match_operand:DF 0 "register_operand" "")
10238	(abs:DF (match_operand:DF 1 "register_operand" "")))
10239   (use (match_operand:V2DF 2 "" ""))
10240   (clobber (reg:CC 17))]
10241  "reload_completed && !SSE_REG_P (operands[0])"
10242  [(parallel [(set (match_dup 0)
10243		   (abs:DF (match_dup 1)))
10244	      (clobber (reg:CC 17))])])
10245
10246(define_split
10247  [(set (match_operand:DF 0 "register_operand" "")
10248	(abs:DF (match_operand:DF 1 "register_operand" "")))
10249   (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10250   (clobber (reg:CC 17))]
10251  "reload_completed && SSE_REG_P (operands[0])"
10252  [(set (match_dup 0)
10253	(and:V2DF (match_dup 1)
10254		  (match_dup 2)))]
10255{
10256  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10257  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10258  /* Avoid possible reformatting on the operands.  */
10259  if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10260    emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10261  if (operands_match_p (operands[0], operands[2]))
10262    {
10263      rtx tmp;
10264      tmp = operands[1];
10265      operands[1] = operands[2];
10266      operands[2] = tmp;
10267    }
10268})
10269
10270
10271;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10272;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10273;; to itself.
10274(define_insn "*absdf2_if"
10275  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10276	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10277   (clobber (reg:CC 17))]
10278  "!TARGET_64BIT && TARGET_80387
10279   && ix86_unary_operator_ok (ABS, DFmode, operands)"
10280  "#")
10281
10282;; FIXME: We should to allow integer registers here.  Problem is that
10283;; we need another scratch register to get constant from.
10284;; Forcing constant to mem if no register available in peep2 should be
10285;; safe even for PIC mode, because of RIP relative addressing.
10286(define_insn "*absdf2_if_rex64"
10287  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10288	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10289   (clobber (reg:CC 17))]
10290  "TARGET_64BIT && TARGET_80387
10291   && ix86_unary_operator_ok (ABS, DFmode, operands)"
10292  "#")
10293
10294(define_split
10295  [(set (match_operand:DF 0 "fp_register_operand" "")
10296	(abs:DF (match_operand:DF 1 "register_operand" "")))
10297   (clobber (reg:CC 17))]
10298  "TARGET_80387 && reload_completed"
10299  [(set (match_dup 0)
10300	(abs:DF (match_dup 1)))]
10301  "")
10302
10303(define_split
10304  [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10305	(abs:DF (match_operand:DF 1 "register_operand" "")))
10306   (clobber (reg:CC 17))]
10307  "!TARGET_64BIT && TARGET_80387 && reload_completed"
10308  [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10309	      (clobber (reg:CC 17))])]
10310  "operands[4] = gen_int_mode (~0x80000000, SImode);
10311   split_di (operands+0, 1, operands+2, operands+3);")
10312
10313(define_expand "absxf2"
10314  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10315		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10316	      (clobber (reg:CC 17))])]
10317  "TARGET_80387"
10318  "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10319
10320;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10321;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10322;; to itself.
10323(define_insn "*absxf2_if"
10324  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10325	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10326   (clobber (reg:CC 17))]
10327  "TARGET_80387
10328   && ix86_unary_operator_ok (ABS, XFmode, operands)"
10329  "#")
10330
10331(define_split
10332  [(set (match_operand:XF 0 "fp_register_operand" "")
10333	(abs:XF (match_operand:XF 1 "register_operand" "")))
10334   (clobber (reg:CC 17))]
10335  "TARGET_80387 && reload_completed"
10336  [(set (match_dup 0)
10337	(abs:XF (match_dup 1)))]
10338  "")
10339
10340(define_split
10341  [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10342	(abs:XF (match_operand:XF 1 "register_operand" "")))
10343   (clobber (reg:CC 17))]
10344  "TARGET_80387 && reload_completed"
10345  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10346	      (clobber (reg:CC 17))])]
10347  "operands[1] = GEN_INT (~0x8000);
10348   operands[0] = gen_rtx_REG (SImode,
10349			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10350
10351(define_insn "*abssf2_1"
10352  [(set (match_operand:SF 0 "register_operand" "=f")
10353	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
10354  "TARGET_80387 && reload_completed"
10355  "fabs"
10356  [(set_attr "type" "fsgn")
10357   (set_attr "mode" "SF")])
10358
10359(define_insn "*absdf2_1"
10360  [(set (match_operand:DF 0 "register_operand" "=f")
10361	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
10362  "TARGET_80387 && reload_completed"
10363  "fabs"
10364  [(set_attr "type" "fsgn")
10365   (set_attr "mode" "DF")])
10366
10367(define_insn "*absextendsfdf2"
10368  [(set (match_operand:DF 0 "register_operand" "=f")
10369	(abs:DF (float_extend:DF
10370		  (match_operand:SF 1 "register_operand" "0"))))]
10371  "TARGET_80387"
10372  "fabs"
10373  [(set_attr "type" "fsgn")
10374   (set_attr "mode" "DF")])
10375
10376(define_insn "*absxf2_1"
10377  [(set (match_operand:XF 0 "register_operand" "=f")
10378	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
10379  "TARGET_80387 && reload_completed"
10380  "fabs"
10381  [(set_attr "type" "fsgn")
10382   (set_attr "mode" "DF")])
10383
10384(define_insn "*absextenddfxf2"
10385  [(set (match_operand:XF 0 "register_operand" "=f")
10386	(abs:XF (float_extend:XF
10387	  (match_operand:DF 1 "register_operand" "0"))))]
10388  "TARGET_80387"
10389  "fabs"
10390  [(set_attr "type" "fsgn")
10391   (set_attr "mode" "XF")])
10392
10393(define_insn "*absextendsfxf2"
10394  [(set (match_operand:XF 0 "register_operand" "=f")
10395	(abs:XF (float_extend:XF
10396	  (match_operand:SF 1 "register_operand" "0"))))]
10397  "TARGET_80387"
10398  "fabs"
10399  [(set_attr "type" "fsgn")
10400   (set_attr "mode" "XF")])
10401
10402;; One complement instructions
10403
10404(define_expand "one_cmpldi2"
10405  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10406	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10407  "TARGET_64BIT"
10408  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10409
10410(define_insn "*one_cmpldi2_1_rex64"
10411  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10412	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10413  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10414  "not{q}\t%0"
10415  [(set_attr "type" "negnot")
10416   (set_attr "mode" "DI")])
10417
10418(define_insn "*one_cmpldi2_2_rex64"
10419  [(set (reg 17)
10420	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10421		 (const_int 0)))
10422   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10423	(not:DI (match_dup 1)))]
10424  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10425   && ix86_unary_operator_ok (NOT, DImode, operands)"
10426  "#"
10427  [(set_attr "type" "alu1")
10428   (set_attr "mode" "DI")])
10429
10430(define_split
10431  [(set (match_operand 0 "flags_reg_operand" "")
10432	(match_operator 2 "compare_operator"
10433	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10434	   (const_int 0)]))
10435   (set (match_operand:DI 1 "nonimmediate_operand" "")
10436	(not:DI (match_dup 3)))]
10437  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10438  [(parallel [(set (match_dup 0)
10439		   (match_op_dup 2
10440		     [(xor:DI (match_dup 3) (const_int -1))
10441		      (const_int 0)]))
10442	      (set (match_dup 1)
10443		   (xor:DI (match_dup 3) (const_int -1)))])]
10444  "")
10445
10446(define_expand "one_cmplsi2"
10447  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10448	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10449  ""
10450  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10451
10452(define_insn "*one_cmplsi2_1"
10453  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10454	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10455  "ix86_unary_operator_ok (NOT, SImode, operands)"
10456  "not{l}\t%0"
10457  [(set_attr "type" "negnot")
10458   (set_attr "mode" "SI")])
10459
10460;; ??? Currently never generated - xor is used instead.
10461(define_insn "*one_cmplsi2_1_zext"
10462  [(set (match_operand:DI 0 "register_operand" "=r")
10463	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10464  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10465  "not{l}\t%k0"
10466  [(set_attr "type" "negnot")
10467   (set_attr "mode" "SI")])
10468
10469(define_insn "*one_cmplsi2_2"
10470  [(set (reg 17)
10471	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10472		 (const_int 0)))
10473   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10474	(not:SI (match_dup 1)))]
10475  "ix86_match_ccmode (insn, CCNOmode)
10476   && ix86_unary_operator_ok (NOT, SImode, operands)"
10477  "#"
10478  [(set_attr "type" "alu1")
10479   (set_attr "mode" "SI")])
10480
10481(define_split
10482  [(set (match_operand 0 "flags_reg_operand" "")
10483	(match_operator 2 "compare_operator"
10484	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10485	   (const_int 0)]))
10486   (set (match_operand:SI 1 "nonimmediate_operand" "")
10487	(not:SI (match_dup 3)))]
10488  "ix86_match_ccmode (insn, CCNOmode)"
10489  [(parallel [(set (match_dup 0)
10490		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10491				    (const_int 0)]))
10492	      (set (match_dup 1)
10493		   (xor:SI (match_dup 3) (const_int -1)))])]
10494  "")
10495
10496;; ??? Currently never generated - xor is used instead.
10497(define_insn "*one_cmplsi2_2_zext"
10498  [(set (reg 17)
10499	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10500		 (const_int 0)))
10501   (set (match_operand:DI 0 "register_operand" "=r")
10502	(zero_extend:DI (not:SI (match_dup 1))))]
10503  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10504   && ix86_unary_operator_ok (NOT, SImode, operands)"
10505  "#"
10506  [(set_attr "type" "alu1")
10507   (set_attr "mode" "SI")])
10508
10509(define_split
10510  [(set (match_operand 0 "flags_reg_operand" "")
10511	(match_operator 2 "compare_operator"
10512	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10513	   (const_int 0)]))
10514   (set (match_operand:DI 1 "register_operand" "")
10515	(zero_extend:DI (not:SI (match_dup 3))))]
10516  "ix86_match_ccmode (insn, CCNOmode)"
10517  [(parallel [(set (match_dup 0)
10518		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10519				    (const_int 0)]))
10520	      (set (match_dup 1)
10521		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10522  "")
10523
10524(define_expand "one_cmplhi2"
10525  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10526	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10527  "TARGET_HIMODE_MATH"
10528  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10529
10530(define_insn "*one_cmplhi2_1"
10531  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10532	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10533  "ix86_unary_operator_ok (NOT, HImode, operands)"
10534  "not{w}\t%0"
10535  [(set_attr "type" "negnot")
10536   (set_attr "mode" "HI")])
10537
10538(define_insn "*one_cmplhi2_2"
10539  [(set (reg 17)
10540	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10541		 (const_int 0)))
10542   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10543	(not:HI (match_dup 1)))]
10544  "ix86_match_ccmode (insn, CCNOmode)
10545   && ix86_unary_operator_ok (NEG, HImode, operands)"
10546  "#"
10547  [(set_attr "type" "alu1")
10548   (set_attr "mode" "HI")])
10549
10550(define_split
10551  [(set (match_operand 0 "flags_reg_operand" "")
10552	(match_operator 2 "compare_operator"
10553	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10554	   (const_int 0)]))
10555   (set (match_operand:HI 1 "nonimmediate_operand" "")
10556	(not:HI (match_dup 3)))]
10557  "ix86_match_ccmode (insn, CCNOmode)"
10558  [(parallel [(set (match_dup 0)
10559		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10560		      		    (const_int 0)]))
10561	      (set (match_dup 1)
10562		   (xor:HI (match_dup 3) (const_int -1)))])]
10563  "")
10564
10565;; %%% Potential partial reg stall on alternative 1.  What to do?
10566(define_expand "one_cmplqi2"
10567  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10568	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10569  "TARGET_QIMODE_MATH"
10570  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10571
10572(define_insn "*one_cmplqi2_1"
10573  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10574	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10575  "ix86_unary_operator_ok (NOT, QImode, operands)"
10576  "@
10577   not{b}\t%0
10578   not{l}\t%k0"
10579  [(set_attr "type" "negnot")
10580   (set_attr "mode" "QI,SI")])
10581
10582(define_insn "*one_cmplqi2_2"
10583  [(set (reg 17)
10584	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10585		 (const_int 0)))
10586   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10587	(not:QI (match_dup 1)))]
10588  "ix86_match_ccmode (insn, CCNOmode)
10589   && ix86_unary_operator_ok (NOT, QImode, operands)"
10590  "#"
10591  [(set_attr "type" "alu1")
10592   (set_attr "mode" "QI")])
10593
10594(define_split
10595  [(set (match_operand 0 "flags_reg_operand" "")
10596	(match_operator 2 "compare_operator"
10597	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10598	   (const_int 0)]))
10599   (set (match_operand:QI 1 "nonimmediate_operand" "")
10600	(not:QI (match_dup 3)))]
10601  "ix86_match_ccmode (insn, CCNOmode)"
10602  [(parallel [(set (match_dup 0)
10603		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10604		      		    (const_int 0)]))
10605	      (set (match_dup 1)
10606		   (xor:QI (match_dup 3) (const_int -1)))])]
10607  "")
10608
10609;; Arithmetic shift instructions
10610
10611;; DImode shifts are implemented using the i386 "shift double" opcode,
10612;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10613;; is variable, then the count is in %cl and the "imm" operand is dropped
10614;; from the assembler input.
10615;;
10616;; This instruction shifts the target reg/mem as usual, but instead of
10617;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10618;; is a left shift double, bits are taken from the high order bits of
10619;; reg, else if the insn is a shift right double, bits are taken from the
10620;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10621;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10622;;
10623;; Since sh[lr]d does not change the `reg' operand, that is done
10624;; separately, making all shifts emit pairs of shift double and normal
10625;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10626;; support a 63 bit shift, each shift where the count is in a reg expands
10627;; to a pair of shifts, a branch, a shift by 32 and a label.
10628;;
10629;; If the shift count is a constant, we need never emit more than one
10630;; shift pair, instead using moves and sign extension for counts greater
10631;; than 31.
10632
10633(define_expand "ashldi3"
10634  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10635		   (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10636			      (match_operand:QI 2 "nonmemory_operand" "")))
10637	      (clobber (reg:CC 17))])]
10638  ""
10639{
10640  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10641    {
10642      emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10643      DONE;
10644    }
10645  ix86_expand_binary_operator (ASHIFT, DImode, operands);
10646  DONE;
10647})
10648
10649(define_insn "*ashldi3_1_rex64"
10650  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10651	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10652		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10653   (clobber (reg:CC 17))]
10654  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10655{
10656  switch (get_attr_type (insn))
10657    {
10658    case TYPE_ALU:
10659      if (operands[2] != const1_rtx)
10660	abort ();
10661      if (!rtx_equal_p (operands[0], operands[1]))
10662	abort ();
10663      return "add{q}\t{%0, %0|%0, %0}";
10664
10665    case TYPE_LEA:
10666      if (GET_CODE (operands[2]) != CONST_INT
10667	  || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10668	abort ();
10669      operands[1] = gen_rtx_MULT (DImode, operands[1],
10670				  GEN_INT (1 << INTVAL (operands[2])));
10671      return "lea{q}\t{%a1, %0|%0, %a1}";
10672
10673    default:
10674      if (REG_P (operands[2]))
10675	return "sal{q}\t{%b2, %0|%0, %b2}";
10676      else if (GET_CODE (operands[2]) == CONST_INT
10677	       && INTVAL (operands[2]) == 1
10678	       && (TARGET_SHIFT1 || optimize_size))
10679	return "sal{q}\t%0";
10680      else
10681	return "sal{q}\t{%2, %0|%0, %2}";
10682    }
10683}
10684  [(set (attr "type")
10685     (cond [(eq_attr "alternative" "1")
10686	      (const_string "lea")
10687            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10688		          (const_int 0))
10689		      (match_operand 0 "register_operand" ""))
10690		 (match_operand 2 "const1_operand" ""))
10691	      (const_string "alu")
10692	   ]
10693	   (const_string "ishift")))
10694   (set_attr "mode" "DI")])
10695
10696;; Convert lea to the lea pattern to avoid flags dependency.
10697(define_split
10698  [(set (match_operand:DI 0 "register_operand" "")
10699	(ashift:DI (match_operand:DI 1 "register_operand" "")
10700		   (match_operand:QI 2 "immediate_operand" "")))
10701   (clobber (reg:CC 17))]
10702  "TARGET_64BIT && reload_completed
10703   && true_regnum (operands[0]) != true_regnum (operands[1])"
10704  [(set (match_dup 0)
10705	(mult:DI (match_dup 1)
10706		 (match_dup 2)))]
10707  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10708
10709;; This pattern can't accept a variable shift count, since shifts by
10710;; zero don't affect the flags.  We assume that shifts by constant
10711;; zero are optimized away.
10712(define_insn "*ashldi3_cmp_rex64"
10713  [(set (reg 17)
10714	(compare
10715	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10716		     (match_operand:QI 2 "immediate_operand" "e"))
10717	  (const_int 0)))
10718   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10719	(ashift:DI (match_dup 1) (match_dup 2)))]
10720  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10721   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10722{
10723  switch (get_attr_type (insn))
10724    {
10725    case TYPE_ALU:
10726      if (operands[2] != const1_rtx)
10727	abort ();
10728      return "add{q}\t{%0, %0|%0, %0}";
10729
10730    default:
10731      if (REG_P (operands[2]))
10732	return "sal{q}\t{%b2, %0|%0, %b2}";
10733      else if (GET_CODE (operands[2]) == CONST_INT
10734	       && INTVAL (operands[2]) == 1
10735	       && (TARGET_SHIFT1 || optimize_size))
10736	return "sal{q}\t%0";
10737      else
10738	return "sal{q}\t{%2, %0|%0, %2}";
10739    }
10740}
10741  [(set (attr "type")
10742     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10743		          (const_int 0))
10744		      (match_operand 0 "register_operand" ""))
10745		 (match_operand 2 "const1_operand" ""))
10746	      (const_string "alu")
10747	   ]
10748	   (const_string "ishift")))
10749   (set_attr "mode" "DI")])
10750
10751(define_insn "ashldi3_1"
10752  [(set (match_operand:DI 0 "register_operand" "=r")
10753	(ashift:DI (match_operand:DI 1 "register_operand" "0")
10754		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
10755   (clobber (match_scratch:SI 3 "=&r"))
10756   (clobber (reg:CC 17))]
10757  "!TARGET_64BIT && TARGET_CMOVE"
10758  "#"
10759  [(set_attr "type" "multi")])
10760
10761(define_insn "*ashldi3_2"
10762  [(set (match_operand:DI 0 "register_operand" "=r")
10763	(ashift:DI (match_operand:DI 1 "register_operand" "0")
10764		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
10765   (clobber (reg:CC 17))]
10766  "!TARGET_64BIT"
10767  "#"
10768  [(set_attr "type" "multi")])
10769
10770(define_split
10771  [(set (match_operand:DI 0 "register_operand" "")
10772	(ashift:DI (match_operand:DI 1 "register_operand" "")
10773		   (match_operand:QI 2 "nonmemory_operand" "")))
10774   (clobber (match_scratch:SI 3 ""))
10775   (clobber (reg:CC 17))]
10776  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10777  [(const_int 0)]
10778  "ix86_split_ashldi (operands, operands[3]); DONE;")
10779
10780(define_split
10781  [(set (match_operand:DI 0 "register_operand" "")
10782	(ashift:DI (match_operand:DI 1 "register_operand" "")
10783		   (match_operand:QI 2 "nonmemory_operand" "")))
10784   (clobber (reg:CC 17))]
10785  "!TARGET_64BIT && reload_completed"
10786  [(const_int 0)]
10787  "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10788
10789(define_insn "x86_shld_1"
10790  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10791        (ior:SI (ashift:SI (match_dup 0)
10792		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10793		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10794		  (minus:QI (const_int 32) (match_dup 2)))))
10795   (clobber (reg:CC 17))]
10796  ""
10797  "@
10798   shld{l}\t{%2, %1, %0|%0, %1, %2}
10799   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10800  [(set_attr "type" "ishift")
10801   (set_attr "prefix_0f" "1")
10802   (set_attr "mode" "SI")
10803   (set_attr "pent_pair" "np")
10804   (set_attr "athlon_decode" "vector")
10805   (set_attr "ppro_uops" "few")])
10806
10807(define_expand "x86_shift_adj_1"
10808  [(set (reg:CCZ 17)
10809	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10810			     (const_int 32))
10811		     (const_int 0)))
10812   (set (match_operand:SI 0 "register_operand" "")
10813        (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10814			 (match_operand:SI 1 "register_operand" "")
10815			 (match_dup 0)))
10816   (set (match_dup 1)
10817	(if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10818			 (match_operand:SI 3 "register_operand" "r")
10819			 (match_dup 1)))]
10820  "TARGET_CMOVE"
10821  "")
10822
10823(define_expand "x86_shift_adj_2"
10824  [(use (match_operand:SI 0 "register_operand" ""))
10825   (use (match_operand:SI 1 "register_operand" ""))
10826   (use (match_operand:QI 2 "register_operand" ""))]
10827  ""
10828{
10829  rtx label = gen_label_rtx ();
10830  rtx tmp;
10831
10832  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10833
10834  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10835  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10836  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10837			      gen_rtx_LABEL_REF (VOIDmode, label),
10838			      pc_rtx);
10839  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10840  JUMP_LABEL (tmp) = label;
10841
10842  emit_move_insn (operands[0], operands[1]);
10843  emit_move_insn (operands[1], const0_rtx);
10844
10845  emit_label (label);
10846  LABEL_NUSES (label) = 1;
10847
10848  DONE;
10849})
10850
10851(define_expand "ashlsi3"
10852  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10853	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10854		   (match_operand:QI 2 "nonmemory_operand" "")))
10855   (clobber (reg:CC 17))]
10856  ""
10857  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10858
10859(define_insn "*ashlsi3_1"
10860  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10861	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10862		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10863   (clobber (reg:CC 17))]
10864  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10865{
10866  switch (get_attr_type (insn))
10867    {
10868    case TYPE_ALU:
10869      if (operands[2] != const1_rtx)
10870	abort ();
10871      if (!rtx_equal_p (operands[0], operands[1]))
10872	abort ();
10873      return "add{l}\t{%0, %0|%0, %0}";
10874
10875    case TYPE_LEA:
10876      return "#";
10877
10878    default:
10879      if (REG_P (operands[2]))
10880	return "sal{l}\t{%b2, %0|%0, %b2}";
10881      else if (GET_CODE (operands[2]) == CONST_INT
10882	       && INTVAL (operands[2]) == 1
10883	       && (TARGET_SHIFT1 || optimize_size))
10884	return "sal{l}\t%0";
10885      else
10886	return "sal{l}\t{%2, %0|%0, %2}";
10887    }
10888}
10889  [(set (attr "type")
10890     (cond [(eq_attr "alternative" "1")
10891	      (const_string "lea")
10892            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893		          (const_int 0))
10894		      (match_operand 0 "register_operand" ""))
10895		 (match_operand 2 "const1_operand" ""))
10896	      (const_string "alu")
10897	   ]
10898	   (const_string "ishift")))
10899   (set_attr "mode" "SI")])
10900
10901;; Convert lea to the lea pattern to avoid flags dependency.
10902(define_split
10903  [(set (match_operand 0 "register_operand" "")
10904	(ashift (match_operand 1 "index_register_operand" "")
10905                (match_operand:QI 2 "const_int_operand" "")))
10906   (clobber (reg:CC 17))]
10907  "reload_completed
10908   && true_regnum (operands[0]) != true_regnum (operands[1])"
10909  [(const_int 0)]
10910{
10911  rtx pat;
10912  operands[0] = gen_lowpart (SImode, operands[0]);
10913  operands[1] = gen_lowpart (Pmode, operands[1]);
10914  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10915  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10916  if (Pmode != SImode)
10917    pat = gen_rtx_SUBREG (SImode, pat, 0);
10918  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10919  DONE;
10920})
10921
10922;; Rare case of shifting RSP is handled by generating move and shift
10923(define_split
10924  [(set (match_operand 0 "register_operand" "")
10925	(ashift (match_operand 1 "register_operand" "")
10926                (match_operand:QI 2 "const_int_operand" "")))
10927   (clobber (reg:CC 17))]
10928  "reload_completed
10929   && true_regnum (operands[0]) != true_regnum (operands[1])"
10930  [(const_int 0)]
10931{
10932  rtx pat, clob;
10933  emit_move_insn (operands[1], operands[0]);
10934  pat = gen_rtx_SET (VOIDmode, operands[0],
10935		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10936				     operands[0], operands[2]));
10937  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10938  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10939  DONE;
10940})
10941
10942(define_insn "*ashlsi3_1_zext"
10943  [(set (match_operand:DI 0 "register_operand" "=r,r")
10944	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10945			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10946   (clobber (reg:CC 17))]
10947  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10948{
10949  switch (get_attr_type (insn))
10950    {
10951    case TYPE_ALU:
10952      if (operands[2] != const1_rtx)
10953	abort ();
10954      return "add{l}\t{%k0, %k0|%k0, %k0}";
10955
10956    case TYPE_LEA:
10957      return "#";
10958
10959    default:
10960      if (REG_P (operands[2]))
10961	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10962      else if (GET_CODE (operands[2]) == CONST_INT
10963	       && INTVAL (operands[2]) == 1
10964	       && (TARGET_SHIFT1 || optimize_size))
10965	return "sal{l}\t%k0";
10966      else
10967	return "sal{l}\t{%2, %k0|%k0, %2}";
10968    }
10969}
10970  [(set (attr "type")
10971     (cond [(eq_attr "alternative" "1")
10972	      (const_string "lea")
10973            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974		     (const_int 0))
10975		 (match_operand 2 "const1_operand" ""))
10976	      (const_string "alu")
10977	   ]
10978	   (const_string "ishift")))
10979   (set_attr "mode" "SI")])
10980
10981;; Convert lea to the lea pattern to avoid flags dependency.
10982(define_split
10983  [(set (match_operand:DI 0 "register_operand" "")
10984	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10985				(match_operand:QI 2 "const_int_operand" ""))))
10986   (clobber (reg:CC 17))]
10987  "TARGET_64BIT && reload_completed
10988   && true_regnum (operands[0]) != true_regnum (operands[1])"
10989  [(set (match_dup 0) (zero_extend:DI
10990			(subreg:SI (mult:SI (match_dup 1)
10991					    (match_dup 2)) 0)))]
10992{
10993  operands[1] = gen_lowpart (Pmode, operands[1]);
10994  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10995})
10996
10997;; This pattern can't accept a variable shift count, since shifts by
10998;; zero don't affect the flags.  We assume that shifts by constant
10999;; zero are optimized away.
11000(define_insn "*ashlsi3_cmp"
11001  [(set (reg 17)
11002	(compare
11003	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11004		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
11005	  (const_int 0)))
11006   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11007	(ashift:SI (match_dup 1) (match_dup 2)))]
11008  "ix86_match_ccmode (insn, CCGOCmode)
11009   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11010{
11011  switch (get_attr_type (insn))
11012    {
11013    case TYPE_ALU:
11014      if (operands[2] != const1_rtx)
11015	abort ();
11016      return "add{l}\t{%0, %0|%0, %0}";
11017
11018    default:
11019      if (REG_P (operands[2]))
11020	return "sal{l}\t{%b2, %0|%0, %b2}";
11021      else if (GET_CODE (operands[2]) == CONST_INT
11022	       && INTVAL (operands[2]) == 1
11023	       && (TARGET_SHIFT1 || optimize_size))
11024	return "sal{l}\t%0";
11025      else
11026	return "sal{l}\t{%2, %0|%0, %2}";
11027    }
11028}
11029  [(set (attr "type")
11030     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031		          (const_int 0))
11032		      (match_operand 0 "register_operand" ""))
11033		 (match_operand 2 "const1_operand" ""))
11034	      (const_string "alu")
11035	   ]
11036	   (const_string "ishift")))
11037   (set_attr "mode" "SI")])
11038
11039(define_insn "*ashlsi3_cmp_zext"
11040  [(set (reg 17)
11041	(compare
11042	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
11043		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
11044	  (const_int 0)))
11045   (set (match_operand:DI 0 "register_operand" "=r")
11046	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11047  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11048   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11049{
11050  switch (get_attr_type (insn))
11051    {
11052    case TYPE_ALU:
11053      if (operands[2] != const1_rtx)
11054	abort ();
11055      return "add{l}\t{%k0, %k0|%k0, %k0}";
11056
11057    default:
11058      if (REG_P (operands[2]))
11059	return "sal{l}\t{%b2, %k0|%k0, %b2}";
11060      else if (GET_CODE (operands[2]) == CONST_INT
11061	       && INTVAL (operands[2]) == 1
11062	       && (TARGET_SHIFT1 || optimize_size))
11063	return "sal{l}\t%k0";
11064      else
11065	return "sal{l}\t{%2, %k0|%k0, %2}";
11066    }
11067}
11068  [(set (attr "type")
11069     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11070		     (const_int 0))
11071		 (match_operand 2 "const1_operand" ""))
11072	      (const_string "alu")
11073	   ]
11074	   (const_string "ishift")))
11075   (set_attr "mode" "SI")])
11076
11077(define_expand "ashlhi3"
11078  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11079	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11080		   (match_operand:QI 2 "nonmemory_operand" "")))
11081   (clobber (reg:CC 17))]
11082  "TARGET_HIMODE_MATH"
11083  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11084
11085(define_insn "*ashlhi3_1_lea"
11086  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11087	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11088		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11089   (clobber (reg:CC 17))]
11090  "!TARGET_PARTIAL_REG_STALL
11091   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11092{
11093  switch (get_attr_type (insn))
11094    {
11095    case TYPE_LEA:
11096      return "#";
11097    case TYPE_ALU:
11098      if (operands[2] != const1_rtx)
11099	abort ();
11100      return "add{w}\t{%0, %0|%0, %0}";
11101
11102    default:
11103      if (REG_P (operands[2]))
11104	return "sal{w}\t{%b2, %0|%0, %b2}";
11105      else if (GET_CODE (operands[2]) == CONST_INT
11106	       && INTVAL (operands[2]) == 1
11107	       && (TARGET_SHIFT1 || optimize_size))
11108	return "sal{w}\t%0";
11109      else
11110	return "sal{w}\t{%2, %0|%0, %2}";
11111    }
11112}
11113  [(set (attr "type")
11114     (cond [(eq_attr "alternative" "1")
11115	      (const_string "lea")
11116            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11117		          (const_int 0))
11118		      (match_operand 0 "register_operand" ""))
11119		 (match_operand 2 "const1_operand" ""))
11120	      (const_string "alu")
11121	   ]
11122	   (const_string "ishift")))
11123   (set_attr "mode" "HI,SI")])
11124
11125(define_insn "*ashlhi3_1"
11126  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11127	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11128		   (match_operand:QI 2 "nonmemory_operand" "cI")))
11129   (clobber (reg:CC 17))]
11130  "TARGET_PARTIAL_REG_STALL
11131   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11132{
11133  switch (get_attr_type (insn))
11134    {
11135    case TYPE_ALU:
11136      if (operands[2] != const1_rtx)
11137	abort ();
11138      return "add{w}\t{%0, %0|%0, %0}";
11139
11140    default:
11141      if (REG_P (operands[2]))
11142	return "sal{w}\t{%b2, %0|%0, %b2}";
11143      else if (GET_CODE (operands[2]) == CONST_INT
11144	       && INTVAL (operands[2]) == 1
11145	       && (TARGET_SHIFT1 || optimize_size))
11146	return "sal{w}\t%0";
11147      else
11148	return "sal{w}\t{%2, %0|%0, %2}";
11149    }
11150}
11151  [(set (attr "type")
11152     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11153		          (const_int 0))
11154		      (match_operand 0 "register_operand" ""))
11155		 (match_operand 2 "const1_operand" ""))
11156	      (const_string "alu")
11157	   ]
11158	   (const_string "ishift")))
11159   (set_attr "mode" "HI")])
11160
11161;; This pattern can't accept a variable shift count, since shifts by
11162;; zero don't affect the flags.  We assume that shifts by constant
11163;; zero are optimized away.
11164(define_insn "*ashlhi3_cmp"
11165  [(set (reg 17)
11166	(compare
11167	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11168		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
11169	  (const_int 0)))
11170   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11171	(ashift:HI (match_dup 1) (match_dup 2)))]
11172  "ix86_match_ccmode (insn, CCGOCmode)
11173   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11174{
11175  switch (get_attr_type (insn))
11176    {
11177    case TYPE_ALU:
11178      if (operands[2] != const1_rtx)
11179	abort ();
11180      return "add{w}\t{%0, %0|%0, %0}";
11181
11182    default:
11183      if (REG_P (operands[2]))
11184	return "sal{w}\t{%b2, %0|%0, %b2}";
11185      else if (GET_CODE (operands[2]) == CONST_INT
11186	       && INTVAL (operands[2]) == 1
11187	       && (TARGET_SHIFT1 || optimize_size))
11188	return "sal{w}\t%0";
11189      else
11190	return "sal{w}\t{%2, %0|%0, %2}";
11191    }
11192}
11193  [(set (attr "type")
11194     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11195		          (const_int 0))
11196		      (match_operand 0 "register_operand" ""))
11197		 (match_operand 2 "const1_operand" ""))
11198	      (const_string "alu")
11199	   ]
11200	   (const_string "ishift")))
11201   (set_attr "mode" "HI")])
11202
11203(define_expand "ashlqi3"
11204  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11205	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11206		   (match_operand:QI 2 "nonmemory_operand" "")))
11207   (clobber (reg:CC 17))]
11208  "TARGET_QIMODE_MATH"
11209  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11210
11211;; %%% Potential partial reg stall on alternative 2.  What to do?
11212
11213(define_insn "*ashlqi3_1_lea"
11214  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11215	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11216		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11217   (clobber (reg:CC 17))]
11218  "!TARGET_PARTIAL_REG_STALL
11219   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11220{
11221  switch (get_attr_type (insn))
11222    {
11223    case TYPE_LEA:
11224      return "#";
11225    case TYPE_ALU:
11226      if (operands[2] != const1_rtx)
11227	abort ();
11228      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11229        return "add{l}\t{%k0, %k0|%k0, %k0}";
11230      else
11231        return "add{b}\t{%0, %0|%0, %0}";
11232
11233    default:
11234      if (REG_P (operands[2]))
11235	{
11236	  if (get_attr_mode (insn) == MODE_SI)
11237	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11238	  else
11239	    return "sal{b}\t{%b2, %0|%0, %b2}";
11240	}
11241      else if (GET_CODE (operands[2]) == CONST_INT
11242	       && INTVAL (operands[2]) == 1
11243	       && (TARGET_SHIFT1 || optimize_size))
11244	{
11245	  if (get_attr_mode (insn) == MODE_SI)
11246	    return "sal{l}\t%0";
11247	  else
11248	    return "sal{b}\t%0";
11249	}
11250      else
11251	{
11252	  if (get_attr_mode (insn) == MODE_SI)
11253	    return "sal{l}\t{%2, %k0|%k0, %2}";
11254	  else
11255	    return "sal{b}\t{%2, %0|%0, %2}";
11256	}
11257    }
11258}
11259  [(set (attr "type")
11260     (cond [(eq_attr "alternative" "2")
11261	      (const_string "lea")
11262            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11263		          (const_int 0))
11264		      (match_operand 0 "register_operand" ""))
11265		 (match_operand 2 "const1_operand" ""))
11266	      (const_string "alu")
11267	   ]
11268	   (const_string "ishift")))
11269   (set_attr "mode" "QI,SI,SI")])
11270
11271(define_insn "*ashlqi3_1"
11272  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11273	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11274		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11275   (clobber (reg:CC 17))]
11276  "TARGET_PARTIAL_REG_STALL
11277   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11278{
11279  switch (get_attr_type (insn))
11280    {
11281    case TYPE_ALU:
11282      if (operands[2] != const1_rtx)
11283	abort ();
11284      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11285        return "add{l}\t{%k0, %k0|%k0, %k0}";
11286      else
11287        return "add{b}\t{%0, %0|%0, %0}";
11288
11289    default:
11290      if (REG_P (operands[2]))
11291	{
11292	  if (get_attr_mode (insn) == MODE_SI)
11293	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11294	  else
11295	    return "sal{b}\t{%b2, %0|%0, %b2}";
11296	}
11297      else if (GET_CODE (operands[2]) == CONST_INT
11298	       && INTVAL (operands[2]) == 1
11299	       && (TARGET_SHIFT1 || optimize_size))
11300	{
11301	  if (get_attr_mode (insn) == MODE_SI)
11302	    return "sal{l}\t%0";
11303	  else
11304	    return "sal{b}\t%0";
11305	}
11306      else
11307	{
11308	  if (get_attr_mode (insn) == MODE_SI)
11309	    return "sal{l}\t{%2, %k0|%k0, %2}";
11310	  else
11311	    return "sal{b}\t{%2, %0|%0, %2}";
11312	}
11313    }
11314}
11315  [(set (attr "type")
11316     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11317		          (const_int 0))
11318		      (match_operand 0 "register_operand" ""))
11319		 (match_operand 2 "const1_operand" ""))
11320	      (const_string "alu")
11321	   ]
11322	   (const_string "ishift")))
11323   (set_attr "mode" "QI,SI")])
11324
11325;; This pattern can't accept a variable shift count, since shifts by
11326;; zero don't affect the flags.  We assume that shifts by constant
11327;; zero are optimized away.
11328(define_insn "*ashlqi3_cmp"
11329  [(set (reg 17)
11330	(compare
11331	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11332		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
11333	  (const_int 0)))
11334   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11335	(ashift:QI (match_dup 1) (match_dup 2)))]
11336  "ix86_match_ccmode (insn, CCGOCmode)
11337   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11338{
11339  switch (get_attr_type (insn))
11340    {
11341    case TYPE_ALU:
11342      if (operands[2] != const1_rtx)
11343	abort ();
11344      return "add{b}\t{%0, %0|%0, %0}";
11345
11346    default:
11347      if (REG_P (operands[2]))
11348	return "sal{b}\t{%b2, %0|%0, %b2}";
11349      else if (GET_CODE (operands[2]) == CONST_INT
11350	       && INTVAL (operands[2]) == 1
11351	       && (TARGET_SHIFT1 || optimize_size))
11352	return "sal{b}\t%0";
11353      else
11354	return "sal{b}\t{%2, %0|%0, %2}";
11355    }
11356}
11357  [(set (attr "type")
11358     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11359		          (const_int 0))
11360		      (match_operand 0 "register_operand" ""))
11361		 (match_operand 2 "const1_operand" ""))
11362	      (const_string "alu")
11363	   ]
11364	   (const_string "ishift")))
11365   (set_attr "mode" "QI")])
11366
11367;; See comment above `ashldi3' about how this works.
11368
11369(define_expand "ashrdi3"
11370  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11371		   (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11372				(match_operand:QI 2 "nonmemory_operand" "")))
11373	      (clobber (reg:CC 17))])]
11374  ""
11375{
11376  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11377    {
11378      emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11379      DONE;
11380    }
11381  ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11382  DONE;
11383})
11384
11385(define_insn "ashrdi3_63_rex64"
11386  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11387	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11388		     (match_operand:DI 2 "const_int_operand" "i,i")))
11389   (clobber (reg:CC 17))]
11390  "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11391   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11392  "@
11393   {cqto|cqo}
11394   sar{q}\t{%2, %0|%0, %2}"
11395  [(set_attr "type" "imovx,ishift")
11396   (set_attr "prefix_0f" "0,*")
11397   (set_attr "length_immediate" "0,*")
11398   (set_attr "modrm" "0,1")
11399   (set_attr "mode" "DI")])
11400
11401(define_insn "*ashrdi3_1_one_bit_rex64"
11402  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11403	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404		     (match_operand:QI 2 "const1_operand" "")))
11405   (clobber (reg:CC 17))]
11406  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11407   && (TARGET_SHIFT1 || optimize_size)"
11408  "sar{q}\t%0"
11409  [(set_attr "type" "ishift")
11410   (set (attr "length") 
11411     (if_then_else (match_operand:DI 0 "register_operand" "") 
11412	(const_string "2")
11413	(const_string "*")))])
11414
11415(define_insn "*ashrdi3_1_rex64"
11416  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11417	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11418		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11419   (clobber (reg:CC 17))]
11420  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11421  "@
11422   sar{q}\t{%2, %0|%0, %2}
11423   sar{q}\t{%b2, %0|%0, %b2}"
11424  [(set_attr "type" "ishift")
11425   (set_attr "mode" "DI")])
11426
11427;; This pattern can't accept a variable shift count, since shifts by
11428;; zero don't affect the flags.  We assume that shifts by constant
11429;; zero are optimized away.
11430(define_insn "*ashrdi3_one_bit_cmp_rex64"
11431  [(set (reg 17)
11432	(compare
11433	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434		       (match_operand:QI 2 "const1_operand" ""))
11435	  (const_int 0)))
11436   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11438  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439   && (TARGET_SHIFT1 || optimize_size)
11440   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11441  "sar{q}\t%0"
11442  [(set_attr "type" "ishift")
11443   (set (attr "length") 
11444     (if_then_else (match_operand:DI 0 "register_operand" "") 
11445	(const_string "2")
11446	(const_string "*")))])
11447
11448;; This pattern can't accept a variable shift count, since shifts by
11449;; zero don't affect the flags.  We assume that shifts by constant
11450;; zero are optimized away.
11451(define_insn "*ashrdi3_cmp_rex64"
11452  [(set (reg 17)
11453	(compare
11454	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11455		       (match_operand:QI 2 "const_int_operand" "n"))
11456	  (const_int 0)))
11457   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11458	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11459  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11460   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11461  "sar{q}\t{%2, %0|%0, %2}"
11462  [(set_attr "type" "ishift")
11463   (set_attr "mode" "DI")])
11464
11465
11466(define_insn "ashrdi3_1"
11467  [(set (match_operand:DI 0 "register_operand" "=r")
11468	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11469		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11470   (clobber (match_scratch:SI 3 "=&r"))
11471   (clobber (reg:CC 17))]
11472  "!TARGET_64BIT && TARGET_CMOVE"
11473  "#"
11474  [(set_attr "type" "multi")])
11475
11476(define_insn "*ashrdi3_2"
11477  [(set (match_operand:DI 0 "register_operand" "=r")
11478	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11479		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11480   (clobber (reg:CC 17))]
11481  "!TARGET_64BIT"
11482  "#"
11483  [(set_attr "type" "multi")])
11484
11485(define_split
11486  [(set (match_operand:DI 0 "register_operand" "")
11487	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11488		     (match_operand:QI 2 "nonmemory_operand" "")))
11489   (clobber (match_scratch:SI 3 ""))
11490   (clobber (reg:CC 17))]
11491  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11492  [(const_int 0)]
11493  "ix86_split_ashrdi (operands, operands[3]); DONE;")
11494
11495(define_split
11496  [(set (match_operand:DI 0 "register_operand" "")
11497	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11498		     (match_operand:QI 2 "nonmemory_operand" "")))
11499   (clobber (reg:CC 17))]
11500  "!TARGET_64BIT && reload_completed"
11501  [(const_int 0)]
11502  "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11503
11504(define_insn "x86_shrd_1"
11505  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11506        (ior:SI (ashiftrt:SI (match_dup 0)
11507		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11508		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11509		  (minus:QI (const_int 32) (match_dup 2)))))
11510   (clobber (reg:CC 17))]
11511  ""
11512  "@
11513   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11514   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11515  [(set_attr "type" "ishift")
11516   (set_attr "prefix_0f" "1")
11517   (set_attr "pent_pair" "np")
11518   (set_attr "ppro_uops" "few")
11519   (set_attr "mode" "SI")])
11520
11521(define_expand "x86_shift_adj_3"
11522  [(use (match_operand:SI 0 "register_operand" ""))
11523   (use (match_operand:SI 1 "register_operand" ""))
11524   (use (match_operand:QI 2 "register_operand" ""))]
11525  ""
11526{
11527  rtx label = gen_label_rtx ();
11528  rtx tmp;
11529
11530  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11531
11532  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11533  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11534  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11535			      gen_rtx_LABEL_REF (VOIDmode, label),
11536			      pc_rtx);
11537  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11538  JUMP_LABEL (tmp) = label;
11539
11540  emit_move_insn (operands[0], operands[1]);
11541  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11542
11543  emit_label (label);
11544  LABEL_NUSES (label) = 1;
11545
11546  DONE;
11547})
11548
11549(define_insn "ashrsi3_31"
11550  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11551	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11552		     (match_operand:SI 2 "const_int_operand" "i,i")))
11553   (clobber (reg:CC 17))]
11554  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11555   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11556  "@
11557   {cltd|cdq}
11558   sar{l}\t{%2, %0|%0, %2}"
11559  [(set_attr "type" "imovx,ishift")
11560   (set_attr "prefix_0f" "0,*")
11561   (set_attr "length_immediate" "0,*")
11562   (set_attr "modrm" "0,1")
11563   (set_attr "mode" "SI")])
11564
11565(define_insn "*ashrsi3_31_zext"
11566  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11567	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11568				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11569   (clobber (reg:CC 17))]
11570  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11571   && INTVAL (operands[2]) == 31
11572   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11573  "@
11574   {cltd|cdq}
11575   sar{l}\t{%2, %k0|%k0, %2}"
11576  [(set_attr "type" "imovx,ishift")
11577   (set_attr "prefix_0f" "0,*")
11578   (set_attr "length_immediate" "0,*")
11579   (set_attr "modrm" "0,1")
11580   (set_attr "mode" "SI")])
11581
11582(define_expand "ashrsi3"
11583  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11584	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11585		     (match_operand:QI 2 "nonmemory_operand" "")))
11586   (clobber (reg:CC 17))]
11587  ""
11588  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11589
11590(define_insn "*ashrsi3_1_one_bit"
11591  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11592	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11593		     (match_operand:QI 2 "const1_operand" "")))
11594   (clobber (reg:CC 17))]
11595  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11596   && (TARGET_SHIFT1 || optimize_size)"
11597  "sar{l}\t%0"
11598  [(set_attr "type" "ishift")
11599   (set (attr "length") 
11600     (if_then_else (match_operand:SI 0 "register_operand" "") 
11601	(const_string "2")
11602	(const_string "*")))])
11603
11604(define_insn "*ashrsi3_1_one_bit_zext"
11605  [(set (match_operand:DI 0 "register_operand" "=r")
11606	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11607				     (match_operand:QI 2 "const1_operand" ""))))
11608   (clobber (reg:CC 17))]
11609  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11610   && (TARGET_SHIFT1 || optimize_size)"
11611  "sar{l}\t%k0"
11612  [(set_attr "type" "ishift")
11613   (set_attr "length" "2")])
11614
11615(define_insn "*ashrsi3_1"
11616  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11617	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11618		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11619   (clobber (reg:CC 17))]
11620  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11621  "@
11622   sar{l}\t{%2, %0|%0, %2}
11623   sar{l}\t{%b2, %0|%0, %b2}"
11624  [(set_attr "type" "ishift")
11625   (set_attr "mode" "SI")])
11626
11627(define_insn "*ashrsi3_1_zext"
11628  [(set (match_operand:DI 0 "register_operand" "=r,r")
11629	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11630				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11631   (clobber (reg:CC 17))]
11632  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11633  "@
11634   sar{l}\t{%2, %k0|%k0, %2}
11635   sar{l}\t{%b2, %k0|%k0, %b2}"
11636  [(set_attr "type" "ishift")
11637   (set_attr "mode" "SI")])
11638
11639;; This pattern can't accept a variable shift count, since shifts by
11640;; zero don't affect the flags.  We assume that shifts by constant
11641;; zero are optimized away.
11642(define_insn "*ashrsi3_one_bit_cmp"
11643  [(set (reg 17)
11644	(compare
11645	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11646		       (match_operand:QI 2 "const1_operand" ""))
11647	  (const_int 0)))
11648   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11649	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11650  "ix86_match_ccmode (insn, CCGOCmode)
11651   && (TARGET_SHIFT1 || optimize_size)
11652   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653  "sar{l}\t%0"
11654  [(set_attr "type" "ishift")
11655   (set (attr "length") 
11656     (if_then_else (match_operand:SI 0 "register_operand" "") 
11657	(const_string "2")
11658	(const_string "*")))])
11659
11660(define_insn "*ashrsi3_one_bit_cmp_zext"
11661  [(set (reg 17)
11662	(compare
11663	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664		       (match_operand:QI 2 "const1_operand" ""))
11665	  (const_int 0)))
11666   (set (match_operand:DI 0 "register_operand" "=r")
11667	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11668  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11669   && (TARGET_SHIFT1 || optimize_size)
11670   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11671  "sar{l}\t%k0"
11672  [(set_attr "type" "ishift")
11673   (set_attr "length" "2")])
11674
11675;; This pattern can't accept a variable shift count, since shifts by
11676;; zero don't affect the flags.  We assume that shifts by constant
11677;; zero are optimized away.
11678(define_insn "*ashrsi3_cmp"
11679  [(set (reg 17)
11680	(compare
11681	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11683	  (const_int 0)))
11684   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11685	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11686  "ix86_match_ccmode (insn, CCGOCmode)
11687   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11688  "sar{l}\t{%2, %0|%0, %2}"
11689  [(set_attr "type" "ishift")
11690   (set_attr "mode" "SI")])
11691
11692(define_insn "*ashrsi3_cmp_zext"
11693  [(set (reg 17)
11694	(compare
11695	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11696		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11697	  (const_int 0)))
11698   (set (match_operand:DI 0 "register_operand" "=r")
11699	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11700  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11701   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11702  "sar{l}\t{%2, %k0|%k0, %2}"
11703  [(set_attr "type" "ishift")
11704   (set_attr "mode" "SI")])
11705
11706(define_expand "ashrhi3"
11707  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709		     (match_operand:QI 2 "nonmemory_operand" "")))
11710   (clobber (reg:CC 17))]
11711  "TARGET_HIMODE_MATH"
11712  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11713
11714(define_insn "*ashrhi3_1_one_bit"
11715  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11716	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717		     (match_operand:QI 2 "const1_operand" "")))
11718   (clobber (reg:CC 17))]
11719  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11720   && (TARGET_SHIFT1 || optimize_size)"
11721  "sar{w}\t%0"
11722  [(set_attr "type" "ishift")
11723   (set (attr "length") 
11724     (if_then_else (match_operand 0 "register_operand" "") 
11725	(const_string "2")
11726	(const_string "*")))])
11727
11728(define_insn "*ashrhi3_1"
11729  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11730	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11731		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11732   (clobber (reg:CC 17))]
11733  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11734  "@
11735   sar{w}\t{%2, %0|%0, %2}
11736   sar{w}\t{%b2, %0|%0, %b2}"
11737  [(set_attr "type" "ishift")
11738   (set_attr "mode" "HI")])
11739
11740;; This pattern can't accept a variable shift count, since shifts by
11741;; zero don't affect the flags.  We assume that shifts by constant
11742;; zero are optimized away.
11743(define_insn "*ashrhi3_one_bit_cmp"
11744  [(set (reg 17)
11745	(compare
11746	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747		       (match_operand:QI 2 "const1_operand" ""))
11748	  (const_int 0)))
11749   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11750	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11751  "ix86_match_ccmode (insn, CCGOCmode)
11752   && (TARGET_SHIFT1 || optimize_size)
11753   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11754  "sar{w}\t%0"
11755  [(set_attr "type" "ishift")
11756   (set (attr "length") 
11757     (if_then_else (match_operand 0 "register_operand" "") 
11758	(const_string "2")
11759	(const_string "*")))])
11760
11761;; This pattern can't accept a variable shift count, since shifts by
11762;; zero don't affect the flags.  We assume that shifts by constant
11763;; zero are optimized away.
11764(define_insn "*ashrhi3_cmp"
11765  [(set (reg 17)
11766	(compare
11767	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11769	  (const_int 0)))
11770   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11771	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11772  "ix86_match_ccmode (insn, CCGOCmode)
11773   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11774  "sar{w}\t{%2, %0|%0, %2}"
11775  [(set_attr "type" "ishift")
11776   (set_attr "mode" "HI")])
11777
11778(define_expand "ashrqi3"
11779  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11780	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11781		     (match_operand:QI 2 "nonmemory_operand" "")))
11782   (clobber (reg:CC 17))]
11783  "TARGET_QIMODE_MATH"
11784  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11785
11786(define_insn "*ashrqi3_1_one_bit"
11787  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789		     (match_operand:QI 2 "const1_operand" "")))
11790   (clobber (reg:CC 17))]
11791  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792   && (TARGET_SHIFT1 || optimize_size)"
11793  "sar{b}\t%0"
11794  [(set_attr "type" "ishift")
11795   (set (attr "length") 
11796     (if_then_else (match_operand 0 "register_operand" "") 
11797	(const_string "2")
11798	(const_string "*")))])
11799
11800(define_insn "*ashrqi3_1_one_bit_slp"
11801  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802	(ashiftrt:QI (match_dup 0)
11803		     (match_operand:QI 1 "const1_operand" "")))
11804   (clobber (reg:CC 17))]
11805  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807   && (TARGET_SHIFT1 || optimize_size)"
11808  "sar{b}\t%0"
11809  [(set_attr "type" "ishift1")
11810   (set (attr "length") 
11811     (if_then_else (match_operand 0 "register_operand" "") 
11812	(const_string "2")
11813	(const_string "*")))])
11814
11815(define_insn "*ashrqi3_1"
11816  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11817	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11818		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11819   (clobber (reg:CC 17))]
11820  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11821  "@
11822   sar{b}\t{%2, %0|%0, %2}
11823   sar{b}\t{%b2, %0|%0, %b2}"
11824  [(set_attr "type" "ishift")
11825   (set_attr "mode" "QI")])
11826
11827(define_insn "*ashrqi3_1_slp"
11828  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829	(ashiftrt:QI (match_dup 0)
11830		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831   (clobber (reg:CC 17))]
11832  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11834  "@
11835   sar{b}\t{%1, %0|%0, %1}
11836   sar{b}\t{%b1, %0|%0, %b1}"
11837  [(set_attr "type" "ishift1")
11838   (set_attr "mode" "QI")])
11839
11840;; This pattern can't accept a variable shift count, since shifts by
11841;; zero don't affect the flags.  We assume that shifts by constant
11842;; zero are optimized away.
11843(define_insn "*ashrqi3_one_bit_cmp"
11844  [(set (reg 17)
11845	(compare
11846	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847		       (match_operand:QI 2 "const1_operand" "I"))
11848	  (const_int 0)))
11849   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11850	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11851  "ix86_match_ccmode (insn, CCGOCmode)
11852   && (TARGET_SHIFT1 || optimize_size)
11853   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11854  "sar{b}\t%0"
11855  [(set_attr "type" "ishift")
11856   (set (attr "length") 
11857     (if_then_else (match_operand 0 "register_operand" "") 
11858	(const_string "2")
11859	(const_string "*")))])
11860
11861;; This pattern can't accept a variable shift count, since shifts by
11862;; zero don't affect the flags.  We assume that shifts by constant
11863;; zero are optimized away.
11864(define_insn "*ashrqi3_cmp"
11865  [(set (reg 17)
11866	(compare
11867	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11868		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11869	  (const_int 0)))
11870   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11871	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11872  "ix86_match_ccmode (insn, CCGOCmode)
11873   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11874  "sar{b}\t{%2, %0|%0, %2}"
11875  [(set_attr "type" "ishift")
11876   (set_attr "mode" "QI")])
11877
11878;; Logical shift instructions
11879
11880;; See comment above `ashldi3' about how this works.
11881
11882(define_expand "lshrdi3"
11883  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11884		   (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11885			        (match_operand:QI 2 "nonmemory_operand" "")))
11886	      (clobber (reg:CC 17))])]
11887  ""
11888{
11889  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11890    {
11891      emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11892      DONE;
11893    }
11894  ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11895  DONE;
11896})
11897
11898(define_insn "*lshrdi3_1_one_bit_rex64"
11899  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11900	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11901		     (match_operand:QI 2 "const1_operand" "")))
11902   (clobber (reg:CC 17))]
11903  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11904   && (TARGET_SHIFT1 || optimize_size)"
11905  "shr{q}\t%0"
11906  [(set_attr "type" "ishift")
11907   (set (attr "length") 
11908     (if_then_else (match_operand:DI 0 "register_operand" "") 
11909	(const_string "2")
11910	(const_string "*")))])
11911
11912(define_insn "*lshrdi3_1_rex64"
11913  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11914	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11915		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11916   (clobber (reg:CC 17))]
11917  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11918  "@
11919   shr{q}\t{%2, %0|%0, %2}
11920   shr{q}\t{%b2, %0|%0, %b2}"
11921  [(set_attr "type" "ishift")
11922   (set_attr "mode" "DI")])
11923
11924;; This pattern can't accept a variable shift count, since shifts by
11925;; zero don't affect the flags.  We assume that shifts by constant
11926;; zero are optimized away.
11927(define_insn "*lshrdi3_cmp_one_bit_rex64"
11928  [(set (reg 17)
11929	(compare
11930	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11931		       (match_operand:QI 2 "const1_operand" ""))
11932	  (const_int 0)))
11933   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11934	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
11935  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11936   && (TARGET_SHIFT1 || optimize_size)
11937   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11938  "shr{q}\t%0"
11939  [(set_attr "type" "ishift")
11940   (set (attr "length") 
11941     (if_then_else (match_operand:DI 0 "register_operand" "") 
11942	(const_string "2")
11943	(const_string "*")))])
11944
11945;; This pattern can't accept a variable shift count, since shifts by
11946;; zero don't affect the flags.  We assume that shifts by constant
11947;; zero are optimized away.
11948(define_insn "*lshrdi3_cmp_rex64"
11949  [(set (reg 17)
11950	(compare
11951	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11952		       (match_operand:QI 2 "const_int_operand" "e"))
11953	  (const_int 0)))
11954   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11955	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
11956  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11957   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11958  "shr{q}\t{%2, %0|%0, %2}"
11959  [(set_attr "type" "ishift")
11960   (set_attr "mode" "DI")])
11961
11962(define_insn "lshrdi3_1"
11963  [(set (match_operand:DI 0 "register_operand" "=r")
11964	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11965		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11966   (clobber (match_scratch:SI 3 "=&r"))
11967   (clobber (reg:CC 17))]
11968  "!TARGET_64BIT && TARGET_CMOVE"
11969  "#"
11970  [(set_attr "type" "multi")])
11971
11972(define_insn "*lshrdi3_2"
11973  [(set (match_operand:DI 0 "register_operand" "=r")
11974	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11975		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11976   (clobber (reg:CC 17))]
11977  "!TARGET_64BIT"
11978  "#"
11979  [(set_attr "type" "multi")])
11980
11981(define_split 
11982  [(set (match_operand:DI 0 "register_operand" "")
11983	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11984		     (match_operand:QI 2 "nonmemory_operand" "")))
11985   (clobber (match_scratch:SI 3 ""))
11986   (clobber (reg:CC 17))]
11987  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11988  [(const_int 0)]
11989  "ix86_split_lshrdi (operands, operands[3]); DONE;")
11990
11991(define_split 
11992  [(set (match_operand:DI 0 "register_operand" "")
11993	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11994		     (match_operand:QI 2 "nonmemory_operand" "")))
11995   (clobber (reg:CC 17))]
11996  "!TARGET_64BIT && reload_completed"
11997  [(const_int 0)]
11998  "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11999
12000(define_expand "lshrsi3"
12001  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12002	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12003		     (match_operand:QI 2 "nonmemory_operand" "")))
12004   (clobber (reg:CC 17))]
12005  ""
12006  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12007
12008(define_insn "*lshrsi3_1_one_bit"
12009  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12010	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12011		     (match_operand:QI 2 "const1_operand" "")))
12012   (clobber (reg:CC 17))]
12013  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12014   && (TARGET_SHIFT1 || optimize_size)"
12015  "shr{l}\t%0"
12016  [(set_attr "type" "ishift")
12017   (set (attr "length") 
12018     (if_then_else (match_operand:SI 0 "register_operand" "") 
12019	(const_string "2")
12020	(const_string "*")))])
12021
12022(define_insn "*lshrsi3_1_one_bit_zext"
12023  [(set (match_operand:DI 0 "register_operand" "=r")
12024	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12025		     (match_operand:QI 2 "const1_operand" "")))
12026   (clobber (reg:CC 17))]
12027  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12028   && (TARGET_SHIFT1 || optimize_size)"
12029  "shr{l}\t%k0"
12030  [(set_attr "type" "ishift")
12031   (set_attr "length" "2")])
12032
12033(define_insn "*lshrsi3_1"
12034  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12035	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12036		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12037   (clobber (reg:CC 17))]
12038  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12039  "@
12040   shr{l}\t{%2, %0|%0, %2}
12041   shr{l}\t{%b2, %0|%0, %b2}"
12042  [(set_attr "type" "ishift")
12043   (set_attr "mode" "SI")])
12044
12045(define_insn "*lshrsi3_1_zext"
12046  [(set (match_operand:DI 0 "register_operand" "=r,r")
12047	(zero_extend:DI
12048	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12049		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12050   (clobber (reg:CC 17))]
12051  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12052  "@
12053   shr{l}\t{%2, %k0|%k0, %2}
12054   shr{l}\t{%b2, %k0|%k0, %b2}"
12055  [(set_attr "type" "ishift")
12056   (set_attr "mode" "SI")])
12057
12058;; This pattern can't accept a variable shift count, since shifts by
12059;; zero don't affect the flags.  We assume that shifts by constant
12060;; zero are optimized away.
12061(define_insn "*lshrsi3_one_bit_cmp"
12062  [(set (reg 17)
12063	(compare
12064	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12065		       (match_operand:QI 2 "const1_operand" ""))
12066	  (const_int 0)))
12067   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12068	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12069  "ix86_match_ccmode (insn, CCGOCmode)
12070   && (TARGET_SHIFT1 || optimize_size)
12071   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12072  "shr{l}\t%0"
12073  [(set_attr "type" "ishift")
12074   (set (attr "length") 
12075     (if_then_else (match_operand:SI 0 "register_operand" "") 
12076	(const_string "2")
12077	(const_string "*")))])
12078
12079(define_insn "*lshrsi3_cmp_one_bit_zext"
12080  [(set (reg 17)
12081	(compare
12082	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12083		       (match_operand:QI 2 "const1_operand" ""))
12084	  (const_int 0)))
12085   (set (match_operand:DI 0 "register_operand" "=r")
12086	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12087  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12088   && (TARGET_SHIFT1 || optimize_size)
12089   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12090  "shr{l}\t%k0"
12091  [(set_attr "type" "ishift")
12092   (set_attr "length" "2")])
12093
12094;; This pattern can't accept a variable shift count, since shifts by
12095;; zero don't affect the flags.  We assume that shifts by constant
12096;; zero are optimized away.
12097(define_insn "*lshrsi3_cmp"
12098  [(set (reg 17)
12099	(compare
12100	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12101		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12102	  (const_int 0)))
12103   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12104	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12105  "ix86_match_ccmode (insn, CCGOCmode)
12106   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12107  "shr{l}\t{%2, %0|%0, %2}"
12108  [(set_attr "type" "ishift")
12109   (set_attr "mode" "SI")])
12110
12111(define_insn "*lshrsi3_cmp_zext"
12112  [(set (reg 17)
12113	(compare
12114	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12115		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12116	  (const_int 0)))
12117   (set (match_operand:DI 0 "register_operand" "=r")
12118	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12119  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12120   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12121  "shr{l}\t{%2, %k0|%k0, %2}"
12122  [(set_attr "type" "ishift")
12123   (set_attr "mode" "SI")])
12124
12125(define_expand "lshrhi3"
12126  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12127	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12128		     (match_operand:QI 2 "nonmemory_operand" "")))
12129   (clobber (reg:CC 17))]
12130  "TARGET_HIMODE_MATH"
12131  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12132
12133(define_insn "*lshrhi3_1_one_bit"
12134  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12135	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136		     (match_operand:QI 2 "const1_operand" "")))
12137   (clobber (reg:CC 17))]
12138  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12139   && (TARGET_SHIFT1 || optimize_size)"
12140  "shr{w}\t%0"
12141  [(set_attr "type" "ishift")
12142   (set (attr "length") 
12143     (if_then_else (match_operand 0 "register_operand" "") 
12144	(const_string "2")
12145	(const_string "*")))])
12146
12147(define_insn "*lshrhi3_1"
12148  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12149	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12150		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12151   (clobber (reg:CC 17))]
12152  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12153  "@
12154   shr{w}\t{%2, %0|%0, %2}
12155   shr{w}\t{%b2, %0|%0, %b2}"
12156  [(set_attr "type" "ishift")
12157   (set_attr "mode" "HI")])
12158
12159;; This pattern can't accept a variable shift count, since shifts by
12160;; zero don't affect the flags.  We assume that shifts by constant
12161;; zero are optimized away.
12162(define_insn "*lshrhi3_one_bit_cmp"
12163  [(set (reg 17)
12164	(compare
12165	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12166		       (match_operand:QI 2 "const1_operand" ""))
12167	  (const_int 0)))
12168   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12169	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12170  "ix86_match_ccmode (insn, CCGOCmode)
12171   && (TARGET_SHIFT1 || optimize_size)
12172   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12173  "shr{w}\t%0"
12174  [(set_attr "type" "ishift")
12175   (set (attr "length") 
12176     (if_then_else (match_operand:SI 0 "register_operand" "") 
12177	(const_string "2")
12178	(const_string "*")))])
12179
12180;; This pattern can't accept a variable shift count, since shifts by
12181;; zero don't affect the flags.  We assume that shifts by constant
12182;; zero are optimized away.
12183(define_insn "*lshrhi3_cmp"
12184  [(set (reg 17)
12185	(compare
12186	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12187		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12188	  (const_int 0)))
12189   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12190	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12191  "ix86_match_ccmode (insn, CCGOCmode)
12192   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12193  "shr{w}\t{%2, %0|%0, %2}"
12194  [(set_attr "type" "ishift")
12195   (set_attr "mode" "HI")])
12196
12197(define_expand "lshrqi3"
12198  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12199	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12200		     (match_operand:QI 2 "nonmemory_operand" "")))
12201   (clobber (reg:CC 17))]
12202  "TARGET_QIMODE_MATH"
12203  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12204
12205(define_insn "*lshrqi3_1_one_bit"
12206  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12207	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12208		     (match_operand:QI 2 "const1_operand" "")))
12209   (clobber (reg:CC 17))]
12210  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12211   && (TARGET_SHIFT1 || optimize_size)"
12212  "shr{b}\t%0"
12213  [(set_attr "type" "ishift")
12214   (set (attr "length") 
12215     (if_then_else (match_operand 0 "register_operand" "") 
12216	(const_string "2")
12217	(const_string "*")))])
12218
12219(define_insn "*lshrqi3_1_one_bit_slp"
12220  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221	(lshiftrt:QI (match_dup 0)
12222		     (match_operand:QI 1 "const1_operand" "")))
12223   (clobber (reg:CC 17))]
12224  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225   && (TARGET_SHIFT1 || optimize_size)"
12226  "shr{b}\t%0"
12227  [(set_attr "type" "ishift1")
12228   (set (attr "length") 
12229     (if_then_else (match_operand 0 "register_operand" "") 
12230	(const_string "2")
12231	(const_string "*")))])
12232
12233(define_insn "*lshrqi3_1"
12234  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12235	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12236		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12237   (clobber (reg:CC 17))]
12238  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12239  "@
12240   shr{b}\t{%2, %0|%0, %2}
12241   shr{b}\t{%b2, %0|%0, %b2}"
12242  [(set_attr "type" "ishift")
12243   (set_attr "mode" "QI")])
12244
12245(define_insn "*lshrqi3_1_slp"
12246  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247	(lshiftrt:QI (match_dup 0)
12248		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249   (clobber (reg:CC 17))]
12250  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12251   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12252  "@
12253   shr{b}\t{%1, %0|%0, %1}
12254   shr{b}\t{%b1, %0|%0, %b1}"
12255  [(set_attr "type" "ishift1")
12256   (set_attr "mode" "QI")])
12257
12258;; This pattern can't accept a variable shift count, since shifts by
12259;; zero don't affect the flags.  We assume that shifts by constant
12260;; zero are optimized away.
12261(define_insn "*lshrqi2_one_bit_cmp"
12262  [(set (reg 17)
12263	(compare
12264	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12265		       (match_operand:QI 2 "const1_operand" ""))
12266	  (const_int 0)))
12267   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12268	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12269  "ix86_match_ccmode (insn, CCGOCmode)
12270   && (TARGET_SHIFT1 || optimize_size)
12271   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12272  "shr{b}\t%0"
12273  [(set_attr "type" "ishift")
12274   (set (attr "length") 
12275     (if_then_else (match_operand:SI 0 "register_operand" "") 
12276	(const_string "2")
12277	(const_string "*")))])
12278
12279;; This pattern can't accept a variable shift count, since shifts by
12280;; zero don't affect the flags.  We assume that shifts by constant
12281;; zero are optimized away.
12282(define_insn "*lshrqi2_cmp"
12283  [(set (reg 17)
12284	(compare
12285	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12286		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12287	  (const_int 0)))
12288   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12289	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12290  "ix86_match_ccmode (insn, CCGOCmode)
12291   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12292  "shr{b}\t{%2, %0|%0, %2}"
12293  [(set_attr "type" "ishift")
12294   (set_attr "mode" "QI")])
12295
12296;; Rotate instructions
12297
12298(define_expand "rotldi3"
12299  [(set (match_operand:DI 0 "nonimmediate_operand" "")
12300	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12301		   (match_operand:QI 2 "nonmemory_operand" "")))
12302   (clobber (reg:CC 17))]
12303  "TARGET_64BIT"
12304  "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12305
12306(define_insn "*rotlsi3_1_one_bit_rex64"
12307  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12308	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12309		   (match_operand:QI 2 "const1_operand" "")))
12310   (clobber (reg:CC 17))]
12311  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12312   && (TARGET_SHIFT1 || optimize_size)"
12313  "rol{q}\t%0"
12314  [(set_attr "type" "rotate")
12315   (set (attr "length") 
12316     (if_then_else (match_operand:DI 0 "register_operand" "") 
12317	(const_string "2")
12318	(const_string "*")))])
12319
12320(define_insn "*rotldi3_1_rex64"
12321  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12322	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12323		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12324   (clobber (reg:CC 17))]
12325  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12326  "@
12327   rol{q}\t{%2, %0|%0, %2}
12328   rol{q}\t{%b2, %0|%0, %b2}"
12329  [(set_attr "type" "rotate")
12330   (set_attr "mode" "DI")])
12331
12332(define_expand "rotlsi3"
12333  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12334	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12335		   (match_operand:QI 2 "nonmemory_operand" "")))
12336   (clobber (reg:CC 17))]
12337  ""
12338  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12339
12340(define_insn "*rotlsi3_1_one_bit"
12341  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12342	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12343		   (match_operand:QI 2 "const1_operand" "")))
12344   (clobber (reg:CC 17))]
12345  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12346   && (TARGET_SHIFT1 || optimize_size)"
12347  "rol{l}\t%0"
12348  [(set_attr "type" "rotate")
12349   (set (attr "length") 
12350     (if_then_else (match_operand:SI 0 "register_operand" "") 
12351	(const_string "2")
12352	(const_string "*")))])
12353
12354(define_insn "*rotlsi3_1_one_bit_zext"
12355  [(set (match_operand:DI 0 "register_operand" "=r")
12356	(zero_extend:DI
12357	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12358		     (match_operand:QI 2 "const1_operand" ""))))
12359   (clobber (reg:CC 17))]
12360  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12361   && (TARGET_SHIFT1 || optimize_size)"
12362  "rol{l}\t%k0"
12363  [(set_attr "type" "rotate")
12364   (set_attr "length" "2")])
12365
12366(define_insn "*rotlsi3_1"
12367  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12368	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12369		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12370   (clobber (reg:CC 17))]
12371  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12372  "@
12373   rol{l}\t{%2, %0|%0, %2}
12374   rol{l}\t{%b2, %0|%0, %b2}"
12375  [(set_attr "type" "rotate")
12376   (set_attr "mode" "SI")])
12377
12378(define_insn "*rotlsi3_1_zext"
12379  [(set (match_operand:DI 0 "register_operand" "=r,r")
12380	(zero_extend:DI
12381	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12382		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12383   (clobber (reg:CC 17))]
12384  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12385  "@
12386   rol{l}\t{%2, %k0|%k0, %2}
12387   rol{l}\t{%b2, %k0|%k0, %b2}"
12388  [(set_attr "type" "rotate")
12389   (set_attr "mode" "SI")])
12390
12391(define_expand "rotlhi3"
12392  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12393	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12394		   (match_operand:QI 2 "nonmemory_operand" "")))
12395   (clobber (reg:CC 17))]
12396  "TARGET_HIMODE_MATH"
12397  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12398
12399(define_insn "*rotlhi3_1_one_bit"
12400  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402		   (match_operand:QI 2 "const1_operand" "")))
12403   (clobber (reg:CC 17))]
12404  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12405   && (TARGET_SHIFT1 || optimize_size)"
12406  "rol{w}\t%0"
12407  [(set_attr "type" "rotate")
12408   (set (attr "length") 
12409     (if_then_else (match_operand 0 "register_operand" "") 
12410	(const_string "2")
12411	(const_string "*")))])
12412
12413(define_insn "*rotlhi3_1"
12414  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12415	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12416		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12417   (clobber (reg:CC 17))]
12418  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12419  "@
12420   rol{w}\t{%2, %0|%0, %2}
12421   rol{w}\t{%b2, %0|%0, %b2}"
12422  [(set_attr "type" "rotate")
12423   (set_attr "mode" "HI")])
12424
12425(define_expand "rotlqi3"
12426  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12427	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12428		   (match_operand:QI 2 "nonmemory_operand" "")))
12429   (clobber (reg:CC 17))]
12430  "TARGET_QIMODE_MATH"
12431  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12432
12433(define_insn "*rotlqi3_1_one_bit_slp"
12434  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12435	(rotate:QI (match_dup 0)
12436		   (match_operand:QI 1 "const1_operand" "")))
12437   (clobber (reg:CC 17))]
12438  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12439   && (TARGET_SHIFT1 || optimize_size)"
12440  "rol{b}\t%0"
12441  [(set_attr "type" "rotate1")
12442   (set (attr "length") 
12443     (if_then_else (match_operand 0 "register_operand" "") 
12444	(const_string "2")
12445	(const_string "*")))])
12446
12447(define_insn "*rotlqi3_1_one_bit"
12448  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12449	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450		   (match_operand:QI 2 "const1_operand" "")))
12451   (clobber (reg:CC 17))]
12452  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12453   && (TARGET_SHIFT1 || optimize_size)"
12454  "rol{b}\t%0"
12455  [(set_attr "type" "rotate")
12456   (set (attr "length") 
12457     (if_then_else (match_operand 0 "register_operand" "") 
12458	(const_string "2")
12459	(const_string "*")))])
12460
12461(define_insn "*rotlqi3_1_slp"
12462  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463	(rotate:QI (match_dup 0)
12464		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465   (clobber (reg:CC 17))]
12466  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12468  "@
12469   rol{b}\t{%1, %0|%0, %1}
12470   rol{b}\t{%b1, %0|%0, %b1}"
12471  [(set_attr "type" "rotate1")
12472   (set_attr "mode" "QI")])
12473
12474(define_insn "*rotlqi3_1"
12475  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478   (clobber (reg:CC 17))]
12479  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12480  "@
12481   rol{b}\t{%2, %0|%0, %2}
12482   rol{b}\t{%b2, %0|%0, %b2}"
12483  [(set_attr "type" "rotate")
12484   (set_attr "mode" "QI")])
12485
12486(define_expand "rotrdi3"
12487  [(set (match_operand:DI 0 "nonimmediate_operand" "")
12488	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12489		     (match_operand:QI 2 "nonmemory_operand" "")))
12490   (clobber (reg:CC 17))]
12491  "TARGET_64BIT"
12492  "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12493
12494(define_insn "*rotrdi3_1_one_bit_rex64"
12495  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12496	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12497		     (match_operand:QI 2 "const1_operand" "")))
12498   (clobber (reg:CC 17))]
12499  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12500   && (TARGET_SHIFT1 || optimize_size)"
12501  "ror{q}\t%0"
12502  [(set_attr "type" "rotate")
12503   (set (attr "length") 
12504     (if_then_else (match_operand:DI 0 "register_operand" "") 
12505	(const_string "2")
12506	(const_string "*")))])
12507
12508(define_insn "*rotrdi3_1_rex64"
12509  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12510	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12511		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12512   (clobber (reg:CC 17))]
12513  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12514  "@
12515   ror{q}\t{%2, %0|%0, %2}
12516   ror{q}\t{%b2, %0|%0, %b2}"
12517  [(set_attr "type" "rotate")
12518   (set_attr "mode" "DI")])
12519
12520(define_expand "rotrsi3"
12521  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12522	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12523		     (match_operand:QI 2 "nonmemory_operand" "")))
12524   (clobber (reg:CC 17))]
12525  ""
12526  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12527
12528(define_insn "*rotrsi3_1_one_bit"
12529  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12530	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12531		     (match_operand:QI 2 "const1_operand" "")))
12532   (clobber (reg:CC 17))]
12533  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12534   && (TARGET_SHIFT1 || optimize_size)"
12535  "ror{l}\t%0"
12536  [(set_attr "type" "rotate")
12537   (set (attr "length") 
12538     (if_then_else (match_operand:SI 0 "register_operand" "") 
12539	(const_string "2")
12540	(const_string "*")))])
12541
12542(define_insn "*rotrsi3_1_one_bit_zext"
12543  [(set (match_operand:DI 0 "register_operand" "=r")
12544	(zero_extend:DI
12545	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12546		       (match_operand:QI 2 "const1_operand" ""))))
12547   (clobber (reg:CC 17))]
12548  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12549   && (TARGET_SHIFT1 || optimize_size)"
12550  "ror{l}\t%k0"
12551  [(set_attr "type" "rotate")
12552   (set (attr "length") 
12553     (if_then_else (match_operand:SI 0 "register_operand" "") 
12554	(const_string "2")
12555	(const_string "*")))])
12556
12557(define_insn "*rotrsi3_1"
12558  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12559	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12560		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12561   (clobber (reg:CC 17))]
12562  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12563  "@
12564   ror{l}\t{%2, %0|%0, %2}
12565   ror{l}\t{%b2, %0|%0, %b2}"
12566  [(set_attr "type" "rotate")
12567   (set_attr "mode" "SI")])
12568
12569(define_insn "*rotrsi3_1_zext"
12570  [(set (match_operand:DI 0 "register_operand" "=r,r")
12571	(zero_extend:DI
12572	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12573		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12574   (clobber (reg:CC 17))]
12575  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12576  "@
12577   ror{l}\t{%2, %k0|%k0, %2}
12578   ror{l}\t{%b2, %k0|%k0, %b2}"
12579  [(set_attr "type" "rotate")
12580   (set_attr "mode" "SI")])
12581
12582(define_expand "rotrhi3"
12583  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12584	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12585		     (match_operand:QI 2 "nonmemory_operand" "")))
12586   (clobber (reg:CC 17))]
12587  "TARGET_HIMODE_MATH"
12588  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12589
12590(define_insn "*rotrhi3_one_bit"
12591  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12592	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12593		     (match_operand:QI 2 "const1_operand" "")))
12594   (clobber (reg:CC 17))]
12595  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12596   && (TARGET_SHIFT1 || optimize_size)"
12597  "ror{w}\t%0"
12598  [(set_attr "type" "rotate")
12599   (set (attr "length") 
12600     (if_then_else (match_operand 0 "register_operand" "") 
12601	(const_string "2")
12602	(const_string "*")))])
12603
12604(define_insn "*rotrhi3"
12605  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12606	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12607		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12608   (clobber (reg:CC 17))]
12609  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12610  "@
12611   ror{w}\t{%2, %0|%0, %2}
12612   ror{w}\t{%b2, %0|%0, %b2}"
12613  [(set_attr "type" "rotate")
12614   (set_attr "mode" "HI")])
12615
12616(define_expand "rotrqi3"
12617  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12618	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12619		     (match_operand:QI 2 "nonmemory_operand" "")))
12620   (clobber (reg:CC 17))]
12621  "TARGET_QIMODE_MATH"
12622  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12623
12624(define_insn "*rotrqi3_1_one_bit"
12625  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12626	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12627		     (match_operand:QI 2 "const1_operand" "")))
12628   (clobber (reg:CC 17))]
12629  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12630   && (TARGET_SHIFT1 || optimize_size)"
12631  "ror{b}\t%0"
12632  [(set_attr "type" "rotate")
12633   (set (attr "length") 
12634     (if_then_else (match_operand 0 "register_operand" "") 
12635	(const_string "2")
12636	(const_string "*")))])
12637
12638(define_insn "*rotrqi3_1_one_bit_slp"
12639  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12640	(rotatert:QI (match_dup 0)
12641		     (match_operand:QI 1 "const1_operand" "")))
12642   (clobber (reg:CC 17))]
12643  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12644   && (TARGET_SHIFT1 || optimize_size)"
12645  "ror{b}\t%0"
12646  [(set_attr "type" "rotate1")
12647   (set (attr "length") 
12648     (if_then_else (match_operand 0 "register_operand" "") 
12649	(const_string "2")
12650	(const_string "*")))])
12651
12652(define_insn "*rotrqi3_1"
12653  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12654	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12655		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12656   (clobber (reg:CC 17))]
12657  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12658  "@
12659   ror{b}\t{%2, %0|%0, %2}
12660   ror{b}\t{%b2, %0|%0, %b2}"
12661  [(set_attr "type" "rotate")
12662   (set_attr "mode" "QI")])
12663
12664(define_insn "*rotrqi3_1_slp"
12665  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12666	(rotatert:QI (match_dup 0)
12667		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12668   (clobber (reg:CC 17))]
12669  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12670   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12671  "@
12672   ror{b}\t{%1, %0|%0, %1}
12673   ror{b}\t{%b1, %0|%0, %b1}"
12674  [(set_attr "type" "rotate1")
12675   (set_attr "mode" "QI")])
12676
12677;; Bit set / bit test instructions
12678
12679(define_expand "extv"
12680  [(set (match_operand:SI 0 "register_operand" "")
12681	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
12682			 (match_operand:SI 2 "immediate_operand" "")
12683			 (match_operand:SI 3 "immediate_operand" "")))]
12684  ""
12685{
12686  /* Handle extractions from %ah et al.  */
12687  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12688    FAIL;
12689
12690  /* From mips.md: extract_bit_field doesn't verify that our source
12691     matches the predicate, so check it again here.  */
12692  if (! register_operand (operands[1], VOIDmode))
12693    FAIL;
12694})
12695
12696(define_expand "extzv"
12697  [(set (match_operand:SI 0 "register_operand" "")
12698	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
12699			 (match_operand:SI 2 "immediate_operand" "")
12700			 (match_operand:SI 3 "immediate_operand" "")))]
12701  ""
12702{
12703  /* Handle extractions from %ah et al.  */
12704  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12705    FAIL;
12706
12707  /* From mips.md: extract_bit_field doesn't verify that our source
12708     matches the predicate, so check it again here.  */
12709  if (! register_operand (operands[1], VOIDmode))
12710    FAIL;
12711})
12712
12713(define_expand "insv"
12714  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12715		      (match_operand 1 "immediate_operand" "")
12716		      (match_operand 2 "immediate_operand" ""))
12717        (match_operand 3 "register_operand" ""))]
12718  ""
12719{
12720  /* Handle extractions from %ah et al.  */
12721  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12722    FAIL;
12723
12724  /* From mips.md: insert_bit_field doesn't verify that our source
12725     matches the predicate, so check it again here.  */
12726  if (! register_operand (operands[0], VOIDmode))
12727    FAIL;
12728
12729  if (TARGET_64BIT)
12730    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12731  else
12732    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12733
12734  DONE;
12735})
12736
12737;; %%% bts, btr, btc, bt.
12738
12739;; Store-flag instructions.
12740
12741;; For all sCOND expanders, also expand the compare or test insn that
12742;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12743
12744;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12745;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12746;; way, which can later delete the movzx if only QImode is needed.
12747
12748(define_expand "seq"
12749  [(set (match_operand:QI 0 "register_operand" "")
12750        (eq:QI (reg:CC 17) (const_int 0)))]
12751  ""
12752  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12753
12754(define_expand "sne"
12755  [(set (match_operand:QI 0 "register_operand" "")
12756        (ne:QI (reg:CC 17) (const_int 0)))]
12757  ""
12758  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12759
12760(define_expand "sgt"
12761  [(set (match_operand:QI 0 "register_operand" "")
12762        (gt:QI (reg:CC 17) (const_int 0)))]
12763  ""
12764  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12765
12766(define_expand "sgtu"
12767  [(set (match_operand:QI 0 "register_operand" "")
12768        (gtu:QI (reg:CC 17) (const_int 0)))]
12769  ""
12770  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12771
12772(define_expand "slt"
12773  [(set (match_operand:QI 0 "register_operand" "")
12774        (lt:QI (reg:CC 17) (const_int 0)))]
12775  ""
12776  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12777
12778(define_expand "sltu"
12779  [(set (match_operand:QI 0 "register_operand" "")
12780        (ltu:QI (reg:CC 17) (const_int 0)))]
12781  ""
12782  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12783
12784(define_expand "sge"
12785  [(set (match_operand:QI 0 "register_operand" "")
12786        (ge:QI (reg:CC 17) (const_int 0)))]
12787  ""
12788  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12789
12790(define_expand "sgeu"
12791  [(set (match_operand:QI 0 "register_operand" "")
12792        (geu:QI (reg:CC 17) (const_int 0)))]
12793  ""
12794  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12795
12796(define_expand "sle"
12797  [(set (match_operand:QI 0 "register_operand" "")
12798        (le:QI (reg:CC 17) (const_int 0)))]
12799  ""
12800  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12801
12802(define_expand "sleu"
12803  [(set (match_operand:QI 0 "register_operand" "")
12804        (leu:QI (reg:CC 17) (const_int 0)))]
12805  ""
12806  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12807
12808(define_expand "sunordered"
12809  [(set (match_operand:QI 0 "register_operand" "")
12810        (unordered:QI (reg:CC 17) (const_int 0)))]
12811  "TARGET_80387 || TARGET_SSE"
12812  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12813
12814(define_expand "sordered"
12815  [(set (match_operand:QI 0 "register_operand" "")
12816        (ordered:QI (reg:CC 17) (const_int 0)))]
12817  "TARGET_80387"
12818  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12819
12820(define_expand "suneq"
12821  [(set (match_operand:QI 0 "register_operand" "")
12822        (uneq:QI (reg:CC 17) (const_int 0)))]
12823  "TARGET_80387 || TARGET_SSE"
12824  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12825
12826(define_expand "sunge"
12827  [(set (match_operand:QI 0 "register_operand" "")
12828        (unge:QI (reg:CC 17) (const_int 0)))]
12829  "TARGET_80387 || TARGET_SSE"
12830  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12831
12832(define_expand "sungt"
12833  [(set (match_operand:QI 0 "register_operand" "")
12834        (ungt:QI (reg:CC 17) (const_int 0)))]
12835  "TARGET_80387 || TARGET_SSE"
12836  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12837
12838(define_expand "sunle"
12839  [(set (match_operand:QI 0 "register_operand" "")
12840        (unle:QI (reg:CC 17) (const_int 0)))]
12841  "TARGET_80387 || TARGET_SSE"
12842  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12843
12844(define_expand "sunlt"
12845  [(set (match_operand:QI 0 "register_operand" "")
12846        (unlt:QI (reg:CC 17) (const_int 0)))]
12847  "TARGET_80387 || TARGET_SSE"
12848  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12849
12850(define_expand "sltgt"
12851  [(set (match_operand:QI 0 "register_operand" "")
12852        (ltgt:QI (reg:CC 17) (const_int 0)))]
12853  "TARGET_80387 || TARGET_SSE"
12854  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12855
12856(define_insn "*setcc_1"
12857  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12858	(match_operator:QI 1 "ix86_comparison_operator"
12859	  [(reg 17) (const_int 0)]))]
12860  ""
12861  "set%C1\t%0"
12862  [(set_attr "type" "setcc")
12863   (set_attr "mode" "QI")])
12864
12865(define_insn "setcc_2"
12866  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12867	(match_operator:QI 1 "ix86_comparison_operator"
12868	  [(reg 17) (const_int 0)]))]
12869  ""
12870  "set%C1\t%0"
12871  [(set_attr "type" "setcc")
12872   (set_attr "mode" "QI")])
12873
12874;; In general it is not safe to assume too much about CCmode registers,
12875;; so simplify-rtx stops when it sees a second one.  Under certain 
12876;; conditions this is safe on x86, so help combine not create
12877;;
12878;;	seta	%al
12879;;	testb	%al, %al
12880;;	sete	%al
12881
12882(define_split 
12883  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12884	(ne:QI (match_operator 1 "ix86_comparison_operator"
12885	         [(reg 17) (const_int 0)])
12886	    (const_int 0)))]
12887  ""
12888  [(set (match_dup 0) (match_dup 1))]
12889{
12890  PUT_MODE (operands[1], QImode);
12891})
12892
12893(define_split 
12894  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12895	(ne:QI (match_operator 1 "ix86_comparison_operator"
12896	         [(reg 17) (const_int 0)])
12897	    (const_int 0)))]
12898  ""
12899  [(set (match_dup 0) (match_dup 1))]
12900{
12901  PUT_MODE (operands[1], QImode);
12902})
12903
12904(define_split 
12905  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12906	(eq:QI (match_operator 1 "ix86_comparison_operator"
12907	         [(reg 17) (const_int 0)])
12908	    (const_int 0)))]
12909  ""
12910  [(set (match_dup 0) (match_dup 1))]
12911{
12912  rtx new_op1 = copy_rtx (operands[1]);
12913  operands[1] = new_op1;
12914  PUT_MODE (new_op1, QImode);
12915  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12916					GET_MODE (XEXP (new_op1, 0))));
12917
12918  /* Make sure that (a) the CCmode we have for the flags is strong
12919     enough for the reversed compare or (b) we have a valid FP compare.  */
12920  if (! ix86_comparison_operator (new_op1, VOIDmode))
12921    FAIL;
12922})
12923
12924(define_split 
12925  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12926	(eq:QI (match_operator 1 "ix86_comparison_operator"
12927	         [(reg 17) (const_int 0)])
12928	    (const_int 0)))]
12929  ""
12930  [(set (match_dup 0) (match_dup 1))]
12931{
12932  rtx new_op1 = copy_rtx (operands[1]);
12933  operands[1] = new_op1;
12934  PUT_MODE (new_op1, QImode);
12935  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12936					GET_MODE (XEXP (new_op1, 0))));
12937
12938  /* Make sure that (a) the CCmode we have for the flags is strong
12939     enough for the reversed compare or (b) we have a valid FP compare.  */
12940  if (! ix86_comparison_operator (new_op1, VOIDmode))
12941    FAIL;
12942})
12943
12944;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12945;; subsequent logical operations are used to imitate conditional moves.
12946;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12947;; it directly.  Further holding this value in pseudo register might bring
12948;; problem in implicit normalization in spill code.
12949;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12950;; instructions after reload by splitting the conditional move patterns.
12951
12952(define_insn "*sse_setccsf"
12953  [(set (match_operand:SF 0 "register_operand" "=x")
12954	(match_operator:SF 1 "sse_comparison_operator"
12955	  [(match_operand:SF 2 "register_operand" "0")
12956	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12957  "TARGET_SSE && reload_completed"
12958  "cmp%D1ss\t{%3, %0|%0, %3}"
12959  [(set_attr "type" "ssecmp")
12960   (set_attr "mode" "SF")])
12961
12962(define_insn "*sse_setccdf"
12963  [(set (match_operand:DF 0 "register_operand" "=Y")
12964	(match_operator:DF 1 "sse_comparison_operator"
12965	  [(match_operand:DF 2 "register_operand" "0")
12966	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12967  "TARGET_SSE2 && reload_completed"
12968  "cmp%D1sd\t{%3, %0|%0, %3}"
12969  [(set_attr "type" "ssecmp")
12970   (set_attr "mode" "DF")])
12971
12972;; Basic conditional jump instructions.
12973;; We ignore the overflow flag for signed branch instructions.
12974
12975;; For all bCOND expanders, also expand the compare or test insn that
12976;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12977
12978(define_expand "beq"
12979  [(set (pc)
12980	(if_then_else (match_dup 1)
12981		      (label_ref (match_operand 0 "" ""))
12982		      (pc)))]
12983  ""
12984  "ix86_expand_branch (EQ, operands[0]); DONE;")
12985
12986(define_expand "bne"
12987  [(set (pc)
12988	(if_then_else (match_dup 1)
12989		      (label_ref (match_operand 0 "" ""))
12990		      (pc)))]
12991  ""
12992  "ix86_expand_branch (NE, operands[0]); DONE;")
12993
12994(define_expand "bgt"
12995  [(set (pc)
12996	(if_then_else (match_dup 1)
12997		      (label_ref (match_operand 0 "" ""))
12998		      (pc)))]
12999  ""
13000  "ix86_expand_branch (GT, operands[0]); DONE;")
13001
13002(define_expand "bgtu"
13003  [(set (pc)
13004	(if_then_else (match_dup 1)
13005		      (label_ref (match_operand 0 "" ""))
13006		      (pc)))]
13007  ""
13008  "ix86_expand_branch (GTU, operands[0]); DONE;")
13009
13010(define_expand "blt"
13011  [(set (pc)
13012	(if_then_else (match_dup 1)
13013		      (label_ref (match_operand 0 "" ""))
13014		      (pc)))]
13015  ""
13016  "ix86_expand_branch (LT, operands[0]); DONE;")
13017
13018(define_expand "bltu"
13019  [(set (pc)
13020	(if_then_else (match_dup 1)
13021		      (label_ref (match_operand 0 "" ""))
13022		      (pc)))]
13023  ""
13024  "ix86_expand_branch (LTU, operands[0]); DONE;")
13025
13026(define_expand "bge"
13027  [(set (pc)
13028	(if_then_else (match_dup 1)
13029		      (label_ref (match_operand 0 "" ""))
13030		      (pc)))]
13031  ""
13032  "ix86_expand_branch (GE, operands[0]); DONE;")
13033
13034(define_expand "bgeu"
13035  [(set (pc)
13036	(if_then_else (match_dup 1)
13037		      (label_ref (match_operand 0 "" ""))
13038		      (pc)))]
13039  ""
13040  "ix86_expand_branch (GEU, operands[0]); DONE;")
13041
13042(define_expand "ble"
13043  [(set (pc)
13044	(if_then_else (match_dup 1)
13045		      (label_ref (match_operand 0 "" ""))
13046		      (pc)))]
13047  ""
13048  "ix86_expand_branch (LE, operands[0]); DONE;")
13049
13050(define_expand "bleu"
13051  [(set (pc)
13052	(if_then_else (match_dup 1)
13053		      (label_ref (match_operand 0 "" ""))
13054		      (pc)))]
13055  ""
13056  "ix86_expand_branch (LEU, operands[0]); DONE;")
13057
13058(define_expand "bunordered"
13059  [(set (pc)
13060	(if_then_else (match_dup 1)
13061		      (label_ref (match_operand 0 "" ""))
13062		      (pc)))]
13063  "TARGET_80387 || TARGET_SSE"
13064  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13065
13066(define_expand "bordered"
13067  [(set (pc)
13068	(if_then_else (match_dup 1)
13069		      (label_ref (match_operand 0 "" ""))
13070		      (pc)))]
13071  "TARGET_80387 || TARGET_SSE"
13072  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13073
13074(define_expand "buneq"
13075  [(set (pc)
13076	(if_then_else (match_dup 1)
13077		      (label_ref (match_operand 0 "" ""))
13078		      (pc)))]
13079  "TARGET_80387 || TARGET_SSE"
13080  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13081
13082(define_expand "bunge"
13083  [(set (pc)
13084	(if_then_else (match_dup 1)
13085		      (label_ref (match_operand 0 "" ""))
13086		      (pc)))]
13087  "TARGET_80387 || TARGET_SSE"
13088  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13089
13090(define_expand "bungt"
13091  [(set (pc)
13092	(if_then_else (match_dup 1)
13093		      (label_ref (match_operand 0 "" ""))
13094		      (pc)))]
13095  "TARGET_80387 || TARGET_SSE"
13096  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13097
13098(define_expand "bunle"
13099  [(set (pc)
13100	(if_then_else (match_dup 1)
13101		      (label_ref (match_operand 0 "" ""))
13102		      (pc)))]
13103  "TARGET_80387 || TARGET_SSE"
13104  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13105
13106(define_expand "bunlt"
13107  [(set (pc)
13108	(if_then_else (match_dup 1)
13109		      (label_ref (match_operand 0 "" ""))
13110		      (pc)))]
13111  "TARGET_80387 || TARGET_SSE"
13112  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13113
13114(define_expand "bltgt"
13115  [(set (pc)
13116	(if_then_else (match_dup 1)
13117		      (label_ref (match_operand 0 "" ""))
13118		      (pc)))]
13119  "TARGET_80387 || TARGET_SSE"
13120  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13121
13122(define_insn "*jcc_1"
13123  [(set (pc)
13124	(if_then_else (match_operator 1 "ix86_comparison_operator"
13125				      [(reg 17) (const_int 0)])
13126		      (label_ref (match_operand 0 "" ""))
13127		      (pc)))]
13128  ""
13129  "%+j%C1\t%l0"
13130  [(set_attr "type" "ibr")
13131   (set_attr "modrm" "0")
13132   (set (attr "length")
13133	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13134				  (const_int -126))
13135			      (lt (minus (match_dup 0) (pc))
13136				  (const_int 128)))
13137	     (const_int 2)
13138	     (const_int 6)))])
13139
13140(define_insn "*jcc_2"
13141  [(set (pc)
13142	(if_then_else (match_operator 1 "ix86_comparison_operator"
13143				      [(reg 17) (const_int 0)])
13144		      (pc)
13145		      (label_ref (match_operand 0 "" ""))))]
13146  ""
13147  "%+j%c1\t%l0"
13148  [(set_attr "type" "ibr")
13149   (set_attr "modrm" "0")
13150   (set (attr "length")
13151	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13152				  (const_int -126))
13153			      (lt (minus (match_dup 0) (pc))
13154				  (const_int 128)))
13155	     (const_int 2)
13156	     (const_int 6)))])
13157
13158;; In general it is not safe to assume too much about CCmode registers,
13159;; so simplify-rtx stops when it sees a second one.  Under certain 
13160;; conditions this is safe on x86, so help combine not create
13161;;
13162;;	seta	%al
13163;;	testb	%al, %al
13164;;	je	Lfoo
13165
13166(define_split 
13167  [(set (pc)
13168	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13169				      [(reg 17) (const_int 0)])
13170			  (const_int 0))
13171		      (label_ref (match_operand 1 "" ""))
13172		      (pc)))]
13173  ""
13174  [(set (pc)
13175	(if_then_else (match_dup 0)
13176		      (label_ref (match_dup 1))
13177		      (pc)))]
13178{
13179  PUT_MODE (operands[0], VOIDmode);
13180})
13181  
13182(define_split 
13183  [(set (pc)
13184	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13185				      [(reg 17) (const_int 0)])
13186			  (const_int 0))
13187		      (label_ref (match_operand 1 "" ""))
13188		      (pc)))]
13189  ""
13190  [(set (pc)
13191	(if_then_else (match_dup 0)
13192		      (label_ref (match_dup 1))
13193		      (pc)))]
13194{
13195  rtx new_op0 = copy_rtx (operands[0]);
13196  operands[0] = new_op0;
13197  PUT_MODE (new_op0, VOIDmode);
13198  PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13199					GET_MODE (XEXP (new_op0, 0))));
13200
13201  /* Make sure that (a) the CCmode we have for the flags is strong
13202     enough for the reversed compare or (b) we have a valid FP compare.  */
13203  if (! ix86_comparison_operator (new_op0, VOIDmode))
13204    FAIL;
13205})
13206
13207;; Define combination compare-and-branch fp compare instructions to use
13208;; during early optimization.  Splitting the operation apart early makes
13209;; for bad code when we want to reverse the operation.
13210
13211(define_insn "*fp_jcc_1"
13212  [(set (pc)
13213	(if_then_else (match_operator 0 "comparison_operator"
13214			[(match_operand 1 "register_operand" "f")
13215			 (match_operand 2 "register_operand" "f")])
13216	  (label_ref (match_operand 3 "" ""))
13217	  (pc)))
13218   (clobber (reg:CCFP 18))
13219   (clobber (reg:CCFP 17))]
13220  "TARGET_CMOVE && TARGET_80387
13221   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13222   && FLOAT_MODE_P (GET_MODE (operands[1]))
13223   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13224   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13225  "#")
13226
13227(define_insn "*fp_jcc_1_sse"
13228  [(set (pc)
13229	(if_then_else (match_operator 0 "comparison_operator"
13230			[(match_operand 1 "register_operand" "f#x,x#f")
13231			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13232	  (label_ref (match_operand 3 "" ""))
13233	  (pc)))
13234   (clobber (reg:CCFP 18))
13235   (clobber (reg:CCFP 17))]
13236  "TARGET_80387
13237   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13238   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13239   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13240  "#")
13241
13242(define_insn "*fp_jcc_1_sse_only"
13243  [(set (pc)
13244	(if_then_else (match_operator 0 "comparison_operator"
13245			[(match_operand 1 "register_operand" "x")
13246			 (match_operand 2 "nonimmediate_operand" "xm")])
13247	  (label_ref (match_operand 3 "" ""))
13248	  (pc)))
13249   (clobber (reg:CCFP 18))
13250   (clobber (reg:CCFP 17))]
13251  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13252   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13253   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13254  "#")
13255
13256(define_insn "*fp_jcc_2"
13257  [(set (pc)
13258	(if_then_else (match_operator 0 "comparison_operator"
13259			[(match_operand 1 "register_operand" "f")
13260			 (match_operand 2 "register_operand" "f")])
13261	  (pc)
13262	  (label_ref (match_operand 3 "" ""))))
13263   (clobber (reg:CCFP 18))
13264   (clobber (reg:CCFP 17))]
13265  "TARGET_CMOVE && TARGET_80387
13266   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13267   && FLOAT_MODE_P (GET_MODE (operands[1]))
13268   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13269   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13270  "#")
13271
13272(define_insn "*fp_jcc_2_sse"
13273  [(set (pc)
13274	(if_then_else (match_operator 0 "comparison_operator"
13275			[(match_operand 1 "register_operand" "f#x,x#f")
13276			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13277	  (pc)
13278	  (label_ref (match_operand 3 "" ""))))
13279   (clobber (reg:CCFP 18))
13280   (clobber (reg:CCFP 17))]
13281  "TARGET_80387
13282   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13283   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13284   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13285  "#")
13286
13287(define_insn "*fp_jcc_2_sse_only"
13288  [(set (pc)
13289	(if_then_else (match_operator 0 "comparison_operator"
13290			[(match_operand 1 "register_operand" "x")
13291			 (match_operand 2 "nonimmediate_operand" "xm")])
13292	  (pc)
13293	  (label_ref (match_operand 3 "" ""))))
13294   (clobber (reg:CCFP 18))
13295   (clobber (reg:CCFP 17))]
13296  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13297   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299  "#")
13300
13301(define_insn "*fp_jcc_3"
13302  [(set (pc)
13303	(if_then_else (match_operator 0 "comparison_operator"
13304			[(match_operand 1 "register_operand" "f")
13305			 (match_operand 2 "nonimmediate_operand" "fm")])
13306	  (label_ref (match_operand 3 "" ""))
13307	  (pc)))
13308   (clobber (reg:CCFP 18))
13309   (clobber (reg:CCFP 17))
13310   (clobber (match_scratch:HI 4 "=a"))]
13311  "TARGET_80387
13312   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13313   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13315   && SELECT_CC_MODE (GET_CODE (operands[0]),
13316		      operands[1], operands[2]) == CCFPmode
13317   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318  "#")
13319
13320(define_insn "*fp_jcc_4"
13321  [(set (pc)
13322	(if_then_else (match_operator 0 "comparison_operator"
13323			[(match_operand 1 "register_operand" "f")
13324			 (match_operand 2 "nonimmediate_operand" "fm")])
13325	  (pc)
13326	  (label_ref (match_operand 3 "" ""))))
13327   (clobber (reg:CCFP 18))
13328   (clobber (reg:CCFP 17))
13329   (clobber (match_scratch:HI 4 "=a"))]
13330  "TARGET_80387
13331   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13332   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13333   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13334   && SELECT_CC_MODE (GET_CODE (operands[0]),
13335		      operands[1], operands[2]) == CCFPmode
13336   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13337  "#")
13338
13339(define_insn "*fp_jcc_5"
13340  [(set (pc)
13341	(if_then_else (match_operator 0 "comparison_operator"
13342			[(match_operand 1 "register_operand" "f")
13343			 (match_operand 2 "register_operand" "f")])
13344	  (label_ref (match_operand 3 "" ""))
13345	  (pc)))
13346   (clobber (reg:CCFP 18))
13347   (clobber (reg:CCFP 17))
13348   (clobber (match_scratch:HI 4 "=a"))]
13349  "TARGET_80387
13350   && FLOAT_MODE_P (GET_MODE (operands[1]))
13351   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13352   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13353  "#")
13354
13355(define_insn "*fp_jcc_6"
13356  [(set (pc)
13357	(if_then_else (match_operator 0 "comparison_operator"
13358			[(match_operand 1 "register_operand" "f")
13359			 (match_operand 2 "register_operand" "f")])
13360	  (pc)
13361	  (label_ref (match_operand 3 "" ""))))
13362   (clobber (reg:CCFP 18))
13363   (clobber (reg:CCFP 17))
13364   (clobber (match_scratch:HI 4 "=a"))]
13365  "TARGET_80387
13366   && FLOAT_MODE_P (GET_MODE (operands[1]))
13367   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13368   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13369  "#")
13370
13371(define_split
13372  [(set (pc)
13373	(if_then_else (match_operator 0 "comparison_operator"
13374			[(match_operand 1 "register_operand" "")
13375			 (match_operand 2 "nonimmediate_operand" "")])
13376	  (match_operand 3 "" "")
13377	  (match_operand 4 "" "")))
13378   (clobber (reg:CCFP 18))
13379   (clobber (reg:CCFP 17))]
13380  "reload_completed"
13381  [(const_int 0)]
13382{
13383  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13384			operands[3], operands[4], NULL_RTX);
13385  DONE;
13386})
13387
13388(define_split
13389  [(set (pc)
13390	(if_then_else (match_operator 0 "comparison_operator"
13391			[(match_operand 1 "register_operand" "")
13392			 (match_operand 2 "nonimmediate_operand" "")])
13393	  (match_operand 3 "" "")
13394	  (match_operand 4 "" "")))
13395   (clobber (reg:CCFP 18))
13396   (clobber (reg:CCFP 17))
13397   (clobber (match_scratch:HI 5 "=a"))]
13398  "reload_completed"
13399  [(set (pc)
13400	(if_then_else (match_dup 6)
13401	  (match_dup 3)
13402	  (match_dup 4)))]
13403{
13404  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13405			operands[3], operands[4], operands[5]);
13406  DONE;
13407})
13408
13409;; Unconditional and other jump instructions
13410
13411(define_insn "jump"
13412  [(set (pc)
13413	(label_ref (match_operand 0 "" "")))]
13414  ""
13415  "jmp\t%l0"
13416  [(set_attr "type" "ibr")
13417   (set (attr "length")
13418	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13419				  (const_int -126))
13420			      (lt (minus (match_dup 0) (pc))
13421				  (const_int 128)))
13422	     (const_int 2)
13423	     (const_int 5)))
13424   (set_attr "modrm" "0")])
13425
13426(define_expand "indirect_jump"
13427  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13428  ""
13429  "")
13430
13431(define_insn "*indirect_jump"
13432  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13433  "!TARGET_64BIT"
13434  "jmp\t%A0"
13435  [(set_attr "type" "ibr")
13436   (set_attr "length_immediate" "0")])
13437
13438(define_insn "*indirect_jump_rtx64"
13439  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13440  "TARGET_64BIT"
13441  "jmp\t%A0"
13442  [(set_attr "type" "ibr")
13443   (set_attr "length_immediate" "0")])
13444
13445(define_expand "tablejump"
13446  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13447	      (use (label_ref (match_operand 1 "" "")))])]
13448  ""
13449{
13450  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13451     relative.  Convert the relative address to an absolute address.  */
13452  if (flag_pic)
13453    {
13454      rtx op0, op1;
13455      enum rtx_code code;
13456
13457      if (TARGET_64BIT)
13458	{
13459	  code = PLUS;
13460	  op0 = operands[0];
13461	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13462	}
13463      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13464	{
13465	  code = PLUS;
13466	  op0 = operands[0];
13467	  op1 = pic_offset_table_rtx;
13468	}
13469      else
13470	{
13471	  code = MINUS;
13472	  op0 = pic_offset_table_rtx;
13473	  op1 = operands[0];
13474	}
13475
13476      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13477					 OPTAB_DIRECT);
13478    }
13479})
13480
13481(define_insn "*tablejump_1"
13482  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13483   (use (label_ref (match_operand 1 "" "")))]
13484  "!TARGET_64BIT"
13485  "jmp\t%A0"
13486  [(set_attr "type" "ibr")
13487   (set_attr "length_immediate" "0")])
13488
13489(define_insn "*tablejump_1_rtx64"
13490  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13491   (use (label_ref (match_operand 1 "" "")))]
13492  "TARGET_64BIT"
13493  "jmp\t%A0"
13494  [(set_attr "type" "ibr")
13495   (set_attr "length_immediate" "0")])
13496
13497;; Loop instruction
13498;;
13499;; This is all complicated by the fact that since this is a jump insn
13500;; we must handle our own reloads.
13501
13502(define_expand "doloop_end"
13503  [(use (match_operand 0 "" ""))        ; loop pseudo
13504   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13505   (use (match_operand 2 "" ""))        ; max iterations
13506   (use (match_operand 3 "" ""))        ; loop level 
13507   (use (match_operand 4 "" ""))]       ; label
13508  "!TARGET_64BIT && TARGET_USE_LOOP"
13509  "                                 
13510{
13511  /* Only use cloop on innermost loops.  */
13512  if (INTVAL (operands[3]) > 1)
13513    FAIL;
13514  if (GET_MODE (operands[0]) != SImode)
13515    FAIL;
13516  emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13517					   operands[0]));
13518  DONE;
13519}")
13520
13521(define_insn "doloop_end_internal"
13522  [(set (pc)
13523	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13524			  (const_int 1))
13525		      (label_ref (match_operand 0 "" ""))
13526		      (pc)))
13527   (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13528	(plus:SI (match_dup 1)
13529		 (const_int -1)))
13530   (clobber (match_scratch:SI 3 "=X,X,r"))
13531   (clobber (reg:CC 17))]
13532  "!TARGET_64BIT && TARGET_USE_LOOP"
13533{
13534  if (which_alternative != 0)
13535    return "#";
13536  if (get_attr_length (insn) == 2)
13537    return "%+loop\t%l0";
13538  else
13539    return "dec{l}\t%1\;%+jne\t%l0";
13540}
13541  [(set_attr "ppro_uops" "many")
13542   (set (attr "length")
13543	(if_then_else (and (eq_attr "alternative" "0")
13544			   (and (ge (minus (match_dup 0) (pc))
13545			            (const_int -126))
13546			        (lt (minus (match_dup 0) (pc))
13547			            (const_int 128))))
13548		      (const_int 2)
13549		      (const_int 16)))
13550   ;; We don't know the type before shorten branches.  Optimistically expect
13551   ;; the loop instruction to match.
13552   (set (attr "type") (const_string "ibr"))])
13553
13554(define_split
13555  [(set (pc)
13556	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
13557			  (const_int 1))
13558		      (match_operand 0 "" "")
13559		      (pc)))
13560   (set (match_dup 1)
13561	(plus:SI (match_dup 1)
13562		 (const_int -1)))
13563   (clobber (match_scratch:SI 2 ""))
13564   (clobber (reg:CC 17))]
13565  "!TARGET_64BIT && TARGET_USE_LOOP
13566   && reload_completed
13567   && REGNO (operands[1]) != 2"
13568  [(parallel [(set (reg:CCZ 17)
13569		   (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13570				 (const_int 0)))
13571	      (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13572   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13573			   (match_dup 0)
13574			   (pc)))]
13575  "")
13576  
13577(define_split
13578  [(set (pc)
13579	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
13580			  (const_int 1))
13581		      (match_operand 0 "" "")
13582		      (pc)))
13583   (set (match_operand:SI 2 "nonimmediate_operand" "")
13584	(plus:SI (match_dup 1)
13585		 (const_int -1)))
13586   (clobber (match_scratch:SI 3 ""))
13587   (clobber (reg:CC 17))]
13588  "!TARGET_64BIT && TARGET_USE_LOOP
13589   && reload_completed
13590   && (! REG_P (operands[2])
13591       || ! rtx_equal_p (operands[1], operands[2]))"
13592  [(set (match_dup 3) (match_dup 1))
13593   (parallel [(set (reg:CCZ 17)
13594		   (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13595				(const_int 0)))
13596	      (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13597   (set (match_dup 2) (match_dup 3))
13598   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13599			   (match_dup 0)
13600			   (pc)))]
13601  "")
13602
13603;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13604
13605(define_peephole2
13606  [(set (reg 17) (match_operand 0 "" ""))
13607   (set (match_operand:QI 1 "register_operand" "")
13608	(match_operator:QI 2 "ix86_comparison_operator"
13609	  [(reg 17) (const_int 0)]))
13610   (set (match_operand 3 "q_regs_operand" "")
13611	(zero_extend (match_dup 1)))]
13612  "(peep2_reg_dead_p (3, operands[1])
13613    || operands_match_p (operands[1], operands[3]))
13614   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13615  [(set (match_dup 4) (match_dup 0))
13616   (set (strict_low_part (match_dup 5))
13617	(match_dup 2))]
13618{
13619  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13620  operands[5] = gen_lowpart (QImode, operands[3]);
13621  ix86_expand_clear (operands[3]);
13622})
13623
13624;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13625
13626(define_peephole2
13627  [(set (reg 17) (match_operand 0 "" ""))
13628   (set (match_operand:QI 1 "register_operand" "")
13629	(match_operator:QI 2 "ix86_comparison_operator"
13630	  [(reg 17) (const_int 0)]))
13631   (parallel [(set (match_operand 3 "q_regs_operand" "")
13632		   (zero_extend (match_dup 1)))
13633	      (clobber (reg:CC 17))])]
13634  "(peep2_reg_dead_p (3, operands[1])
13635    || operands_match_p (operands[1], operands[3]))
13636   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13637  [(set (match_dup 4) (match_dup 0))
13638   (set (strict_low_part (match_dup 5))
13639	(match_dup 2))]
13640{
13641  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13642  operands[5] = gen_lowpart (QImode, operands[3]);
13643  ix86_expand_clear (operands[3]);
13644})
13645
13646;; Call instructions.
13647
13648;; The predicates normally associated with named expanders are not properly
13649;; checked for calls.  This is a bug in the generic code, but it isn't that
13650;; easy to fix.  Ignore it for now and be prepared to fix things up.
13651
13652;; Call subroutine returning no value.
13653
13654(define_expand "call_pop"
13655  [(parallel [(call (match_operand:QI 0 "" "")
13656		    (match_operand:SI 1 "" ""))
13657	      (set (reg:SI 7)
13658		   (plus:SI (reg:SI 7)
13659			    (match_operand:SI 3 "" "")))])]
13660  "!TARGET_64BIT"
13661{
13662  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13663  DONE;
13664})
13665
13666(define_insn "*call_pop_0"
13667  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13668	 (match_operand:SI 1 "" ""))
13669   (set (reg:SI 7) (plus:SI (reg:SI 7)
13670			    (match_operand:SI 2 "immediate_operand" "")))]
13671  "!TARGET_64BIT"
13672{
13673  if (SIBLING_CALL_P (insn))
13674    return "jmp\t%P0";
13675  else
13676    return "call\t%P0";
13677}
13678  [(set_attr "type" "call")])
13679  
13680(define_insn "*call_pop_1"
13681  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13682	 (match_operand:SI 1 "" ""))
13683   (set (reg:SI 7) (plus:SI (reg:SI 7)
13684			    (match_operand:SI 2 "immediate_operand" "i")))]
13685  "!TARGET_64BIT"
13686{
13687  if (constant_call_address_operand (operands[0], Pmode))
13688    {
13689      if (SIBLING_CALL_P (insn))
13690	return "jmp\t%P0";
13691      else
13692	return "call\t%P0";
13693    }
13694  if (SIBLING_CALL_P (insn))
13695    return "jmp\t%A0";
13696  else
13697    return "call\t%A0";
13698}
13699  [(set_attr "type" "call")])
13700
13701(define_expand "call"
13702  [(call (match_operand:QI 0 "" "")
13703	 (match_operand 1 "" ""))
13704   (use (match_operand 2 "" ""))]
13705  ""
13706{
13707  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13708  DONE;
13709})
13710
13711(define_expand "sibcall"
13712  [(call (match_operand:QI 0 "" "")
13713	 (match_operand 1 "" ""))
13714   (use (match_operand 2 "" ""))]
13715  ""
13716{
13717  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13718  DONE;
13719})
13720
13721(define_insn "*call_0"
13722  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13723	 (match_operand 1 "" ""))]
13724  ""
13725{
13726  if (SIBLING_CALL_P (insn))
13727    return "jmp\t%P0";
13728  else
13729    return "call\t%P0";
13730}
13731  [(set_attr "type" "call")])
13732
13733(define_insn "*call_1"
13734  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13735	 (match_operand 1 "" ""))]
13736  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13737{
13738  if (constant_call_address_operand (operands[0], QImode))
13739    return "call\t%P0";
13740  return "call\t%A0";
13741}
13742  [(set_attr "type" "call")])
13743
13744(define_insn "*sibcall_1"
13745  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13746	 (match_operand 1 "" ""))]
13747  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13748{
13749  if (constant_call_address_operand (operands[0], QImode))
13750    return "jmp\t%P0";
13751  return "jmp\t%A0";
13752}
13753  [(set_attr "type" "call")])
13754
13755(define_insn "*call_1_rex64"
13756  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13757	 (match_operand 1 "" ""))]
13758  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13759{
13760  if (constant_call_address_operand (operands[0], QImode))
13761    return "call\t%P0";
13762  return "call\t%A0";
13763}
13764  [(set_attr "type" "call")])
13765
13766(define_insn "*sibcall_1_rex64"
13767  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13768	 (match_operand 1 "" ""))]
13769  "SIBLING_CALL_P (insn) && TARGET_64BIT"
13770  "jmp\t%P0"
13771  [(set_attr "type" "call")])
13772
13773(define_insn "*sibcall_1_rex64_v"
13774  [(call (mem:QI (reg:DI 40))
13775	 (match_operand 0 "" ""))]
13776  "SIBLING_CALL_P (insn) && TARGET_64BIT"
13777  "jmp\t*%%r11"
13778  [(set_attr "type" "call")])
13779
13780
13781;; Call subroutine, returning value in operand 0
13782
13783(define_expand "call_value_pop"
13784  [(parallel [(set (match_operand 0 "" "")
13785		   (call (match_operand:QI 1 "" "")
13786			 (match_operand:SI 2 "" "")))
13787	      (set (reg:SI 7)
13788		   (plus:SI (reg:SI 7)
13789			    (match_operand:SI 4 "" "")))])]
13790  "!TARGET_64BIT"
13791{
13792  ix86_expand_call (operands[0], operands[1], operands[2],
13793		    operands[3], operands[4], 0);
13794  DONE;
13795})
13796
13797(define_expand "call_value"
13798  [(set (match_operand 0 "" "")
13799	(call (match_operand:QI 1 "" "")
13800	      (match_operand:SI 2 "" "")))
13801   (use (match_operand:SI 3 "" ""))]
13802  ;; Operand 2 not used on the i386.
13803  ""
13804{
13805  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13806  DONE;
13807})
13808
13809(define_expand "sibcall_value"
13810  [(set (match_operand 0 "" "")
13811	(call (match_operand:QI 1 "" "")
13812	      (match_operand:SI 2 "" "")))
13813   (use (match_operand:SI 3 "" ""))]
13814  ;; Operand 2 not used on the i386.
13815  ""
13816{
13817  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13818  DONE;
13819})
13820
13821;; Call subroutine returning any type.
13822
13823(define_expand "untyped_call"
13824  [(parallel [(call (match_operand 0 "" "")
13825		    (const_int 0))
13826	      (match_operand 1 "" "")
13827	      (match_operand 2 "" "")])]
13828  ""
13829{
13830  int i;
13831
13832  /* In order to give reg-stack an easier job in validating two
13833     coprocessor registers as containing a possible return value,
13834     simply pretend the untyped call returns a complex long double
13835     value.  */
13836
13837  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13838		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13839		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13840		    NULL, 0);
13841
13842  for (i = 0; i < XVECLEN (operands[2], 0); i++)
13843    {
13844      rtx set = XVECEXP (operands[2], 0, i);
13845      emit_move_insn (SET_DEST (set), SET_SRC (set));
13846    }
13847
13848  /* The optimizer does not know that the call sets the function value
13849     registers we stored in the result block.  We avoid problems by
13850     claiming that all hard registers are used and clobbered at this
13851     point.  */
13852  emit_insn (gen_blockage (const0_rtx));
13853
13854  DONE;
13855})
13856
13857;; Prologue and epilogue instructions
13858
13859;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13860;; all of memory.  This blocks insns from being moved across this point.
13861
13862(define_insn "blockage"
13863  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13864  ""
13865  ""
13866  [(set_attr "length" "0")])
13867
13868;; Insn emitted into the body of a function to return from a function.
13869;; This is only done if the function's epilogue is known to be simple.
13870;; See comments for ix86_can_use_return_insn_p in i386.c.
13871
13872(define_expand "return"
13873  [(return)]
13874  "ix86_can_use_return_insn_p ()"
13875{
13876  if (current_function_pops_args)
13877    {
13878      rtx popc = GEN_INT (current_function_pops_args);
13879      emit_jump_insn (gen_return_pop_internal (popc));
13880      DONE;
13881    }
13882})
13883
13884(define_insn "return_internal"
13885  [(return)]
13886  "reload_completed"
13887  "ret"
13888  [(set_attr "length" "1")
13889   (set_attr "length_immediate" "0")
13890   (set_attr "modrm" "0")])
13891
13892;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13893;; instruction Athlon and K8 have.
13894
13895(define_insn "return_internal_long"
13896  [(return)
13897   (unspec [(const_int 0)] UNSPEC_REP)]
13898  "reload_completed"
13899  "rep {;} ret"
13900  [(set_attr "length" "1")
13901   (set_attr "length_immediate" "0")
13902   (set_attr "prefix_rep" "1")
13903   (set_attr "modrm" "0")])
13904
13905(define_insn "return_pop_internal"
13906  [(return)
13907   (use (match_operand:SI 0 "const_int_operand" ""))]
13908  "reload_completed"
13909  "ret\t%0"
13910  [(set_attr "length" "3")
13911   (set_attr "length_immediate" "2")
13912   (set_attr "modrm" "0")])
13913
13914(define_insn "return_indirect_internal"
13915  [(return)
13916   (use (match_operand:SI 0 "register_operand" "r"))]
13917  "reload_completed"
13918  "jmp\t%A0"
13919  [(set_attr "type" "ibr")
13920   (set_attr "length_immediate" "0")])
13921
13922(define_insn "nop"
13923  [(const_int 0)]
13924  ""
13925  "nop"
13926  [(set_attr "length" "1")
13927   (set_attr "length_immediate" "0")
13928   (set_attr "modrm" "0")
13929   (set_attr "ppro_uops" "one")])
13930
13931;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13932;; branch prediction penalty for the third jump in a 16-byte
13933;; block on K8.
13934
13935(define_insn "align"
13936  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13937  ""
13938{
13939#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13940  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13941#else
13942  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13943     The align insn is used to avoid 3 jump instructions in the row to improve
13944     branch prediction and the benefits hardly outweight the cost of extra 8
13945     nops on the average inserted by full alignment pseudo operation.  */
13946#endif
13947  return "";
13948}
13949  [(set_attr "length" "16")])
13950
13951(define_expand "prologue"
13952  [(const_int 1)]
13953  ""
13954  "ix86_expand_prologue (); DONE;")
13955
13956(define_insn "set_got"
13957  [(set (match_operand:SI 0 "register_operand" "=r")
13958	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13959   (clobber (reg:CC 17))]
13960  "!TARGET_64BIT"
13961  { return output_set_got (operands[0]); }
13962  [(set_attr "type" "multi")
13963   (set_attr "length" "12")])
13964
13965(define_expand "epilogue"
13966  [(const_int 1)]
13967  ""
13968  "ix86_expand_epilogue (1); DONE;")
13969
13970(define_expand "sibcall_epilogue"
13971  [(const_int 1)]
13972  ""
13973  "ix86_expand_epilogue (0); DONE;")
13974
13975(define_expand "eh_return"
13976  [(use (match_operand 0 "register_operand" ""))]
13977  ""
13978{
13979  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13980
13981  /* Tricky bit: we write the address of the handler to which we will
13982     be returning into someone else's stack frame, one word below the
13983     stack address we wish to restore.  */
13984  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13985  tmp = plus_constant (tmp, -UNITS_PER_WORD);
13986  tmp = gen_rtx_MEM (Pmode, tmp);
13987  emit_move_insn (tmp, ra);
13988
13989  if (Pmode == SImode)
13990    emit_insn (gen_eh_return_si (sa));
13991  else
13992    emit_insn (gen_eh_return_di (sa));
13993  emit_barrier ();
13994  DONE;
13995})
13996
13997(define_insn_and_split "eh_return_si"
13998  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13999		    UNSPECV_EH_RETURN)]
14000  "!TARGET_64BIT"
14001  "#"
14002  "reload_completed"
14003  [(const_int 1)]
14004  "ix86_expand_epilogue (2); DONE;")
14005
14006(define_insn_and_split "eh_return_di"
14007  [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14008		    UNSPECV_EH_RETURN)]
14009  "TARGET_64BIT"
14010  "#"
14011  "reload_completed"
14012  [(const_int 1)]
14013  "ix86_expand_epilogue (2); DONE;")
14014
14015(define_insn "leave"
14016  [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14017   (set (reg:SI 6) (mem:SI (reg:SI 6)))
14018   (clobber (mem:BLK (scratch)))]
14019  "!TARGET_64BIT"
14020  "leave"
14021  [(set_attr "type" "leave")])
14022
14023(define_insn "leave_rex64"
14024  [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14025   (set (reg:DI 6) (mem:DI (reg:DI 6)))
14026   (clobber (mem:BLK (scratch)))]
14027  "TARGET_64BIT"
14028  "leave"
14029  [(set_attr "type" "leave")])
14030
14031(define_expand "ffssi2"
14032  [(parallel
14033     [(set (match_operand:SI 0 "register_operand" "") 
14034	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14035      (clobber (match_scratch:SI 2 ""))
14036      (clobber (reg:CC 17))])]
14037  ""
14038  "")
14039
14040(define_insn_and_split "*ffs_cmove"
14041  [(set (match_operand:SI 0 "register_operand" "=r") 
14042	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14043   (clobber (match_scratch:SI 2 "=&r"))
14044   (clobber (reg:CC 17))]
14045  "TARGET_CMOVE"
14046  "#"
14047  "&& reload_completed"
14048  [(set (match_dup 2) (const_int -1))
14049   (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14050	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14051   (set (match_dup 0) (if_then_else:SI
14052			(eq (reg:CCZ 17) (const_int 0))
14053			(match_dup 2)
14054			(match_dup 0)))
14055   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14056	      (clobber (reg:CC 17))])]
14057  "")
14058
14059(define_insn_and_split "*ffs_no_cmove"
14060  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14061	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14062   (clobber (match_scratch:SI 2 "=&q"))
14063   (clobber (reg:CC 17))]
14064  ""
14065  "#"
14066  "reload_completed"
14067  [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14068	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14069   (set (strict_low_part (match_dup 3))
14070	(eq:QI (reg:CCZ 17) (const_int 0)))
14071   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14072	      (clobber (reg:CC 17))])
14073   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14074	      (clobber (reg:CC 17))])
14075   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14076	      (clobber (reg:CC 17))])]
14077{
14078  operands[3] = gen_lowpart (QImode, operands[2]);
14079  ix86_expand_clear (operands[2]);
14080})
14081
14082(define_insn "*ffssi_1"
14083  [(set (reg:CCZ 17)
14084	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14085		     (const_int 0)))
14086   (set (match_operand:SI 0 "register_operand" "=r")
14087	(ctz:SI (match_dup 1)))]
14088  ""
14089  "bsf{l}\t{%1, %0|%0, %1}"
14090  [(set_attr "prefix_0f" "1")
14091   (set_attr "ppro_uops" "few")])
14092
14093(define_insn "ctzsi2"
14094  [(set (match_operand:SI 0 "register_operand" "=r")
14095	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14096   (clobber (reg:CC 17))]
14097  ""
14098  "bsf{l}\t{%1, %0|%0, %1}"
14099  [(set_attr "prefix_0f" "1")
14100   (set_attr "ppro_uops" "few")])
14101
14102(define_expand "clzsi2"
14103  [(parallel
14104     [(set (match_operand:SI 0 "register_operand" "")
14105	   (minus:SI (const_int 31)
14106		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14107      (clobber (reg:CC 17))])
14108   (parallel
14109     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14110      (clobber (reg:CC 17))])]
14111  ""
14112  "")
14113
14114(define_insn "*bsr"
14115  [(set (match_operand:SI 0 "register_operand" "=r")
14116	(minus:SI (const_int 31)
14117		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14118   (clobber (reg:CC 17))]
14119  ""
14120  "bsr{l}\t{%1, %0|%0, %1}"
14121  [(set_attr "prefix_0f" "1")
14122   (set_attr "ppro_uops" "few")])
14123
14124;; Thread-local storage patterns for ELF.
14125;;
14126;; Note that these code sequences must appear exactly as shown
14127;; in order to allow linker relaxation.
14128
14129(define_insn "*tls_global_dynamic_32_gnu"
14130  [(set (match_operand:SI 0 "register_operand" "=a")
14131	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14132		    (match_operand:SI 2 "tls_symbolic_operand" "")
14133		    (match_operand:SI 3 "call_insn_operand" "")]
14134		    UNSPEC_TLS_GD))
14135   (clobber (match_scratch:SI 4 "=d"))
14136   (clobber (match_scratch:SI 5 "=c"))
14137   (clobber (reg:CC 17))]
14138  "!TARGET_64BIT && TARGET_GNU_TLS"
14139  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14140  [(set_attr "type" "multi")
14141   (set_attr "length" "12")])
14142
14143(define_insn "*tls_global_dynamic_32_sun"
14144  [(set (match_operand:SI 0 "register_operand" "=a")
14145	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14146		    (match_operand:SI 2 "tls_symbolic_operand" "")
14147		    (match_operand:SI 3 "call_insn_operand" "")]
14148		    UNSPEC_TLS_GD))
14149   (clobber (match_scratch:SI 4 "=d"))
14150   (clobber (match_scratch:SI 5 "=c"))
14151   (clobber (reg:CC 17))]
14152  "!TARGET_64BIT && TARGET_SUN_TLS"
14153  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14154	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14155  [(set_attr "type" "multi")
14156   (set_attr "length" "14")])
14157
14158(define_expand "tls_global_dynamic_32"
14159  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14160		   (unspec:SI
14161		    [(match_dup 2)
14162		     (match_operand:SI 1 "tls_symbolic_operand" "")
14163		     (match_dup 3)]
14164		    UNSPEC_TLS_GD))
14165	      (clobber (match_scratch:SI 4 ""))
14166	      (clobber (match_scratch:SI 5 ""))
14167	      (clobber (reg:CC 17))])]
14168  ""
14169{
14170  if (flag_pic)
14171    operands[2] = pic_offset_table_rtx;
14172  else
14173    {
14174      operands[2] = gen_reg_rtx (Pmode);
14175      emit_insn (gen_set_got (operands[2]));
14176    }
14177  operands[3] = ix86_tls_get_addr ();
14178})
14179
14180(define_insn "*tls_global_dynamic_64"
14181  [(set (match_operand:DI 0 "register_operand" "=a")
14182	(call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14183		      (match_operand:DI 3 "" "")))
14184   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14185	      UNSPEC_TLS_GD)]
14186  "TARGET_64BIT"
14187  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14188  [(set_attr "type" "multi")
14189   (set_attr "length" "16")])
14190
14191(define_expand "tls_global_dynamic_64"
14192  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14193		   (call (mem:QI (match_dup 2)) (const_int 0)))
14194	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14195			 UNSPEC_TLS_GD)])]
14196  ""
14197{
14198  operands[2] = ix86_tls_get_addr ();
14199})
14200
14201(define_insn "*tls_local_dynamic_base_32_gnu"
14202  [(set (match_operand:SI 0 "register_operand" "=a")
14203	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14204                    (match_operand:SI 2 "call_insn_operand" "")]
14205		   UNSPEC_TLS_LD_BASE))
14206   (clobber (match_scratch:SI 3 "=d"))
14207   (clobber (match_scratch:SI 4 "=c"))
14208   (clobber (reg:CC 17))]
14209  "!TARGET_64BIT && TARGET_GNU_TLS"
14210  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14211  [(set_attr "type" "multi")
14212   (set_attr "length" "11")])
14213
14214(define_insn "*tls_local_dynamic_base_32_sun"
14215  [(set (match_operand:SI 0 "register_operand" "=a")
14216	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14217                    (match_operand:SI 2 "call_insn_operand" "")]
14218		   UNSPEC_TLS_LD_BASE))
14219   (clobber (match_scratch:SI 3 "=d"))
14220   (clobber (match_scratch:SI 4 "=c"))
14221   (clobber (reg:CC 17))]
14222  "!TARGET_64BIT && TARGET_SUN_TLS"
14223  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14224	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14225  [(set_attr "type" "multi")
14226   (set_attr "length" "13")])
14227
14228(define_expand "tls_local_dynamic_base_32"
14229  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14230		   (unspec:SI [(match_dup 1) (match_dup 2)]
14231			      UNSPEC_TLS_LD_BASE))
14232	      (clobber (match_scratch:SI 3 ""))
14233	      (clobber (match_scratch:SI 4 ""))
14234	      (clobber (reg:CC 17))])]
14235  ""
14236{
14237  if (flag_pic)
14238    operands[1] = pic_offset_table_rtx;
14239  else
14240    {
14241      operands[1] = gen_reg_rtx (Pmode);
14242      emit_insn (gen_set_got (operands[1]));
14243    }
14244  operands[2] = ix86_tls_get_addr ();
14245})
14246
14247(define_insn "*tls_local_dynamic_base_64"
14248  [(set (match_operand:DI 0 "register_operand" "=a")
14249	(call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14250		      (match_operand:DI 2 "" "")))
14251   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14252  "TARGET_64BIT"
14253  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14254  [(set_attr "type" "multi")
14255   (set_attr "length" "12")])
14256
14257(define_expand "tls_local_dynamic_base_64"
14258  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14259		   (call (mem:QI (match_dup 1)) (const_int 0)))
14260	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14261  ""
14262{
14263  operands[1] = ix86_tls_get_addr ();
14264})
14265
14266;; Local dynamic of a single variable is a lose.  Show combine how
14267;; to convert that back to global dynamic.
14268
14269(define_insn_and_split "*tls_local_dynamic_32_once"
14270  [(set (match_operand:SI 0 "register_operand" "=a")
14271	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14272			     (match_operand:SI 2 "call_insn_operand" "")]
14273			    UNSPEC_TLS_LD_BASE)
14274		 (const:SI (unspec:SI
14275			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
14276			    UNSPEC_DTPOFF))))
14277   (clobber (match_scratch:SI 4 "=d"))
14278   (clobber (match_scratch:SI 5 "=c"))
14279   (clobber (reg:CC 17))]
14280  ""
14281  "#"
14282  ""
14283  [(parallel [(set (match_dup 0)
14284		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14285			      UNSPEC_TLS_GD))
14286	      (clobber (match_dup 4))
14287	      (clobber (match_dup 5))
14288	      (clobber (reg:CC 17))])]
14289  "")
14290
14291;; Load and add the thread base pointer from %gs:0.
14292
14293(define_insn "*load_tp_si"
14294  [(set (match_operand:SI 0 "register_operand" "=r")
14295	(unspec:SI [(const_int 0)] UNSPEC_TP))]
14296  "!TARGET_64BIT"
14297  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14298  [(set_attr "type" "imov")
14299   (set_attr "modrm" "0")
14300   (set_attr "length" "7")
14301   (set_attr "memory" "load")
14302   (set_attr "imm_disp" "false")])
14303
14304(define_insn "*add_tp_si"
14305  [(set (match_operand:SI 0 "register_operand" "=r")
14306	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14307		 (match_operand:SI 1 "register_operand" "0")))
14308   (clobber (reg:CC 17))]
14309  "!TARGET_64BIT"
14310  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14311  [(set_attr "type" "alu")
14312   (set_attr "modrm" "0")
14313   (set_attr "length" "7")
14314   (set_attr "memory" "load")
14315   (set_attr "imm_disp" "false")])
14316
14317(define_insn "*load_tp_di"
14318  [(set (match_operand:DI 0 "register_operand" "=r")
14319	(unspec:DI [(const_int 0)] UNSPEC_TP))]
14320  "TARGET_64BIT"
14321  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14322  [(set_attr "type" "imov")
14323   (set_attr "modrm" "0")
14324   (set_attr "length" "7")
14325   (set_attr "memory" "load")
14326   (set_attr "imm_disp" "false")])
14327
14328(define_insn "*add_tp_di"
14329  [(set (match_operand:DI 0 "register_operand" "=r")
14330	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14331		 (match_operand:DI 1 "register_operand" "0")))
14332   (clobber (reg:CC 17))]
14333  "TARGET_64BIT"
14334  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14335  [(set_attr "type" "alu")
14336   (set_attr "modrm" "0")
14337   (set_attr "length" "7")
14338   (set_attr "memory" "load")
14339   (set_attr "imm_disp" "false")])
14340
14341;; These patterns match the binary 387 instructions for addM3, subM3,
14342;; mulM3 and divM3.  There are three patterns for each of DFmode and
14343;; SFmode.  The first is the normal insn, the second the same insn but
14344;; with one operand a conversion, and the third the same insn but with
14345;; the other operand a conversion.  The conversion may be SFmode or
14346;; SImode if the target mode DFmode, but only SImode if the target mode
14347;; is SFmode.
14348
14349;; Gcc is slightly more smart about handling normal two address instructions
14350;; so use special patterns for add and mull.
14351(define_insn "*fop_sf_comm_nosse"
14352  [(set (match_operand:SF 0 "register_operand" "=f")
14353	(match_operator:SF 3 "binary_fp_operator"
14354			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14355			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14356  "TARGET_80387 && !TARGET_SSE_MATH
14357   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14358   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14359  "* return output_387_binary_op (insn, operands);"
14360  [(set (attr "type") 
14361	(if_then_else (match_operand:SF 3 "mult_operator" "") 
14362	   (const_string "fmul")
14363	   (const_string "fop")))
14364   (set_attr "mode" "SF")])
14365
14366(define_insn "*fop_sf_comm"
14367  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14368	(match_operator:SF 3 "binary_fp_operator"
14369			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14370			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14371  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14372   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14373   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374  "* return output_387_binary_op (insn, operands);"
14375  [(set (attr "type") 
14376	(if_then_else (eq_attr "alternative" "1")
14377	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14378	      (const_string "ssemul")
14379	      (const_string "sseadd"))
14380	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14381	      (const_string "fmul")
14382	      (const_string "fop"))))
14383   (set_attr "mode" "SF")])
14384
14385(define_insn "*fop_sf_comm_sse"
14386  [(set (match_operand:SF 0 "register_operand" "=x")
14387	(match_operator:SF 3 "binary_fp_operator"
14388			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14389			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14390  "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14391   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14392  "* return output_387_binary_op (insn, operands);"
14393  [(set (attr "type") 
14394        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14395	   (const_string "ssemul")
14396	   (const_string "sseadd")))
14397   (set_attr "mode" "SF")])
14398
14399(define_insn "*fop_df_comm_nosse"
14400  [(set (match_operand:DF 0 "register_operand" "=f")
14401	(match_operator:DF 3 "binary_fp_operator"
14402			[(match_operand:DF 1 "nonimmediate_operand" "%0")
14403			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14404  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14405   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14406   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14407  "* return output_387_binary_op (insn, operands);"
14408  [(set (attr "type") 
14409	(if_then_else (match_operand:SF 3 "mult_operator" "") 
14410	   (const_string "fmul")
14411	   (const_string "fop")))
14412   (set_attr "mode" "DF")])
14413
14414(define_insn "*fop_df_comm"
14415  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14416	(match_operator:DF 3 "binary_fp_operator"
14417			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14418			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14419  "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14420   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14421   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422  "* return output_387_binary_op (insn, operands);"
14423  [(set (attr "type") 
14424	(if_then_else (eq_attr "alternative" "1")
14425	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14426	      (const_string "ssemul")
14427	      (const_string "sseadd"))
14428	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14429	      (const_string "fmul")
14430	      (const_string "fop"))))
14431   (set_attr "mode" "DF")])
14432
14433(define_insn "*fop_df_comm_sse"
14434  [(set (match_operand:DF 0 "register_operand" "=Y")
14435	(match_operator:DF 3 "binary_fp_operator"
14436			[(match_operand:DF 1 "nonimmediate_operand" "%0")
14437			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14438  "TARGET_SSE2 && TARGET_SSE_MATH
14439   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14440   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14441  "* return output_387_binary_op (insn, operands);"
14442  [(set (attr "type") 
14443        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14444	   (const_string "ssemul")
14445	   (const_string "sseadd")))
14446   (set_attr "mode" "DF")])
14447
14448(define_insn "*fop_xf_comm"
14449  [(set (match_operand:XF 0 "register_operand" "=f")
14450	(match_operator:XF 3 "binary_fp_operator"
14451			[(match_operand:XF 1 "register_operand" "%0")
14452			 (match_operand:XF 2 "register_operand" "f")]))]
14453  "TARGET_80387
14454   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14455  "* return output_387_binary_op (insn, operands);"
14456  [(set (attr "type") 
14457        (if_then_else (match_operand:XF 3 "mult_operator" "") 
14458           (const_string "fmul")
14459           (const_string "fop")))
14460   (set_attr "mode" "XF")])
14461
14462(define_insn "*fop_sf_1_nosse"
14463  [(set (match_operand:SF 0 "register_operand" "=f,f")
14464	(match_operator:SF 3 "binary_fp_operator"
14465			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14466			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14467  "TARGET_80387 && !TARGET_SSE_MATH
14468   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14469   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14470  "* return output_387_binary_op (insn, operands);"
14471  [(set (attr "type") 
14472        (cond [(match_operand:SF 3 "mult_operator" "") 
14473                 (const_string "fmul")
14474               (match_operand:SF 3 "div_operator" "") 
14475                 (const_string "fdiv")
14476              ]
14477              (const_string "fop")))
14478   (set_attr "mode" "SF")])
14479
14480(define_insn "*fop_sf_1"
14481  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14482	(match_operator:SF 3 "binary_fp_operator"
14483			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14484			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14485  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14486   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14487   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14488  "* return output_387_binary_op (insn, operands);"
14489  [(set (attr "type") 
14490        (cond [(and (eq_attr "alternative" "2")
14491	            (match_operand:SF 3 "mult_operator" ""))
14492                 (const_string "ssemul")
14493	       (and (eq_attr "alternative" "2")
14494	            (match_operand:SF 3 "div_operator" ""))
14495                 (const_string "ssediv")
14496	       (eq_attr "alternative" "2")
14497                 (const_string "sseadd")
14498	       (match_operand:SF 3 "mult_operator" "") 
14499                 (const_string "fmul")
14500               (match_operand:SF 3 "div_operator" "") 
14501                 (const_string "fdiv")
14502              ]
14503              (const_string "fop")))
14504   (set_attr "mode" "SF")])
14505
14506(define_insn "*fop_sf_1_sse"
14507  [(set (match_operand:SF 0 "register_operand" "=x")
14508	(match_operator:SF 3 "binary_fp_operator"
14509			[(match_operand:SF 1 "register_operand" "0")
14510			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14511  "TARGET_SSE_MATH
14512   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14513  "* return output_387_binary_op (insn, operands);"
14514  [(set (attr "type") 
14515        (cond [(match_operand:SF 3 "mult_operator" "")
14516                 (const_string "ssemul")
14517	       (match_operand:SF 3 "div_operator" "")
14518                 (const_string "ssediv")
14519              ]
14520              (const_string "sseadd")))
14521   (set_attr "mode" "SF")])
14522
14523;; ??? Add SSE splitters for these!
14524(define_insn "*fop_sf_2"
14525  [(set (match_operand:SF 0 "register_operand" "=f,f")
14526	(match_operator:SF 3 "binary_fp_operator"
14527	  [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14528	   (match_operand:SF 2 "register_operand" "0,0")]))]
14529  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14530  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14531  [(set (attr "type") 
14532        (cond [(match_operand:SF 3 "mult_operator" "") 
14533                 (const_string "fmul")
14534               (match_operand:SF 3 "div_operator" "") 
14535                 (const_string "fdiv")
14536              ]
14537              (const_string "fop")))
14538   (set_attr "fp_int_src" "true")
14539   (set_attr "ppro_uops" "many")
14540   (set_attr "mode" "SI")])
14541
14542(define_insn "*fop_sf_3"
14543  [(set (match_operand:SF 0 "register_operand" "=f,f")
14544	(match_operator:SF 3 "binary_fp_operator"
14545	  [(match_operand:SF 1 "register_operand" "0,0")
14546	   (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14547  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14548  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14549  [(set (attr "type") 
14550        (cond [(match_operand:SF 3 "mult_operator" "") 
14551                 (const_string "fmul")
14552               (match_operand:SF 3 "div_operator" "") 
14553                 (const_string "fdiv")
14554              ]
14555              (const_string "fop")))
14556   (set_attr "fp_int_src" "true")
14557   (set_attr "ppro_uops" "many")
14558   (set_attr "mode" "SI")])
14559
14560(define_insn "*fop_df_1_nosse"
14561  [(set (match_operand:DF 0 "register_operand" "=f,f")
14562	(match_operator:DF 3 "binary_fp_operator"
14563			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14564			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14565  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14566   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14567   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14568  "* return output_387_binary_op (insn, operands);"
14569  [(set (attr "type") 
14570        (cond [(match_operand:DF 3 "mult_operator" "") 
14571                 (const_string "fmul")
14572               (match_operand:DF 3 "div_operator" "")
14573                 (const_string "fdiv")
14574              ]
14575              (const_string "fop")))
14576   (set_attr "mode" "DF")])
14577
14578
14579(define_insn "*fop_df_1"
14580  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14581	(match_operator:DF 3 "binary_fp_operator"
14582			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14583			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14584  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14585   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14586   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14587  "* return output_387_binary_op (insn, operands);"
14588  [(set (attr "type") 
14589        (cond [(and (eq_attr "alternative" "2")
14590	            (match_operand:SF 3 "mult_operator" ""))
14591                 (const_string "ssemul")
14592	       (and (eq_attr "alternative" "2")
14593	            (match_operand:SF 3 "div_operator" ""))
14594                 (const_string "ssediv")
14595	       (eq_attr "alternative" "2")
14596                 (const_string "sseadd")
14597	       (match_operand:DF 3 "mult_operator" "") 
14598                 (const_string "fmul")
14599               (match_operand:DF 3 "div_operator" "") 
14600                 (const_string "fdiv")
14601              ]
14602              (const_string "fop")))
14603   (set_attr "mode" "DF")])
14604
14605(define_insn "*fop_df_1_sse"
14606  [(set (match_operand:DF 0 "register_operand" "=Y")
14607	(match_operator:DF 3 "binary_fp_operator"
14608			[(match_operand:DF 1 "register_operand" "0")
14609			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14610  "TARGET_SSE2 && TARGET_SSE_MATH
14611   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14612  "* return output_387_binary_op (insn, operands);"
14613  [(set_attr "mode" "DF")
14614   (set (attr "type") 
14615        (cond [(match_operand:SF 3 "mult_operator" "")
14616                 (const_string "ssemul")
14617	       (match_operand:SF 3 "div_operator" "")
14618                 (const_string "ssediv")
14619              ]
14620              (const_string "sseadd")))])
14621
14622;; ??? Add SSE splitters for these!
14623(define_insn "*fop_df_2"
14624  [(set (match_operand:DF 0 "register_operand" "=f,f")
14625	(match_operator:DF 3 "binary_fp_operator"
14626	   [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14627	    (match_operand:DF 2 "register_operand" "0,0")]))]
14628  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14629  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14630  [(set (attr "type") 
14631        (cond [(match_operand:DF 3 "mult_operator" "") 
14632                 (const_string "fmul")
14633               (match_operand:DF 3 "div_operator" "") 
14634                 (const_string "fdiv")
14635              ]
14636              (const_string "fop")))
14637   (set_attr "fp_int_src" "true")
14638   (set_attr "ppro_uops" "many")
14639   (set_attr "mode" "SI")])
14640
14641(define_insn "*fop_df_3"
14642  [(set (match_operand:DF 0 "register_operand" "=f,f")
14643	(match_operator:DF 3 "binary_fp_operator"
14644	   [(match_operand:DF 1 "register_operand" "0,0")
14645	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14646  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14647  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14648  [(set (attr "type") 
14649        (cond [(match_operand:DF 3 "mult_operator" "") 
14650                 (const_string "fmul")
14651               (match_operand:DF 3 "div_operator" "") 
14652                 (const_string "fdiv")
14653              ]
14654              (const_string "fop")))
14655   (set_attr "fp_int_src" "true")
14656   (set_attr "ppro_uops" "many")
14657   (set_attr "mode" "SI")])
14658
14659(define_insn "*fop_df_4"
14660  [(set (match_operand:DF 0 "register_operand" "=f,f")
14661	(match_operator:DF 3 "binary_fp_operator"
14662	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14663	    (match_operand:DF 2 "register_operand" "0,f")]))]
14664  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14665   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14666  "* return output_387_binary_op (insn, operands);"
14667  [(set (attr "type") 
14668        (cond [(match_operand:DF 3 "mult_operator" "") 
14669                 (const_string "fmul")
14670               (match_operand:DF 3 "div_operator" "") 
14671                 (const_string "fdiv")
14672              ]
14673              (const_string "fop")))
14674   (set_attr "mode" "SF")])
14675
14676(define_insn "*fop_df_5"
14677  [(set (match_operand:DF 0 "register_operand" "=f,f")
14678	(match_operator:DF 3 "binary_fp_operator"
14679	  [(match_operand:DF 1 "register_operand" "0,f")
14680	   (float_extend:DF
14681	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14682  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14683  "* return output_387_binary_op (insn, operands);"
14684  [(set (attr "type") 
14685        (cond [(match_operand:DF 3 "mult_operator" "") 
14686                 (const_string "fmul")
14687               (match_operand:DF 3 "div_operator" "") 
14688                 (const_string "fdiv")
14689              ]
14690              (const_string "fop")))
14691   (set_attr "mode" "SF")])
14692
14693(define_insn "*fop_df_6"
14694  [(set (match_operand:DF 0 "register_operand" "=f,f")
14695	(match_operator:DF 3 "binary_fp_operator"
14696	  [(float_extend:DF
14697	    (match_operand:SF 1 "register_operand" "0,f"))
14698	   (float_extend:DF
14699	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14700  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14701  "* return output_387_binary_op (insn, operands);"
14702  [(set (attr "type") 
14703        (cond [(match_operand:DF 3 "mult_operator" "") 
14704                 (const_string "fmul")
14705               (match_operand:DF 3 "div_operator" "") 
14706                 (const_string "fdiv")
14707              ]
14708              (const_string "fop")))
14709   (set_attr "mode" "SF")])
14710
14711(define_insn "*fop_xf_1"
14712  [(set (match_operand:XF 0 "register_operand" "=f,f")
14713	(match_operator:XF 3 "binary_fp_operator"
14714			[(match_operand:XF 1 "register_operand" "0,f")
14715			 (match_operand:XF 2 "register_operand" "f,0")]))]
14716  "TARGET_80387
14717   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14718  "* return output_387_binary_op (insn, operands);"
14719  [(set (attr "type") 
14720        (cond [(match_operand:XF 3 "mult_operator" "") 
14721                 (const_string "fmul")
14722               (match_operand:XF 3 "div_operator" "") 
14723                 (const_string "fdiv")
14724              ]
14725              (const_string "fop")))
14726   (set_attr "mode" "XF")])
14727
14728(define_insn "*fop_xf_2"
14729  [(set (match_operand:XF 0 "register_operand" "=f,f")
14730	(match_operator:XF 3 "binary_fp_operator"
14731	   [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14732	    (match_operand:XF 2 "register_operand" "0,0")]))]
14733  "TARGET_80387 && TARGET_USE_FIOP"
14734  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14735  [(set (attr "type") 
14736        (cond [(match_operand:XF 3 "mult_operator" "") 
14737                 (const_string "fmul")
14738               (match_operand:XF 3 "div_operator" "") 
14739                 (const_string "fdiv")
14740              ]
14741              (const_string "fop")))
14742   (set_attr "fp_int_src" "true")
14743   (set_attr "mode" "SI")
14744   (set_attr "ppro_uops" "many")])
14745
14746(define_insn "*fop_xf_3"
14747  [(set (match_operand:XF 0 "register_operand" "=f,f")
14748	(match_operator:XF 3 "binary_fp_operator"
14749	  [(match_operand:XF 1 "register_operand" "0,0")
14750	   (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14751  "TARGET_80387 && TARGET_USE_FIOP"
14752  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14753  [(set (attr "type") 
14754        (cond [(match_operand:XF 3 "mult_operator" "") 
14755                 (const_string "fmul")
14756               (match_operand:XF 3 "div_operator" "") 
14757                 (const_string "fdiv")
14758              ]
14759              (const_string "fop")))
14760   (set_attr "fp_int_src" "true")
14761   (set_attr "mode" "SI")
14762   (set_attr "ppro_uops" "many")])
14763
14764(define_insn "*fop_xf_4"
14765  [(set (match_operand:XF 0 "register_operand" "=f,f")
14766	(match_operator:XF 3 "binary_fp_operator"
14767	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14768	    (match_operand:XF 2 "register_operand" "0,f")]))]
14769  "TARGET_80387"
14770  "* return output_387_binary_op (insn, operands);"
14771  [(set (attr "type") 
14772        (cond [(match_operand:XF 3 "mult_operator" "") 
14773                 (const_string "fmul")
14774               (match_operand:XF 3 "div_operator" "") 
14775                 (const_string "fdiv")
14776              ]
14777              (const_string "fop")))
14778   (set_attr "mode" "SF")])
14779
14780(define_insn "*fop_xf_5"
14781  [(set (match_operand:XF 0 "register_operand" "=f,f")
14782	(match_operator:XF 3 "binary_fp_operator"
14783	  [(match_operand:XF 1 "register_operand" "0,f")
14784	   (float_extend:XF
14785	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14786  "TARGET_80387"
14787  "* return output_387_binary_op (insn, operands);"
14788  [(set (attr "type") 
14789        (cond [(match_operand:XF 3 "mult_operator" "") 
14790                 (const_string "fmul")
14791               (match_operand:XF 3 "div_operator" "") 
14792                 (const_string "fdiv")
14793              ]
14794              (const_string "fop")))
14795   (set_attr "mode" "SF")])
14796
14797(define_insn "*fop_xf_6"
14798  [(set (match_operand:XF 0 "register_operand" "=f,f")
14799	(match_operator:XF 3 "binary_fp_operator"
14800	  [(float_extend:XF
14801	    (match_operand 1 "register_operand" "0,f"))
14802	   (float_extend:XF
14803	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14804  "TARGET_80387"
14805  "* return output_387_binary_op (insn, operands);"
14806  [(set (attr "type") 
14807        (cond [(match_operand:XF 3 "mult_operator" "") 
14808                 (const_string "fmul")
14809               (match_operand:XF 3 "div_operator" "") 
14810                 (const_string "fdiv")
14811              ]
14812              (const_string "fop")))
14813   (set_attr "mode" "SF")])
14814
14815(define_split
14816  [(set (match_operand 0 "register_operand" "")
14817	(match_operator 3 "binary_fp_operator"
14818	   [(float (match_operand:SI 1 "register_operand" ""))
14819	    (match_operand 2 "register_operand" "")]))]
14820  "TARGET_80387 && reload_completed
14821   && FLOAT_MODE_P (GET_MODE (operands[0]))"
14822  [(const_int 0)]
14823{ 
14824  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14825  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14826  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14827			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
14828					  GET_MODE (operands[3]),
14829					  operands[4],
14830					  operands[2])));
14831  ix86_free_from_memory (GET_MODE (operands[1]));
14832  DONE;
14833})
14834
14835(define_split
14836  [(set (match_operand 0 "register_operand" "")
14837	(match_operator 3 "binary_fp_operator"
14838	   [(match_operand 1 "register_operand" "")
14839	    (float (match_operand:SI 2 "register_operand" ""))]))]
14840  "TARGET_80387 && reload_completed
14841   && FLOAT_MODE_P (GET_MODE (operands[0]))"
14842  [(const_int 0)]
14843{
14844  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14845  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14846  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14847			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
14848					  GET_MODE (operands[3]),
14849					  operands[1],
14850					  operands[4])));
14851  ix86_free_from_memory (GET_MODE (operands[2]));
14852  DONE;
14853})
14854
14855;; FPU special functions.
14856
14857(define_expand "sqrtsf2"
14858  [(set (match_operand:SF 0 "register_operand" "")
14859	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14860  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14861{
14862  if (!TARGET_SSE_MATH)
14863    operands[1] = force_reg (SFmode, operands[1]);
14864})
14865
14866(define_insn "sqrtsf2_1"
14867  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14868	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14869  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14870   && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14871  "@
14872   fsqrt
14873   sqrtss\t{%1, %0|%0, %1}"
14874  [(set_attr "type" "fpspc,sse")
14875   (set_attr "mode" "SF,SF")
14876   (set_attr "athlon_decode" "direct,*")])
14877
14878(define_insn "sqrtsf2_1_sse_only"
14879  [(set (match_operand:SF 0 "register_operand" "=x")
14880	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14881  "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14882  "sqrtss\t{%1, %0|%0, %1}"
14883  [(set_attr "type" "sse")
14884   (set_attr "mode" "SF")
14885   (set_attr "athlon_decode" "*")])
14886
14887(define_insn "sqrtsf2_i387"
14888  [(set (match_operand:SF 0 "register_operand" "=f")
14889	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14890  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14891   && !TARGET_SSE_MATH"
14892  "fsqrt"
14893  [(set_attr "type" "fpspc")
14894   (set_attr "mode" "SF")
14895   (set_attr "athlon_decode" "direct")])
14896
14897(define_expand "sqrtdf2"
14898  [(set (match_operand:DF 0 "register_operand" "")
14899	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14900  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14901   || (TARGET_SSE2 && TARGET_SSE_MATH)"
14902{
14903  if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14904    operands[1] = force_reg (DFmode, operands[1]);
14905})
14906
14907(define_insn "sqrtdf2_1"
14908  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14909	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14910  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14911   && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14912  "@
14913   fsqrt
14914   sqrtsd\t{%1, %0|%0, %1}"
14915  [(set_attr "type" "fpspc,sse")
14916   (set_attr "mode" "DF,DF")
14917   (set_attr "athlon_decode" "direct,*")])
14918
14919(define_insn "sqrtdf2_1_sse_only"
14920  [(set (match_operand:DF 0 "register_operand" "=Y")
14921	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14922  "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14923  "sqrtsd\t{%1, %0|%0, %1}"
14924  [(set_attr "type" "sse")
14925   (set_attr "mode" "DF")
14926   (set_attr "athlon_decode" "*")])
14927
14928(define_insn "sqrtdf2_i387"
14929  [(set (match_operand:DF 0 "register_operand" "=f")
14930	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14931  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14932   && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14933  "fsqrt"
14934  [(set_attr "type" "fpspc")
14935   (set_attr "mode" "DF")
14936   (set_attr "athlon_decode" "direct")])
14937
14938(define_insn "*sqrtextendsfdf2"
14939  [(set (match_operand:DF 0 "register_operand" "=f")
14940	(sqrt:DF (float_extend:DF
14941		  (match_operand:SF 1 "register_operand" "0"))))]
14942  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14943   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14944  "fsqrt"
14945  [(set_attr "type" "fpspc")
14946   (set_attr "mode" "DF")
14947   (set_attr "athlon_decode" "direct")])
14948
14949(define_insn "sqrtxf2"
14950  [(set (match_operand:XF 0 "register_operand" "=f")
14951	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14952  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14953   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14954  "fsqrt"
14955  [(set_attr "type" "fpspc")
14956   (set_attr "mode" "XF")
14957   (set_attr "athlon_decode" "direct")])
14958
14959(define_insn "*sqrtextenddfxf2"
14960  [(set (match_operand:XF 0 "register_operand" "=f")
14961	(sqrt:XF (float_extend:XF
14962		  (match_operand:DF 1 "register_operand" "0"))))]
14963  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14964  "fsqrt"
14965  [(set_attr "type" "fpspc")
14966   (set_attr "mode" "XF")
14967   (set_attr "athlon_decode" "direct")])
14968
14969(define_insn "*sqrtextendsfxf2"
14970  [(set (match_operand:XF 0 "register_operand" "=f")
14971	(sqrt:XF (float_extend:XF
14972		  (match_operand:SF 1 "register_operand" "0"))))]
14973  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14974  "fsqrt"
14975  [(set_attr "type" "fpspc")
14976   (set_attr "mode" "XF")
14977   (set_attr "athlon_decode" "direct")])
14978
14979(define_insn "sindf2"
14980  [(set (match_operand:DF 0 "register_operand" "=f")
14981	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14982  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14983   && flag_unsafe_math_optimizations"
14984  "fsin"
14985  [(set_attr "type" "fpspc")
14986   (set_attr "mode" "DF")])
14987
14988(define_insn "sinsf2"
14989  [(set (match_operand:SF 0 "register_operand" "=f")
14990	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14991  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14992   && flag_unsafe_math_optimizations"
14993  "fsin"
14994  [(set_attr "type" "fpspc")
14995   (set_attr "mode" "SF")])
14996
14997(define_insn "*sinextendsfdf2"
14998  [(set (match_operand:DF 0 "register_operand" "=f")
14999	(unspec:DF [(float_extend:DF
15000		     (match_operand:SF 1 "register_operand" "0"))]
15001		   UNSPEC_SIN))]
15002  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15003   && flag_unsafe_math_optimizations"
15004  "fsin"
15005  [(set_attr "type" "fpspc")
15006   (set_attr "mode" "DF")])
15007
15008(define_insn "sinxf2"
15009  [(set (match_operand:XF 0 "register_operand" "=f")
15010	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15011  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15012   && flag_unsafe_math_optimizations"
15013  "fsin"
15014  [(set_attr "type" "fpspc")
15015   (set_attr "mode" "XF")])
15016
15017(define_insn "cosdf2"
15018  [(set (match_operand:DF 0 "register_operand" "=f")
15019	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15020  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15021   && flag_unsafe_math_optimizations"
15022  "fcos"
15023  [(set_attr "type" "fpspc")
15024   (set_attr "mode" "DF")])
15025
15026(define_insn "cossf2"
15027  [(set (match_operand:SF 0 "register_operand" "=f")
15028	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15029  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15030   && flag_unsafe_math_optimizations"
15031  "fcos"
15032  [(set_attr "type" "fpspc")
15033   (set_attr "mode" "SF")])
15034
15035(define_insn "*cosextendsfdf2"
15036  [(set (match_operand:DF 0 "register_operand" "=f")
15037	(unspec:DF [(float_extend:DF
15038		     (match_operand:SF 1 "register_operand" "0"))]
15039		   UNSPEC_COS))]
15040  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15041   && flag_unsafe_math_optimizations"
15042  "fcos"
15043  [(set_attr "type" "fpspc")
15044   (set_attr "mode" "DF")])
15045
15046(define_insn "cosxf2"
15047  [(set (match_operand:XF 0 "register_operand" "=f")
15048	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15049  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15050   && flag_unsafe_math_optimizations"
15051  "fcos"
15052  [(set_attr "type" "fpspc")
15053   (set_attr "mode" "XF")])
15054
15055(define_insn "atan2df3_1"
15056  [(set (match_operand:DF 0 "register_operand" "=f")
15057	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
15058		    (match_operand:DF 1 "register_operand" "u")]
15059		   UNSPEC_FPATAN))
15060   (clobber (match_scratch:DF 3 "=1"))]
15061  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15062   && flag_unsafe_math_optimizations"
15063  "fpatan"
15064  [(set_attr "type" "fpspc")
15065   (set_attr "mode" "DF")])
15066
15067(define_expand "atan2df3"
15068  [(use (match_operand:DF 0 "register_operand" "=f"))
15069   (use (match_operand:DF 2 "register_operand" "0"))
15070   (use (match_operand:DF 1 "register_operand" "u"))]
15071  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15072   && flag_unsafe_math_optimizations"
15073{
15074  rtx copy = gen_reg_rtx (DFmode);
15075  emit_move_insn (copy, operands[1]);
15076  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15077  DONE;
15078})
15079
15080(define_insn "atan2sf3_1"
15081  [(set (match_operand:SF 0 "register_operand" "=f")
15082        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15083		    (match_operand:SF 1 "register_operand" "u")]
15084		   UNSPEC_FPATAN))
15085   (clobber (match_scratch:SF 3 "=1"))]
15086  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15087   && flag_unsafe_math_optimizations"
15088  "fpatan"
15089  [(set_attr "type" "fpspc")
15090   (set_attr "mode" "SF")])
15091
15092(define_expand "atan2sf3"
15093  [(use (match_operand:SF 0 "register_operand" "=f"))
15094   (use (match_operand:SF 2 "register_operand" "0"))
15095   (use (match_operand:SF 1 "register_operand" "u"))]
15096  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15097   && flag_unsafe_math_optimizations"
15098{
15099  rtx copy = gen_reg_rtx (SFmode);
15100  emit_move_insn (copy, operands[1]);
15101  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15102  DONE;
15103})
15104
15105(define_insn "atan2xf3_1"
15106  [(set (match_operand:XF 0 "register_operand" "=f")
15107        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15108	            (match_operand:XF 1 "register_operand" "u")]
15109	           UNSPEC_FPATAN))
15110   (clobber (match_scratch:XF 3 "=1"))]
15111  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15112   && flag_unsafe_math_optimizations"
15113  "fpatan"
15114  [(set_attr "type" "fpspc")
15115   (set_attr "mode" "XF")])
15116
15117(define_expand "atan2xf3"
15118  [(use (match_operand:XF 0 "register_operand" "=f"))
15119   (use (match_operand:XF 2 "register_operand" "0"))
15120   (use (match_operand:XF 1 "register_operand" "u"))]
15121  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15122   && flag_unsafe_math_optimizations"
15123{
15124  rtx copy = gen_reg_rtx (XFmode);
15125  emit_move_insn (copy, operands[1]);
15126  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15127  DONE;
15128})
15129
15130(define_insn "*fyl2x_sfxf3"
15131  [(set (match_operand:SF 0 "register_operand" "=f")
15132         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15133		     (match_operand:XF 1 "register_operand" "u")]
15134		    UNSPEC_FYL2X))
15135   (clobber (match_scratch:SF 3 "=1"))]
15136  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137   && flag_unsafe_math_optimizations"
15138  "fyl2x"
15139  [(set_attr "type" "fpspc")
15140   (set_attr "mode" "SF")])
15141
15142(define_insn "*fyl2x_dfxf3"
15143  [(set (match_operand:DF 0 "register_operand" "=f")
15144         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15145		     (match_operand:XF 1 "register_operand" "u")]
15146		    UNSPEC_FYL2X))
15147   (clobber (match_scratch:DF 3 "=1"))]
15148  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15149   && flag_unsafe_math_optimizations"
15150  "fyl2x"
15151  [(set_attr "type" "fpspc")
15152   (set_attr "mode" "DF")])
15153
15154(define_insn "*fyl2x_xf3"
15155  [(set (match_operand:XF 0 "register_operand" "=f")
15156        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15157		    (match_operand:XF 1 "register_operand" "u")]
15158	           UNSPEC_FYL2X))
15159   (clobber (match_scratch:XF 3 "=1"))]
15160  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15161   && flag_unsafe_math_optimizations"
15162  "fyl2x"
15163  [(set_attr "type" "fpspc")
15164   (set_attr "mode" "XF")])
15165
15166(define_expand "logsf2"
15167  [(parallel [(set (match_operand:SF 0 "register_operand" "")
15168		   (unspec:SF [(match_operand:SF 1 "register_operand" "")
15169			       (match_dup 2)] UNSPEC_FYL2X))
15170	      (clobber (match_scratch:SF 3 ""))])]
15171  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15172   && flag_unsafe_math_optimizations"
15173{
15174  rtx temp;
15175
15176  operands[2] = gen_reg_rtx (XFmode);
15177  temp = standard_80387_constant_rtx (4); /* fldln2 */
15178  emit_move_insn (operands[2], temp);
15179})
15180
15181(define_expand "logdf2"
15182  [(parallel [(set (match_operand:DF 0 "register_operand" "")
15183		   (unspec:DF [(match_operand:DF 1 "register_operand" "")
15184			       (match_dup 2)] UNSPEC_FYL2X))
15185	      (clobber (match_scratch:DF 3 ""))])]
15186  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15187   && flag_unsafe_math_optimizations"
15188{
15189  rtx temp;
15190
15191  operands[2] = gen_reg_rtx (XFmode);
15192  temp = standard_80387_constant_rtx (4); /* fldln2 */
15193  emit_move_insn (operands[2], temp);
15194})
15195
15196(define_expand "logxf2"
15197  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15198		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
15199			       (match_dup 2)] UNSPEC_FYL2X))
15200	      (clobber (match_scratch:XF 3 ""))])]
15201  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15202   && flag_unsafe_math_optimizations"
15203{
15204  rtx temp;
15205
15206  operands[2] = gen_reg_rtx (XFmode);
15207  temp = standard_80387_constant_rtx (4); /* fldln2 */
15208  emit_move_insn (operands[2], temp);
15209})
15210
15211(define_insn "*fscale_sfxf3"
15212  [(set (match_operand:SF 0 "register_operand" "=f")
15213	 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15214		     (match_operand:XF 1 "register_operand" "u")]
15215		    UNSPEC_FSCALE))
15216   (clobber (match_scratch:SF 3 "=1"))]
15217  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15218   && flag_unsafe_math_optimizations"
15219  "fscale\;fstp\t%y1"
15220  [(set_attr "type" "fpspc")
15221   (set_attr "mode" "SF")])
15222
15223(define_insn "*fscale_dfxf3"
15224  [(set (match_operand:DF 0 "register_operand" "=f")
15225	 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15226		     (match_operand:XF 1 "register_operand" "u")]
15227		    UNSPEC_FSCALE))
15228   (clobber (match_scratch:DF 3 "=1"))]
15229  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15230   && flag_unsafe_math_optimizations"
15231  "fscale\;fstp\t%y1"
15232  [(set_attr "type" "fpspc")
15233   (set_attr "mode" "DF")])
15234
15235(define_insn "*fscale_xf3"
15236  [(set (match_operand:XF 0 "register_operand" "=f")
15237	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15238		    (match_operand:XF 1 "register_operand" "u")]
15239	           UNSPEC_FSCALE))
15240   (clobber (match_scratch:XF 3 "=1"))]
15241  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15242   && flag_unsafe_math_optimizations"
15243  "fscale\;fstp\t%y1"
15244  [(set_attr "type" "fpspc")
15245   (set_attr "mode" "XF")])
15246
15247(define_insn "*frndintxf2"
15248  [(set (match_operand:XF 0 "register_operand" "=f")
15249	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15250	 UNSPEC_FRNDINT))]
15251  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15252   && flag_unsafe_math_optimizations"
15253  "frndint"
15254  [(set_attr "type" "fpspc")
15255   (set_attr "mode" "XF")])
15256
15257(define_insn "*f2xm1xf2"
15258  [(set (match_operand:XF 0 "register_operand" "=f")
15259	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260	 UNSPEC_F2XM1))]
15261  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15262   && flag_unsafe_math_optimizations"
15263  "f2xm1"
15264  [(set_attr "type" "fpspc")
15265   (set_attr "mode" "XF")])
15266
15267(define_expand "expsf2"
15268  [(set (match_dup 2)
15269	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
15270   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15271   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15272   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15273   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15274   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15275   (parallel [(set (match_operand:SF 0 "register_operand" "")
15276		   (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15277	      (clobber (match_scratch:SF 5 ""))])]
15278  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15279   && flag_unsafe_math_optimizations"
15280{
15281  rtx temp;
15282  int i;
15283
15284  for (i=2; i<10; i++)
15285    operands[i] = gen_reg_rtx (XFmode);
15286  temp = standard_80387_constant_rtx (5); /* fldl2e */
15287  emit_move_insn (operands[3], temp);
15288  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15289})
15290
15291(define_expand "expdf2"
15292  [(set (match_dup 2)
15293	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
15294   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15295   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15296   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15297   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15298   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15299   (parallel [(set (match_operand:DF 0 "register_operand" "")
15300		   (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15301	      (clobber (match_scratch:DF 5 ""))])]
15302  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15303   && flag_unsafe_math_optimizations"
15304{
15305  rtx temp;
15306  int i;
15307
15308  for (i=2; i<10; i++)
15309    operands[i] = gen_reg_rtx (XFmode);
15310  temp = standard_80387_constant_rtx (5); /* fldl2e */
15311  emit_move_insn (operands[3], temp);
15312  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15313})
15314
15315(define_expand "expxf2"
15316  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15317			       (match_dup 2)))
15318   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15319   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15320   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15321   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15322   (parallel [(set (match_operand:XF 0 "register_operand" "")
15323		   (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15324	      (clobber (match_scratch:XF 5 ""))])]
15325  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15326   && flag_unsafe_math_optimizations"
15327{
15328  rtx temp;
15329  int i;
15330
15331  for (i=2; i<9; i++)
15332    operands[i] = gen_reg_rtx (XFmode);
15333  temp = standard_80387_constant_rtx (5); /* fldl2e */
15334  emit_move_insn (operands[2], temp);
15335  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15336})
15337
15338(define_expand "atansf2"
15339  [(parallel [(set (match_operand:SF 0 "register_operand" "")
15340		   (unspec:SF [(match_dup 2)
15341			       (match_operand:SF 1 "register_operand" "")]
15342		    UNSPEC_FPATAN))
15343	      (clobber (match_scratch:SF 3 ""))])]
15344  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15345   && flag_unsafe_math_optimizations"
15346{
15347  operands[2] = gen_reg_rtx (SFmode);
15348  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15349})
15350
15351(define_expand "atandf2"
15352  [(parallel [(set (match_operand:DF 0 "register_operand" "")
15353		   (unspec:DF [(match_dup 2)
15354			       (match_operand:DF 1 "register_operand" "")]
15355		    UNSPEC_FPATAN))
15356	      (clobber (match_scratch:DF 3 ""))])]
15357  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15358   && flag_unsafe_math_optimizations"
15359{
15360  operands[2] = gen_reg_rtx (DFmode);
15361  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15362})
15363
15364(define_expand "atanxf2"
15365  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15366		   (unspec:XF [(match_dup 2)
15367			       (match_operand:XF 1 "register_operand" "")]
15368		    UNSPEC_FPATAN))
15369	      (clobber (match_scratch:XF 3 ""))])]
15370  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15371   && flag_unsafe_math_optimizations"
15372{
15373  operands[2] = gen_reg_rtx (XFmode);
15374  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15375})
15376
15377;; Block operation instructions
15378
15379(define_insn "cld"
15380 [(set (reg:SI 19) (const_int 0))]
15381 ""
15382 "cld"
15383  [(set_attr "type" "cld")])
15384
15385(define_expand "movstrsi"
15386  [(use (match_operand:BLK 0 "memory_operand" ""))
15387   (use (match_operand:BLK 1 "memory_operand" ""))
15388   (use (match_operand:SI 2 "nonmemory_operand" ""))
15389   (use (match_operand:SI 3 "const_int_operand" ""))]
15390  "! optimize_size"
15391{
15392 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15393   DONE;
15394 else
15395   FAIL;
15396})
15397
15398(define_expand "movstrdi"
15399  [(use (match_operand:BLK 0 "memory_operand" ""))
15400   (use (match_operand:BLK 1 "memory_operand" ""))
15401   (use (match_operand:DI 2 "nonmemory_operand" ""))
15402   (use (match_operand:DI 3 "const_int_operand" ""))]
15403  "TARGET_64BIT"
15404{
15405 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15406   DONE;
15407 else
15408   FAIL;
15409})
15410
15411;; Most CPUs don't like single string operations
15412;; Handle this case here to simplify previous expander.
15413
15414(define_expand "strmov"
15415  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15416   (set (match_operand 1 "memory_operand" "") (match_dup 4))
15417   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15418	      (clobber (reg:CC 17))])
15419   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15420	      (clobber (reg:CC 17))])]
15421  ""
15422{
15423  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15424
15425  /* If .md ever supports :P for Pmode, these can be directly
15426     in the pattern above.  */
15427  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15428  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15429
15430  if (TARGET_SINGLE_STRINGOP || optimize_size)
15431    {
15432      emit_insn (gen_strmov_singleop (operands[0], operands[1],
15433				      operands[2], operands[3],
15434				      operands[5], operands[6]));
15435      DONE;
15436    }
15437
15438  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15439})
15440
15441(define_expand "strmov_singleop"
15442  [(parallel [(set (match_operand 1 "memory_operand" "")
15443		   (match_operand 3 "memory_operand" ""))
15444	      (set (match_operand 0 "register_operand" "")
15445		   (match_operand 4 "" ""))
15446	      (set (match_operand 2 "register_operand" "")
15447		   (match_operand 5 "" ""))
15448	      (use (reg:SI 19))])]
15449  "TARGET_SINGLE_STRINGOP || optimize_size"
15450  "")
15451
15452(define_insn "*strmovdi_rex_1"
15453  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15454	(mem:DI (match_operand:DI 3 "register_operand" "1")))
15455   (set (match_operand:DI 0 "register_operand" "=D")
15456	(plus:DI (match_dup 2)
15457		 (const_int 8)))
15458   (set (match_operand:DI 1 "register_operand" "=S")
15459	(plus:DI (match_dup 3)
15460		 (const_int 8)))
15461   (use (reg:SI 19))]
15462  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15463  "movsq"
15464  [(set_attr "type" "str")
15465   (set_attr "mode" "DI")
15466   (set_attr "memory" "both")])
15467
15468(define_insn "*strmovsi_1"
15469  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15470	(mem:SI (match_operand:SI 3 "register_operand" "1")))
15471   (set (match_operand:SI 0 "register_operand" "=D")
15472	(plus:SI (match_dup 2)
15473		 (const_int 4)))
15474   (set (match_operand:SI 1 "register_operand" "=S")
15475	(plus:SI (match_dup 3)
15476		 (const_int 4)))
15477   (use (reg:SI 19))]
15478  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15479  "{movsl|movsd}"
15480  [(set_attr "type" "str")
15481   (set_attr "mode" "SI")
15482   (set_attr "memory" "both")])
15483
15484(define_insn "*strmovsi_rex_1"
15485  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15486	(mem:SI (match_operand:DI 3 "register_operand" "1")))
15487   (set (match_operand:DI 0 "register_operand" "=D")
15488	(plus:DI (match_dup 2)
15489		 (const_int 4)))
15490   (set (match_operand:DI 1 "register_operand" "=S")
15491	(plus:DI (match_dup 3)
15492		 (const_int 4)))
15493   (use (reg:SI 19))]
15494  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15495  "{movsl|movsd}"
15496  [(set_attr "type" "str")
15497   (set_attr "mode" "SI")
15498   (set_attr "memory" "both")])
15499
15500(define_insn "*strmovhi_1"
15501  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15502	(mem:HI (match_operand:SI 3 "register_operand" "1")))
15503   (set (match_operand:SI 0 "register_operand" "=D")
15504	(plus:SI (match_dup 2)
15505		 (const_int 2)))
15506   (set (match_operand:SI 1 "register_operand" "=S")
15507	(plus:SI (match_dup 3)
15508		 (const_int 2)))
15509   (use (reg:SI 19))]
15510  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15511  "movsw"
15512  [(set_attr "type" "str")
15513   (set_attr "memory" "both")
15514   (set_attr "mode" "HI")])
15515
15516(define_insn "*strmovhi_rex_1"
15517  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15518	(mem:HI (match_operand:DI 3 "register_operand" "1")))
15519   (set (match_operand:DI 0 "register_operand" "=D")
15520	(plus:DI (match_dup 2)
15521		 (const_int 2)))
15522   (set (match_operand:DI 1 "register_operand" "=S")
15523	(plus:DI (match_dup 3)
15524		 (const_int 2)))
15525   (use (reg:SI 19))]
15526  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15527  "movsw"
15528  [(set_attr "type" "str")
15529   (set_attr "memory" "both")
15530   (set_attr "mode" "HI")])
15531
15532(define_insn "*strmovqi_1"
15533  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15534	(mem:QI (match_operand:SI 3 "register_operand" "1")))
15535   (set (match_operand:SI 0 "register_operand" "=D")
15536	(plus:SI (match_dup 2)
15537		 (const_int 1)))
15538   (set (match_operand:SI 1 "register_operand" "=S")
15539	(plus:SI (match_dup 3)
15540		 (const_int 1)))
15541   (use (reg:SI 19))]
15542  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15543  "movsb"
15544  [(set_attr "type" "str")
15545   (set_attr "memory" "both")
15546   (set_attr "mode" "QI")])
15547
15548(define_insn "*strmovqi_rex_1"
15549  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15550	(mem:QI (match_operand:DI 3 "register_operand" "1")))
15551   (set (match_operand:DI 0 "register_operand" "=D")
15552	(plus:DI (match_dup 2)
15553		 (const_int 1)))
15554   (set (match_operand:DI 1 "register_operand" "=S")
15555	(plus:DI (match_dup 3)
15556		 (const_int 1)))
15557   (use (reg:SI 19))]
15558  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15559  "movsb"
15560  [(set_attr "type" "str")
15561   (set_attr "memory" "both")
15562   (set_attr "mode" "QI")])
15563
15564(define_expand "rep_mov"
15565  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15566	      (set (match_operand 0 "register_operand" "")
15567		   (match_operand 5 "" ""))
15568	      (set (match_operand 2 "register_operand" "")
15569		   (match_operand 6 "" ""))
15570	      (set (match_operand 1 "memory_operand" "")
15571		   (match_operand 3 "memory_operand" ""))
15572	      (use (match_dup 4))
15573	      (use (reg:SI 19))])]
15574  ""
15575  "")
15576
15577(define_insn "*rep_movdi_rex64"
15578  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15579   (set (match_operand:DI 0 "register_operand" "=D") 
15580        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15581			    (const_int 3))
15582		 (match_operand:DI 3 "register_operand" "0")))
15583   (set (match_operand:DI 1 "register_operand" "=S") 
15584        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15585		 (match_operand:DI 4 "register_operand" "1")))
15586   (set (mem:BLK (match_dup 3))
15587	(mem:BLK (match_dup 4)))
15588   (use (match_dup 5))
15589   (use (reg:SI 19))]
15590  "TARGET_64BIT"
15591  "{rep\;movsq|rep movsq}"
15592  [(set_attr "type" "str")
15593   (set_attr "prefix_rep" "1")
15594   (set_attr "memory" "both")
15595   (set_attr "mode" "DI")])
15596
15597(define_insn "*rep_movsi"
15598  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15599   (set (match_operand:SI 0 "register_operand" "=D") 
15600        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15601			    (const_int 2))
15602		 (match_operand:SI 3 "register_operand" "0")))
15603   (set (match_operand:SI 1 "register_operand" "=S") 
15604        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15605		 (match_operand:SI 4 "register_operand" "1")))
15606   (set (mem:BLK (match_dup 3))
15607	(mem:BLK (match_dup 4)))
15608   (use (match_dup 5))
15609   (use (reg:SI 19))]
15610  "!TARGET_64BIT"
15611  "{rep\;movsl|rep movsd}"
15612  [(set_attr "type" "str")
15613   (set_attr "prefix_rep" "1")
15614   (set_attr "memory" "both")
15615   (set_attr "mode" "SI")])
15616
15617(define_insn "*rep_movsi_rex64"
15618  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15619   (set (match_operand:DI 0 "register_operand" "=D") 
15620        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15621			    (const_int 2))
15622		 (match_operand:DI 3 "register_operand" "0")))
15623   (set (match_operand:DI 1 "register_operand" "=S") 
15624        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15625		 (match_operand:DI 4 "register_operand" "1")))
15626   (set (mem:BLK (match_dup 3))
15627	(mem:BLK (match_dup 4)))
15628   (use (match_dup 5))
15629   (use (reg:SI 19))]
15630  "TARGET_64BIT"
15631  "{rep\;movsl|rep movsd}"
15632  [(set_attr "type" "str")
15633   (set_attr "prefix_rep" "1")
15634   (set_attr "memory" "both")
15635   (set_attr "mode" "SI")])
15636
15637(define_insn "*rep_movqi"
15638  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15639   (set (match_operand:SI 0 "register_operand" "=D") 
15640        (plus:SI (match_operand:SI 3 "register_operand" "0")
15641		 (match_operand:SI 5 "register_operand" "2")))
15642   (set (match_operand:SI 1 "register_operand" "=S") 
15643        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15644   (set (mem:BLK (match_dup 3))
15645	(mem:BLK (match_dup 4)))
15646   (use (match_dup 5))
15647   (use (reg:SI 19))]
15648  "!TARGET_64BIT"
15649  "{rep\;movsb|rep movsb}"
15650  [(set_attr "type" "str")
15651   (set_attr "prefix_rep" "1")
15652   (set_attr "memory" "both")
15653   (set_attr "mode" "SI")])
15654
15655(define_insn "*rep_movqi_rex64"
15656  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15657   (set (match_operand:DI 0 "register_operand" "=D") 
15658        (plus:DI (match_operand:DI 3 "register_operand" "0")
15659		 (match_operand:DI 5 "register_operand" "2")))
15660   (set (match_operand:DI 1 "register_operand" "=S") 
15661        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15662   (set (mem:BLK (match_dup 3))
15663	(mem:BLK (match_dup 4)))
15664   (use (match_dup 5))
15665   (use (reg:SI 19))]
15666  "TARGET_64BIT"
15667  "{rep\;movsb|rep movsb}"
15668  [(set_attr "type" "str")
15669   (set_attr "prefix_rep" "1")
15670   (set_attr "memory" "both")
15671   (set_attr "mode" "SI")])
15672
15673(define_expand "clrstrsi"
15674   [(use (match_operand:BLK 0 "memory_operand" ""))
15675    (use (match_operand:SI 1 "nonmemory_operand" ""))
15676    (use (match_operand 2 "const_int_operand" ""))]
15677  ""
15678{
15679 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15680   DONE;
15681 else
15682   FAIL;
15683})
15684
15685(define_expand "clrstrdi"
15686   [(use (match_operand:BLK 0 "memory_operand" ""))
15687    (use (match_operand:DI 1 "nonmemory_operand" ""))
15688    (use (match_operand 2 "const_int_operand" ""))]
15689  "TARGET_64BIT"
15690{
15691 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15692   DONE;
15693 else
15694   FAIL;
15695})
15696
15697;; Most CPUs don't like single string operations
15698;; Handle this case here to simplify previous expander.
15699
15700(define_expand "strset"
15701  [(set (match_operand 1 "memory_operand" "")
15702	(match_operand 2 "register_operand" ""))
15703   (parallel [(set (match_operand 0 "register_operand" "")
15704		   (match_dup 3))
15705	      (clobber (reg:CC 17))])]
15706  ""
15707{
15708  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15709    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15710
15711  /* If .md ever supports :P for Pmode, this can be directly
15712     in the pattern above.  */
15713  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15714			      GEN_INT (GET_MODE_SIZE (GET_MODE
15715						      (operands[2]))));
15716  if (TARGET_SINGLE_STRINGOP || optimize_size)
15717    {
15718      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15719				      operands[3]));
15720      DONE;
15721    }
15722})
15723
15724(define_expand "strset_singleop"
15725  [(parallel [(set (match_operand 1 "memory_operand" "")
15726		   (match_operand 2 "register_operand" ""))
15727	      (set (match_operand 0 "register_operand" "")
15728		   (match_operand 3 "" ""))
15729	      (use (reg:SI 19))])]
15730  "TARGET_SINGLE_STRINGOP || optimize_size"
15731  "")
15732
15733(define_insn "*strsetdi_rex_1"
15734  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15735	(match_operand:SI 2 "register_operand" "a"))
15736   (set (match_operand:DI 0 "register_operand" "=D")
15737	(plus:DI (match_dup 1)
15738		 (const_int 8)))
15739   (use (reg:SI 19))]
15740  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15741  "stosq"
15742  [(set_attr "type" "str")
15743   (set_attr "memory" "store")
15744   (set_attr "mode" "DI")])
15745
15746(define_insn "*strsetsi_1"
15747  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15748	(match_operand:SI 2 "register_operand" "a"))
15749   (set (match_operand:SI 0 "register_operand" "=D")
15750	(plus:SI (match_dup 1)
15751		 (const_int 4)))
15752   (use (reg:SI 19))]
15753  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15754  "{stosl|stosd}"
15755  [(set_attr "type" "str")
15756   (set_attr "memory" "store")
15757   (set_attr "mode" "SI")])
15758
15759(define_insn "*strsetsi_rex_1"
15760  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15761	(match_operand:SI 2 "register_operand" "a"))
15762   (set (match_operand:DI 0 "register_operand" "=D")
15763	(plus:DI (match_dup 1)
15764		 (const_int 4)))
15765   (use (reg:SI 19))]
15766  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15767  "{stosl|stosd}"
15768  [(set_attr "type" "str")
15769   (set_attr "memory" "store")
15770   (set_attr "mode" "SI")])
15771
15772(define_insn "*strsethi_1"
15773  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15774	(match_operand:HI 2 "register_operand" "a"))
15775   (set (match_operand:SI 0 "register_operand" "=D")
15776	(plus:SI (match_dup 1)
15777		 (const_int 2)))
15778   (use (reg:SI 19))]
15779  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15780  "stosw"
15781  [(set_attr "type" "str")
15782   (set_attr "memory" "store")
15783   (set_attr "mode" "HI")])
15784
15785(define_insn "*strsethi_rex_1"
15786  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15787	(match_operand:HI 2 "register_operand" "a"))
15788   (set (match_operand:DI 0 "register_operand" "=D")
15789	(plus:DI (match_dup 1)
15790		 (const_int 2)))
15791   (use (reg:SI 19))]
15792  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15793  "stosw"
15794  [(set_attr "type" "str")
15795   (set_attr "memory" "store")
15796   (set_attr "mode" "HI")])
15797
15798(define_insn "*strsetqi_1"
15799  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15800	(match_operand:QI 2 "register_operand" "a"))
15801   (set (match_operand:SI 0 "register_operand" "=D")
15802	(plus:SI (match_dup 1)
15803		 (const_int 1)))
15804   (use (reg:SI 19))]
15805  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15806  "stosb"
15807  [(set_attr "type" "str")
15808   (set_attr "memory" "store")
15809   (set_attr "mode" "QI")])
15810
15811(define_insn "*strsetqi_rex_1"
15812  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15813	(match_operand:QI 2 "register_operand" "a"))
15814   (set (match_operand:DI 0 "register_operand" "=D")
15815	(plus:DI (match_dup 1)
15816		 (const_int 1)))
15817   (use (reg:SI 19))]
15818  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15819  "stosb"
15820  [(set_attr "type" "str")
15821   (set_attr "memory" "store")
15822   (set_attr "mode" "QI")])
15823
15824(define_expand "rep_stos"
15825  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15826	      (set (match_operand 0 "register_operand" "")
15827		   (match_operand 4 "" ""))
15828	      (set (match_operand 2 "memory_operand" "") (const_int 0))
15829	      (use (match_operand 3 "register_operand" ""))
15830	      (use (match_dup 1))
15831	      (use (reg:SI 19))])]
15832  ""
15833  "")
15834
15835(define_insn "*rep_stosdi_rex64"
15836  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15837   (set (match_operand:DI 0 "register_operand" "=D") 
15838        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15839			    (const_int 3))
15840		 (match_operand:DI 3 "register_operand" "0")))
15841   (set (mem:BLK (match_dup 3))
15842	(const_int 0))
15843   (use (match_operand:DI 2 "register_operand" "a"))
15844   (use (match_dup 4))
15845   (use (reg:SI 19))]
15846  "TARGET_64BIT"
15847  "{rep\;stosq|rep stosq}"
15848  [(set_attr "type" "str")
15849   (set_attr "prefix_rep" "1")
15850   (set_attr "memory" "store")
15851   (set_attr "mode" "DI")])
15852
15853(define_insn "*rep_stossi"
15854  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15855   (set (match_operand:SI 0 "register_operand" "=D") 
15856        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15857			    (const_int 2))
15858		 (match_operand:SI 3 "register_operand" "0")))
15859   (set (mem:BLK (match_dup 3))
15860	(const_int 0))
15861   (use (match_operand:SI 2 "register_operand" "a"))
15862   (use (match_dup 4))
15863   (use (reg:SI 19))]
15864  "!TARGET_64BIT"
15865  "{rep\;stosl|rep stosd}"
15866  [(set_attr "type" "str")
15867   (set_attr "prefix_rep" "1")
15868   (set_attr "memory" "store")
15869   (set_attr "mode" "SI")])
15870
15871(define_insn "*rep_stossi_rex64"
15872  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15873   (set (match_operand:DI 0 "register_operand" "=D") 
15874        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15875			    (const_int 2))
15876		 (match_operand:DI 3 "register_operand" "0")))
15877   (set (mem:BLK (match_dup 3))
15878	(const_int 0))
15879   (use (match_operand:SI 2 "register_operand" "a"))
15880   (use (match_dup 4))
15881   (use (reg:SI 19))]
15882  "TARGET_64BIT"
15883  "{rep\;stosl|rep stosd}"
15884  [(set_attr "type" "str")
15885   (set_attr "prefix_rep" "1")
15886   (set_attr "memory" "store")
15887   (set_attr "mode" "SI")])
15888
15889(define_insn "*rep_stosqi"
15890  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15891   (set (match_operand:SI 0 "register_operand" "=D") 
15892        (plus:SI (match_operand:SI 3 "register_operand" "0")
15893		 (match_operand:SI 4 "register_operand" "1")))
15894   (set (mem:BLK (match_dup 3))
15895	(const_int 0))
15896   (use (match_operand:QI 2 "register_operand" "a"))
15897   (use (match_dup 4))
15898   (use (reg:SI 19))]
15899  "!TARGET_64BIT"
15900  "{rep\;stosb|rep stosb}"
15901  [(set_attr "type" "str")
15902   (set_attr "prefix_rep" "1")
15903   (set_attr "memory" "store")
15904   (set_attr "mode" "QI")])
15905
15906(define_insn "*rep_stosqi_rex64"
15907  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15908   (set (match_operand:DI 0 "register_operand" "=D") 
15909        (plus:DI (match_operand:DI 3 "register_operand" "0")
15910		 (match_operand:DI 4 "register_operand" "1")))
15911   (set (mem:BLK (match_dup 3))
15912	(const_int 0))
15913   (use (match_operand:QI 2 "register_operand" "a"))
15914   (use (match_dup 4))
15915   (use (reg:SI 19))]
15916  "TARGET_64BIT"
15917  "{rep\;stosb|rep stosb}"
15918  [(set_attr "type" "str")
15919   (set_attr "prefix_rep" "1")
15920   (set_attr "memory" "store")
15921   (set_attr "mode" "QI")])
15922
15923(define_expand "cmpstrsi"
15924  [(set (match_operand:SI 0 "register_operand" "")
15925	(compare:SI (match_operand:BLK 1 "general_operand" "")
15926		    (match_operand:BLK 2 "general_operand" "")))
15927   (use (match_operand 3 "general_operand" ""))
15928   (use (match_operand 4 "immediate_operand" ""))]
15929  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15930{
15931  rtx addr1, addr2, out, outlow, count, countreg, align;
15932
15933  /* Can't use this if the user has appropriated esi or edi.  */
15934  if (global_regs[4] || global_regs[5])
15935    FAIL;
15936
15937  out = operands[0];
15938  if (GET_CODE (out) != REG)
15939    out = gen_reg_rtx (SImode);
15940
15941  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15942  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15943  if (addr1 != XEXP (operands[1], 0))
15944    operands[1] = replace_equiv_address_nv (operands[1], addr1);
15945  if (addr2 != XEXP (operands[2], 0))
15946    operands[2] = replace_equiv_address_nv (operands[2], addr2);
15947
15948  count = operands[3];
15949  countreg = ix86_zero_extend_to_Pmode (count);
15950
15951  /* %%% Iff we are testing strict equality, we can use known alignment
15952     to good advantage.  This may be possible with combine, particularly
15953     once cc0 is dead.  */
15954  align = operands[4];
15955
15956  emit_insn (gen_cld ());
15957  if (GET_CODE (count) == CONST_INT)
15958    {
15959      if (INTVAL (count) == 0)
15960	{
15961	  emit_move_insn (operands[0], const0_rtx);
15962	  DONE;
15963	}
15964      emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15965				    operands[1], operands[2]));
15966    }
15967  else
15968    {
15969      if (TARGET_64BIT)
15970	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15971      else
15972	emit_insn (gen_cmpsi_1 (countreg, countreg));
15973      emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15974				 operands[1], operands[2]));
15975    }
15976
15977  outlow = gen_lowpart (QImode, out);
15978  emit_insn (gen_cmpintqi (outlow));
15979  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15980
15981  if (operands[0] != out)
15982    emit_move_insn (operands[0], out);
15983
15984  DONE;
15985})
15986
15987;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15988
15989(define_expand "cmpintqi"
15990  [(set (match_dup 1)
15991	(gtu:QI (reg:CC 17) (const_int 0)))
15992   (set (match_dup 2)
15993	(ltu:QI (reg:CC 17) (const_int 0)))
15994   (parallel [(set (match_operand:QI 0 "register_operand" "")
15995		   (minus:QI (match_dup 1)
15996			     (match_dup 2)))
15997	      (clobber (reg:CC 17))])]
15998  ""
15999  "operands[1] = gen_reg_rtx (QImode);
16000   operands[2] = gen_reg_rtx (QImode);")
16001
16002;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16003;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16004
16005(define_expand "cmpstrqi_nz_1"
16006  [(parallel [(set (reg:CC 17)
16007		   (compare:CC (match_operand 4 "memory_operand" "")
16008			       (match_operand 5 "memory_operand" "")))
16009	      (use (match_operand 2 "register_operand" ""))
16010	      (use (match_operand:SI 3 "immediate_operand" ""))
16011	      (use (reg:SI 19))
16012	      (clobber (match_operand 0 "register_operand" ""))
16013	      (clobber (match_operand 1 "register_operand" ""))
16014	      (clobber (match_dup 2))])]
16015  ""
16016  "")
16017
16018(define_insn "*cmpstrqi_nz_1"
16019  [(set (reg:CC 17)
16020	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16021		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16022   (use (match_operand:SI 6 "register_operand" "2"))
16023   (use (match_operand:SI 3 "immediate_operand" "i"))
16024   (use (reg:SI 19))
16025   (clobber (match_operand:SI 0 "register_operand" "=S"))
16026   (clobber (match_operand:SI 1 "register_operand" "=D"))
16027   (clobber (match_operand:SI 2 "register_operand" "=c"))]
16028  "!TARGET_64BIT"
16029  "repz{\;| }cmpsb"
16030  [(set_attr "type" "str")
16031   (set_attr "mode" "QI")
16032   (set_attr "prefix_rep" "1")])
16033
16034(define_insn "*cmpstrqi_nz_rex_1"
16035  [(set (reg:CC 17)
16036	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16037		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16038   (use (match_operand:DI 6 "register_operand" "2"))
16039   (use (match_operand:SI 3 "immediate_operand" "i"))
16040   (use (reg:SI 19))
16041   (clobber (match_operand:DI 0 "register_operand" "=S"))
16042   (clobber (match_operand:DI 1 "register_operand" "=D"))
16043   (clobber (match_operand:DI 2 "register_operand" "=c"))]
16044  "TARGET_64BIT"
16045  "repz{\;| }cmpsb"
16046  [(set_attr "type" "str")
16047   (set_attr "mode" "QI")
16048   (set_attr "prefix_rep" "1")])
16049
16050;; The same, but the count is not known to not be zero.
16051
16052(define_expand "cmpstrqi_1"
16053  [(parallel [(set (reg:CC 17)
16054		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
16055				     (const_int 0))
16056		  (compare:CC (match_operand 4 "memory_operand" "")
16057			      (match_operand 5 "memory_operand" ""))
16058		  (const_int 0)))
16059	      (use (match_operand:SI 3 "immediate_operand" ""))
16060	      (use (reg:CC 17))
16061	      (use (reg:SI 19))
16062	      (clobber (match_operand 0 "register_operand" ""))
16063	      (clobber (match_operand 1 "register_operand" ""))
16064	      (clobber (match_dup 2))])]
16065  ""
16066  "")
16067
16068(define_insn "*cmpstrqi_1"
16069  [(set (reg:CC 17)
16070	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16071			     (const_int 0))
16072	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16073		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16074	  (const_int 0)))
16075   (use (match_operand:SI 3 "immediate_operand" "i"))
16076   (use (reg:CC 17))
16077   (use (reg:SI 19))
16078   (clobber (match_operand:SI 0 "register_operand" "=S"))
16079   (clobber (match_operand:SI 1 "register_operand" "=D"))
16080   (clobber (match_operand:SI 2 "register_operand" "=c"))]
16081  "!TARGET_64BIT"
16082  "repz{\;| }cmpsb"
16083  [(set_attr "type" "str")
16084   (set_attr "mode" "QI")
16085   (set_attr "prefix_rep" "1")])
16086
16087(define_insn "*cmpstrqi_rex_1"
16088  [(set (reg:CC 17)
16089	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16090			     (const_int 0))
16091	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16092		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16093	  (const_int 0)))
16094   (use (match_operand:SI 3 "immediate_operand" "i"))
16095   (use (reg:CC 17))
16096   (use (reg:SI 19))
16097   (clobber (match_operand:DI 0 "register_operand" "=S"))
16098   (clobber (match_operand:DI 1 "register_operand" "=D"))
16099   (clobber (match_operand:DI 2 "register_operand" "=c"))]
16100  "TARGET_64BIT"
16101  "repz{\;| }cmpsb"
16102  [(set_attr "type" "str")
16103   (set_attr "mode" "QI")
16104   (set_attr "prefix_rep" "1")])
16105
16106(define_expand "strlensi"
16107  [(set (match_operand:SI 0 "register_operand" "")
16108	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
16109		    (match_operand:QI 2 "immediate_operand" "")
16110		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16111  ""
16112{
16113 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16114   DONE;
16115 else
16116   FAIL;
16117})
16118
16119(define_expand "strlendi"
16120  [(set (match_operand:DI 0 "register_operand" "")
16121	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
16122		    (match_operand:QI 2 "immediate_operand" "")
16123		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16124  ""
16125{
16126 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16127   DONE;
16128 else
16129   FAIL;
16130})
16131
16132(define_expand "strlenqi_1"
16133  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16134	      (use (reg:SI 19))
16135	      (clobber (match_operand 1 "register_operand" ""))
16136	      (clobber (reg:CC 17))])]
16137  ""
16138  "")
16139
16140(define_insn "*strlenqi_1"
16141  [(set (match_operand:SI 0 "register_operand" "=&c")
16142	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16143		    (match_operand:QI 2 "register_operand" "a")
16144		    (match_operand:SI 3 "immediate_operand" "i")
16145		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16146   (use (reg:SI 19))
16147   (clobber (match_operand:SI 1 "register_operand" "=D"))
16148   (clobber (reg:CC 17))]
16149  "!TARGET_64BIT"
16150  "repnz{\;| }scasb"
16151  [(set_attr "type" "str")
16152   (set_attr "mode" "QI")
16153   (set_attr "prefix_rep" "1")])
16154
16155(define_insn "*strlenqi_rex_1"
16156  [(set (match_operand:DI 0 "register_operand" "=&c")
16157	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16158		    (match_operand:QI 2 "register_operand" "a")
16159		    (match_operand:DI 3 "immediate_operand" "i")
16160		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16161   (use (reg:SI 19))
16162   (clobber (match_operand:DI 1 "register_operand" "=D"))
16163   (clobber (reg:CC 17))]
16164  "TARGET_64BIT"
16165  "repnz{\;| }scasb"
16166  [(set_attr "type" "str")
16167   (set_attr "mode" "QI")
16168   (set_attr "prefix_rep" "1")])
16169
16170;; Peephole optimizations to clean up after cmpstr*.  This should be
16171;; handled in combine, but it is not currently up to the task.
16172;; When used for their truth value, the cmpstr* expanders generate
16173;; code like this:
16174;;
16175;;   repz cmpsb
16176;;   seta 	%al
16177;;   setb 	%dl
16178;;   cmpb 	%al, %dl
16179;;   jcc	label
16180;;
16181;; The intermediate three instructions are unnecessary.
16182
16183;; This one handles cmpstr*_nz_1...
16184(define_peephole2
16185  [(parallel[
16186     (set (reg:CC 17)
16187	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16188		      (mem:BLK (match_operand 5 "register_operand" ""))))
16189     (use (match_operand 6 "register_operand" ""))
16190     (use (match_operand:SI 3 "immediate_operand" ""))
16191     (use (reg:SI 19))
16192     (clobber (match_operand 0 "register_operand" ""))
16193     (clobber (match_operand 1 "register_operand" ""))
16194     (clobber (match_operand 2 "register_operand" ""))])
16195   (set (match_operand:QI 7 "register_operand" "")
16196	(gtu:QI (reg:CC 17) (const_int 0)))
16197   (set (match_operand:QI 8 "register_operand" "")
16198	(ltu:QI (reg:CC 17) (const_int 0)))
16199   (set (reg 17)
16200	(compare (match_dup 7) (match_dup 8)))
16201  ]
16202  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16203  [(parallel[
16204     (set (reg:CC 17)
16205	  (compare:CC (mem:BLK (match_dup 4))
16206		      (mem:BLK (match_dup 5))))
16207     (use (match_dup 6))
16208     (use (match_dup 3))
16209     (use (reg:SI 19))
16210     (clobber (match_dup 0))
16211     (clobber (match_dup 1))
16212     (clobber (match_dup 2))])]
16213  "")
16214
16215;; ...and this one handles cmpstr*_1.
16216(define_peephole2
16217  [(parallel[
16218     (set (reg:CC 17)
16219	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16220			       (const_int 0))
16221	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16222		        (mem:BLK (match_operand 5 "register_operand" "")))
16223	    (const_int 0)))
16224     (use (match_operand:SI 3 "immediate_operand" ""))
16225     (use (reg:CC 17))
16226     (use (reg:SI 19))
16227     (clobber (match_operand 0 "register_operand" ""))
16228     (clobber (match_operand 1 "register_operand" ""))
16229     (clobber (match_operand 2 "register_operand" ""))])
16230   (set (match_operand:QI 7 "register_operand" "")
16231	(gtu:QI (reg:CC 17) (const_int 0)))
16232   (set (match_operand:QI 8 "register_operand" "")
16233	(ltu:QI (reg:CC 17) (const_int 0)))
16234   (set (reg 17)
16235	(compare (match_dup 7) (match_dup 8)))
16236  ]
16237  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16238  [(parallel[
16239     (set (reg:CC 17)
16240	  (if_then_else:CC (ne (match_dup 6)
16241			       (const_int 0))
16242	    (compare:CC (mem:BLK (match_dup 4))
16243			(mem:BLK (match_dup 5)))
16244	    (const_int 0)))
16245     (use (match_dup 3))
16246     (use (reg:CC 17))
16247     (use (reg:SI 19))
16248     (clobber (match_dup 0))
16249     (clobber (match_dup 1))
16250     (clobber (match_dup 2))])]
16251  "")
16252
16253
16254
16255;; Conditional move instructions.
16256
16257(define_expand "movdicc"
16258  [(set (match_operand:DI 0 "register_operand" "")
16259	(if_then_else:DI (match_operand 1 "comparison_operator" "")
16260			 (match_operand:DI 2 "general_operand" "")
16261			 (match_operand:DI 3 "general_operand" "")))]
16262  "TARGET_64BIT"
16263  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16264
16265(define_insn "x86_movdicc_0_m1_rex64"
16266  [(set (match_operand:DI 0 "register_operand" "=r")
16267	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16268	  (const_int -1)
16269	  (const_int 0)))
16270   (clobber (reg:CC 17))]
16271  "TARGET_64BIT"
16272  "sbb{q}\t%0, %0"
16273  ; Since we don't have the proper number of operands for an alu insn,
16274  ; fill in all the blanks.
16275  [(set_attr "type" "alu")
16276   (set_attr "pent_pair" "pu")
16277   (set_attr "memory" "none")
16278   (set_attr "imm_disp" "false")
16279   (set_attr "mode" "DI")
16280   (set_attr "length_immediate" "0")])
16281
16282(define_insn "movdicc_c_rex64"
16283  [(set (match_operand:DI 0 "register_operand" "=r,r")
16284	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
16285				[(reg 17) (const_int 0)])
16286		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16287		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16288  "TARGET_64BIT && TARGET_CMOVE
16289   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16290  "@
16291   cmov%O2%C1\t{%2, %0|%0, %2}
16292   cmov%O2%c1\t{%3, %0|%0, %3}"
16293  [(set_attr "type" "icmov")
16294   (set_attr "mode" "DI")])
16295
16296(define_expand "movsicc"
16297  [(set (match_operand:SI 0 "register_operand" "")
16298	(if_then_else:SI (match_operand 1 "comparison_operator" "")
16299			 (match_operand:SI 2 "general_operand" "")
16300			 (match_operand:SI 3 "general_operand" "")))]
16301  ""
16302  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16303
16304;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16305;; the register first winds up with `sbbl $0,reg', which is also weird.
16306;; So just document what we're doing explicitly.
16307
16308(define_insn "x86_movsicc_0_m1"
16309  [(set (match_operand:SI 0 "register_operand" "=r")
16310	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16311	  (const_int -1)
16312	  (const_int 0)))
16313   (clobber (reg:CC 17))]
16314  ""
16315  "sbb{l}\t%0, %0"
16316  ; Since we don't have the proper number of operands for an alu insn,
16317  ; fill in all the blanks.
16318  [(set_attr "type" "alu")
16319   (set_attr "pent_pair" "pu")
16320   (set_attr "memory" "none")
16321   (set_attr "imm_disp" "false")
16322   (set_attr "mode" "SI")
16323   (set_attr "length_immediate" "0")])
16324
16325(define_insn "*movsicc_noc"
16326  [(set (match_operand:SI 0 "register_operand" "=r,r")
16327	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
16328				[(reg 17) (const_int 0)])
16329		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16330		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16331  "TARGET_CMOVE
16332   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16333  "@
16334   cmov%O2%C1\t{%2, %0|%0, %2}
16335   cmov%O2%c1\t{%3, %0|%0, %3}"
16336  [(set_attr "type" "icmov")
16337   (set_attr "mode" "SI")])
16338
16339(define_expand "movhicc"
16340  [(set (match_operand:HI 0 "register_operand" "")
16341	(if_then_else:HI (match_operand 1 "comparison_operator" "")
16342			 (match_operand:HI 2 "general_operand" "")
16343			 (match_operand:HI 3 "general_operand" "")))]
16344  "TARGET_HIMODE_MATH"
16345  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16346
16347(define_insn "*movhicc_noc"
16348  [(set (match_operand:HI 0 "register_operand" "=r,r")
16349	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
16350				[(reg 17) (const_int 0)])
16351		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16352		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16353  "TARGET_CMOVE
16354   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16355  "@
16356   cmov%O2%C1\t{%2, %0|%0, %2}
16357   cmov%O2%c1\t{%3, %0|%0, %3}"
16358  [(set_attr "type" "icmov")
16359   (set_attr "mode" "HI")])
16360
16361(define_expand "movqicc"
16362  [(set (match_operand:QI 0 "register_operand" "")
16363	(if_then_else:QI (match_operand 1 "comparison_operator" "")
16364			 (match_operand:QI 2 "general_operand" "")
16365			 (match_operand:QI 3 "general_operand" "")))]
16366  "TARGET_QIMODE_MATH"
16367  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16368
16369(define_insn_and_split "*movqicc_noc"
16370  [(set (match_operand:QI 0 "register_operand" "=r,r")
16371	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
16372				[(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16373		      (match_operand:QI 2 "register_operand" "r,0")
16374		      (match_operand:QI 3 "register_operand" "0,r")))]
16375  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16376  "#"
16377  "&& reload_completed"
16378  [(set (match_dup 0)
16379	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16380		      (match_dup 2)
16381		      (match_dup 3)))]
16382  "operands[0] = gen_lowpart (SImode, operands[0]);
16383   operands[2] = gen_lowpart (SImode, operands[2]);
16384   operands[3] = gen_lowpart (SImode, operands[3]);"
16385  [(set_attr "type" "icmov")
16386   (set_attr "mode" "SI")])
16387
16388(define_expand "movsfcc"
16389  [(set (match_operand:SF 0 "register_operand" "")
16390	(if_then_else:SF (match_operand 1 "comparison_operator" "")
16391			 (match_operand:SF 2 "register_operand" "")
16392			 (match_operand:SF 3 "register_operand" "")))]
16393  "TARGET_CMOVE"
16394  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16395
16396(define_insn "*movsfcc_1"
16397  [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16398	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
16399				[(reg 17) (const_int 0)])
16400		      (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16401		      (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16402  "TARGET_CMOVE
16403   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16404  "@
16405   fcmov%F1\t{%2, %0|%0, %2}
16406   fcmov%f1\t{%3, %0|%0, %3}
16407   cmov%O2%C1\t{%2, %0|%0, %2}
16408   cmov%O2%c1\t{%3, %0|%0, %3}"
16409  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16410   (set_attr "mode" "SF,SF,SI,SI")])
16411
16412(define_expand "movdfcc"
16413  [(set (match_operand:DF 0 "register_operand" "")
16414	(if_then_else:DF (match_operand 1 "comparison_operator" "")
16415			 (match_operand:DF 2 "register_operand" "")
16416			 (match_operand:DF 3 "register_operand" "")))]
16417  "TARGET_CMOVE"
16418  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16419
16420(define_insn "*movdfcc_1"
16421  [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16422	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16423				[(reg 17) (const_int 0)])
16424		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16425		      (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16426  "!TARGET_64BIT && TARGET_CMOVE
16427   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16428  "@
16429   fcmov%F1\t{%2, %0|%0, %2}
16430   fcmov%f1\t{%3, %0|%0, %3}
16431   #
16432   #"
16433  [(set_attr "type" "fcmov,fcmov,multi,multi")
16434   (set_attr "mode" "DF")])
16435
16436(define_insn "*movdfcc_1_rex64"
16437  [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16438	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16439				[(reg 17) (const_int 0)])
16440		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16441		      (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16442  "TARGET_64BIT && TARGET_CMOVE
16443   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16444  "@
16445   fcmov%F1\t{%2, %0|%0, %2}
16446   fcmov%f1\t{%3, %0|%0, %3}
16447   cmov%O2%C1\t{%2, %0|%0, %2}
16448   cmov%O2%c1\t{%3, %0|%0, %3}"
16449  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16450   (set_attr "mode" "DF")])
16451
16452(define_split
16453  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16454	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16455				[(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16456		      (match_operand:DF 2 "nonimmediate_operand" "")
16457		      (match_operand:DF 3 "nonimmediate_operand" "")))]
16458  "!TARGET_64BIT && reload_completed"
16459  [(set (match_dup 2)
16460	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16461		      (match_dup 5)
16462		      (match_dup 7)))
16463   (set (match_dup 3)
16464	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16465		      (match_dup 6)
16466		      (match_dup 8)))]
16467  "split_di (operands+2, 1, operands+5, operands+6);
16468   split_di (operands+3, 1, operands+7, operands+8);
16469   split_di (operands, 1, operands+2, operands+3);")
16470
16471(define_expand "movxfcc"
16472  [(set (match_operand:XF 0 "register_operand" "")
16473	(if_then_else:XF (match_operand 1 "comparison_operator" "")
16474			 (match_operand:XF 2 "register_operand" "")
16475			 (match_operand:XF 3 "register_operand" "")))]
16476  "TARGET_CMOVE"
16477  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16478
16479(define_insn "*movxfcc_1"
16480  [(set (match_operand:XF 0 "register_operand" "=f,f")
16481	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
16482				[(reg 17) (const_int 0)])
16483		      (match_operand:XF 2 "register_operand" "f,0")
16484		      (match_operand:XF 3 "register_operand" "0,f")))]
16485  "TARGET_CMOVE"
16486  "@
16487   fcmov%F1\t{%2, %0|%0, %2}
16488   fcmov%f1\t{%3, %0|%0, %3}"
16489  [(set_attr "type" "fcmov")
16490   (set_attr "mode" "XF")])
16491
16492(define_expand "minsf3"
16493  [(parallel [
16494     (set (match_operand:SF 0 "register_operand" "")
16495	  (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16496			       (match_operand:SF 2 "nonimmediate_operand" ""))
16497			   (match_dup 1)
16498			   (match_dup 2)))
16499     (clobber (reg:CC 17))])]
16500  "TARGET_SSE"
16501  "")
16502
16503(define_insn "*minsf"
16504  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16505	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16506			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16507			 (match_dup 1)
16508			 (match_dup 2)))
16509   (clobber (reg:CC 17))]
16510  "TARGET_SSE && TARGET_IEEE_FP"
16511  "#")
16512
16513(define_insn "*minsf_nonieee"
16514  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16515	(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16516			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16517			 (match_dup 1)
16518			 (match_dup 2)))
16519   (clobber (reg:CC 17))]
16520  "TARGET_SSE && !TARGET_IEEE_FP
16521   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16522  "#")
16523
16524(define_split
16525  [(set (match_operand:SF 0 "register_operand" "")
16526	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16527			     (match_operand:SF 2 "nonimmediate_operand" ""))
16528			 (match_operand:SF 3 "register_operand" "")
16529			 (match_operand:SF 4 "nonimmediate_operand" "")))
16530   (clobber (reg:CC 17))]
16531  "SSE_REG_P (operands[0]) && reload_completed
16532   && ((operands_match_p (operands[1], operands[3])
16533	&& operands_match_p (operands[2], operands[4]))
16534       || (operands_match_p (operands[1], operands[4])
16535	   && operands_match_p (operands[2], operands[3])))"
16536  [(set (match_dup 0)
16537	(if_then_else:SF (lt (match_dup 1)
16538			     (match_dup 2))
16539			 (match_dup 1)
16540			 (match_dup 2)))])
16541
16542;; Conditional addition patterns
16543(define_expand "addqicc"
16544  [(match_operand:QI 0 "register_operand" "")
16545   (match_operand 1 "comparison_operator" "")
16546   (match_operand:QI 2 "register_operand" "")
16547   (match_operand:QI 3 "const_int_operand" "")]
16548  ""
16549  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16550
16551(define_expand "addhicc"
16552  [(match_operand:HI 0 "register_operand" "")
16553   (match_operand 1 "comparison_operator" "")
16554   (match_operand:HI 2 "register_operand" "")
16555   (match_operand:HI 3 "const_int_operand" "")]
16556  ""
16557  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16558
16559(define_expand "addsicc"
16560  [(match_operand:SI 0 "register_operand" "")
16561   (match_operand 1 "comparison_operator" "")
16562   (match_operand:SI 2 "register_operand" "")
16563   (match_operand:SI 3 "const_int_operand" "")]
16564  ""
16565  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16566
16567(define_expand "adddicc"
16568  [(match_operand:DI 0 "register_operand" "")
16569   (match_operand 1 "comparison_operator" "")
16570   (match_operand:DI 2 "register_operand" "")
16571   (match_operand:DI 3 "const_int_operand" "")]
16572  "TARGET_64BIT"
16573  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16574
16575;; We can't represent the LT test directly.  Do this by swapping the operands.
16576
16577(define_split
16578  [(set (match_operand:SF 0 "fp_register_operand" "")
16579	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16580			     (match_operand:SF 2 "register_operand" ""))
16581			 (match_operand:SF 3 "register_operand" "")
16582			 (match_operand:SF 4 "register_operand" "")))
16583   (clobber (reg:CC 17))]
16584  "reload_completed
16585   && ((operands_match_p (operands[1], operands[3])
16586	&& operands_match_p (operands[2], operands[4]))
16587       || (operands_match_p (operands[1], operands[4])
16588	   && operands_match_p (operands[2], operands[3])))"
16589  [(set (reg:CCFP 17)
16590	(compare:CCFP (match_dup 2)
16591		      (match_dup 1)))
16592   (set (match_dup 0)
16593	(if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16594			 (match_dup 1)
16595			 (match_dup 2)))])
16596
16597(define_insn "*minsf_sse"
16598  [(set (match_operand:SF 0 "register_operand" "=x")
16599	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16600			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
16601			 (match_dup 1)
16602			 (match_dup 2)))]
16603  "TARGET_SSE && reload_completed"
16604  "minss\t{%2, %0|%0, %2}"
16605  [(set_attr "type" "sse")
16606   (set_attr "mode" "SF")])
16607
16608(define_expand "mindf3"
16609  [(parallel [
16610     (set (match_operand:DF 0 "register_operand" "")
16611	  (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16612			       (match_operand:DF 2 "nonimmediate_operand" ""))
16613			   (match_dup 1)
16614			   (match_dup 2)))
16615     (clobber (reg:CC 17))])]
16616  "TARGET_SSE2 && TARGET_SSE_MATH"
16617  "#")
16618
16619(define_insn "*mindf"
16620  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16621	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16622			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16623			 (match_dup 1)
16624			 (match_dup 2)))
16625   (clobber (reg:CC 17))]
16626  "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16627  "#")
16628
16629(define_insn "*mindf_nonieee"
16630  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16631	(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16632			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16633			 (match_dup 1)
16634			 (match_dup 2)))
16635   (clobber (reg:CC 17))]
16636  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16637   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16638  "#")
16639
16640(define_split
16641  [(set (match_operand:DF 0 "register_operand" "")
16642	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16643			     (match_operand:DF 2 "nonimmediate_operand" ""))
16644			 (match_operand:DF 3 "register_operand" "")
16645			 (match_operand:DF 4 "nonimmediate_operand" "")))
16646   (clobber (reg:CC 17))]
16647  "SSE_REG_P (operands[0]) && reload_completed
16648   && ((operands_match_p (operands[1], operands[3])
16649	&& operands_match_p (operands[2], operands[4]))
16650       || (operands_match_p (operands[1], operands[4])
16651	   && operands_match_p (operands[2], operands[3])))"
16652  [(set (match_dup 0)
16653	(if_then_else:DF (lt (match_dup 1)
16654			     (match_dup 2))
16655			 (match_dup 1)
16656			 (match_dup 2)))])
16657
16658;; We can't represent the LT test directly.  Do this by swapping the operands.
16659(define_split
16660  [(set (match_operand:DF 0 "fp_register_operand" "")
16661	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16662			     (match_operand:DF 2 "register_operand" ""))
16663			 (match_operand:DF 3 "register_operand" "")
16664			 (match_operand:DF 4 "register_operand" "")))
16665   (clobber (reg:CC 17))]
16666  "reload_completed
16667   && ((operands_match_p (operands[1], operands[3])
16668	&& operands_match_p (operands[2], operands[4]))
16669       || (operands_match_p (operands[1], operands[4])
16670	   && operands_match_p (operands[2], operands[3])))"
16671  [(set (reg:CCFP 17)
16672	(compare:CCFP (match_dup 2)
16673		      (match_dup 1)))
16674   (set (match_dup 0)
16675	(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16676			 (match_dup 1)
16677			 (match_dup 2)))])
16678
16679(define_insn "*mindf_sse"
16680  [(set (match_operand:DF 0 "register_operand" "=Y")
16681	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16682			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16683			 (match_dup 1)
16684			 (match_dup 2)))]
16685  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16686  "minsd\t{%2, %0|%0, %2}"
16687  [(set_attr "type" "sse")
16688   (set_attr "mode" "DF")])
16689
16690(define_expand "maxsf3"
16691  [(parallel [
16692     (set (match_operand:SF 0 "register_operand" "")
16693	  (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16694			       (match_operand:SF 2 "nonimmediate_operand" ""))
16695			   (match_dup 1)
16696			   (match_dup 2)))
16697     (clobber (reg:CC 17))])]
16698  "TARGET_SSE"
16699  "#")
16700
16701(define_insn "*maxsf"
16702  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16703	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16704			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16705			 (match_dup 1)
16706			 (match_dup 2)))
16707   (clobber (reg:CC 17))]
16708  "TARGET_SSE && TARGET_IEEE_FP"
16709  "#")
16710
16711(define_insn "*maxsf_nonieee"
16712  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16713	(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16714			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16715			 (match_dup 1)
16716			 (match_dup 2)))
16717   (clobber (reg:CC 17))]
16718  "TARGET_SSE && !TARGET_IEEE_FP
16719   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16720  "#")
16721
16722(define_split
16723  [(set (match_operand:SF 0 "register_operand" "")
16724	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16725			     (match_operand:SF 2 "nonimmediate_operand" ""))
16726			 (match_operand:SF 3 "register_operand" "")
16727			 (match_operand:SF 4 "nonimmediate_operand" "")))
16728   (clobber (reg:CC 17))]
16729  "SSE_REG_P (operands[0]) && reload_completed
16730   && ((operands_match_p (operands[1], operands[3])
16731	&& operands_match_p (operands[2], operands[4]))
16732       || (operands_match_p (operands[1], operands[4])
16733	   && operands_match_p (operands[2], operands[3])))"
16734  [(set (match_dup 0)
16735	(if_then_else:SF (gt (match_dup 1)
16736			     (match_dup 2))
16737			 (match_dup 1)
16738			 (match_dup 2)))])
16739
16740(define_split
16741  [(set (match_operand:SF 0 "fp_register_operand" "")
16742	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16743			     (match_operand:SF 2 "register_operand" ""))
16744			 (match_operand:SF 3 "register_operand" "")
16745			 (match_operand:SF 4 "register_operand" "")))
16746   (clobber (reg:CC 17))]
16747  "reload_completed
16748   && ((operands_match_p (operands[1], operands[3])
16749	&& operands_match_p (operands[2], operands[4]))
16750       || (operands_match_p (operands[1], operands[4])
16751	   && operands_match_p (operands[2], operands[3])))"
16752  [(set (reg:CCFP 17)
16753	(compare:CCFP (match_dup 1)
16754		      (match_dup 2)))
16755   (set (match_dup 0)
16756	(if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16757			 (match_dup 1)
16758			 (match_dup 2)))])
16759
16760(define_insn "*maxsf_sse"
16761  [(set (match_operand:SF 0 "register_operand" "=x")
16762	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16763			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
16764			 (match_dup 1)
16765			 (match_dup 2)))]
16766  "TARGET_SSE && reload_completed"
16767  "maxss\t{%2, %0|%0, %2}"
16768  [(set_attr "type" "sse")
16769   (set_attr "mode" "SF")])
16770
16771(define_expand "maxdf3"
16772  [(parallel [
16773     (set (match_operand:DF 0 "register_operand" "")
16774	  (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16775			       (match_operand:DF 2 "nonimmediate_operand" ""))
16776			   (match_dup 1)
16777			   (match_dup 2)))
16778     (clobber (reg:CC 17))])]
16779  "TARGET_SSE2 && TARGET_SSE_MATH"
16780  "#")
16781
16782(define_insn "*maxdf"
16783  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16784	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16785			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16786			 (match_dup 1)
16787			 (match_dup 2)))
16788   (clobber (reg:CC 17))]
16789  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16790  "#")
16791
16792(define_insn "*maxdf_nonieee"
16793  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16794	(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16795			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16796			 (match_dup 1)
16797			 (match_dup 2)))
16798   (clobber (reg:CC 17))]
16799  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16800   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16801  "#")
16802
16803(define_split
16804  [(set (match_operand:DF 0 "register_operand" "")
16805	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16806			     (match_operand:DF 2 "nonimmediate_operand" ""))
16807			 (match_operand:DF 3 "register_operand" "")
16808			 (match_operand:DF 4 "nonimmediate_operand" "")))
16809   (clobber (reg:CC 17))]
16810  "SSE_REG_P (operands[0]) && reload_completed
16811   && ((operands_match_p (operands[1], operands[3])
16812	&& operands_match_p (operands[2], operands[4]))
16813       || (operands_match_p (operands[1], operands[4])
16814	   && operands_match_p (operands[2], operands[3])))"
16815  [(set (match_dup 0)
16816	(if_then_else:DF (gt (match_dup 1)
16817			     (match_dup 2))
16818			 (match_dup 1)
16819			 (match_dup 2)))])
16820
16821(define_split
16822  [(set (match_operand:DF 0 "fp_register_operand" "")
16823	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16824			     (match_operand:DF 2 "register_operand" ""))
16825			 (match_operand:DF 3 "register_operand" "")
16826			 (match_operand:DF 4 "register_operand" "")))
16827   (clobber (reg:CC 17))]
16828  "reload_completed
16829   && ((operands_match_p (operands[1], operands[3])
16830	&& operands_match_p (operands[2], operands[4]))
16831       || (operands_match_p (operands[1], operands[4])
16832	   && operands_match_p (operands[2], operands[3])))"
16833  [(set (reg:CCFP 17)
16834	(compare:CCFP (match_dup 1)
16835		      (match_dup 2)))
16836   (set (match_dup 0)
16837	(if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16838			 (match_dup 1)
16839			 (match_dup 2)))])
16840
16841(define_insn "*maxdf_sse"
16842  [(set (match_operand:DF 0 "register_operand" "=Y")
16843	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16844			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16845			 (match_dup 1)
16846			 (match_dup 2)))]
16847  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16848  "maxsd\t{%2, %0|%0, %2}"
16849  [(set_attr "type" "sse")
16850   (set_attr "mode" "DF")])
16851
16852;; Misc patterns (?)
16853
16854;; This pattern exists to put a dependency on all ebp-based memory accesses.
16855;; Otherwise there will be nothing to keep
16856;; 
16857;; [(set (reg ebp) (reg esp))]
16858;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16859;;  (clobber (eflags)]
16860;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16861;;
16862;; in proper program order.
16863(define_insn "pro_epilogue_adjust_stack_1"
16864  [(set (match_operand:SI 0 "register_operand" "=r,r")
16865	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
16866	         (match_operand:SI 2 "immediate_operand" "i,i")))
16867   (clobber (reg:CC 17))
16868   (clobber (mem:BLK (scratch)))]
16869  "!TARGET_64BIT"
16870{
16871  switch (get_attr_type (insn))
16872    {
16873    case TYPE_IMOV:
16874      return "mov{l}\t{%1, %0|%0, %1}";
16875
16876    case TYPE_ALU:
16877      if (GET_CODE (operands[2]) == CONST_INT
16878          && (INTVAL (operands[2]) == 128
16879	      || (INTVAL (operands[2]) < 0
16880	          && INTVAL (operands[2]) != -128)))
16881	{
16882	  operands[2] = GEN_INT (-INTVAL (operands[2]));
16883	  return "sub{l}\t{%2, %0|%0, %2}";
16884	}
16885      return "add{l}\t{%2, %0|%0, %2}";
16886
16887    case TYPE_LEA:
16888      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16889      return "lea{l}\t{%a2, %0|%0, %a2}";
16890
16891    default:
16892      abort ();
16893    }
16894}
16895  [(set (attr "type")
16896	(cond [(eq_attr "alternative" "0")
16897		 (const_string "alu")
16898	       (match_operand:SI 2 "const0_operand" "")
16899		 (const_string "imov")
16900	      ]
16901	      (const_string "lea")))
16902   (set_attr "mode" "SI")])
16903
16904(define_insn "pro_epilogue_adjust_stack_rex64"
16905  [(set (match_operand:DI 0 "register_operand" "=r,r")
16906	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
16907		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16908   (clobber (reg:CC 17))
16909   (clobber (mem:BLK (scratch)))]
16910  "TARGET_64BIT"
16911{
16912  switch (get_attr_type (insn))
16913    {
16914    case TYPE_IMOV:
16915      return "mov{q}\t{%1, %0|%0, %1}";
16916
16917    case TYPE_ALU:
16918      if (GET_CODE (operands[2]) == CONST_INT
16919	  /* Avoid overflows.  */
16920	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16921          && (INTVAL (operands[2]) == 128
16922	      || (INTVAL (operands[2]) < 0
16923	          && INTVAL (operands[2]) != -128)))
16924	{
16925	  operands[2] = GEN_INT (-INTVAL (operands[2]));
16926	  return "sub{q}\t{%2, %0|%0, %2}";
16927	}
16928      return "add{q}\t{%2, %0|%0, %2}";
16929
16930    case TYPE_LEA:
16931      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16932      return "lea{q}\t{%a2, %0|%0, %a2}";
16933
16934    default:
16935      abort ();
16936    }
16937}
16938  [(set (attr "type")
16939	(cond [(eq_attr "alternative" "0")
16940		 (const_string "alu")
16941	       (match_operand:DI 2 "const0_operand" "")
16942		 (const_string "imov")
16943	      ]
16944	      (const_string "lea")))
16945   (set_attr "mode" "DI")])
16946
16947(define_insn "pro_epilogue_adjust_stack_rex64_2"
16948  [(set (match_operand:DI 0 "register_operand" "=r,r")
16949	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
16950		 (match_operand:DI 3 "immediate_operand" "i,i")))
16951   (use (match_operand:DI 2 "register_operand" "r,r"))
16952   (clobber (reg:CC 17))
16953   (clobber (mem:BLK (scratch)))]
16954  "TARGET_64BIT"
16955{
16956  switch (get_attr_type (insn))
16957    {
16958    case TYPE_ALU:
16959      return "add{q}\t{%2, %0|%0, %2}";
16960
16961    case TYPE_LEA:
16962      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16963      return "lea{q}\t{%a2, %0|%0, %a2}";
16964
16965    default:
16966      abort ();
16967    }
16968}
16969  [(set_attr "type" "alu,lea")
16970   (set_attr "mode" "DI")])
16971
16972;; Placeholder for the conditional moves.  This one is split either to SSE
16973;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
16974;; fact is that compares supported by the cmp??ss instructions are exactly
16975;; swapped of those supported by cmove sequence.
16976;; The EQ/NE comparisons also needs bit care, since they are not directly
16977;; supported by i387 comparisons and we do need to emit two conditional moves
16978;; in tandem.
16979
16980(define_insn "sse_movsfcc"
16981  [(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")
16982	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
16983			[(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")
16984			 (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")])
16985		      (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")
16986		      (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")))
16987   (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16988   (clobber (reg:CC 17))]
16989  "TARGET_SSE
16990   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16991   /* Avoid combine from being smart and converting min/max
16992      instruction patterns into conditional moves.  */
16993   && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16994	&& GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16995       || !rtx_equal_p (operands[4], operands[2])
16996       || !rtx_equal_p (operands[5], operands[3]))
16997   && (!TARGET_IEEE_FP
16998       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16999  "#")
17000
17001(define_insn "sse_movsfcc_eq"
17002  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17003	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17004			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17005		      (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17006		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17007   (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17008   (clobber (reg:CC 17))]
17009  "TARGET_SSE
17010   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17011  "#")
17012
17013(define_insn "sse_movdfcc"
17014  [(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")
17015	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17016			[(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")
17017			 (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")])
17018		      (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")
17019		      (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")))
17020   (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17021   (clobber (reg:CC 17))]
17022  "TARGET_SSE2
17023   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17024   /* Avoid combine from being smart and converting min/max
17025      instruction patterns into conditional moves.  */
17026   && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17027	&& GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17028       || !rtx_equal_p (operands[4], operands[2])
17029       || !rtx_equal_p (operands[5], operands[3]))
17030   && (!TARGET_IEEE_FP
17031       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17032  "#")
17033
17034(define_insn "sse_movdfcc_eq"
17035  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17036	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17037			     (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17038		      (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17039		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17040   (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17041   (clobber (reg:CC 17))]
17042  "TARGET_SSE
17043   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17044  "#")
17045
17046;; For non-sse moves just expand the usual cmove sequence.
17047(define_split
17048  [(set (match_operand 0 "register_operand" "")
17049	(if_then_else (match_operator 1 "comparison_operator"
17050			[(match_operand 4 "nonimmediate_operand" "")
17051			 (match_operand 5 "register_operand" "")])
17052		      (match_operand 2 "nonimmediate_operand" "")
17053		      (match_operand 3 "nonimmediate_operand" "")))
17054   (clobber (match_operand 6 "" ""))
17055   (clobber (reg:CC 17))]
17056  "!SSE_REG_P (operands[0]) && reload_completed
17057   && (GET_MODE (operands[0]) == SFmode
17058       || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
17059  [(const_int 0)]
17060{
17061   ix86_compare_op0 = operands[5];
17062   ix86_compare_op1 = operands[4];
17063   operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17064				 VOIDmode, operands[5], operands[4]);
17065   ix86_expand_fp_movcc (operands);
17066   DONE;
17067})
17068
17069;; Split SSE based conditional move into sequence:
17070;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
17071;; and   op2, op0   -  zero op2 if comparison was false
17072;; nand  op0, op3   -  load op3 to op0 if comparison was false
17073;; or	 op2, op0   -  get the nonzero one into the result.
17074(define_split
17075  [(set (match_operand:SF 0 "register_operand" "")
17076	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
17077			   [(match_operand:SF 4 "register_operand" "")
17078			    (match_operand:SF 5 "nonimmediate_operand" "")])
17079			 (match_operand:SF 2 "register_operand" "")
17080			 (match_operand:SF 3 "register_operand" "")))
17081   (clobber (match_operand 6 "" ""))
17082   (clobber (reg:CC 17))]
17083  "SSE_REG_P (operands[0]) && reload_completed"
17084  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17085   (set (match_dup 2) (and:V4SF (match_dup 2)
17086			        (match_dup 8)))
17087   (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17088				          (match_dup 3)))
17089   (set (match_dup 0) (ior:V4SF (match_dup 6)
17090			        (match_dup 7)))]
17091{
17092  /* If op2 == op3, op3 would be clobbered before it is used.  */
17093  if (operands_match_p (operands[2], operands[3]))
17094    {
17095      emit_move_insn (operands[0], operands[2]);
17096      DONE;
17097    }
17098
17099  PUT_MODE (operands[1], GET_MODE (operands[0]));
17100  if (operands_match_p (operands[0], operands[4]))
17101    operands[6] = operands[4], operands[7] = operands[2];
17102  else
17103    operands[6] = operands[2], operands[7] = operands[4];
17104  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17105  operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17106  operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17107  operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17108  operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17109  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17110})
17111
17112(define_split
17113  [(set (match_operand:DF 0 "register_operand" "")
17114	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17115			   [(match_operand:DF 4 "register_operand" "")
17116			    (match_operand:DF 5 "nonimmediate_operand" "")])
17117			 (match_operand:DF 2 "register_operand" "")
17118			 (match_operand:DF 3 "register_operand" "")))
17119   (clobber (match_operand 6 "" ""))
17120   (clobber (reg:CC 17))]
17121  "SSE_REG_P (operands[0]) && reload_completed"
17122  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17123   (set (match_dup 2) (and:V2DF (match_dup 2)
17124			        (match_dup 8)))
17125   (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17126				          (match_dup 3)))
17127   (set (match_dup 0) (ior:V2DF (match_dup 6)
17128			        (match_dup 7)))]
17129{
17130  if (GET_MODE (operands[2]) == DFmode
17131      && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17132    {
17133      rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17134      emit_insn (gen_sse2_unpcklpd (op, op, op));
17135      op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17136      emit_insn (gen_sse2_unpcklpd (op, op, op));
17137    }
17138
17139  /* If op2 == op3, op3 would be clobbered before it is used.  */
17140  if (operands_match_p (operands[2], operands[3]))
17141    {
17142      emit_move_insn (operands[0], operands[2]);
17143      DONE;
17144    }
17145
17146  PUT_MODE (operands[1], GET_MODE (operands[0]));
17147  if (operands_match_p (operands[0], operands[4]))
17148    operands[6] = operands[4], operands[7] = operands[2];
17149  else
17150    operands[6] = operands[2], operands[7] = operands[4];
17151  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17152  operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17153  operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17154  operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17155  operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17156  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17157})
17158
17159;; Special case of conditional move we can handle effectively.
17160;; Do not brother with the integer/floating point case, since these are
17161;; bot considerably slower, unlike in the generic case.
17162(define_insn "*sse_movsfcc_const0_1"
17163  [(set (match_operand:SF 0 "register_operand" "=&x")
17164	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
17165			[(match_operand:SF 4 "register_operand" "0")
17166			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17167		      (match_operand:SF 2 "register_operand" "x")
17168		      (match_operand:SF 3 "const0_operand" "X")))]
17169  "TARGET_SSE"
17170  "#")
17171
17172(define_insn "*sse_movsfcc_const0_2"
17173  [(set (match_operand:SF 0 "register_operand" "=&x")
17174	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
17175			[(match_operand:SF 4 "register_operand" "0")
17176			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17177		      (match_operand:SF 2 "const0_operand" "X")
17178		      (match_operand:SF 3 "register_operand" "x")))]
17179  "TARGET_SSE"
17180  "#")
17181
17182(define_insn "*sse_movsfcc_const0_3"
17183  [(set (match_operand:SF 0 "register_operand" "=&x")
17184	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17185			[(match_operand:SF 4 "nonimmediate_operand" "xm")
17186			 (match_operand:SF 5 "register_operand" "0")])
17187		      (match_operand:SF 2 "register_operand" "x")
17188		      (match_operand:SF 3 "const0_operand" "X")))]
17189  "TARGET_SSE"
17190  "#")
17191
17192(define_insn "*sse_movsfcc_const0_4"
17193  [(set (match_operand:SF 0 "register_operand" "=&x")
17194	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17195			[(match_operand:SF 4 "nonimmediate_operand" "xm")
17196			 (match_operand:SF 5 "register_operand" "0")])
17197		      (match_operand:SF 2 "const0_operand" "X")
17198		      (match_operand:SF 3 "register_operand" "x")))]
17199  "TARGET_SSE"
17200  "#")
17201
17202(define_insn "*sse_movdfcc_const0_1"
17203  [(set (match_operand:DF 0 "register_operand" "=&Y")
17204	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17205			[(match_operand:DF 4 "register_operand" "0")
17206			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17207		      (match_operand:DF 2 "register_operand" "Y")
17208		      (match_operand:DF 3 "const0_operand" "X")))]
17209  "TARGET_SSE2"
17210  "#")
17211
17212(define_insn "*sse_movdfcc_const0_2"
17213  [(set (match_operand:DF 0 "register_operand" "=&Y")
17214	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
17215			[(match_operand:DF 4 "register_operand" "0")
17216			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17217		      (match_operand:DF 2 "const0_operand" "X")
17218		      (match_operand:DF 3 "register_operand" "Y")))]
17219  "TARGET_SSE2"
17220  "#")
17221
17222(define_insn "*sse_movdfcc_const0_3"
17223  [(set (match_operand:DF 0 "register_operand" "=&Y")
17224	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17225			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
17226			 (match_operand:DF 5 "register_operand" "0")])
17227		      (match_operand:DF 2 "register_operand" "Y")
17228		      (match_operand:DF 3 "const0_operand" "X")))]
17229  "TARGET_SSE2"
17230  "#")
17231
17232(define_insn "*sse_movdfcc_const0_4"
17233  [(set (match_operand:DF 0 "register_operand" "=&Y")
17234	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17235			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
17236			 (match_operand:DF 5 "register_operand" "0")])
17237		      (match_operand:DF 2 "const0_operand" "X")
17238		      (match_operand:DF 3 "register_operand" "Y")))]
17239  "TARGET_SSE2"
17240  "#")
17241
17242(define_split
17243  [(set (match_operand:SF 0 "register_operand" "")
17244	(if_then_else:SF (match_operator 1 "comparison_operator"
17245			   [(match_operand:SF 4 "nonimmediate_operand" "")
17246			    (match_operand:SF 5 "nonimmediate_operand" "")])
17247			 (match_operand:SF 2 "nonmemory_operand" "")
17248			 (match_operand:SF 3 "nonmemory_operand" "")))]
17249  "SSE_REG_P (operands[0]) && reload_completed
17250   && (const0_operand (operands[2], GET_MODE (operands[0]))
17251       || const0_operand (operands[3], GET_MODE (operands[0])))"
17252  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17253   (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17254{
17255  PUT_MODE (operands[1], GET_MODE (operands[0]));
17256  if (!sse_comparison_operator (operands[1], VOIDmode)
17257      || !rtx_equal_p (operands[0], operands[4]))
17258    {
17259      rtx tmp = operands[5];
17260      operands[5] = operands[4];
17261      operands[4] = tmp;
17262      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17263    }
17264  if (!rtx_equal_p (operands[0], operands[4]))
17265    abort ();
17266  operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17267  if (const0_operand (operands[2], GET_MODE (operands[2])))
17268    {
17269      operands[7] = operands[3];
17270      operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17271    }
17272  else
17273    {
17274      operands[7] = operands[2];
17275      operands[6] = operands[8];
17276    }
17277  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17278})
17279
17280(define_split
17281  [(set (match_operand:DF 0 "register_operand" "")
17282	(if_then_else:DF (match_operator 1 "comparison_operator"
17283			   [(match_operand:DF 4 "nonimmediate_operand" "")
17284			    (match_operand:DF 5 "nonimmediate_operand" "")])
17285			 (match_operand:DF 2 "nonmemory_operand" "")
17286			 (match_operand:DF 3 "nonmemory_operand" "")))]
17287  "SSE_REG_P (operands[0]) && reload_completed
17288   && (const0_operand (operands[2], GET_MODE (operands[0]))
17289       || const0_operand (operands[3], GET_MODE (operands[0])))"
17290  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17291   (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17292{
17293  if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17294      && GET_MODE (operands[2]) == DFmode)
17295    {
17296      if (REG_P (operands[2]))
17297	{
17298	  rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17299	  emit_insn (gen_sse2_unpcklpd (op, op, op));
17300	}
17301      if (REG_P (operands[3]))
17302	{
17303	  rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17304	  emit_insn (gen_sse2_unpcklpd (op, op, op));
17305	}
17306    }
17307  PUT_MODE (operands[1], GET_MODE (operands[0]));
17308  if (!sse_comparison_operator (operands[1], VOIDmode)
17309      || !rtx_equal_p (operands[0], operands[4]))
17310    {
17311      rtx tmp = operands[5];
17312      operands[5] = operands[4];
17313      operands[4] = tmp;
17314      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17315    }
17316  if (!rtx_equal_p (operands[0], operands[4]))
17317    abort ();
17318  operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17319  if (const0_operand (operands[2], GET_MODE (operands[2])))
17320    {
17321      operands[7] = operands[3];
17322      operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17323    }
17324  else
17325    {
17326      operands[7] = operands[2];
17327      operands[6] = operands[8];
17328    }
17329  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17330})
17331
17332(define_expand "allocate_stack_worker"
17333  [(match_operand:SI 0 "register_operand" "")]
17334  "TARGET_STACK_PROBE"
17335{
17336  if (reload_completed)
17337    {
17338      if (TARGET_64BIT)
17339	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17340      else
17341	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17342    }
17343  else
17344    {
17345      if (TARGET_64BIT)
17346	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17347      else
17348	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17349    }
17350  DONE;
17351})
17352
17353(define_insn "allocate_stack_worker_1"
17354  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17355    UNSPECV_STACK_PROBE)
17356   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17357   (clobber (match_scratch:SI 1 "=0"))
17358   (clobber (reg:CC 17))]
17359  "!TARGET_64BIT && TARGET_STACK_PROBE"
17360  "call\t__alloca"
17361  [(set_attr "type" "multi")
17362   (set_attr "length" "5")])
17363
17364(define_expand "allocate_stack_worker_postreload"
17365  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17366				    UNSPECV_STACK_PROBE)
17367	      (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17368	      (clobber (match_dup 0))
17369	      (clobber (reg:CC 17))])]
17370  ""
17371  "")
17372
17373(define_insn "allocate_stack_worker_rex64"
17374  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17375    UNSPECV_STACK_PROBE)
17376   (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17377   (clobber (match_scratch:DI 1 "=0"))
17378   (clobber (reg:CC 17))]
17379  "TARGET_64BIT && TARGET_STACK_PROBE"
17380  "call\t__alloca"
17381  [(set_attr "type" "multi")
17382   (set_attr "length" "5")])
17383
17384(define_expand "allocate_stack_worker_rex64_postreload"
17385  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17386				    UNSPECV_STACK_PROBE)
17387	      (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17388	      (clobber (match_dup 0))
17389	      (clobber (reg:CC 17))])]
17390  ""
17391  "")
17392
17393(define_expand "allocate_stack"
17394  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17395		   (minus:SI (reg:SI 7)
17396			     (match_operand:SI 1 "general_operand" "")))
17397	      (clobber (reg:CC 17))])
17398   (parallel [(set (reg:SI 7)
17399		   (minus:SI (reg:SI 7) (match_dup 1)))
17400	      (clobber (reg:CC 17))])]
17401  "TARGET_STACK_PROBE"
17402{
17403#ifdef CHECK_STACK_LIMIT
17404  if (GET_CODE (operands[1]) == CONST_INT
17405      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17406    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17407			   operands[1]));
17408  else 
17409#endif
17410    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17411							    operands[1])));
17412
17413  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17414  DONE;
17415})
17416
17417(define_expand "builtin_setjmp_receiver"
17418  [(label_ref (match_operand 0 "" ""))]
17419  "!TARGET_64BIT && flag_pic"
17420{
17421  emit_insn (gen_set_got (pic_offset_table_rtx));
17422  DONE;
17423})
17424
17425;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17426
17427(define_split
17428  [(set (match_operand 0 "register_operand" "")
17429	(match_operator 3 "promotable_binary_operator"
17430	   [(match_operand 1 "register_operand" "")
17431	    (match_operand 2 "aligned_operand" "")]))
17432   (clobber (reg:CC 17))]
17433  "! TARGET_PARTIAL_REG_STALL && reload_completed
17434   && ((GET_MODE (operands[0]) == HImode 
17435	&& ((!optimize_size && !TARGET_FAST_PREFIX)
17436	    || GET_CODE (operands[2]) != CONST_INT
17437	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17438       || (GET_MODE (operands[0]) == QImode 
17439	   && (TARGET_PROMOTE_QImode || optimize_size)))"
17440  [(parallel [(set (match_dup 0)
17441		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17442	      (clobber (reg:CC 17))])]
17443  "operands[0] = gen_lowpart (SImode, operands[0]);
17444   operands[1] = gen_lowpart (SImode, operands[1]);
17445   if (GET_CODE (operands[3]) != ASHIFT)
17446     operands[2] = gen_lowpart (SImode, operands[2]);
17447   PUT_MODE (operands[3], SImode);")
17448
17449; Promote the QImode tests, as i386 has encoding of the AND
17450; instruction with 32-bit sign-extended immediate and thus the
17451; instruction size is unchanged, except in the %eax case for
17452; which it is increased by one byte, hence the ! optimize_size.
17453(define_split
17454  [(set (match_operand 0 "flags_reg_operand" "")
17455	(match_operator 2 "compare_operator"
17456	  [(and (match_operand 3 "aligned_operand" "")
17457		(match_operand 4 "const_int_operand" ""))
17458	   (const_int 0)]))
17459   (set (match_operand 1 "register_operand" "")
17460	(and (match_dup 3) (match_dup 4)))]
17461  "! TARGET_PARTIAL_REG_STALL && reload_completed
17462   /* Ensure that the operand will remain sign-extended immediate.  */
17463   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
17464   && ! optimize_size
17465   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17466       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
17467  [(parallel [(set (match_dup 0)
17468		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17469			            (const_int 0)]))
17470	      (set (match_dup 1)
17471		   (and:SI (match_dup 3) (match_dup 4)))])]
17472{
17473  operands[4]
17474    = gen_int_mode (INTVAL (operands[4])
17475		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17476  operands[1] = gen_lowpart (SImode, operands[1]);
17477  operands[3] = gen_lowpart (SImode, operands[3]);
17478})
17479
17480; Don't promote the QImode tests, as i386 doesn't have encoding of
17481; the TEST instruction with 32-bit sign-extended immediate and thus
17482; the instruction size would at least double, which is not what we
17483; want even with ! optimize_size.
17484(define_split
17485  [(set (match_operand 0 "flags_reg_operand" "")
17486	(match_operator 1 "compare_operator"
17487	  [(and (match_operand:HI 2 "aligned_operand" "")
17488		(match_operand:HI 3 "const_int_operand" ""))
17489	   (const_int 0)]))]
17490  "! TARGET_PARTIAL_REG_STALL && reload_completed
17491   /* Ensure that the operand will remain sign-extended immediate.  */
17492   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
17493   && ! TARGET_FAST_PREFIX
17494   && ! optimize_size"
17495  [(set (match_dup 0)
17496	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17497		         (const_int 0)]))]
17498{
17499  operands[3]
17500    = gen_int_mode (INTVAL (operands[3])
17501		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17502  operands[2] = gen_lowpart (SImode, operands[2]);
17503})
17504
17505(define_split
17506  [(set (match_operand 0 "register_operand" "")
17507	(neg (match_operand 1 "register_operand" "")))
17508   (clobber (reg:CC 17))]
17509  "! TARGET_PARTIAL_REG_STALL && reload_completed
17510   && (GET_MODE (operands[0]) == HImode
17511       || (GET_MODE (operands[0]) == QImode 
17512	   && (TARGET_PROMOTE_QImode || optimize_size)))"
17513  [(parallel [(set (match_dup 0)
17514		   (neg:SI (match_dup 1)))
17515	      (clobber (reg:CC 17))])]
17516  "operands[0] = gen_lowpart (SImode, operands[0]);
17517   operands[1] = gen_lowpart (SImode, operands[1]);")
17518
17519(define_split
17520  [(set (match_operand 0 "register_operand" "")
17521	(not (match_operand 1 "register_operand" "")))]
17522  "! TARGET_PARTIAL_REG_STALL && reload_completed
17523   && (GET_MODE (operands[0]) == HImode
17524       || (GET_MODE (operands[0]) == QImode 
17525	   && (TARGET_PROMOTE_QImode || optimize_size)))"
17526  [(set (match_dup 0)
17527	(not:SI (match_dup 1)))]
17528  "operands[0] = gen_lowpart (SImode, operands[0]);
17529   operands[1] = gen_lowpart (SImode, operands[1]);")
17530
17531(define_split 
17532  [(set (match_operand 0 "register_operand" "")
17533	(if_then_else (match_operator 1 "comparison_operator" 
17534				[(reg 17) (const_int 0)])
17535		      (match_operand 2 "register_operand" "")
17536		      (match_operand 3 "register_operand" "")))]
17537  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17538   && (GET_MODE (operands[0]) == HImode
17539       || (GET_MODE (operands[0]) == QImode 
17540	   && (TARGET_PROMOTE_QImode || optimize_size)))"
17541  [(set (match_dup 0)
17542	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17543  "operands[0] = gen_lowpart (SImode, operands[0]);
17544   operands[2] = gen_lowpart (SImode, operands[2]);
17545   operands[3] = gen_lowpart (SImode, operands[3]);")
17546			
17547
17548;; RTL Peephole optimizations, run before sched2.  These primarily look to
17549;; transform a complex memory operation into two memory to register operations.
17550
17551;; Don't push memory operands
17552(define_peephole2
17553  [(set (match_operand:SI 0 "push_operand" "")
17554	(match_operand:SI 1 "memory_operand" ""))
17555   (match_scratch:SI 2 "r")]
17556  "! optimize_size && ! TARGET_PUSH_MEMORY"
17557  [(set (match_dup 2) (match_dup 1))
17558   (set (match_dup 0) (match_dup 2))]
17559  "")
17560
17561(define_peephole2
17562  [(set (match_operand:DI 0 "push_operand" "")
17563	(match_operand:DI 1 "memory_operand" ""))
17564   (match_scratch:DI 2 "r")]
17565  "! optimize_size && ! TARGET_PUSH_MEMORY"
17566  [(set (match_dup 2) (match_dup 1))
17567   (set (match_dup 0) (match_dup 2))]
17568  "")
17569
17570;; We need to handle SFmode only, because DFmode and XFmode is split to
17571;; SImode pushes.
17572(define_peephole2
17573  [(set (match_operand:SF 0 "push_operand" "")
17574	(match_operand:SF 1 "memory_operand" ""))
17575   (match_scratch:SF 2 "r")]
17576  "! optimize_size && ! TARGET_PUSH_MEMORY"
17577  [(set (match_dup 2) (match_dup 1))
17578   (set (match_dup 0) (match_dup 2))]
17579  "")
17580
17581(define_peephole2
17582  [(set (match_operand:HI 0 "push_operand" "")
17583	(match_operand:HI 1 "memory_operand" ""))
17584   (match_scratch:HI 2 "r")]
17585  "! optimize_size && ! TARGET_PUSH_MEMORY"
17586  [(set (match_dup 2) (match_dup 1))
17587   (set (match_dup 0) (match_dup 2))]
17588  "")
17589
17590(define_peephole2
17591  [(set (match_operand:QI 0 "push_operand" "")
17592	(match_operand:QI 1 "memory_operand" ""))
17593   (match_scratch:QI 2 "q")]
17594  "! optimize_size && ! TARGET_PUSH_MEMORY"
17595  [(set (match_dup 2) (match_dup 1))
17596   (set (match_dup 0) (match_dup 2))]
17597  "")
17598
17599;; Don't move an immediate directly to memory when the instruction
17600;; gets too big.
17601(define_peephole2
17602  [(match_scratch:SI 1 "r")
17603   (set (match_operand:SI 0 "memory_operand" "")
17604        (const_int 0))]
17605  "! optimize_size
17606   && ! TARGET_USE_MOV0
17607   && TARGET_SPLIT_LONG_MOVES
17608   && get_attr_length (insn) >= ix86_cost->large_insn
17609   && peep2_regno_dead_p (0, FLAGS_REG)"
17610  [(parallel [(set (match_dup 1) (const_int 0))
17611	      (clobber (reg:CC 17))])
17612   (set (match_dup 0) (match_dup 1))]
17613  "")
17614
17615(define_peephole2
17616  [(match_scratch:HI 1 "r")
17617   (set (match_operand:HI 0 "memory_operand" "")
17618        (const_int 0))]
17619  "! optimize_size
17620   && ! TARGET_USE_MOV0
17621   && TARGET_SPLIT_LONG_MOVES
17622   && get_attr_length (insn) >= ix86_cost->large_insn
17623   && peep2_regno_dead_p (0, FLAGS_REG)"
17624  [(parallel [(set (match_dup 2) (const_int 0))
17625	      (clobber (reg:CC 17))])
17626   (set (match_dup 0) (match_dup 1))]
17627  "operands[2] = gen_lowpart (SImode, operands[1]);")
17628
17629(define_peephole2
17630  [(match_scratch:QI 1 "q")
17631   (set (match_operand:QI 0 "memory_operand" "")
17632        (const_int 0))]
17633  "! optimize_size
17634   && ! TARGET_USE_MOV0
17635   && TARGET_SPLIT_LONG_MOVES
17636   && get_attr_length (insn) >= ix86_cost->large_insn
17637   && peep2_regno_dead_p (0, FLAGS_REG)"
17638  [(parallel [(set (match_dup 2) (const_int 0))
17639	      (clobber (reg:CC 17))])
17640   (set (match_dup 0) (match_dup 1))]
17641  "operands[2] = gen_lowpart (SImode, operands[1]);")
17642
17643(define_peephole2
17644  [(match_scratch:SI 2 "r")
17645   (set (match_operand:SI 0 "memory_operand" "")
17646        (match_operand:SI 1 "immediate_operand" ""))]
17647  "! optimize_size
17648   && get_attr_length (insn) >= ix86_cost->large_insn
17649   && TARGET_SPLIT_LONG_MOVES"
17650  [(set (match_dup 2) (match_dup 1))
17651   (set (match_dup 0) (match_dup 2))]
17652  "")
17653
17654(define_peephole2
17655  [(match_scratch:HI 2 "r")
17656   (set (match_operand:HI 0 "memory_operand" "")
17657        (match_operand:HI 1 "immediate_operand" ""))]
17658  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17659  && TARGET_SPLIT_LONG_MOVES"
17660  [(set (match_dup 2) (match_dup 1))
17661   (set (match_dup 0) (match_dup 2))]
17662  "")
17663
17664(define_peephole2
17665  [(match_scratch:QI 2 "q")
17666   (set (match_operand:QI 0 "memory_operand" "")
17667        (match_operand:QI 1 "immediate_operand" ""))]
17668  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17669  && TARGET_SPLIT_LONG_MOVES"
17670  [(set (match_dup 2) (match_dup 1))
17671   (set (match_dup 0) (match_dup 2))]
17672  "")
17673
17674;; Don't compare memory with zero, load and use a test instead.
17675(define_peephole2
17676  [(set (match_operand 0 "flags_reg_operand" "")
17677 	(match_operator 1 "compare_operator"
17678	  [(match_operand:SI 2 "memory_operand" "")
17679	   (const_int 0)]))
17680   (match_scratch:SI 3 "r")]
17681  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17682  [(set (match_dup 3) (match_dup 2))
17683   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17684  "")
17685
17686;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
17687;; Don't split NOTs with a displacement operand, because resulting XOR
17688;; will not be pairable anyway.
17689;;
17690;; On AMD K6, NOT is vector decoded with memory operand that can not be
17691;; represented using a modRM byte.  The XOR replacement is long decoded,
17692;; so this split helps here as well.
17693;;
17694;; Note: Can't do this as a regular split because we can't get proper
17695;; lifetime information then.
17696
17697(define_peephole2
17698  [(set (match_operand:SI 0 "nonimmediate_operand" "")
17699	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17700  "!optimize_size
17701   && peep2_regno_dead_p (0, FLAGS_REG)
17702   && ((TARGET_PENTIUM 
17703        && (GET_CODE (operands[0]) != MEM
17704            || !memory_displacement_operand (operands[0], SImode)))
17705       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17706  [(parallel [(set (match_dup 0)
17707		   (xor:SI (match_dup 1) (const_int -1)))
17708	      (clobber (reg:CC 17))])]
17709  "")
17710
17711(define_peephole2
17712  [(set (match_operand:HI 0 "nonimmediate_operand" "")
17713	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17714  "!optimize_size
17715   && peep2_regno_dead_p (0, FLAGS_REG)
17716   && ((TARGET_PENTIUM 
17717        && (GET_CODE (operands[0]) != MEM
17718            || !memory_displacement_operand (operands[0], HImode)))
17719       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17720  [(parallel [(set (match_dup 0)
17721		   (xor:HI (match_dup 1) (const_int -1)))
17722	      (clobber (reg:CC 17))])]
17723  "")
17724
17725(define_peephole2
17726  [(set (match_operand:QI 0 "nonimmediate_operand" "")
17727	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17728  "!optimize_size
17729   && peep2_regno_dead_p (0, FLAGS_REG)
17730   && ((TARGET_PENTIUM 
17731        && (GET_CODE (operands[0]) != MEM
17732            || !memory_displacement_operand (operands[0], QImode)))
17733       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17734  [(parallel [(set (match_dup 0)
17735		   (xor:QI (match_dup 1) (const_int -1)))
17736	      (clobber (reg:CC 17))])]
17737  "")
17738
17739;; Non pairable "test imm, reg" instructions can be translated to
17740;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17741;; byte opcode instead of two, have a short form for byte operands),
17742;; so do it for other CPUs as well.  Given that the value was dead,
17743;; this should not create any new dependencies.  Pass on the sub-word
17744;; versions if we're concerned about partial register stalls.
17745
17746(define_peephole2
17747  [(set (match_operand 0 "flags_reg_operand" "")
17748	(match_operator 1 "compare_operator"
17749	  [(and:SI (match_operand:SI 2 "register_operand" "")
17750		   (match_operand:SI 3 "immediate_operand" ""))
17751	   (const_int 0)]))]
17752  "ix86_match_ccmode (insn, CCNOmode)
17753   && (true_regnum (operands[2]) != 0
17754       || (GET_CODE (operands[3]) == CONST_INT
17755	   && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
17756   && peep2_reg_dead_p (1, operands[2])"
17757  [(parallel
17758     [(set (match_dup 0)
17759	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17760		            (const_int 0)]))
17761      (set (match_dup 2)
17762	   (and:SI (match_dup 2) (match_dup 3)))])]
17763  "")
17764
17765;; We don't need to handle HImode case, because it will be promoted to SImode
17766;; on ! TARGET_PARTIAL_REG_STALL
17767
17768(define_peephole2
17769  [(set (match_operand 0 "flags_reg_operand" "")
17770	(match_operator 1 "compare_operator"
17771	  [(and:QI (match_operand:QI 2 "register_operand" "")
17772		   (match_operand:QI 3 "immediate_operand" ""))
17773	   (const_int 0)]))]
17774  "! TARGET_PARTIAL_REG_STALL
17775   && ix86_match_ccmode (insn, CCNOmode)
17776   && true_regnum (operands[2]) != 0
17777   && peep2_reg_dead_p (1, operands[2])"
17778  [(parallel
17779     [(set (match_dup 0)
17780	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17781		            (const_int 0)]))
17782      (set (match_dup 2)
17783	   (and:QI (match_dup 2) (match_dup 3)))])]
17784  "")
17785
17786(define_peephole2
17787  [(set (match_operand 0 "flags_reg_operand" "")
17788	(match_operator 1 "compare_operator"
17789	  [(and:SI
17790	     (zero_extract:SI
17791	       (match_operand 2 "ext_register_operand" "")
17792	       (const_int 8)
17793	       (const_int 8))
17794	     (match_operand 3 "const_int_operand" ""))
17795	   (const_int 0)]))]
17796  "! TARGET_PARTIAL_REG_STALL
17797   && ix86_match_ccmode (insn, CCNOmode)
17798   && true_regnum (operands[2]) != 0
17799   && peep2_reg_dead_p (1, operands[2])"
17800  [(parallel [(set (match_dup 0)
17801		   (match_op_dup 1
17802		     [(and:SI
17803			(zero_extract:SI
17804			  (match_dup 2)
17805			  (const_int 8)
17806			  (const_int 8))
17807			(match_dup 3))
17808		      (const_int 0)]))
17809	      (set (zero_extract:SI (match_dup 2)
17810				    (const_int 8)
17811				    (const_int 8))
17812		   (and:SI 
17813		     (zero_extract:SI
17814		       (match_dup 2)
17815		       (const_int 8)
17816		       (const_int 8))
17817		     (match_dup 3)))])]
17818  "")
17819
17820;; Don't do logical operations with memory inputs.
17821(define_peephole2
17822  [(match_scratch:SI 2 "r")
17823   (parallel [(set (match_operand:SI 0 "register_operand" "")
17824                   (match_operator:SI 3 "arith_or_logical_operator"
17825                     [(match_dup 0)
17826                      (match_operand:SI 1 "memory_operand" "")]))
17827              (clobber (reg:CC 17))])]
17828  "! optimize_size && ! TARGET_READ_MODIFY"
17829  [(set (match_dup 2) (match_dup 1))
17830   (parallel [(set (match_dup 0)
17831                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17832              (clobber (reg:CC 17))])]
17833  "")
17834
17835(define_peephole2
17836  [(match_scratch:SI 2 "r")
17837   (parallel [(set (match_operand:SI 0 "register_operand" "")
17838                   (match_operator:SI 3 "arith_or_logical_operator"
17839                     [(match_operand:SI 1 "memory_operand" "")
17840                      (match_dup 0)]))
17841              (clobber (reg:CC 17))])]
17842  "! optimize_size && ! TARGET_READ_MODIFY"
17843  [(set (match_dup 2) (match_dup 1))
17844   (parallel [(set (match_dup 0)
17845                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17846              (clobber (reg:CC 17))])]
17847  "")
17848
17849; Don't do logical operations with memory outputs
17850;
17851; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17852; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17853; the same decoder scheduling characteristics as the original.
17854
17855(define_peephole2
17856  [(match_scratch:SI 2 "r")
17857   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17858                   (match_operator:SI 3 "arith_or_logical_operator"
17859                     [(match_dup 0)
17860                      (match_operand:SI 1 "nonmemory_operand" "")]))
17861              (clobber (reg:CC 17))])]
17862  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17863  [(set (match_dup 2) (match_dup 0))
17864   (parallel [(set (match_dup 2)
17865                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17866              (clobber (reg:CC 17))])
17867   (set (match_dup 0) (match_dup 2))]
17868  "")
17869
17870(define_peephole2
17871  [(match_scratch:SI 2 "r")
17872   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17873                   (match_operator:SI 3 "arith_or_logical_operator"
17874                     [(match_operand:SI 1 "nonmemory_operand" "")
17875                      (match_dup 0)]))
17876              (clobber (reg:CC 17))])]
17877  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17878  [(set (match_dup 2) (match_dup 0))
17879   (parallel [(set (match_dup 2)
17880                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17881              (clobber (reg:CC 17))])
17882   (set (match_dup 0) (match_dup 2))]
17883  "")
17884
17885;; Attempt to always use XOR for zeroing registers.
17886(define_peephole2
17887  [(set (match_operand 0 "register_operand" "")
17888	(const_int 0))]
17889  "(GET_MODE (operands[0]) == QImode
17890    || GET_MODE (operands[0]) == HImode
17891    || GET_MODE (operands[0]) == SImode
17892    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17893   && (! TARGET_USE_MOV0 || optimize_size)
17894   && peep2_regno_dead_p (0, FLAGS_REG)"
17895  [(parallel [(set (match_dup 0) (const_int 0))
17896	      (clobber (reg:CC 17))])]
17897  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17898			      operands[0]);")
17899
17900(define_peephole2
17901  [(set (strict_low_part (match_operand 0 "register_operand" ""))
17902	(const_int 0))]
17903  "(GET_MODE (operands[0]) == QImode
17904    || GET_MODE (operands[0]) == HImode)
17905   && (! TARGET_USE_MOV0 || optimize_size)
17906   && peep2_regno_dead_p (0, FLAGS_REG)"
17907  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17908	      (clobber (reg:CC 17))])])
17909
17910;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17911(define_peephole2
17912  [(set (match_operand 0 "register_operand" "")
17913	(const_int -1))]
17914  "(GET_MODE (operands[0]) == HImode
17915    || GET_MODE (operands[0]) == SImode 
17916    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17917   && (optimize_size || TARGET_PENTIUM)
17918   && peep2_regno_dead_p (0, FLAGS_REG)"
17919  [(parallel [(set (match_dup 0) (const_int -1))
17920	      (clobber (reg:CC 17))])]
17921  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17922			      operands[0]);")
17923
17924;; Attempt to convert simple leas to adds. These can be created by
17925;; move expanders.
17926(define_peephole2
17927  [(set (match_operand:SI 0 "register_operand" "")
17928  	(plus:SI (match_dup 0)
17929		 (match_operand:SI 1 "nonmemory_operand" "")))]
17930  "peep2_regno_dead_p (0, FLAGS_REG)"
17931  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17932	      (clobber (reg:CC 17))])]
17933  "")
17934
17935(define_peephole2
17936  [(set (match_operand:SI 0 "register_operand" "")
17937  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17938			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17939  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17940  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17941	      (clobber (reg:CC 17))])]
17942  "operands[2] = gen_lowpart (SImode, operands[2]);")
17943
17944(define_peephole2
17945  [(set (match_operand:DI 0 "register_operand" "")
17946  	(plus:DI (match_dup 0)
17947		 (match_operand:DI 1 "x86_64_general_operand" "")))]
17948  "peep2_regno_dead_p (0, FLAGS_REG)"
17949  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17950	      (clobber (reg:CC 17))])]
17951  "")
17952
17953(define_peephole2
17954  [(set (match_operand:SI 0 "register_operand" "")
17955  	(mult:SI (match_dup 0)
17956		 (match_operand:SI 1 "const_int_operand" "")))]
17957  "exact_log2 (INTVAL (operands[1])) >= 0
17958   && peep2_regno_dead_p (0, FLAGS_REG)"
17959  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17960	      (clobber (reg:CC 17))])]
17961  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17962
17963(define_peephole2
17964  [(set (match_operand:DI 0 "register_operand" "")
17965  	(mult:DI (match_dup 0)
17966		 (match_operand:DI 1 "const_int_operand" "")))]
17967  "exact_log2 (INTVAL (operands[1])) >= 0
17968   && peep2_regno_dead_p (0, FLAGS_REG)"
17969  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17970	      (clobber (reg:CC 17))])]
17971  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17972
17973(define_peephole2
17974  [(set (match_operand:SI 0 "register_operand" "")
17975  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17976		   (match_operand:DI 2 "const_int_operand" "")) 0))]
17977  "exact_log2 (INTVAL (operands[2])) >= 0
17978   && REGNO (operands[0]) == REGNO (operands[1])
17979   && peep2_regno_dead_p (0, FLAGS_REG)"
17980  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17981	      (clobber (reg:CC 17))])]
17982  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17983
17984;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17985;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17986;; many CPUs it is also faster, since special hardware to avoid esp
17987;; dependencies is present.
17988
17989;; While some of these conversions may be done using splitters, we use peepholes
17990;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17991
17992;; Convert prologue esp subtractions to push.
17993;; We need register to push.  In order to keep verify_flow_info happy we have
17994;; two choices
17995;; - use scratch and clobber it in order to avoid dependencies
17996;; - use already live register
17997;; We can't use the second way right now, since there is no reliable way how to
17998;; verify that given register is live.  First choice will also most likely in
17999;; fewer dependencies.  On the place of esp adjustments it is very likely that
18000;; call clobbered registers are dead.  We may want to use base pointer as an
18001;; alternative when no register is available later.
18002
18003(define_peephole2
18004  [(match_scratch:SI 0 "r")
18005   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18006	      (clobber (reg:CC 17))
18007	      (clobber (mem:BLK (scratch)))])]
18008  "optimize_size || !TARGET_SUB_ESP_4"
18009  [(clobber (match_dup 0))
18010   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18011	      (clobber (mem:BLK (scratch)))])])
18012
18013(define_peephole2
18014  [(match_scratch:SI 0 "r")
18015   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18016	      (clobber (reg:CC 17))
18017	      (clobber (mem:BLK (scratch)))])]
18018  "optimize_size || !TARGET_SUB_ESP_8"
18019  [(clobber (match_dup 0))
18020   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18021   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18022	      (clobber (mem:BLK (scratch)))])])
18023
18024;; Convert esp subtractions to push.
18025(define_peephole2
18026  [(match_scratch:SI 0 "r")
18027   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18028	      (clobber (reg:CC 17))])]
18029  "optimize_size || !TARGET_SUB_ESP_4"
18030  [(clobber (match_dup 0))
18031   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18032
18033(define_peephole2
18034  [(match_scratch:SI 0 "r")
18035   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18036	      (clobber (reg:CC 17))])]
18037  "optimize_size || !TARGET_SUB_ESP_8"
18038  [(clobber (match_dup 0))
18039   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18040   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18041
18042;; Convert epilogue deallocator to pop.
18043(define_peephole2
18044  [(match_scratch:SI 0 "r")
18045   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18046	      (clobber (reg:CC 17))
18047	      (clobber (mem:BLK (scratch)))])]
18048  "optimize_size || !TARGET_ADD_ESP_4"
18049  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18050	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18051	      (clobber (mem:BLK (scratch)))])]
18052  "")
18053
18054;; Two pops case is tricky, since pop causes dependency on destination register.
18055;; We use two registers if available.
18056(define_peephole2
18057  [(match_scratch:SI 0 "r")
18058   (match_scratch:SI 1 "r")
18059   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18060	      (clobber (reg:CC 17))
18061	      (clobber (mem:BLK (scratch)))])]
18062  "optimize_size || !TARGET_ADD_ESP_8"
18063  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18064	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18065	      (clobber (mem:BLK (scratch)))])
18066   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18067	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18068  "")
18069
18070(define_peephole2
18071  [(match_scratch:SI 0 "r")
18072   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18073	      (clobber (reg:CC 17))
18074	      (clobber (mem:BLK (scratch)))])]
18075  "optimize_size"
18076  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18077	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18078	      (clobber (mem:BLK (scratch)))])
18079   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18080	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18081  "")
18082
18083;; Convert esp additions to pop.
18084(define_peephole2
18085  [(match_scratch:SI 0 "r")
18086   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18087	      (clobber (reg:CC 17))])]
18088  ""
18089  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18090	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18091  "")
18092
18093;; Two pops case is tricky, since pop causes dependency on destination register.
18094;; We use two registers if available.
18095(define_peephole2
18096  [(match_scratch:SI 0 "r")
18097   (match_scratch:SI 1 "r")
18098   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18099	      (clobber (reg:CC 17))])]
18100  ""
18101  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18102	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18103   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18104	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18105  "")
18106
18107(define_peephole2
18108  [(match_scratch:SI 0 "r")
18109   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18110	      (clobber (reg:CC 17))])]
18111  "optimize_size"
18112  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18113	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18114   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18115	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18116  "")
18117
18118;; Convert compares with 1 to shorter inc/dec operations when CF is not
18119;; required and register dies.  Similarly for 128 to plus -128.
18120(define_peephole2
18121  [(set (match_operand 0 "flags_reg_operand" "")
18122	(match_operator 1 "compare_operator"
18123	  [(match_operand 2 "register_operand" "")
18124	   (match_operand 3 "const_int_operand" "")]))]
18125  "(INTVAL (operands[3]) == -1
18126    || INTVAL (operands[3]) == 1
18127    || INTVAL (operands[3]) == 128)
18128   && ix86_match_ccmode (insn, CCGCmode)
18129   && peep2_reg_dead_p (1, operands[2])"
18130  [(parallel [(set (match_dup 0)
18131		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18132	      (clobber (match_dup 2))])]
18133  "")
18134
18135(define_peephole2
18136  [(match_scratch:DI 0 "r")
18137   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18138	      (clobber (reg:CC 17))
18139	      (clobber (mem:BLK (scratch)))])]
18140  "optimize_size || !TARGET_SUB_ESP_4"
18141  [(clobber (match_dup 0))
18142   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18143	      (clobber (mem:BLK (scratch)))])])
18144
18145(define_peephole2
18146  [(match_scratch:DI 0 "r")
18147   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18148	      (clobber (reg:CC 17))
18149	      (clobber (mem:BLK (scratch)))])]
18150  "optimize_size || !TARGET_SUB_ESP_8"
18151  [(clobber (match_dup 0))
18152   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18153   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18154	      (clobber (mem:BLK (scratch)))])])
18155
18156;; Convert esp subtractions to push.
18157(define_peephole2
18158  [(match_scratch:DI 0 "r")
18159   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18160	      (clobber (reg:CC 17))])]
18161  "optimize_size || !TARGET_SUB_ESP_4"
18162  [(clobber (match_dup 0))
18163   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18164
18165(define_peephole2
18166  [(match_scratch:DI 0 "r")
18167   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18168	      (clobber (reg:CC 17))])]
18169  "optimize_size || !TARGET_SUB_ESP_8"
18170  [(clobber (match_dup 0))
18171   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18172   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18173
18174;; Convert epilogue deallocator to pop.
18175(define_peephole2
18176  [(match_scratch:DI 0 "r")
18177   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18178	      (clobber (reg:CC 17))
18179	      (clobber (mem:BLK (scratch)))])]
18180  "optimize_size || !TARGET_ADD_ESP_4"
18181  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18182	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18183	      (clobber (mem:BLK (scratch)))])]
18184  "")
18185
18186;; Two pops case is tricky, since pop causes dependency on destination register.
18187;; We use two registers if available.
18188(define_peephole2
18189  [(match_scratch:DI 0 "r")
18190   (match_scratch:DI 1 "r")
18191   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18192	      (clobber (reg:CC 17))
18193	      (clobber (mem:BLK (scratch)))])]
18194  "optimize_size || !TARGET_ADD_ESP_8"
18195  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18196	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18197	      (clobber (mem:BLK (scratch)))])
18198   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18199	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18200  "")
18201
18202(define_peephole2
18203  [(match_scratch:DI 0 "r")
18204   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18205	      (clobber (reg:CC 17))
18206	      (clobber (mem:BLK (scratch)))])]
18207  "optimize_size"
18208  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18209	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18210	      (clobber (mem:BLK (scratch)))])
18211   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18212	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18213  "")
18214
18215;; Convert esp additions to pop.
18216(define_peephole2
18217  [(match_scratch:DI 0 "r")
18218   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18219	      (clobber (reg:CC 17))])]
18220  ""
18221  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18222	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18223  "")
18224
18225;; Two pops case is tricky, since pop causes dependency on destination register.
18226;; We use two registers if available.
18227(define_peephole2
18228  [(match_scratch:DI 0 "r")
18229   (match_scratch:DI 1 "r")
18230   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18231	      (clobber (reg:CC 17))])]
18232  ""
18233  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18234	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18235   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18236	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18237  "")
18238
18239(define_peephole2
18240  [(match_scratch:DI 0 "r")
18241   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18242	      (clobber (reg:CC 17))])]
18243  "optimize_size"
18244  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18245	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18246   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18247	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18248  "")
18249
18250;; Imul $32bit_imm, mem, reg is vector decoded, while
18251;; imul $32bit_imm, reg, reg is direct decoded.
18252(define_peephole2
18253  [(match_scratch:DI 3 "r")
18254   (parallel [(set (match_operand:DI 0 "register_operand" "")
18255		   (mult:DI (match_operand:DI 1 "memory_operand" "")
18256			    (match_operand:DI 2 "immediate_operand" "")))
18257	      (clobber (reg:CC 17))])]
18258  "TARGET_K8 && !optimize_size
18259   && (GET_CODE (operands[2]) != CONST_INT
18260       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18261  [(set (match_dup 3) (match_dup 1))
18262   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18263	      (clobber (reg:CC 17))])]
18264"")
18265
18266(define_peephole2
18267  [(match_scratch:SI 3 "r")
18268   (parallel [(set (match_operand:SI 0 "register_operand" "")
18269		   (mult:SI (match_operand:SI 1 "memory_operand" "")
18270			    (match_operand:SI 2 "immediate_operand" "")))
18271	      (clobber (reg:CC 17))])]
18272  "TARGET_K8 && !optimize_size
18273   && (GET_CODE (operands[2]) != CONST_INT
18274       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18275  [(set (match_dup 3) (match_dup 1))
18276   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18277	      (clobber (reg:CC 17))])]
18278"")
18279
18280(define_peephole2
18281  [(match_scratch:SI 3 "r")
18282   (parallel [(set (match_operand:DI 0 "register_operand" "")
18283		   (zero_extend:DI
18284		     (mult:SI (match_operand:SI 1 "memory_operand" "")
18285			      (match_operand:SI 2 "immediate_operand" ""))))
18286	      (clobber (reg:CC 17))])]
18287  "TARGET_K8 && !optimize_size
18288   && (GET_CODE (operands[2]) != CONST_INT
18289       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18290  [(set (match_dup 3) (match_dup 1))
18291   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18292	      (clobber (reg:CC 17))])]
18293"")
18294
18295;; imul $8/16bit_imm, regmem, reg is vector decoded.
18296;; Convert it into imul reg, reg
18297;; It would be better to force assembler to encode instruction using long
18298;; immediate, but there is apparently no way to do so.
18299(define_peephole2
18300  [(parallel [(set (match_operand:DI 0 "register_operand" "")
18301		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18302			    (match_operand:DI 2 "const_int_operand" "")))
18303	      (clobber (reg:CC 17))])
18304   (match_scratch:DI 3 "r")]
18305  "TARGET_K8 && !optimize_size
18306   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18307  [(set (match_dup 3) (match_dup 2))
18308   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18309	      (clobber (reg:CC 17))])]
18310{
18311  if (!rtx_equal_p (operands[0], operands[1]))
18312    emit_move_insn (operands[0], operands[1]);
18313})
18314
18315(define_peephole2
18316  [(parallel [(set (match_operand:SI 0 "register_operand" "")
18317		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18318			    (match_operand:SI 2 "const_int_operand" "")))
18319	      (clobber (reg:CC 17))])
18320   (match_scratch:SI 3 "r")]
18321  "TARGET_K8 && !optimize_size
18322   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18323  [(set (match_dup 3) (match_dup 2))
18324   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18325	      (clobber (reg:CC 17))])]
18326{
18327  if (!rtx_equal_p (operands[0], operands[1]))
18328    emit_move_insn (operands[0], operands[1]);
18329})
18330
18331(define_peephole2
18332  [(parallel [(set (match_operand:HI 0 "register_operand" "")
18333		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18334			    (match_operand:HI 2 "immediate_operand" "")))
18335	      (clobber (reg:CC 17))])
18336   (match_scratch:HI 3 "r")]
18337  "TARGET_K8 && !optimize_size"
18338  [(set (match_dup 3) (match_dup 2))
18339   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18340	      (clobber (reg:CC 17))])]
18341{
18342  if (!rtx_equal_p (operands[0], operands[1]))
18343    emit_move_insn (operands[0], operands[1]);
18344})
18345
18346;; Call-value patterns last so that the wildcard operand does not
18347;; disrupt insn-recog's switch tables.
18348
18349(define_insn "*call_value_pop_0"
18350  [(set (match_operand 0 "" "")
18351	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18352	      (match_operand:SI 2 "" "")))
18353   (set (reg:SI 7) (plus:SI (reg:SI 7)
18354			    (match_operand:SI 3 "immediate_operand" "")))]
18355  "!TARGET_64BIT"
18356{
18357  if (SIBLING_CALL_P (insn))
18358    return "jmp\t%P1";
18359  else
18360    return "call\t%P1";
18361}
18362  [(set_attr "type" "callv")])
18363
18364(define_insn "*call_value_pop_1"
18365  [(set (match_operand 0 "" "")
18366	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18367	      (match_operand:SI 2 "" "")))
18368   (set (reg:SI 7) (plus:SI (reg:SI 7)
18369			    (match_operand:SI 3 "immediate_operand" "i")))]
18370  "!TARGET_64BIT"
18371{
18372  if (constant_call_address_operand (operands[1], QImode))
18373    {
18374      if (SIBLING_CALL_P (insn))
18375	return "jmp\t%P1";
18376      else
18377	return "call\t%P1";
18378    }
18379  if (SIBLING_CALL_P (insn))
18380    return "jmp\t%A1";
18381  else
18382    return "call\t%A1";
18383}
18384  [(set_attr "type" "callv")])
18385
18386(define_insn "*call_value_0"
18387  [(set (match_operand 0 "" "")
18388	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18389	      (match_operand:SI 2 "" "")))]
18390  "!TARGET_64BIT"
18391{
18392  if (SIBLING_CALL_P (insn))
18393    return "jmp\t%P1";
18394  else
18395    return "call\t%P1";
18396}
18397  [(set_attr "type" "callv")])
18398
18399(define_insn "*call_value_0_rex64"
18400  [(set (match_operand 0 "" "")
18401	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18402	      (match_operand:DI 2 "const_int_operand" "")))]
18403  "TARGET_64BIT"
18404{
18405  if (SIBLING_CALL_P (insn))
18406    return "jmp\t%P1";
18407  else
18408    return "call\t%P1";
18409}
18410  [(set_attr "type" "callv")])
18411
18412(define_insn "*call_value_1"
18413  [(set (match_operand 0 "" "")
18414	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18415	      (match_operand:SI 2 "" "")))]
18416  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18417{
18418  if (constant_call_address_operand (operands[1], QImode))
18419    return "call\t%P1";
18420  return "call\t%A1";
18421}
18422  [(set_attr "type" "callv")])
18423
18424(define_insn "*sibcall_value_1"
18425  [(set (match_operand 0 "" "")
18426	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18427	      (match_operand:SI 2 "" "")))]
18428  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18429{
18430  if (constant_call_address_operand (operands[1], QImode))
18431    return "jmp\t%P1";
18432  return "jmp\t%A1";
18433}
18434  [(set_attr "type" "callv")])
18435
18436(define_insn "*call_value_1_rex64"
18437  [(set (match_operand 0 "" "")
18438	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18439	      (match_operand:DI 2 "" "")))]
18440  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18441{
18442  if (constant_call_address_operand (operands[1], QImode))
18443    return "call\t%P1";
18444  return "call\t%A1";
18445}
18446  [(set_attr "type" "callv")])
18447
18448(define_insn "*sibcall_value_1_rex64"
18449  [(set (match_operand 0 "" "")
18450	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18451	      (match_operand:DI 2 "" "")))]
18452  "SIBLING_CALL_P (insn) && TARGET_64BIT"
18453  "jmp\t%P1"
18454  [(set_attr "type" "callv")])
18455
18456(define_insn "*sibcall_value_1_rex64_v"
18457  [(set (match_operand 0 "" "")
18458	(call (mem:QI (reg:DI 40))
18459	      (match_operand:DI 1 "" "")))]
18460  "SIBLING_CALL_P (insn) && TARGET_64BIT"
18461  "jmp\t*%%r11"
18462  [(set_attr "type" "callv")])
18463
18464(define_insn "trap"
18465  [(trap_if (const_int 1) (const_int 5))]
18466  ""
18467  "int\t$5")
18468
18469;;; ix86 doesn't have conditional trap instructions, but we fake them
18470;;; for the sake of bounds checking.  By emitting bounds checks as
18471;;; conditional traps rather than as conditional jumps around
18472;;; unconditional traps we avoid introducing spurious basic-block
18473;;; boundaries and facilitate elimination of redundant checks.  In
18474;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18475;;; interrupt 5.
18476;;; 
18477;;; FIXME: Static branch prediction rules for ix86 are such that
18478;;; forward conditional branches predict as untaken.  As implemented
18479;;; below, pseudo conditional traps violate that rule.  We should use
18480;;; .pushsection/.popsection to place all of the `int 5's in a special
18481;;; section loaded at the end of the text segment and branch forward
18482;;; there on bounds-failure, and then jump back immediately (in case
18483;;; the system chooses to ignore bounds violations, or to report
18484;;; violations and continue execution).
18485
18486(define_expand "conditional_trap"
18487  [(trap_if (match_operator 0 "comparison_operator"
18488	     [(match_dup 2) (const_int 0)])
18489	    (match_operand 1 "const_int_operand" ""))]
18490  ""
18491{
18492  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18493			      ix86_expand_compare (GET_CODE (operands[0]),
18494						   NULL, NULL),
18495			      operands[1]));
18496  DONE;
18497})
18498
18499(define_insn "*conditional_trap_1"
18500  [(trap_if (match_operator 0 "comparison_operator"
18501	     [(reg 17) (const_int 0)])
18502	    (match_operand 1 "const_int_operand" ""))]
18503  ""
18504{
18505  operands[2] = gen_label_rtx ();
18506  output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18507  (*targetm.asm_out.internal_label) (asm_out_file, "L",
18508			     CODE_LABEL_NUMBER (operands[2]));
18509  RET;
18510})
18511
18512	;; Pentium III SIMD instructions.
18513
18514;; Moves for SSE/MMX regs.
18515
18516(define_insn "*movv4sf_internal"
18517  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18518	(match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18519  "TARGET_SSE
18520   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18521  "@
18522    xorps\t%0, %0
18523    movaps\t{%1, %0|%0, %1}
18524    movaps\t{%1, %0|%0, %1}"
18525  [(set_attr "type" "ssemov")
18526   (set_attr "mode" "V4SF")])
18527
18528(define_split
18529  [(set (match_operand:V4SF 0 "register_operand" "")
18530	(match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18531  "TARGET_SSE && reload_completed"
18532  [(set (match_dup 0)
18533	(vec_merge:V4SF
18534	 (vec_duplicate:V4SF (match_dup 1))
18535	 (match_dup 2)
18536	 (const_int 1)))]
18537{
18538  operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18539  operands[2] = CONST0_RTX (V4SFmode);
18540})
18541
18542(define_insn "*movv4si_internal"
18543  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18544	(match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18545  "TARGET_SSE
18546   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18547{
18548  switch (which_alternative)
18549    {
18550    case 0:
18551      if (get_attr_mode (insn) == MODE_V4SF)
18552	return "xorps\t%0, %0";
18553      else
18554	return "pxor\t%0, %0";
18555    case 1:
18556    case 2:
18557      if (get_attr_mode (insn) == MODE_V4SF)
18558	return "movaps\t{%1, %0|%0, %1}";
18559      else
18560	return "movdqa\t{%1, %0|%0, %1}";
18561    default:
18562      abort ();
18563    }
18564}
18565  [(set_attr "type" "ssemov")
18566   (set (attr "mode")
18567        (cond [(eq_attr "alternative" "0,1")
18568		 (if_then_else
18569		   (ne (symbol_ref "optimize_size")
18570		       (const_int 0))
18571		   (const_string "V4SF")
18572		   (const_string "TI"))
18573	       (eq_attr "alternative" "2")
18574		 (if_then_else
18575		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18576			    (const_int 0))
18577			(ne (symbol_ref "optimize_size")
18578			    (const_int 0)))
18579		   (const_string "V4SF")
18580		   (const_string "TI"))]
18581	       (const_string "TI")))])
18582
18583(define_insn "*movv2di_internal"
18584  [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18585	(match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18586  "TARGET_SSE
18587   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18588{
18589  switch (which_alternative)
18590    {
18591    case 0:
18592      if (get_attr_mode (insn) == MODE_V4SF)
18593	return "xorps\t%0, %0";
18594      else
18595	return "pxor\t%0, %0";
18596    case 1:
18597    case 2:
18598      if (get_attr_mode (insn) == MODE_V4SF)
18599	return "movaps\t{%1, %0|%0, %1}";
18600      else
18601	return "movdqa\t{%1, %0|%0, %1}";
18602    default:
18603      abort ();
18604    }
18605}
18606  [(set_attr "type" "ssemov")
18607   (set (attr "mode")
18608        (cond [(eq_attr "alternative" "0,1")
18609		 (if_then_else
18610		   (ne (symbol_ref "optimize_size")
18611		       (const_int 0))
18612		   (const_string "V4SF")
18613		   (const_string "TI"))
18614	       (eq_attr "alternative" "2")
18615		 (if_then_else
18616		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18617			    (const_int 0))
18618			(ne (symbol_ref "optimize_size")
18619			    (const_int 0)))
18620		   (const_string "V4SF")
18621		   (const_string "TI"))]
18622	       (const_string "TI")))])
18623
18624(define_split
18625  [(set (match_operand:V2DF 0 "register_operand" "")
18626	(match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18627  "TARGET_SSE2 && reload_completed"
18628  [(set (match_dup 0)
18629	(vec_merge:V2DF
18630	 (vec_duplicate:V2DF (match_dup 1))
18631	 (match_dup 2)
18632	 (const_int 1)))]
18633{
18634  operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18635  operands[2] = CONST0_RTX (V2DFmode);
18636})
18637
18638(define_insn "*movv2si_internal"
18639  [(set (match_operand:V2SI 0 "nonimmediate_operand"
18640					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18641	(match_operand:V2SI 1 "vector_move_operand"
18642					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18643  "TARGET_MMX
18644   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18645  "@
18646    pxor\t%0, %0
18647    movq\t{%1, %0|%0, %1}
18648    movq\t{%1, %0|%0, %1}
18649    movdq2q\t{%1, %0|%0, %1}
18650    movq2dq\t{%1, %0|%0, %1}
18651    pxor\t%0, %0
18652    movq\t{%1, %0|%0, %1}
18653    movq\t{%1, %0|%0, %1}"
18654  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18655   (set_attr "mode" "DI")])
18656
18657(define_insn "*movv4hi_internal"
18658  [(set (match_operand:V4HI 0 "nonimmediate_operand"
18659					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18660	(match_operand:V4HI 1 "vector_move_operand"
18661					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18662  "TARGET_MMX
18663   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18664  "@
18665    pxor\t%0, %0
18666    movq\t{%1, %0|%0, %1}
18667    movq\t{%1, %0|%0, %1}
18668    movdq2q\t{%1, %0|%0, %1}
18669    movq2dq\t{%1, %0|%0, %1}
18670    pxor\t%0, %0
18671    movq\t{%1, %0|%0, %1}
18672    movq\t{%1, %0|%0, %1}"
18673  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18674   (set_attr "mode" "DI")])
18675
18676(define_insn "*movv8qi_internal"
18677  [(set (match_operand:V8QI 0 "nonimmediate_operand"
18678					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18679	(match_operand:V8QI 1 "vector_move_operand"
18680					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18681  "TARGET_MMX
18682   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18683  "@
18684    pxor\t%0, %0
18685    movq\t{%1, %0|%0, %1}
18686    movq\t{%1, %0|%0, %1}
18687    movdq2q\t{%1, %0|%0, %1}
18688    movq2dq\t{%1, %0|%0, %1}
18689    pxor\t%0, %0
18690    movq\t{%1, %0|%0, %1}
18691    movq\t{%1, %0|%0, %1}"
18692  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18693   (set_attr "mode" "DI")])
18694
18695(define_insn "*movv2sf_internal"
18696  [(set (match_operand:V2SF 0 "nonimmediate_operand"
18697					"=y,y ,m,!y,!*Y,*x,?*x,?m")
18698        (match_operand:V2SF 1 "vector_move_operand"
18699					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
18700  "TARGET_MMX
18701   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18702  "@
18703    pxor\t%0, %0
18704    movq\t{%1, %0|%0, %1}
18705    movq\t{%1, %0|%0, %1}
18706    movdq2q\t{%1, %0|%0, %1}
18707    movq2dq\t{%1, %0|%0, %1}
18708    xorps\t%0, %0
18709    movq\t{%1, %0|%0, %1}
18710    movq\t{%1, %0|%0, %1}"
18711  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18712   (set_attr "mode" "DI")])
18713
18714(define_expand "movti"
18715  [(set (match_operand:TI 0 "nonimmediate_operand" "")
18716	(match_operand:TI 1 "nonimmediate_operand" ""))]
18717  "TARGET_SSE || TARGET_64BIT"
18718{
18719  if (TARGET_64BIT)
18720    ix86_expand_move (TImode, operands);
18721  else
18722    ix86_expand_vector_move (TImode, operands);
18723  DONE;
18724})
18725
18726(define_expand "movtf"
18727  [(set (match_operand:TF 0 "nonimmediate_operand" "")
18728	(match_operand:TF 1 "nonimmediate_operand" ""))]
18729  "TARGET_64BIT"
18730{
18731  ix86_expand_move (TFmode, operands);
18732  DONE;
18733})
18734
18735(define_insn "*movv2df_internal"
18736  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18737	(match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18738  "TARGET_SSE
18739   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18740{
18741  switch (which_alternative)
18742    {
18743    case 0:
18744      if (get_attr_mode (insn) == MODE_V4SF)
18745	return "xorps\t%0, %0";
18746      else
18747	return "xorpd\t%0, %0";
18748    case 1:
18749    case 2:
18750      if (get_attr_mode (insn) == MODE_V4SF)
18751	return "movaps\t{%1, %0|%0, %1}";
18752      else
18753	return "movapd\t{%1, %0|%0, %1}";
18754    default:
18755      abort ();
18756    }
18757}
18758  [(set_attr "type" "ssemov")
18759   (set (attr "mode")
18760        (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
18761		 (const_string "V4SF")
18762	       (eq_attr "alternative" "0,1")
18763		 (if_then_else
18764		   (ne (symbol_ref "optimize_size")
18765		       (const_int 0))
18766		   (const_string "V4SF")
18767		   (const_string "V2DF"))
18768	       (eq_attr "alternative" "2")
18769		 (if_then_else
18770		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18771			    (const_int 0))
18772			(ne (symbol_ref "optimize_size")
18773			    (const_int 0)))
18774		   (const_string "V4SF")
18775		   (const_string "V2DF"))]
18776	       (const_string "V2DF")))])
18777
18778(define_insn "*movv8hi_internal"
18779  [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18780	(match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18781  "TARGET_SSE
18782   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18783{
18784  switch (which_alternative)
18785    {
18786    case 0:
18787      if (get_attr_mode (insn) == MODE_V4SF)
18788	return "xorps\t%0, %0";
18789      else
18790	return "pxor\t%0, %0";
18791    case 1:
18792    case 2:
18793      if (get_attr_mode (insn) == MODE_V4SF)
18794	return "movaps\t{%1, %0|%0, %1}";
18795      else
18796	return "movdqa\t{%1, %0|%0, %1}";
18797    default:
18798      abort ();
18799    }
18800}
18801  [(set_attr "type" "ssemov")
18802   (set (attr "mode")
18803        (cond [(eq_attr "alternative" "0,1")
18804		 (if_then_else
18805		   (ne (symbol_ref "optimize_size")
18806		       (const_int 0))
18807		   (const_string "V4SF")
18808		   (const_string "TI"))
18809	       (eq_attr "alternative" "2")
18810		 (if_then_else
18811		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18812			    (const_int 0))
18813			(ne (symbol_ref "optimize_size")
18814			    (const_int 0)))
18815		   (const_string "V4SF")
18816		   (const_string "TI"))]
18817	       (const_string "TI")))])
18818
18819(define_insn "*movv16qi_internal"
18820  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18821	(match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
18822  "TARGET_SSE
18823   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18824{
18825  switch (which_alternative)
18826    {
18827    case 0:
18828      if (get_attr_mode (insn) == MODE_V4SF)
18829	return "xorps\t%0, %0";
18830      else
18831	return "pxor\t%0, %0";
18832    case 1:
18833    case 2:
18834      if (get_attr_mode (insn) == MODE_V4SF)
18835	return "movaps\t{%1, %0|%0, %1}";
18836      else
18837	return "movdqa\t{%1, %0|%0, %1}";
18838    default:
18839      abort ();
18840    }
18841}
18842  [(set_attr "type" "ssemov")
18843   (set (attr "mode")
18844        (cond [(eq_attr "alternative" "0,1")
18845		 (if_then_else
18846		   (ne (symbol_ref "optimize_size")
18847		       (const_int 0))
18848		   (const_string "V4SF")
18849		   (const_string "TI"))
18850	       (eq_attr "alternative" "2")
18851		 (if_then_else
18852		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18853			    (const_int 0))
18854			(ne (symbol_ref "optimize_size")
18855			    (const_int 0)))
18856		   (const_string "V4SF")
18857		   (const_string "TI"))]
18858	       (const_string "TI")))])
18859
18860(define_expand "movv2df"
18861  [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18862	(match_operand:V2DF 1 "nonimmediate_operand" ""))]
18863  "TARGET_SSE"
18864{
18865  ix86_expand_vector_move (V2DFmode, operands);
18866  DONE;
18867})
18868
18869(define_expand "movv8hi"
18870  [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18871	(match_operand:V8HI 1 "nonimmediate_operand" ""))]
18872  "TARGET_SSE"
18873{
18874  ix86_expand_vector_move (V8HImode, operands);
18875  DONE;
18876})
18877
18878(define_expand "movv16qi"
18879  [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18880	(match_operand:V16QI 1 "nonimmediate_operand" ""))]
18881  "TARGET_SSE"
18882{
18883  ix86_expand_vector_move (V16QImode, operands);
18884  DONE;
18885})
18886
18887(define_expand "movv4sf"
18888  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18889	(match_operand:V4SF 1 "nonimmediate_operand" ""))]
18890  "TARGET_SSE"
18891{
18892  ix86_expand_vector_move (V4SFmode, operands);
18893  DONE;
18894})
18895
18896(define_expand "movv4si"
18897  [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18898	(match_operand:V4SI 1 "nonimmediate_operand" ""))]
18899  "TARGET_SSE"
18900{
18901  ix86_expand_vector_move (V4SImode, operands);
18902  DONE;
18903})
18904
18905(define_expand "movv2di"
18906  [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18907	(match_operand:V2DI 1 "nonimmediate_operand" ""))]
18908  "TARGET_SSE"
18909{
18910  ix86_expand_vector_move (V2DImode, operands);
18911  DONE;
18912})
18913
18914(define_expand "movv2si"
18915  [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18916	(match_operand:V2SI 1 "nonimmediate_operand" ""))]
18917  "TARGET_MMX"
18918{
18919  ix86_expand_vector_move (V2SImode, operands);
18920  DONE;
18921})
18922
18923(define_expand "movv4hi"
18924  [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18925	(match_operand:V4HI 1 "nonimmediate_operand" ""))]
18926  "TARGET_MMX"
18927{
18928  ix86_expand_vector_move (V4HImode, operands);
18929  DONE;
18930})
18931
18932(define_expand "movv8qi"
18933  [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18934	(match_operand:V8QI 1 "nonimmediate_operand" ""))]
18935  "TARGET_MMX"
18936{
18937  ix86_expand_vector_move (V8QImode, operands);
18938  DONE;
18939})
18940
18941(define_expand "movv2sf"
18942  [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18943	(match_operand:V2SF 1 "nonimmediate_operand" ""))]
18944  "TARGET_MMX"
18945{
18946  ix86_expand_vector_move (V2SFmode, operands);
18947  DONE;
18948})
18949
18950(define_insn "*pushti"
18951  [(set (match_operand:TI 0 "push_operand" "=<")
18952	(match_operand:TI 1 "register_operand" "x"))]
18953  "TARGET_SSE"
18954  "#")
18955
18956(define_insn "*pushv2df"
18957  [(set (match_operand:V2DF 0 "push_operand" "=<")
18958	(match_operand:V2DF 1 "register_operand" "x"))]
18959  "TARGET_SSE"
18960  "#")
18961
18962(define_insn "*pushv2di"
18963  [(set (match_operand:V2DI 0 "push_operand" "=<")
18964	(match_operand:V2DI 1 "register_operand" "x"))]
18965  "TARGET_SSE"
18966  "#")
18967
18968(define_insn "*pushv8hi"
18969  [(set (match_operand:V8HI 0 "push_operand" "=<")
18970	(match_operand:V8HI 1 "register_operand" "x"))]
18971  "TARGET_SSE"
18972  "#")
18973
18974(define_insn "*pushv16qi"
18975  [(set (match_operand:V16QI 0 "push_operand" "=<")
18976	(match_operand:V16QI 1 "register_operand" "x"))]
18977  "TARGET_SSE"
18978  "#")
18979
18980(define_insn "*pushv4sf"
18981  [(set (match_operand:V4SF 0 "push_operand" "=<")
18982	(match_operand:V4SF 1 "register_operand" "x"))]
18983  "TARGET_SSE"
18984  "#")
18985
18986(define_insn "*pushv4si"
18987  [(set (match_operand:V4SI 0 "push_operand" "=<")
18988	(match_operand:V4SI 1 "register_operand" "x"))]
18989  "TARGET_SSE"
18990  "#")
18991
18992(define_insn "*pushv2si"
18993  [(set (match_operand:V2SI 0 "push_operand" "=<")
18994	(match_operand:V2SI 1 "register_operand" "y"))]
18995  "TARGET_MMX"
18996  "#")
18997
18998(define_insn "*pushv4hi"
18999  [(set (match_operand:V4HI 0 "push_operand" "=<")
19000	(match_operand:V4HI 1 "register_operand" "y"))]
19001  "TARGET_MMX"
19002  "#")
19003
19004(define_insn "*pushv8qi"
19005  [(set (match_operand:V8QI 0 "push_operand" "=<")
19006	(match_operand:V8QI 1 "register_operand" "y"))]
19007  "TARGET_MMX"
19008  "#")
19009
19010(define_insn "*pushv2sf"
19011  [(set (match_operand:V2SF 0 "push_operand" "=<")
19012	(match_operand:V2SF 1 "register_operand" "y"))]
19013  "TARGET_MMX"
19014  "#")
19015
19016(define_split
19017  [(set (match_operand 0 "push_operand" "")
19018	(match_operand 1 "register_operand" ""))]
19019  "!TARGET_64BIT && reload_completed
19020   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19021  [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19022   (set (match_dup 2) (match_dup 1))]
19023  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19024				 stack_pointer_rtx);
19025   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19026
19027(define_split
19028  [(set (match_operand 0 "push_operand" "")
19029	(match_operand 1 "register_operand" ""))]
19030  "TARGET_64BIT && reload_completed
19031   && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19032  [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19033   (set (match_dup 2) (match_dup 1))]
19034  "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19035				 stack_pointer_rtx);
19036   operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19037
19038
19039(define_insn "*movti_internal"
19040  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19041	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19042  "TARGET_SSE && !TARGET_64BIT
19043   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19044{
19045  switch (which_alternative)
19046    {
19047    case 0:
19048      if (get_attr_mode (insn) == MODE_V4SF)
19049	return "xorps\t%0, %0";
19050      else
19051	return "pxor\t%0, %0";
19052    case 1:
19053    case 2:
19054      if (get_attr_mode (insn) == MODE_V4SF)
19055	return "movaps\t{%1, %0|%0, %1}";
19056      else
19057	return "movdqa\t{%1, %0|%0, %1}";
19058    default:
19059      abort ();
19060    }
19061}
19062  [(set_attr "type" "ssemov,ssemov,ssemov")
19063   (set (attr "mode")
19064        (cond [(eq_attr "alternative" "0,1")
19065		 (if_then_else
19066		   (ne (symbol_ref "optimize_size")
19067		       (const_int 0))
19068		   (const_string "V4SF")
19069		   (const_string "TI"))
19070	       (eq_attr "alternative" "2")
19071		 (if_then_else
19072		   (ne (symbol_ref "optimize_size")
19073		       (const_int 0))
19074		   (const_string "V4SF")
19075		   (const_string "TI"))]
19076	       (const_string "TI")))])
19077
19078(define_insn "*movti_rex64"
19079  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19080	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19081  "TARGET_64BIT
19082   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19083{
19084  switch (which_alternative)
19085    {
19086    case 0:
19087    case 1:
19088      return "#";
19089    case 2:
19090      if (get_attr_mode (insn) == MODE_V4SF)
19091	return "xorps\t%0, %0";
19092      else
19093	return "pxor\t%0, %0";
19094    case 3:
19095    case 4:
19096      if (get_attr_mode (insn) == MODE_V4SF)
19097	return "movaps\t{%1, %0|%0, %1}";
19098      else
19099	return "movdqa\t{%1, %0|%0, %1}";
19100    default:
19101      abort ();
19102    }
19103}
19104  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19105   (set (attr "mode")
19106        (cond [(eq_attr "alternative" "2,3")
19107		 (if_then_else
19108		   (ne (symbol_ref "optimize_size")
19109		       (const_int 0))
19110		   (const_string "V4SF")
19111		   (const_string "TI"))
19112	       (eq_attr "alternative" "4")
19113		 (if_then_else
19114		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19115			    (const_int 0))
19116			(ne (symbol_ref "optimize_size")
19117			    (const_int 0)))
19118		   (const_string "V4SF")
19119		   (const_string "TI"))]
19120	       (const_string "DI")))])
19121
19122(define_insn "*movtf_rex64"
19123  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19124	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19125  "TARGET_64BIT
19126   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19127{
19128  switch (which_alternative)
19129    {
19130    case 0:
19131    case 1:
19132      return "#";
19133    case 2:
19134      if (get_attr_mode (insn) == MODE_V4SF)
19135	return "xorps\t%0, %0";
19136      else
19137	return "pxor\t%0, %0";
19138    case 3:
19139    case 4:
19140      if (get_attr_mode (insn) == MODE_V4SF)
19141	return "movaps\t{%1, %0|%0, %1}";
19142      else
19143	return "movdqa\t{%1, %0|%0, %1}";
19144    default:
19145      abort ();
19146    }
19147}
19148  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19149   (set (attr "mode")
19150        (cond [(eq_attr "alternative" "2,3")
19151		 (if_then_else
19152		   (ne (symbol_ref "optimize_size")
19153		       (const_int 0))
19154		   (const_string "V4SF")
19155		   (const_string "TI"))
19156	       (eq_attr "alternative" "4")
19157		 (if_then_else
19158		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19159			    (const_int 0))
19160			(ne (symbol_ref "optimize_size")
19161			    (const_int 0)))
19162		   (const_string "V4SF")
19163		   (const_string "TI"))]
19164	       (const_string "DI")))])
19165
19166(define_split
19167  [(set (match_operand:TI 0 "nonimmediate_operand" "")
19168        (match_operand:TI 1 "general_operand" ""))]
19169  "reload_completed && !SSE_REG_P (operands[0])
19170   && !SSE_REG_P (operands[1])"
19171  [(const_int 0)]
19172  "ix86_split_long_move (operands); DONE;")
19173
19174(define_split
19175  [(set (match_operand:TF 0 "nonimmediate_operand" "")
19176        (match_operand:TF 1 "general_operand" ""))]
19177  "reload_completed && !SSE_REG_P (operands[0])
19178   && !SSE_REG_P (operands[1])"
19179  [(const_int 0)]
19180  "ix86_split_long_move (operands); DONE;")
19181
19182;; These two patterns are useful for specifying exactly whether to use
19183;; movaps or movups
19184(define_expand "sse_movaps"
19185  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19186	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19187		     UNSPEC_MOVA))]
19188  "TARGET_SSE"
19189{
19190  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19191    {
19192      rtx tmp = gen_reg_rtx (V4SFmode);
19193      emit_insn (gen_sse_movaps (tmp, operands[1]));
19194      emit_move_insn (operands[0], tmp);
19195      DONE;
19196    }
19197})
19198
19199(define_insn "*sse_movaps_1"
19200  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19201	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19202		     UNSPEC_MOVA))]
19203  "TARGET_SSE
19204   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19205  "movaps\t{%1, %0|%0, %1}"
19206  [(set_attr "type" "ssemov,ssemov")
19207   (set_attr "mode" "V4SF")])
19208
19209(define_expand "sse_movups"
19210  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19211	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19212		     UNSPEC_MOVU))]
19213  "TARGET_SSE"
19214{
19215  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19216    {
19217      rtx tmp = gen_reg_rtx (V4SFmode);
19218      emit_insn (gen_sse_movups (tmp, operands[1]));
19219      emit_move_insn (operands[0], tmp);
19220      DONE;
19221    }
19222})
19223
19224(define_insn "*sse_movups_1"
19225  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19226	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19227		     UNSPEC_MOVU))]
19228  "TARGET_SSE
19229   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19230  "movups\t{%1, %0|%0, %1}"
19231  [(set_attr "type" "ssecvt,ssecvt")
19232   (set_attr "mode" "V4SF")])
19233
19234;; SSE Strange Moves.
19235
19236(define_insn "sse_movmskps"
19237  [(set (match_operand:SI 0 "register_operand" "=r")
19238	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19239		   UNSPEC_MOVMSK))]
19240  "TARGET_SSE"
19241  "movmskps\t{%1, %0|%0, %1}"
19242  [(set_attr "type" "ssecvt")
19243   (set_attr "mode" "V4SF")])
19244
19245(define_insn "mmx_pmovmskb"
19246  [(set (match_operand:SI 0 "register_operand" "=r")
19247	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19248		   UNSPEC_MOVMSK))]
19249  "TARGET_SSE || TARGET_3DNOW_A"
19250  "pmovmskb\t{%1, %0|%0, %1}"
19251  [(set_attr "type" "ssecvt")
19252   (set_attr "mode" "V4SF")])
19253
19254
19255(define_insn "mmx_maskmovq"
19256  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19257	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19258		      (match_operand:V8QI 2 "register_operand" "y")]
19259		     UNSPEC_MASKMOV))]
19260  "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19261  ;; @@@ check ordering of operands in intel/nonintel syntax
19262  "maskmovq\t{%2, %1|%1, %2}"
19263  [(set_attr "type" "mmxcvt")
19264   (set_attr "mode" "DI")])
19265
19266(define_insn "mmx_maskmovq_rex"
19267  [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19268	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19269		      (match_operand:V8QI 2 "register_operand" "y")]
19270		     UNSPEC_MASKMOV))]
19271  "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19272  ;; @@@ check ordering of operands in intel/nonintel syntax
19273  "maskmovq\t{%2, %1|%1, %2}"
19274  [(set_attr "type" "mmxcvt")
19275   (set_attr "mode" "DI")])
19276
19277(define_insn "sse_movntv4sf"
19278  [(set (match_operand:V4SF 0 "memory_operand" "=m")
19279	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19280		     UNSPEC_MOVNT))]
19281  "TARGET_SSE"
19282  "movntps\t{%1, %0|%0, %1}"
19283  [(set_attr "type" "ssemov")
19284   (set_attr "mode" "V4SF")])
19285
19286(define_insn "sse_movntdi"
19287  [(set (match_operand:DI 0 "memory_operand" "=m")
19288	(unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19289		   UNSPEC_MOVNT))]
19290  "TARGET_SSE || TARGET_3DNOW_A"
19291  "movntq\t{%1, %0|%0, %1}"
19292  [(set_attr "type" "mmxmov")
19293   (set_attr "mode" "DI")])
19294
19295(define_insn "sse_movhlps"
19296  [(set (match_operand:V4SF 0 "register_operand" "=x")
19297	(vec_merge:V4SF
19298	 (match_operand:V4SF 1 "register_operand" "0")
19299	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19300			  (parallel [(const_int 2)
19301				     (const_int 3)
19302				     (const_int 0)
19303				     (const_int 1)]))
19304	 (const_int 3)))]
19305  "TARGET_SSE"
19306  "movhlps\t{%2, %0|%0, %2}"
19307  [(set_attr "type" "ssecvt")
19308   (set_attr "mode" "V4SF")])
19309
19310(define_insn "sse_movlhps"
19311  [(set (match_operand:V4SF 0 "register_operand" "=x")
19312	(vec_merge:V4SF
19313	 (match_operand:V4SF 1 "register_operand" "0")
19314	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19315			  (parallel [(const_int 2)
19316				     (const_int 3)
19317				     (const_int 0)
19318				     (const_int 1)]))
19319	 (const_int 12)))]
19320  "TARGET_SSE"
19321  "movlhps\t{%2, %0|%0, %2}"
19322  [(set_attr "type" "ssecvt")
19323   (set_attr "mode" "V4SF")])
19324
19325(define_insn "sse_movhps"
19326  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19327	(vec_merge:V4SF
19328	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19329	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19330	 (const_int 12)))]
19331  "TARGET_SSE
19332   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19333  "movhps\t{%2, %0|%0, %2}"
19334  [(set_attr "type" "ssecvt")
19335   (set_attr "mode" "V4SF")])
19336
19337(define_insn "sse_movlps"
19338  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19339	(vec_merge:V4SF
19340	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19341	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19342	 (const_int 3)))]
19343  "TARGET_SSE
19344   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19345  "movlps\t{%2, %0|%0, %2}"
19346  [(set_attr "type" "ssecvt")
19347   (set_attr "mode" "V4SF")])
19348
19349(define_expand "sse_loadss"
19350  [(match_operand:V4SF 0 "register_operand" "")
19351   (match_operand:SF 1 "memory_operand" "")]
19352  "TARGET_SSE"
19353{
19354  emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19355			       CONST0_RTX (V4SFmode)));
19356  DONE;
19357})
19358
19359(define_insn "sse_loadss_1"
19360  [(set (match_operand:V4SF 0 "register_operand" "=x")
19361	(vec_merge:V4SF
19362	 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19363	 (match_operand:V4SF 2 "const0_operand" "X")
19364	 (const_int 1)))]
19365  "TARGET_SSE"
19366  "movss\t{%1, %0|%0, %1}"
19367  [(set_attr "type" "ssemov")
19368   (set_attr "mode" "SF")])
19369
19370(define_insn "sse_movss"
19371  [(set (match_operand:V4SF 0 "register_operand" "=x")
19372	(vec_merge:V4SF
19373	 (match_operand:V4SF 1 "register_operand" "0")
19374	 (match_operand:V4SF 2 "register_operand" "x")
19375	 (const_int 1)))]
19376  "TARGET_SSE"
19377  "movss\t{%2, %0|%0, %2}"
19378  [(set_attr "type" "ssemov")
19379   (set_attr "mode" "SF")])
19380
19381(define_insn "sse_storess"
19382  [(set (match_operand:SF 0 "memory_operand" "=m")
19383	(vec_select:SF
19384	 (match_operand:V4SF 1 "register_operand" "x")
19385	 (parallel [(const_int 0)])))]
19386  "TARGET_SSE"
19387  "movss\t{%1, %0|%0, %1}"
19388  [(set_attr "type" "ssemov")
19389   (set_attr "mode" "SF")])
19390
19391(define_insn "sse_shufps"
19392  [(set (match_operand:V4SF 0 "register_operand" "=x")
19393        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19394		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19395		      (match_operand:SI 3 "immediate_operand" "i")]
19396		     UNSPEC_SHUFFLE))]
19397  "TARGET_SSE"
19398  ;; @@@ check operand order for intel/nonintel syntax
19399  "shufps\t{%3, %2, %0|%0, %2, %3}"
19400  [(set_attr "type" "ssecvt")
19401   (set_attr "mode" "V4SF")])
19402
19403
19404;; SSE arithmetic
19405
19406(define_insn "addv4sf3"
19407  [(set (match_operand:V4SF 0 "register_operand" "=x")
19408        (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19409	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19410  "TARGET_SSE"
19411  "addps\t{%2, %0|%0, %2}"
19412  [(set_attr "type" "sseadd")
19413   (set_attr "mode" "V4SF")])
19414
19415(define_insn "vmaddv4sf3"
19416  [(set (match_operand:V4SF 0 "register_operand" "=x")
19417	(vec_merge:V4SF
19418	 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19419		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19420	 (match_dup 1)
19421	 (const_int 1)))]
19422  "TARGET_SSE"
19423  "addss\t{%2, %0|%0, %2}"
19424  [(set_attr "type" "sseadd")
19425   (set_attr "mode" "SF")])
19426
19427(define_insn "subv4sf3"
19428  [(set (match_operand:V4SF 0 "register_operand" "=x")
19429        (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19430		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19431  "TARGET_SSE"
19432  "subps\t{%2, %0|%0, %2}"
19433  [(set_attr "type" "sseadd")
19434   (set_attr "mode" "V4SF")])
19435
19436(define_insn "vmsubv4sf3"
19437  [(set (match_operand:V4SF 0 "register_operand" "=x")
19438	(vec_merge:V4SF
19439	 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19440		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19441	 (match_dup 1)
19442	 (const_int 1)))]
19443  "TARGET_SSE"
19444  "subss\t{%2, %0|%0, %2}"
19445  [(set_attr "type" "sseadd")
19446   (set_attr "mode" "SF")])
19447
19448(define_insn "mulv4sf3"
19449  [(set (match_operand:V4SF 0 "register_operand" "=x")
19450        (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19451	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19452  "TARGET_SSE"
19453  "mulps\t{%2, %0|%0, %2}"
19454  [(set_attr "type" "ssemul")
19455   (set_attr "mode" "V4SF")])
19456
19457(define_insn "vmmulv4sf3"
19458  [(set (match_operand:V4SF 0 "register_operand" "=x")
19459	(vec_merge:V4SF
19460	 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19461		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19462	 (match_dup 1)
19463	 (const_int 1)))]
19464  "TARGET_SSE"
19465  "mulss\t{%2, %0|%0, %2}"
19466  [(set_attr "type" "ssemul")
19467   (set_attr "mode" "SF")])
19468
19469(define_insn "divv4sf3"
19470  [(set (match_operand:V4SF 0 "register_operand" "=x")
19471        (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19472	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19473  "TARGET_SSE"
19474  "divps\t{%2, %0|%0, %2}"
19475  [(set_attr "type" "ssediv")
19476   (set_attr "mode" "V4SF")])
19477
19478(define_insn "vmdivv4sf3"
19479  [(set (match_operand:V4SF 0 "register_operand" "=x")
19480	(vec_merge:V4SF
19481	 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19482		   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19483	 (match_dup 1)
19484	 (const_int 1)))]
19485  "TARGET_SSE"
19486  "divss\t{%2, %0|%0, %2}"
19487  [(set_attr "type" "ssediv")
19488   (set_attr "mode" "SF")])
19489
19490
19491;; SSE square root/reciprocal
19492
19493(define_insn "rcpv4sf2"
19494  [(set (match_operand:V4SF 0 "register_operand" "=x")
19495        (unspec:V4SF
19496	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19497  "TARGET_SSE"
19498  "rcpps\t{%1, %0|%0, %1}"
19499  [(set_attr "type" "sse")
19500   (set_attr "mode" "V4SF")])
19501
19502(define_insn "vmrcpv4sf2"
19503  [(set (match_operand:V4SF 0 "register_operand" "=x")
19504	(vec_merge:V4SF
19505	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19506		      UNSPEC_RCP)
19507	 (match_operand:V4SF 2 "register_operand" "0")
19508	 (const_int 1)))]
19509  "TARGET_SSE"
19510  "rcpss\t{%1, %0|%0, %1}"
19511  [(set_attr "type" "sse")
19512   (set_attr "mode" "SF")])
19513
19514(define_insn "rsqrtv4sf2"
19515  [(set (match_operand:V4SF 0 "register_operand" "=x")
19516        (unspec:V4SF
19517	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19518  "TARGET_SSE"
19519  "rsqrtps\t{%1, %0|%0, %1}"
19520  [(set_attr "type" "sse")
19521   (set_attr "mode" "V4SF")])
19522
19523(define_insn "vmrsqrtv4sf2"
19524  [(set (match_operand:V4SF 0 "register_operand" "=x")
19525	(vec_merge:V4SF
19526	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19527		      UNSPEC_RSQRT)
19528	 (match_operand:V4SF 2 "register_operand" "0")
19529	 (const_int 1)))]
19530  "TARGET_SSE"
19531  "rsqrtss\t{%1, %0|%0, %1}"
19532  [(set_attr "type" "sse")
19533   (set_attr "mode" "SF")])
19534
19535(define_insn "sqrtv4sf2"
19536  [(set (match_operand:V4SF 0 "register_operand" "=x")
19537        (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19538  "TARGET_SSE"
19539  "sqrtps\t{%1, %0|%0, %1}"
19540  [(set_attr "type" "sse")
19541   (set_attr "mode" "V4SF")])
19542
19543(define_insn "vmsqrtv4sf2"
19544  [(set (match_operand:V4SF 0 "register_operand" "=x")
19545	(vec_merge:V4SF
19546	 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19547	 (match_operand:V4SF 2 "register_operand" "0")
19548	 (const_int 1)))]
19549  "TARGET_SSE"
19550  "sqrtss\t{%1, %0|%0, %1}"
19551  [(set_attr "type" "sse")
19552   (set_attr "mode" "SF")])
19553
19554;; SSE logical operations.
19555
19556;; SSE defines logical operations on floating point values.  This brings
19557;; interesting challenge to RTL representation where logicals are only valid
19558;; on integral types.  We deal with this by representing the floating point
19559;; logical as logical on arguments casted to TImode as this is what hardware
19560;; really does.  Unfortunately hardware requires the type information to be
19561;; present and thus we must avoid subregs from being simplified and eliminated
19562;; in later compilation phases.
19563;;
19564;; We have following variants from each instruction:
19565;; sse_andsf3 - the operation taking V4SF vector operands
19566;;              and doing TImode cast on them
19567;; *sse_andsf3_memory - the operation taking one memory operand casted to
19568;;                      TImode, since backend insist on eliminating casts
19569;;                      on memory operands
19570;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19571;;                   We can not accept memory operand here as instruction reads
19572;;		     whole scalar.  This is generated only post reload by GCC
19573;;		     scalar float operations that expands to logicals (fabs)
19574;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19575;;		     memory operand.  Eventually combine can be able
19576;;		     to synthesize these using splitter.
19577;; sse2_anddf3, *sse2_anddf3_memory
19578;;              
19579;; 
19580;; These are not called andti3 etc. because we really really don't want
19581;; the compiler to widen DImode ands to TImode ands and then try to move
19582;; into DImode subregs of SSE registers, and them together, and move out
19583;; of DImode subregs again!
19584;; SSE1 single precision floating point logical operation
19585(define_expand "sse_andv4sf3"
19586  [(set (match_operand:V4SF 0 "register_operand" "")
19587        (and:V4SF (match_operand:V4SF 1 "register_operand" "")
19588		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19589  "TARGET_SSE"
19590  "")
19591
19592(define_insn "*sse_andv4sf3"
19593  [(set (match_operand:V4SF 0 "register_operand" "=x")
19594        (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19595		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19596  "TARGET_SSE
19597   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19598  "andps\t{%2, %0|%0, %2}"
19599  [(set_attr "type" "sselog")
19600   (set_attr "mode" "V4SF")])
19601
19602(define_expand "sse_nandv4sf3"
19603  [(set (match_operand:V4SF 0 "register_operand" "")
19604        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
19605	          (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19606  "TARGET_SSE"
19607  "")
19608
19609(define_insn "*sse_nandv4sf3"
19610  [(set (match_operand:V4SF 0 "register_operand" "=x")
19611        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
19612	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19613  "TARGET_SSE"
19614  "andnps\t{%2, %0|%0, %2}"
19615  [(set_attr "type" "sselog")
19616   (set_attr "mode" "V4SF")])
19617
19618(define_expand "sse_iorv4sf3"
19619  [(set (match_operand:V4SF 0 "register_operand" "")
19620        (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
19621		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19622  "TARGET_SSE"
19623  "")
19624
19625(define_insn "*sse_iorv4sf3"
19626  [(set (match_operand:V4SF 0 "register_operand" "=x")
19627        (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19628		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19629  "TARGET_SSE
19630   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19631  "orps\t{%2, %0|%0, %2}"
19632  [(set_attr "type" "sselog")
19633   (set_attr "mode" "V4SF")])
19634
19635(define_expand "sse_xorv4sf3"
19636  [(set (match_operand:V4SF 0 "register_operand" "")
19637        (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
19638		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19639  "TARGET_SSE"
19640  "")
19641
19642(define_insn "*sse_xorv4sf3"
19643  [(set (match_operand:V4SF 0 "register_operand" "=x")
19644        (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19645		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19646  "TARGET_SSE
19647   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19648  "xorps\t{%2, %0|%0, %2}"
19649  [(set_attr "type" "sselog")
19650   (set_attr "mode" "V4SF")])
19651
19652;; SSE2 double precision floating point logical operation
19653
19654(define_expand "sse2_andv2df3"
19655  [(set (match_operand:V2DF 0 "register_operand" "")
19656        (and:V2DF (match_operand:V2DF 1 "register_operand" "")
19657	          (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19658  "TARGET_SSE2"
19659  "")
19660
19661(define_insn "*sse2_andv2df3"
19662  [(set (match_operand:V2DF 0 "register_operand" "=x")
19663        (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19664		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19665  "TARGET_SSE2
19666   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19667  "andpd\t{%2, %0|%0, %2}"
19668  [(set_attr "type" "sselog")
19669   (set_attr "mode" "V2DF")])
19670
19671(define_expand "sse2_nandv2df3"
19672  [(set (match_operand:V2DF 0 "register_operand" "")
19673        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
19674	          (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19675  "TARGET_SSE2"
19676  "")
19677
19678(define_insn "*sse2_nandv2df3"
19679  [(set (match_operand:V2DF 0 "register_operand" "=x")
19680        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
19681	          (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19682  "TARGET_SSE2"
19683  "andnpd\t{%2, %0|%0, %2}"
19684  [(set_attr "type" "sselog")
19685   (set_attr "mode" "V2DF")])
19686
19687(define_expand "sse2_iorv2df3"
19688  [(set (match_operand:V2DF 0 "register_operand" "")
19689        (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
19690		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19691  "TARGET_SSE2"
19692  "")
19693
19694(define_insn "*sse2_iorv2df3"
19695  [(set (match_operand:V2DF 0 "register_operand" "=x")
19696        (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19697		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19698  "TARGET_SSE2
19699   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19700  "orpd\t{%2, %0|%0, %2}"
19701  [(set_attr "type" "sselog")
19702   (set_attr "mode" "V2DF")])
19703
19704(define_expand "sse2_xorv2df3"
19705  [(set (match_operand:V2DF 0 "register_operand" "")
19706        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
19707		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19708  "TARGET_SSE2"
19709  "")
19710
19711(define_insn "*sse2_xorv2df3"
19712  [(set (match_operand:V2DF 0 "register_operand" "=x")
19713        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19714		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19715  "TARGET_SSE2
19716   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19717  "xorpd\t{%2, %0|%0, %2}"
19718  [(set_attr "type" "sselog")
19719   (set_attr "mode" "V2DF")])
19720
19721;; SSE2 integral logicals.  These patterns must always come after floating
19722;; point ones since we don't want compiler to use integer opcodes on floating
19723;; point SSE values to avoid matching of subregs in the match_operand.
19724(define_insn "*sse2_andti3"
19725  [(set (match_operand:TI 0 "register_operand" "=x")
19726        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19727		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
19728  "TARGET_SSE2
19729   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19730  "pand\t{%2, %0|%0, %2}"
19731  [(set_attr "type" "sselog")
19732   (set_attr "mode" "TI")])
19733
19734(define_insn "sse2_andv2di3"
19735  [(set (match_operand:V2DI 0 "register_operand" "=x")
19736        (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19737		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19738  "TARGET_SSE2
19739   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19740  "pand\t{%2, %0|%0, %2}"
19741  [(set_attr "type" "sselog")
19742   (set_attr "mode" "TI")])
19743
19744(define_insn "*sse2_nandti3"
19745  [(set (match_operand:TI 0 "register_operand" "=x")
19746        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19747		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
19748  "TARGET_SSE2"
19749  "pandn\t{%2, %0|%0, %2}"
19750  [(set_attr "type" "sselog")
19751   (set_attr "mode" "TI")])
19752
19753(define_insn "sse2_nandv2di3"
19754  [(set (match_operand:V2DI 0 "register_operand" "=x")
19755        (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19756		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19757  "TARGET_SSE2
19758   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19759  "pandn\t{%2, %0|%0, %2}"
19760  [(set_attr "type" "sselog")
19761   (set_attr "mode" "TI")])
19762
19763(define_insn "*sse2_iorti3"
19764  [(set (match_operand:TI 0 "register_operand" "=x")
19765        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19766		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
19767  "TARGET_SSE2
19768   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19769  "por\t{%2, %0|%0, %2}"
19770  [(set_attr "type" "sselog")
19771   (set_attr "mode" "TI")])
19772
19773(define_insn "sse2_iorv2di3"
19774  [(set (match_operand:V2DI 0 "register_operand" "=x")
19775        (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19776		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19777  "TARGET_SSE2
19778   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19779  "por\t{%2, %0|%0, %2}"
19780  [(set_attr "type" "sselog")
19781   (set_attr "mode" "TI")])
19782
19783(define_insn "*sse2_xorti3"
19784  [(set (match_operand:TI 0 "register_operand" "=x")
19785        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19786		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
19787  "TARGET_SSE2
19788   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19789  "pxor\t{%2, %0|%0, %2}"
19790  [(set_attr "type" "sselog")
19791   (set_attr "mode" "TI")])
19792
19793(define_insn "sse2_xorv2di3"
19794  [(set (match_operand:V2DI 0 "register_operand" "=x")
19795        (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19796		  (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19797  "TARGET_SSE2
19798   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19799  "pxor\t{%2, %0|%0, %2}"
19800  [(set_attr "type" "sselog")
19801   (set_attr "mode" "TI")])
19802
19803;; Use xor, but don't show input operands so they aren't live before
19804;; this insn.
19805(define_insn "sse_clrv4sf"
19806  [(set (match_operand:V4SF 0 "register_operand" "=x")
19807	(match_operand:V4SF 1 "const0_operand" "X"))]
19808  "TARGET_SSE"
19809{
19810  if (get_attr_mode (insn) == MODE_TI)
19811    return "pxor\t{%0, %0|%0, %0}";
19812  else
19813    return "xorps\t{%0, %0|%0, %0}";
19814}
19815  [(set_attr "type" "sselog")
19816   (set_attr "memory" "none")
19817   (set (attr "mode")
19818	(if_then_else
19819	   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19820			 (const_int 0))
19821		     (ne (symbol_ref "TARGET_SSE2")
19822			 (const_int 0)))
19823		(eq (symbol_ref "optimize_size")
19824		    (const_int 0)))
19825	 (const_string "TI")
19826	 (const_string "V4SF")))])
19827
19828;; Use xor, but don't show input operands so they aren't live before
19829;; this insn.
19830(define_insn "sse_clrv2df"
19831  [(set (match_operand:V2DF 0 "register_operand" "=x")
19832        (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19833  "TARGET_SSE2"
19834  "xorpd\t{%0, %0|%0, %0}"
19835  [(set_attr "type" "sselog")
19836   (set_attr "memory" "none")
19837   (set_attr "mode" "V4SF")])
19838
19839;; SSE mask-generating compares
19840
19841(define_insn "maskcmpv4sf3"
19842  [(set (match_operand:V4SI 0 "register_operand" "=x")
19843        (match_operator:V4SI 3 "sse_comparison_operator"
19844		[(match_operand:V4SF 1 "register_operand" "0")
19845		 (match_operand:V4SF 2 "register_operand" "x")]))]
19846  "TARGET_SSE"
19847  "cmp%D3ps\t{%2, %0|%0, %2}"
19848  [(set_attr "type" "ssecmp")
19849   (set_attr "mode" "V4SF")])
19850
19851(define_insn "maskncmpv4sf3"
19852  [(set (match_operand:V4SI 0 "register_operand" "=x")
19853        (not:V4SI
19854	 (match_operator:V4SI 3 "sse_comparison_operator"
19855		[(match_operand:V4SF 1 "register_operand" "0")
19856		 (match_operand:V4SF 2 "register_operand" "x")])))]
19857  "TARGET_SSE"
19858{
19859  if (GET_CODE (operands[3]) == UNORDERED)
19860    return "cmpordps\t{%2, %0|%0, %2}";
19861  else
19862    return "cmpn%D3ps\t{%2, %0|%0, %2}";
19863}
19864  [(set_attr "type" "ssecmp")
19865   (set_attr "mode" "V4SF")])
19866
19867(define_insn "vmmaskcmpv4sf3"
19868  [(set (match_operand:V4SI 0 "register_operand" "=x")
19869	(vec_merge:V4SI
19870	 (match_operator:V4SI 3 "sse_comparison_operator"
19871		[(match_operand:V4SF 1 "register_operand" "0")
19872		 (match_operand:V4SF 2 "register_operand" "x")])
19873	 (subreg:V4SI (match_dup 1) 0)
19874	 (const_int 1)))]
19875  "TARGET_SSE"
19876  "cmp%D3ss\t{%2, %0|%0, %2}"
19877  [(set_attr "type" "ssecmp")
19878   (set_attr "mode" "SF")])
19879
19880(define_insn "vmmaskncmpv4sf3"
19881  [(set (match_operand:V4SI 0 "register_operand" "=x")
19882	(vec_merge:V4SI
19883	 (not:V4SI
19884	  (match_operator:V4SI 3 "sse_comparison_operator"
19885		[(match_operand:V4SF 1 "register_operand" "0")
19886		 (match_operand:V4SF 2 "register_operand" "x")]))
19887	 (subreg:V4SI (match_dup 1) 0)
19888	 (const_int 1)))]
19889  "TARGET_SSE"
19890{
19891  if (GET_CODE (operands[3]) == UNORDERED)
19892    return "cmpordss\t{%2, %0|%0, %2}";
19893  else
19894    return "cmpn%D3ss\t{%2, %0|%0, %2}";
19895}
19896  [(set_attr "type" "ssecmp")
19897   (set_attr "mode" "SF")])
19898
19899(define_insn "sse_comi"
19900  [(set (reg:CCFP 17)
19901        (compare:CCFP (vec_select:SF
19902		       (match_operand:V4SF 0 "register_operand" "x")
19903		       (parallel [(const_int 0)]))
19904		      (vec_select:SF
19905		       (match_operand:V4SF 1 "register_operand" "x")
19906		       (parallel [(const_int 0)]))))]
19907  "TARGET_SSE"
19908  "comiss\t{%1, %0|%0, %1}"
19909  [(set_attr "type" "ssecomi")
19910   (set_attr "mode" "SF")])
19911
19912(define_insn "sse_ucomi"
19913  [(set (reg:CCFPU 17)
19914	(compare:CCFPU (vec_select:SF
19915			(match_operand:V4SF 0 "register_operand" "x")
19916			(parallel [(const_int 0)]))
19917		       (vec_select:SF
19918			(match_operand:V4SF 1 "register_operand" "x")
19919			(parallel [(const_int 0)]))))]
19920  "TARGET_SSE"
19921  "ucomiss\t{%1, %0|%0, %1}"
19922  [(set_attr "type" "ssecomi")
19923   (set_attr "mode" "SF")])
19924
19925
19926;; SSE unpack
19927
19928(define_insn "sse_unpckhps"
19929  [(set (match_operand:V4SF 0 "register_operand" "=x")
19930	(vec_merge:V4SF
19931	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19932			  (parallel [(const_int 2)
19933				     (const_int 0)
19934				     (const_int 3)
19935				     (const_int 1)]))
19936	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19937			  (parallel [(const_int 0)
19938				     (const_int 2)
19939				     (const_int 1)
19940				     (const_int 3)]))
19941	 (const_int 5)))]
19942  "TARGET_SSE"
19943  "unpckhps\t{%2, %0|%0, %2}"
19944  [(set_attr "type" "ssecvt")
19945   (set_attr "mode" "V4SF")])
19946
19947(define_insn "sse_unpcklps"
19948  [(set (match_operand:V4SF 0 "register_operand" "=x")
19949	(vec_merge:V4SF
19950	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19951			  (parallel [(const_int 0)
19952				     (const_int 2)
19953				     (const_int 1)
19954				     (const_int 3)]))
19955	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19956			  (parallel [(const_int 2)
19957				     (const_int 0)
19958				     (const_int 3)
19959				     (const_int 1)]))
19960	 (const_int 5)))]
19961  "TARGET_SSE"
19962  "unpcklps\t{%2, %0|%0, %2}"
19963  [(set_attr "type" "ssecvt")
19964   (set_attr "mode" "V4SF")])
19965
19966
19967;; SSE min/max
19968
19969(define_insn "smaxv4sf3"
19970  [(set (match_operand:V4SF 0 "register_operand" "=x")
19971        (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19972		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19973  "TARGET_SSE"
19974  "maxps\t{%2, %0|%0, %2}"
19975  [(set_attr "type" "sse")
19976   (set_attr "mode" "V4SF")])
19977
19978(define_insn "vmsmaxv4sf3"
19979  [(set (match_operand:V4SF 0 "register_operand" "=x")
19980	(vec_merge:V4SF
19981	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19982		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19983	 (match_dup 1)
19984	 (const_int 1)))]
19985  "TARGET_SSE"
19986  "maxss\t{%2, %0|%0, %2}"
19987  [(set_attr "type" "sse")
19988   (set_attr "mode" "SF")])
19989
19990(define_insn "sminv4sf3"
19991  [(set (match_operand:V4SF 0 "register_operand" "=x")
19992        (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19993		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19994  "TARGET_SSE"
19995  "minps\t{%2, %0|%0, %2}"
19996  [(set_attr "type" "sse")
19997   (set_attr "mode" "V4SF")])
19998
19999(define_insn "vmsminv4sf3"
20000  [(set (match_operand:V4SF 0 "register_operand" "=x")
20001	(vec_merge:V4SF
20002	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20003		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20004	 (match_dup 1)
20005	 (const_int 1)))]
20006  "TARGET_SSE"
20007  "minss\t{%2, %0|%0, %2}"
20008  [(set_attr "type" "sse")
20009   (set_attr "mode" "SF")])
20010
20011;; SSE <-> integer/MMX conversions
20012
20013(define_insn "cvtpi2ps"
20014  [(set (match_operand:V4SF 0 "register_operand" "=x")
20015	(vec_merge:V4SF
20016	 (match_operand:V4SF 1 "register_operand" "0")
20017	 (vec_duplicate:V4SF
20018	  (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20019	 (const_int 12)))]
20020  "TARGET_SSE"
20021  "cvtpi2ps\t{%2, %0|%0, %2}"
20022  [(set_attr "type" "ssecvt")
20023   (set_attr "mode" "V4SF")])
20024
20025(define_insn "cvtps2pi"
20026  [(set (match_operand:V2SI 0 "register_operand" "=y")
20027	(vec_select:V2SI
20028	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20029	 (parallel [(const_int 0) (const_int 1)])))]
20030  "TARGET_SSE"
20031  "cvtps2pi\t{%1, %0|%0, %1}"
20032  [(set_attr "type" "ssecvt")
20033   (set_attr "mode" "V4SF")])
20034
20035(define_insn "cvttps2pi"
20036  [(set (match_operand:V2SI 0 "register_operand" "=y")
20037	(vec_select:V2SI
20038	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20039		      UNSPEC_FIX)
20040	 (parallel [(const_int 0) (const_int 1)])))]
20041  "TARGET_SSE"
20042  "cvttps2pi\t{%1, %0|%0, %1}"
20043  [(set_attr "type" "ssecvt")
20044   (set_attr "mode" "SF")])
20045
20046(define_insn "cvtsi2ss"
20047  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20048	(vec_merge:V4SF
20049	 (match_operand:V4SF 1 "register_operand" "0,0")
20050	 (vec_duplicate:V4SF
20051	  (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20052	 (const_int 14)))]
20053  "TARGET_SSE"
20054  "cvtsi2ss\t{%2, %0|%0, %2}"
20055  [(set_attr "type" "sseicvt")
20056   (set_attr "athlon_decode" "vector,double")
20057   (set_attr "mode" "SF")])
20058
20059(define_insn "cvtsi2ssq"
20060  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20061	(vec_merge:V4SF
20062	 (match_operand:V4SF 1 "register_operand" "0,0")
20063	 (vec_duplicate:V4SF
20064	  (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20065	 (const_int 14)))]
20066  "TARGET_SSE && TARGET_64BIT"
20067  "cvtsi2ssq\t{%2, %0|%0, %2}"
20068  [(set_attr "type" "sseicvt")
20069   (set_attr "athlon_decode" "vector,double")
20070   (set_attr "mode" "SF")])
20071
20072(define_insn "cvtss2si"
20073  [(set (match_operand:SI 0 "register_operand" "=r,r")
20074	(vec_select:SI
20075	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20076	 (parallel [(const_int 0)])))]
20077  "TARGET_SSE"
20078  "cvtss2si\t{%1, %0|%0, %1}"
20079  [(set_attr "type" "sseicvt")
20080   (set_attr "athlon_decode" "double,vector")
20081   (set_attr "mode" "SI")])
20082
20083(define_insn "cvtss2siq"
20084  [(set (match_operand:DI 0 "register_operand" "=r,r")
20085	(vec_select:DI
20086	 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20087	 (parallel [(const_int 0)])))]
20088  "TARGET_SSE"
20089  "cvtss2siq\t{%1, %0|%0, %1}"
20090  [(set_attr "type" "sseicvt")
20091   (set_attr "athlon_decode" "double,vector")
20092   (set_attr "mode" "DI")])
20093
20094(define_insn "cvttss2si"
20095  [(set (match_operand:SI 0 "register_operand" "=r,r")
20096	(vec_select:SI
20097	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20098		      UNSPEC_FIX)
20099	 (parallel [(const_int 0)])))]
20100  "TARGET_SSE"
20101  "cvttss2si\t{%1, %0|%0, %1}"
20102  [(set_attr "type" "sseicvt")
20103   (set_attr "mode" "SF")
20104   (set_attr "athlon_decode" "double,vector")])
20105
20106(define_insn "cvttss2siq"
20107  [(set (match_operand:DI 0 "register_operand" "=r,r")
20108	(vec_select:DI
20109	 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20110		      UNSPEC_FIX)
20111	 (parallel [(const_int 0)])))]
20112  "TARGET_SSE && TARGET_64BIT"
20113  "cvttss2siq\t{%1, %0|%0, %1}"
20114  [(set_attr "type" "sseicvt")
20115   (set_attr "mode" "SF")
20116   (set_attr "athlon_decode" "double,vector")])
20117
20118
20119;; MMX insns
20120
20121;; MMX arithmetic
20122
20123(define_insn "addv8qi3"
20124  [(set (match_operand:V8QI 0 "register_operand" "=y")
20125        (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20126	           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20127  "TARGET_MMX"
20128  "paddb\t{%2, %0|%0, %2}"
20129  [(set_attr "type" "mmxadd")
20130   (set_attr "mode" "DI")])
20131
20132(define_insn "addv4hi3"
20133  [(set (match_operand:V4HI 0 "register_operand" "=y")
20134        (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20135	           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20136  "TARGET_MMX"
20137  "paddw\t{%2, %0|%0, %2}"
20138  [(set_attr "type" "mmxadd")
20139   (set_attr "mode" "DI")])
20140
20141(define_insn "addv2si3"
20142  [(set (match_operand:V2SI 0 "register_operand" "=y")
20143        (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20144	           (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20145  "TARGET_MMX"
20146  "paddd\t{%2, %0|%0, %2}"
20147  [(set_attr "type" "mmxadd")
20148   (set_attr "mode" "DI")])
20149
20150(define_insn "mmx_adddi3"
20151  [(set (match_operand:DI 0 "register_operand" "=y")
20152        (unspec:DI
20153	 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20154		   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20155	 UNSPEC_NOP))]
20156  "TARGET_MMX"
20157  "paddq\t{%2, %0|%0, %2}"
20158  [(set_attr "type" "mmxadd")
20159   (set_attr "mode" "DI")])
20160
20161(define_insn "ssaddv8qi3"
20162  [(set (match_operand:V8QI 0 "register_operand" "=y")
20163        (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20164		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20165  "TARGET_MMX"
20166  "paddsb\t{%2, %0|%0, %2}"
20167  [(set_attr "type" "mmxadd")
20168   (set_attr "mode" "DI")])
20169
20170(define_insn "ssaddv4hi3"
20171  [(set (match_operand:V4HI 0 "register_operand" "=y")
20172        (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20173		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20174  "TARGET_MMX"
20175  "paddsw\t{%2, %0|%0, %2}"
20176  [(set_attr "type" "mmxadd")
20177   (set_attr "mode" "DI")])
20178
20179(define_insn "usaddv8qi3"
20180  [(set (match_operand:V8QI 0 "register_operand" "=y")
20181        (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20182		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20183  "TARGET_MMX"
20184  "paddusb\t{%2, %0|%0, %2}"
20185  [(set_attr "type" "mmxadd")
20186   (set_attr "mode" "DI")])
20187
20188(define_insn "usaddv4hi3"
20189  [(set (match_operand:V4HI 0 "register_operand" "=y")
20190        (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20191		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20192  "TARGET_MMX"
20193  "paddusw\t{%2, %0|%0, %2}"
20194  [(set_attr "type" "mmxadd")
20195   (set_attr "mode" "DI")])
20196
20197(define_insn "subv8qi3"
20198  [(set (match_operand:V8QI 0 "register_operand" "=y")
20199        (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20200		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20201  "TARGET_MMX"
20202  "psubb\t{%2, %0|%0, %2}"
20203  [(set_attr "type" "mmxadd")
20204   (set_attr "mode" "DI")])
20205
20206(define_insn "subv4hi3"
20207  [(set (match_operand:V4HI 0 "register_operand" "=y")
20208        (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20209		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20210  "TARGET_MMX"
20211  "psubw\t{%2, %0|%0, %2}"
20212  [(set_attr "type" "mmxadd")
20213   (set_attr "mode" "DI")])
20214
20215(define_insn "subv2si3"
20216  [(set (match_operand:V2SI 0 "register_operand" "=y")
20217        (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20218		    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20219  "TARGET_MMX"
20220  "psubd\t{%2, %0|%0, %2}"
20221  [(set_attr "type" "mmxadd")
20222   (set_attr "mode" "DI")])
20223
20224(define_insn "mmx_subdi3"
20225  [(set (match_operand:DI 0 "register_operand" "=y")
20226        (unspec:DI
20227	 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20228		    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20229	 UNSPEC_NOP))]
20230  "TARGET_MMX"
20231  "psubq\t{%2, %0|%0, %2}"
20232  [(set_attr "type" "mmxadd")
20233   (set_attr "mode" "DI")])
20234
20235(define_insn "sssubv8qi3"
20236  [(set (match_operand:V8QI 0 "register_operand" "=y")
20237        (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20238		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20239  "TARGET_MMX"
20240  "psubsb\t{%2, %0|%0, %2}"
20241  [(set_attr "type" "mmxadd")
20242   (set_attr "mode" "DI")])
20243
20244(define_insn "sssubv4hi3"
20245  [(set (match_operand:V4HI 0 "register_operand" "=y")
20246        (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20247		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20248  "TARGET_MMX"
20249  "psubsw\t{%2, %0|%0, %2}"
20250  [(set_attr "type" "mmxadd")
20251   (set_attr "mode" "DI")])
20252
20253(define_insn "ussubv8qi3"
20254  [(set (match_operand:V8QI 0 "register_operand" "=y")
20255        (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20256		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20257  "TARGET_MMX"
20258  "psubusb\t{%2, %0|%0, %2}"
20259  [(set_attr "type" "mmxadd")
20260   (set_attr "mode" "DI")])
20261
20262(define_insn "ussubv4hi3"
20263  [(set (match_operand:V4HI 0 "register_operand" "=y")
20264        (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20265		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20266  "TARGET_MMX"
20267  "psubusw\t{%2, %0|%0, %2}"
20268  [(set_attr "type" "mmxadd")
20269   (set_attr "mode" "DI")])
20270
20271(define_insn "mulv4hi3"
20272  [(set (match_operand:V4HI 0 "register_operand" "=y")
20273        (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20274		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20275  "TARGET_MMX"
20276  "pmullw\t{%2, %0|%0, %2}"
20277  [(set_attr "type" "mmxmul")
20278   (set_attr "mode" "DI")])
20279
20280(define_insn "smulv4hi3_highpart"
20281  [(set (match_operand:V4HI 0 "register_operand" "=y")
20282	(truncate:V4HI
20283	 (lshiftrt:V4SI
20284	  (mult:V4SI (sign_extend:V4SI
20285		      (match_operand:V4HI 1 "register_operand" "0"))
20286		     (sign_extend:V4SI
20287		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20288	  (const_int 16))))]
20289  "TARGET_MMX"
20290  "pmulhw\t{%2, %0|%0, %2}"
20291  [(set_attr "type" "mmxmul")
20292   (set_attr "mode" "DI")])
20293
20294(define_insn "umulv4hi3_highpart"
20295  [(set (match_operand:V4HI 0 "register_operand" "=y")
20296	(truncate:V4HI
20297	 (lshiftrt:V4SI
20298	  (mult:V4SI (zero_extend:V4SI
20299		      (match_operand:V4HI 1 "register_operand" "0"))
20300		     (zero_extend:V4SI
20301		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20302	  (const_int 16))))]
20303  "TARGET_SSE || TARGET_3DNOW_A"
20304  "pmulhuw\t{%2, %0|%0, %2}"
20305  [(set_attr "type" "mmxmul")
20306   (set_attr "mode" "DI")])
20307
20308(define_insn "mmx_pmaddwd"
20309  [(set (match_operand:V2SI 0 "register_operand" "=y")
20310        (plus:V2SI
20311	 (mult:V2SI
20312	  (sign_extend:V2SI
20313	   (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20314			    (parallel [(const_int 0) (const_int 2)])))
20315	  (sign_extend:V2SI
20316	   (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20317			    (parallel [(const_int 0) (const_int 2)]))))
20318	 (mult:V2SI
20319	  (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20320					     (parallel [(const_int 1)
20321							(const_int 3)])))
20322	  (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20323					     (parallel [(const_int 1)
20324							(const_int 3)]))))))]
20325  "TARGET_MMX"
20326  "pmaddwd\t{%2, %0|%0, %2}"
20327  [(set_attr "type" "mmxmul")
20328   (set_attr "mode" "DI")])
20329
20330
20331;; MMX logical operations
20332;; Note we don't want to declare these as regular iordi3 insns to prevent
20333;; normal code that also wants to use the FPU from getting broken.
20334;; The UNSPECs are there to prevent the combiner from getting overly clever.
20335(define_insn "mmx_iordi3"
20336  [(set (match_operand:DI 0 "register_operand" "=y")
20337        (unspec:DI
20338	 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20339		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20340	 UNSPEC_NOP))]
20341  "TARGET_MMX"
20342  "por\t{%2, %0|%0, %2}"
20343  [(set_attr "type" "mmxadd")
20344   (set_attr "mode" "DI")])
20345
20346(define_insn "mmx_xordi3"
20347  [(set (match_operand:DI 0 "register_operand" "=y")
20348        (unspec:DI
20349	 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20350		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20351	 UNSPEC_NOP))]
20352  "TARGET_MMX"
20353  "pxor\t{%2, %0|%0, %2}"
20354  [(set_attr "type" "mmxadd")
20355   (set_attr "mode" "DI")
20356   (set_attr "memory" "none")])
20357
20358;; Same as pxor, but don't show input operands so that we don't think
20359;; they are live.
20360(define_insn "mmx_clrdi"
20361  [(set (match_operand:DI 0 "register_operand" "=y")
20362        (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20363  "TARGET_MMX"
20364  "pxor\t{%0, %0|%0, %0}"
20365  [(set_attr "type" "mmxadd")
20366   (set_attr "mode" "DI")
20367   (set_attr "memory" "none")])
20368
20369(define_insn "mmx_anddi3"
20370  [(set (match_operand:DI 0 "register_operand" "=y")
20371        (unspec:DI
20372	 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20373		  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20374	 UNSPEC_NOP))]
20375  "TARGET_MMX"
20376  "pand\t{%2, %0|%0, %2}"
20377  [(set_attr "type" "mmxadd")
20378   (set_attr "mode" "DI")])
20379
20380(define_insn "mmx_nanddi3"
20381  [(set (match_operand:DI 0 "register_operand" "=y")
20382        (unspec:DI
20383	 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20384			  (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20385	 UNSPEC_NOP))]
20386  "TARGET_MMX"
20387  "pandn\t{%2, %0|%0, %2}"
20388  [(set_attr "type" "mmxadd")
20389   (set_attr "mode" "DI")])
20390
20391
20392;; MMX unsigned averages/sum of absolute differences
20393
20394(define_insn "mmx_uavgv8qi3"
20395  [(set (match_operand:V8QI 0 "register_operand" "=y")
20396        (ashiftrt:V8QI
20397	 (plus:V8QI (plus:V8QI
20398		     (match_operand:V8QI 1 "register_operand" "0")
20399		     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20400		    (const_vector:V8QI [(const_int 1)
20401					(const_int 1)
20402					(const_int 1)
20403					(const_int 1)
20404					(const_int 1)
20405					(const_int 1)
20406					(const_int 1)
20407					(const_int 1)]))
20408	 (const_int 1)))]
20409  "TARGET_SSE || TARGET_3DNOW_A"
20410  "pavgb\t{%2, %0|%0, %2}"
20411  [(set_attr "type" "mmxshft")
20412   (set_attr "mode" "DI")])
20413
20414(define_insn "mmx_uavgv4hi3"
20415  [(set (match_operand:V4HI 0 "register_operand" "=y")
20416        (ashiftrt:V4HI
20417	 (plus:V4HI (plus:V4HI
20418		     (match_operand:V4HI 1 "register_operand" "0")
20419		     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20420		    (const_vector:V4HI [(const_int 1)
20421					(const_int 1)
20422					(const_int 1)
20423					(const_int 1)]))
20424	 (const_int 1)))]
20425  "TARGET_SSE || TARGET_3DNOW_A"
20426  "pavgw\t{%2, %0|%0, %2}"
20427  [(set_attr "type" "mmxshft")
20428   (set_attr "mode" "DI")])
20429
20430(define_insn "mmx_psadbw"
20431  [(set (match_operand:DI 0 "register_operand" "=y")
20432        (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20433		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20434		   UNSPEC_PSADBW))]
20435  "TARGET_SSE || TARGET_3DNOW_A"
20436  "psadbw\t{%2, %0|%0, %2}"
20437  [(set_attr "type" "mmxshft")
20438   (set_attr "mode" "DI")])
20439
20440
20441;; MMX insert/extract/shuffle
20442
20443(define_insn "mmx_pinsrw"
20444  [(set (match_operand:V4HI 0 "register_operand" "=y")
20445        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20446			(vec_duplicate:V4HI
20447			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20448			(match_operand:SI 3 "const_0_to_15_operand" "N")))]
20449  "TARGET_SSE || TARGET_3DNOW_A"
20450  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20451  [(set_attr "type" "mmxcvt")
20452   (set_attr "mode" "DI")])
20453
20454(define_insn "mmx_pextrw"
20455  [(set (match_operand:SI 0 "register_operand" "=r")
20456        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20457				       (parallel
20458					[(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20459  "TARGET_SSE || TARGET_3DNOW_A"
20460  "pextrw\t{%2, %1, %0|%0, %1, %2}"
20461  [(set_attr "type" "mmxcvt")
20462   (set_attr "mode" "DI")])
20463
20464(define_insn "mmx_pshufw"
20465  [(set (match_operand:V4HI 0 "register_operand" "=y")
20466        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20467		      (match_operand:SI 2 "immediate_operand" "i")]
20468		     UNSPEC_SHUFFLE))]
20469  "TARGET_SSE || TARGET_3DNOW_A"
20470  "pshufw\t{%2, %1, %0|%0, %1, %2}"
20471  [(set_attr "type" "mmxcvt")
20472   (set_attr "mode" "DI")])
20473
20474
20475;; MMX mask-generating comparisons
20476
20477(define_insn "eqv8qi3"
20478  [(set (match_operand:V8QI 0 "register_operand" "=y")
20479        (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20480		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20481  "TARGET_MMX"
20482  "pcmpeqb\t{%2, %0|%0, %2}"
20483  [(set_attr "type" "mmxcmp")
20484   (set_attr "mode" "DI")])
20485
20486(define_insn "eqv4hi3"
20487  [(set (match_operand:V4HI 0 "register_operand" "=y")
20488        (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20489		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20490  "TARGET_MMX"
20491  "pcmpeqw\t{%2, %0|%0, %2}"
20492  [(set_attr "type" "mmxcmp")
20493   (set_attr "mode" "DI")])
20494
20495(define_insn "eqv2si3"
20496  [(set (match_operand:V2SI 0 "register_operand" "=y")
20497        (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20498		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20499  "TARGET_MMX"
20500  "pcmpeqd\t{%2, %0|%0, %2}"
20501  [(set_attr "type" "mmxcmp")
20502   (set_attr "mode" "DI")])
20503
20504(define_insn "gtv8qi3"
20505  [(set (match_operand:V8QI 0 "register_operand" "=y")
20506        (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20507		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20508  "TARGET_MMX"
20509  "pcmpgtb\t{%2, %0|%0, %2}"
20510  [(set_attr "type" "mmxcmp")
20511   (set_attr "mode" "DI")])
20512
20513(define_insn "gtv4hi3"
20514  [(set (match_operand:V4HI 0 "register_operand" "=y")
20515        (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20516		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20517  "TARGET_MMX"
20518  "pcmpgtw\t{%2, %0|%0, %2}"
20519  [(set_attr "type" "mmxcmp")
20520   (set_attr "mode" "DI")])
20521
20522(define_insn "gtv2si3"
20523  [(set (match_operand:V2SI 0 "register_operand" "=y")
20524        (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20525		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20526  "TARGET_MMX"
20527  "pcmpgtd\t{%2, %0|%0, %2}"
20528  [(set_attr "type" "mmxcmp")
20529   (set_attr "mode" "DI")])
20530
20531
20532;; MMX max/min insns
20533
20534(define_insn "umaxv8qi3"
20535  [(set (match_operand:V8QI 0 "register_operand" "=y")
20536        (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20537		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20538  "TARGET_SSE || TARGET_3DNOW_A"
20539  "pmaxub\t{%2, %0|%0, %2}"
20540  [(set_attr "type" "mmxadd")
20541   (set_attr "mode" "DI")])
20542
20543(define_insn "smaxv4hi3"
20544  [(set (match_operand:V4HI 0 "register_operand" "=y")
20545        (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20546		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20547  "TARGET_SSE || TARGET_3DNOW_A"
20548  "pmaxsw\t{%2, %0|%0, %2}"
20549  [(set_attr "type" "mmxadd")
20550   (set_attr "mode" "DI")])
20551
20552(define_insn "uminv8qi3"
20553  [(set (match_operand:V8QI 0 "register_operand" "=y")
20554        (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20555		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20556  "TARGET_SSE || TARGET_3DNOW_A"
20557  "pminub\t{%2, %0|%0, %2}"
20558  [(set_attr "type" "mmxadd")
20559   (set_attr "mode" "DI")])
20560
20561(define_insn "sminv4hi3"
20562  [(set (match_operand:V4HI 0 "register_operand" "=y")
20563        (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20564		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20565  "TARGET_SSE || TARGET_3DNOW_A"
20566  "pminsw\t{%2, %0|%0, %2}"
20567  [(set_attr "type" "mmxadd")
20568   (set_attr "mode" "DI")])
20569
20570
20571;; MMX shifts
20572
20573(define_insn "ashrv4hi3"
20574  [(set (match_operand:V4HI 0 "register_operand" "=y")
20575        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20576		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
20577  "TARGET_MMX"
20578  "psraw\t{%2, %0|%0, %2}"
20579  [(set_attr "type" "mmxshft")
20580   (set_attr "mode" "DI")])
20581
20582(define_insn "ashrv2si3"
20583  [(set (match_operand:V2SI 0 "register_operand" "=y")
20584        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20585		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
20586  "TARGET_MMX"
20587  "psrad\t{%2, %0|%0, %2}"
20588  [(set_attr "type" "mmxshft")
20589   (set_attr "mode" "DI")])
20590
20591(define_insn "lshrv4hi3"
20592  [(set (match_operand:V4HI 0 "register_operand" "=y")
20593        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20594		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
20595  "TARGET_MMX"
20596  "psrlw\t{%2, %0|%0, %2}"
20597  [(set_attr "type" "mmxshft")
20598   (set_attr "mode" "DI")])
20599
20600(define_insn "lshrv2si3"
20601  [(set (match_operand:V2SI 0 "register_operand" "=y")
20602        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20603		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
20604  "TARGET_MMX"
20605  "psrld\t{%2, %0|%0, %2}"
20606  [(set_attr "type" "mmxshft")
20607   (set_attr "mode" "DI")])
20608
20609;; See logical MMX insns.
20610(define_insn "mmx_lshrdi3"
20611  [(set (match_operand:DI 0 "register_operand" "=y")
20612        (unspec:DI
20613	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20614		       (match_operand:DI 2 "nonmemory_operand" "yi"))]
20615	  UNSPEC_NOP))]
20616  "TARGET_MMX"
20617  "psrlq\t{%2, %0|%0, %2}"
20618  [(set_attr "type" "mmxshft")
20619   (set_attr "mode" "DI")])
20620
20621(define_insn "ashlv4hi3"
20622  [(set (match_operand:V4HI 0 "register_operand" "=y")
20623        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20624		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
20625  "TARGET_MMX"
20626  "psllw\t{%2, %0|%0, %2}"
20627  [(set_attr "type" "mmxshft")
20628   (set_attr "mode" "DI")])
20629
20630(define_insn "ashlv2si3"
20631  [(set (match_operand:V2SI 0 "register_operand" "=y")
20632        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20633		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
20634  "TARGET_MMX"
20635  "pslld\t{%2, %0|%0, %2}"
20636  [(set_attr "type" "mmxshft")
20637   (set_attr "mode" "DI")])
20638
20639;; See logical MMX insns.
20640(define_insn "mmx_ashldi3"
20641  [(set (match_operand:DI 0 "register_operand" "=y")
20642        (unspec:DI
20643	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20644		     (match_operand:DI 2 "nonmemory_operand" "yi"))]
20645	 UNSPEC_NOP))]
20646  "TARGET_MMX"
20647  "psllq\t{%2, %0|%0, %2}"
20648  [(set_attr "type" "mmxshft")
20649   (set_attr "mode" "DI")])
20650
20651
20652;; MMX pack/unpack insns.
20653
20654(define_insn "mmx_packsswb"
20655  [(set (match_operand:V8QI 0 "register_operand" "=y")
20656	(vec_concat:V8QI
20657	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20658	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20659  "TARGET_MMX"
20660  "packsswb\t{%2, %0|%0, %2}"
20661  [(set_attr "type" "mmxshft")
20662   (set_attr "mode" "DI")])
20663
20664(define_insn "mmx_packssdw"
20665  [(set (match_operand:V4HI 0 "register_operand" "=y")
20666	(vec_concat:V4HI
20667	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20668	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20669  "TARGET_MMX"
20670  "packssdw\t{%2, %0|%0, %2}"
20671  [(set_attr "type" "mmxshft")
20672   (set_attr "mode" "DI")])
20673
20674(define_insn "mmx_packuswb"
20675  [(set (match_operand:V8QI 0 "register_operand" "=y")
20676	(vec_concat:V8QI
20677	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20678	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20679  "TARGET_MMX"
20680  "packuswb\t{%2, %0|%0, %2}"
20681  [(set_attr "type" "mmxshft")
20682   (set_attr "mode" "DI")])
20683
20684(define_insn "mmx_punpckhbw"
20685  [(set (match_operand:V8QI 0 "register_operand" "=y")
20686	(vec_merge:V8QI
20687	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20688			  (parallel [(const_int 4)
20689				     (const_int 0)
20690				     (const_int 5)
20691				     (const_int 1)
20692				     (const_int 6)
20693				     (const_int 2)
20694				     (const_int 7)
20695				     (const_int 3)]))
20696	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20697			  (parallel [(const_int 0)
20698				     (const_int 4)
20699				     (const_int 1)
20700				     (const_int 5)
20701				     (const_int 2)
20702				     (const_int 6)
20703				     (const_int 3)
20704				     (const_int 7)]))
20705	 (const_int 85)))]
20706  "TARGET_MMX"
20707  "punpckhbw\t{%2, %0|%0, %2}"
20708  [(set_attr "type" "mmxcvt")
20709   (set_attr "mode" "DI")])
20710
20711(define_insn "mmx_punpckhwd"
20712  [(set (match_operand:V4HI 0 "register_operand" "=y")
20713	(vec_merge:V4HI
20714	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20715			  (parallel [(const_int 0)
20716				     (const_int 2)
20717				     (const_int 1)
20718				     (const_int 3)]))
20719	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20720			  (parallel [(const_int 2)
20721				     (const_int 0)
20722				     (const_int 3)
20723				     (const_int 1)]))
20724	 (const_int 5)))]
20725  "TARGET_MMX"
20726  "punpckhwd\t{%2, %0|%0, %2}"
20727  [(set_attr "type" "mmxcvt")
20728   (set_attr "mode" "DI")])
20729
20730(define_insn "mmx_punpckhdq"
20731  [(set (match_operand:V2SI 0 "register_operand" "=y")
20732	(vec_merge:V2SI
20733	 (match_operand:V2SI 1 "register_operand" "0")
20734	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20735			  (parallel [(const_int 1)
20736				     (const_int 0)]))
20737	 (const_int 1)))]
20738  "TARGET_MMX"
20739  "punpckhdq\t{%2, %0|%0, %2}"
20740  [(set_attr "type" "mmxcvt")
20741   (set_attr "mode" "DI")])
20742
20743(define_insn "mmx_punpcklbw"
20744  [(set (match_operand:V8QI 0 "register_operand" "=y")
20745	(vec_merge:V8QI
20746	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20747			  (parallel [(const_int 0)
20748				     (const_int 4)
20749				     (const_int 1)
20750				     (const_int 5)
20751				     (const_int 2)
20752				     (const_int 6)
20753				     (const_int 3)
20754				     (const_int 7)]))
20755	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20756			  (parallel [(const_int 4)
20757				     (const_int 0)
20758				     (const_int 5)
20759				     (const_int 1)
20760				     (const_int 6)
20761				     (const_int 2)
20762				     (const_int 7)
20763				     (const_int 3)]))
20764	 (const_int 85)))]
20765  "TARGET_MMX"
20766  "punpcklbw\t{%2, %0|%0, %2}"
20767  [(set_attr "type" "mmxcvt")
20768   (set_attr "mode" "DI")])
20769
20770(define_insn "mmx_punpcklwd"
20771  [(set (match_operand:V4HI 0 "register_operand" "=y")
20772	(vec_merge:V4HI
20773	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20774			  (parallel [(const_int 2)
20775				     (const_int 0)
20776				     (const_int 3)
20777				     (const_int 1)]))
20778	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20779			  (parallel [(const_int 0)
20780				     (const_int 2)
20781				     (const_int 1)
20782				     (const_int 3)]))
20783	 (const_int 5)))]
20784  "TARGET_MMX"
20785  "punpcklwd\t{%2, %0|%0, %2}"
20786  [(set_attr "type" "mmxcvt")
20787   (set_attr "mode" "DI")])
20788
20789(define_insn "mmx_punpckldq"
20790  [(set (match_operand:V2SI 0 "register_operand" "=y")
20791	(vec_merge:V2SI
20792	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20793			   (parallel [(const_int 1)
20794				      (const_int 0)]))
20795	 (match_operand:V2SI 2 "register_operand" "y")
20796	 (const_int 1)))]
20797  "TARGET_MMX"
20798  "punpckldq\t{%2, %0|%0, %2}"
20799  [(set_attr "type" "mmxcvt")
20800   (set_attr "mode" "DI")])
20801
20802
20803;; Miscellaneous stuff
20804
20805(define_insn "emms"
20806  [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20807   (clobber (reg:XF 8))
20808   (clobber (reg:XF 9))
20809   (clobber (reg:XF 10))
20810   (clobber (reg:XF 11))
20811   (clobber (reg:XF 12))
20812   (clobber (reg:XF 13))
20813   (clobber (reg:XF 14))
20814   (clobber (reg:XF 15))
20815   (clobber (reg:DI 29))
20816   (clobber (reg:DI 30))
20817   (clobber (reg:DI 31))
20818   (clobber (reg:DI 32))
20819   (clobber (reg:DI 33))
20820   (clobber (reg:DI 34))
20821   (clobber (reg:DI 35))
20822   (clobber (reg:DI 36))]
20823  "TARGET_MMX"
20824  "emms"
20825  [(set_attr "type" "mmx")
20826   (set_attr "memory" "unknown")])
20827
20828(define_insn "ldmxcsr"
20829  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20830		    UNSPECV_LDMXCSR)]
20831  "TARGET_SSE"
20832  "ldmxcsr\t%0"
20833  [(set_attr "type" "sse")
20834   (set_attr "memory" "load")])
20835
20836(define_insn "stmxcsr"
20837  [(set (match_operand:SI 0 "memory_operand" "=m")
20838	(unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20839  "TARGET_SSE"
20840  "stmxcsr\t%0"
20841  [(set_attr "type" "sse")
20842   (set_attr "memory" "store")])
20843
20844(define_expand "sfence"
20845  [(set (match_dup 0)
20846	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20847  "TARGET_SSE || TARGET_3DNOW_A"
20848{
20849  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20850  MEM_VOLATILE_P (operands[0]) = 1;
20851})
20852
20853(define_insn "*sfence_insn"
20854  [(set (match_operand:BLK 0 "" "")
20855	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20856  "TARGET_SSE || TARGET_3DNOW_A"
20857  "sfence"
20858  [(set_attr "type" "sse")
20859   (set_attr "memory" "unknown")])
20860
20861(define_expand "sse_prologue_save"
20862  [(parallel [(set (match_operand:BLK 0 "" "")
20863		   (unspec:BLK [(reg:DI 21)
20864				(reg:DI 22)
20865				(reg:DI 23)
20866				(reg:DI 24)
20867				(reg:DI 25)
20868				(reg:DI 26)
20869				(reg:DI 27)
20870				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20871	      (use (match_operand:DI 1 "register_operand" ""))
20872	      (use (match_operand:DI 2 "immediate_operand" ""))
20873	      (use (label_ref:DI (match_operand 3 "" "")))])]
20874  "TARGET_64BIT"
20875  "")
20876
20877(define_insn "*sse_prologue_save_insn"
20878  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20879			  (match_operand:DI 4 "const_int_operand" "n")))
20880	(unspec:BLK [(reg:DI 21)
20881		     (reg:DI 22)
20882		     (reg:DI 23)
20883		     (reg:DI 24)
20884		     (reg:DI 25)
20885		     (reg:DI 26)
20886		     (reg:DI 27)
20887		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20888   (use (match_operand:DI 1 "register_operand" "r"))
20889   (use (match_operand:DI 2 "const_int_operand" "i"))
20890   (use (label_ref:DI (match_operand 3 "" "X")))]
20891  "TARGET_64BIT
20892   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20893   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20894  "*
20895{
20896  int i;
20897  operands[0] = gen_rtx_MEM (Pmode,
20898			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20899  output_asm_insn (\"jmp\\t%A1\", operands);
20900  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20901    {
20902      operands[4] = adjust_address (operands[0], DImode, i*16);
20903      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20904      PUT_MODE (operands[4], TImode);
20905      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20906        output_asm_insn (\"rex\", operands);
20907      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20908    }
20909  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20910			     CODE_LABEL_NUMBER (operands[3]));
20911  RET;
20912}
20913  "
20914  [(set_attr "type" "other")
20915   (set_attr "length_immediate" "0")
20916   (set_attr "length_address" "0")
20917   (set_attr "length" "135")
20918   (set_attr "memory" "store")
20919   (set_attr "modrm" "0")
20920   (set_attr "mode" "DI")])
20921
20922;; 3Dnow! instructions
20923
20924(define_insn "addv2sf3"
20925  [(set (match_operand:V2SF 0 "register_operand" "=y")
20926	(plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20927		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20928  "TARGET_3DNOW"
20929  "pfadd\\t{%2, %0|%0, %2}"
20930  [(set_attr "type" "mmxadd")
20931   (set_attr "mode" "V2SF")])
20932
20933(define_insn "subv2sf3"
20934  [(set (match_operand:V2SF 0 "register_operand" "=y")
20935        (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20936		    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20937  "TARGET_3DNOW"
20938  "pfsub\\t{%2, %0|%0, %2}"
20939  [(set_attr "type" "mmxadd")
20940   (set_attr "mode" "V2SF")])
20941
20942(define_insn "subrv2sf3"
20943  [(set (match_operand:V2SF 0 "register_operand" "=y")
20944        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20945                    (match_operand:V2SF 1 "register_operand" "0")))]
20946  "TARGET_3DNOW"
20947  "pfsubr\\t{%2, %0|%0, %2}"
20948  [(set_attr "type" "mmxadd")
20949   (set_attr "mode" "V2SF")])
20950
20951(define_insn "gtv2sf3"
20952  [(set (match_operand:V2SI 0 "register_operand" "=y")
20953	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20954		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20955 "TARGET_3DNOW"
20956  "pfcmpgt\\t{%2, %0|%0, %2}"
20957  [(set_attr "type" "mmxcmp")
20958   (set_attr "mode" "V2SF")])
20959
20960(define_insn "gev2sf3"
20961  [(set (match_operand:V2SI 0 "register_operand" "=y")
20962	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20963		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20964  "TARGET_3DNOW"
20965  "pfcmpge\\t{%2, %0|%0, %2}"
20966  [(set_attr "type" "mmxcmp")
20967   (set_attr "mode" "V2SF")])
20968
20969(define_insn "eqv2sf3"
20970  [(set (match_operand:V2SI 0 "register_operand" "=y")
20971	(eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20972		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20973  "TARGET_3DNOW"
20974  "pfcmpeq\\t{%2, %0|%0, %2}"
20975  [(set_attr "type" "mmxcmp")
20976   (set_attr "mode" "V2SF")])
20977
20978(define_insn "pfmaxv2sf3"
20979  [(set (match_operand:V2SF 0 "register_operand" "=y")
20980        (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20981                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20982  "TARGET_3DNOW"
20983  "pfmax\\t{%2, %0|%0, %2}"
20984  [(set_attr "type" "mmxadd")
20985   (set_attr "mode" "V2SF")])
20986
20987(define_insn "pfminv2sf3"
20988  [(set (match_operand:V2SF 0 "register_operand" "=y")
20989        (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20990                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20991  "TARGET_3DNOW"
20992  "pfmin\\t{%2, %0|%0, %2}"
20993  [(set_attr "type" "mmxadd")
20994   (set_attr "mode" "V2SF")])
20995
20996(define_insn "mulv2sf3"
20997  [(set (match_operand:V2SF 0 "register_operand" "=y")
20998	(mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20999		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21000  "TARGET_3DNOW"
21001  "pfmul\\t{%2, %0|%0, %2}"
21002  [(set_attr "type" "mmxmul")
21003   (set_attr "mode" "V2SF")])
21004
21005(define_insn "femms"
21006  [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21007   (clobber (reg:XF 8))
21008   (clobber (reg:XF 9))
21009   (clobber (reg:XF 10))
21010   (clobber (reg:XF 11))
21011   (clobber (reg:XF 12))
21012   (clobber (reg:XF 13))
21013   (clobber (reg:XF 14))
21014   (clobber (reg:XF 15))
21015   (clobber (reg:DI 29))
21016   (clobber (reg:DI 30))
21017   (clobber (reg:DI 31))
21018   (clobber (reg:DI 32))
21019   (clobber (reg:DI 33))
21020   (clobber (reg:DI 34))
21021   (clobber (reg:DI 35))
21022   (clobber (reg:DI 36))]
21023  "TARGET_3DNOW"
21024  "femms"
21025  [(set_attr "type" "mmx")
21026   (set_attr "memory" "none")]) 
21027
21028(define_insn "pf2id"
21029  [(set (match_operand:V2SI 0 "register_operand" "=y")
21030	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21031  "TARGET_3DNOW"
21032  "pf2id\\t{%1, %0|%0, %1}"
21033  [(set_attr "type" "mmxcvt")
21034   (set_attr "mode" "V2SF")])
21035
21036(define_insn "pf2iw"
21037  [(set (match_operand:V2SI 0 "register_operand" "=y")
21038	(sign_extend:V2SI
21039	   (ss_truncate:V2HI
21040	      (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21041  "TARGET_3DNOW_A"
21042  "pf2iw\\t{%1, %0|%0, %1}"
21043  [(set_attr "type" "mmxcvt")
21044   (set_attr "mode" "V2SF")])
21045
21046(define_insn "pfacc"
21047  [(set (match_operand:V2SF 0 "register_operand" "=y")
21048	(vec_concat:V2SF
21049	   (plus:SF
21050	      (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21051			     (parallel [(const_int  0)]))
21052	      (vec_select:SF (match_dup 1)
21053			     (parallel [(const_int 1)])))
21054           (plus:SF
21055              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21056			     (parallel [(const_int  0)]))
21057              (vec_select:SF (match_dup 2)
21058			     (parallel [(const_int 1)])))))]
21059  "TARGET_3DNOW"
21060  "pfacc\\t{%2, %0|%0, %2}"
21061  [(set_attr "type" "mmxadd")
21062   (set_attr "mode" "V2SF")])
21063
21064(define_insn "pfnacc"
21065  [(set (match_operand:V2SF 0 "register_operand" "=y")
21066  	(vec_concat:V2SF
21067           (minus:SF
21068              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21069			     (parallel [(const_int 0)]))
21070              (vec_select:SF (match_dup 1)
21071			     (parallel [(const_int 1)])))
21072           (minus:SF
21073              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21074			     (parallel [(const_int  0)]))
21075              (vec_select:SF (match_dup 2)
21076			     (parallel [(const_int 1)])))))]
21077  "TARGET_3DNOW_A"
21078  "pfnacc\\t{%2, %0|%0, %2}"
21079  [(set_attr "type" "mmxadd")
21080   (set_attr "mode" "V2SF")])
21081
21082(define_insn "pfpnacc"
21083  [(set (match_operand:V2SF 0 "register_operand" "=y")
21084        (vec_concat:V2SF
21085           (minus:SF
21086              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21087			     (parallel [(const_int 0)]))
21088              (vec_select:SF (match_dup 1)
21089			     (parallel [(const_int 1)])))
21090           (plus:SF
21091              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21092			     (parallel [(const_int 0)]))
21093              (vec_select:SF (match_dup 2)
21094			     (parallel [(const_int 1)])))))]
21095  "TARGET_3DNOW_A"
21096  "pfpnacc\\t{%2, %0|%0, %2}"
21097  [(set_attr "type" "mmxadd")
21098   (set_attr "mode" "V2SF")])
21099
21100(define_insn "pi2fw"
21101  [(set (match_operand:V2SF 0 "register_operand" "=y")
21102	(float:V2SF
21103	   (vec_concat:V2SI
21104	      (sign_extend:SI
21105		 (truncate:HI
21106		    (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21107				   (parallel [(const_int 0)]))))
21108              (sign_extend:SI
21109		 (truncate:HI
21110                    (vec_select:SI (match_dup 1)
21111				   (parallel [(const_int  1)])))))))]
21112  "TARGET_3DNOW_A"
21113  "pi2fw\\t{%1, %0|%0, %1}"
21114  [(set_attr "type" "mmxcvt")
21115   (set_attr "mode" "V2SF")])
21116
21117(define_insn "floatv2si2"
21118  [(set (match_operand:V2SF 0 "register_operand" "=y")
21119	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21120  "TARGET_3DNOW"
21121  "pi2fd\\t{%1, %0|%0, %1}"
21122  [(set_attr "type" "mmxcvt")
21123   (set_attr "mode" "V2SF")])
21124
21125;; This insn is identical to pavgb in operation, but the opcode is
21126;; different.  To avoid accidentally matching pavgb, use an unspec.
21127
21128(define_insn "pavgusb"
21129 [(set (match_operand:V8QI 0 "register_operand" "=y")
21130       (unspec:V8QI
21131          [(match_operand:V8QI 1 "register_operand" "0")
21132           (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21133	  UNSPEC_PAVGUSB))]
21134  "TARGET_3DNOW"
21135  "pavgusb\\t{%2, %0|%0, %2}"
21136  [(set_attr "type" "mmxshft")
21137   (set_attr "mode" "TI")])
21138
21139;; 3DNow reciprocal and sqrt
21140 
21141(define_insn "pfrcpv2sf2"
21142  [(set (match_operand:V2SF 0 "register_operand" "=y")
21143        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21144	UNSPEC_PFRCP))]
21145  "TARGET_3DNOW"
21146  "pfrcp\\t{%1, %0|%0, %1}"
21147  [(set_attr "type" "mmx")
21148   (set_attr "mode" "TI")])
21149
21150(define_insn "pfrcpit1v2sf3"
21151  [(set (match_operand:V2SF 0 "register_operand" "=y")
21152	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21153		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21154		     UNSPEC_PFRCPIT1))]
21155  "TARGET_3DNOW"
21156  "pfrcpit1\\t{%2, %0|%0, %2}"
21157  [(set_attr "type" "mmx")
21158   (set_attr "mode" "TI")])
21159
21160(define_insn "pfrcpit2v2sf3"
21161  [(set (match_operand:V2SF 0 "register_operand" "=y")
21162	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21163		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21164		     UNSPEC_PFRCPIT2))]
21165  "TARGET_3DNOW"
21166  "pfrcpit2\\t{%2, %0|%0, %2}"
21167  [(set_attr "type" "mmx")
21168   (set_attr "mode" "TI")])
21169
21170(define_insn "pfrsqrtv2sf2"
21171  [(set (match_operand:V2SF 0 "register_operand" "=y")
21172	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21173		     UNSPEC_PFRSQRT))]
21174  "TARGET_3DNOW"
21175  "pfrsqrt\\t{%1, %0|%0, %1}"
21176  [(set_attr "type" "mmx")
21177   (set_attr "mode" "TI")])
21178		
21179(define_insn "pfrsqit1v2sf3"
21180  [(set (match_operand:V2SF 0 "register_operand" "=y")
21181	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21182		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21183		     UNSPEC_PFRSQIT1))]
21184  "TARGET_3DNOW"
21185  "pfrsqit1\\t{%2, %0|%0, %2}"
21186  [(set_attr "type" "mmx")
21187   (set_attr "mode" "TI")])
21188
21189(define_insn "pmulhrwv4hi3"
21190  [(set (match_operand:V4HI 0 "register_operand" "=y")
21191	(truncate:V4HI
21192	   (lshiftrt:V4SI
21193	      (plus:V4SI
21194	         (mult:V4SI
21195	            (sign_extend:V4SI
21196		       (match_operand:V4HI 1 "register_operand" "0"))
21197	            (sign_extend:V4SI
21198		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21199		 (const_vector:V4SI [(const_int 32768)
21200				     (const_int 32768)
21201				     (const_int 32768)
21202				     (const_int 32768)]))
21203	      (const_int 16))))]
21204  "TARGET_3DNOW"
21205  "pmulhrw\\t{%2, %0|%0, %2}"
21206  [(set_attr "type" "mmxmul")
21207   (set_attr "mode" "TI")])
21208
21209(define_insn "pswapdv2si2"
21210  [(set (match_operand:V2SI 0 "register_operand" "=y")
21211	(vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21212			 (parallel [(const_int 1) (const_int 0)])))]
21213  "TARGET_3DNOW_A"
21214  "pswapd\\t{%1, %0|%0, %1}"
21215  [(set_attr "type" "mmxcvt")
21216   (set_attr "mode" "TI")])
21217
21218(define_insn "pswapdv2sf2"
21219  [(set (match_operand:V2SF 0 "register_operand" "=y")
21220	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21221			 (parallel [(const_int 1) (const_int 0)])))]
21222  "TARGET_3DNOW_A"
21223  "pswapd\\t{%1, %0|%0, %1}"
21224  [(set_attr "type" "mmxcvt")
21225   (set_attr "mode" "TI")])
21226
21227(define_expand "prefetch"
21228  [(prefetch (match_operand 0 "address_operand" "")
21229	     (match_operand:SI 1 "const_int_operand" "")
21230	     (match_operand:SI 2 "const_int_operand" ""))]
21231  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21232{
21233  int rw = INTVAL (operands[1]);
21234  int locality = INTVAL (operands[2]);
21235
21236  if (rw != 0 && rw != 1)
21237    abort ();
21238  if (locality < 0 || locality > 3)
21239    abort ();
21240  if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21241    abort ();
21242
21243  /* Use 3dNOW prefetch in case we are asking for write prefetch not
21244     suported by SSE counterpart or the SSE prefetch is not available
21245     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21246     of locality.  */
21247  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21248    operands[2] = GEN_INT (3);
21249  else
21250    operands[1] = const0_rtx;
21251})
21252
21253(define_insn "*prefetch_sse"
21254  [(prefetch (match_operand:SI 0 "address_operand" "p")
21255	     (const_int 0)
21256	     (match_operand:SI 1 "const_int_operand" ""))]
21257  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21258{
21259  static const char * const patterns[4] = {
21260   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21261  };
21262
21263  int locality = INTVAL (operands[1]);
21264  if (locality < 0 || locality > 3)
21265    abort ();
21266
21267  return patterns[locality];  
21268}
21269  [(set_attr "type" "sse")
21270   (set_attr "memory" "none")])
21271
21272(define_insn "*prefetch_sse_rex"
21273  [(prefetch (match_operand:DI 0 "address_operand" "p")
21274	     (const_int 0)
21275	     (match_operand:SI 1 "const_int_operand" ""))]
21276  "TARGET_PREFETCH_SSE && TARGET_64BIT"
21277{
21278  static const char * const patterns[4] = {
21279   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21280  };
21281
21282  int locality = INTVAL (operands[1]);
21283  if (locality < 0 || locality > 3)
21284    abort ();
21285
21286  return patterns[locality];  
21287}
21288  [(set_attr "type" "sse")
21289   (set_attr "memory" "none")])
21290
21291(define_insn "*prefetch_3dnow"
21292  [(prefetch (match_operand:SI 0 "address_operand" "p")
21293	     (match_operand:SI 1 "const_int_operand" "n")
21294	     (const_int 3))]
21295  "TARGET_3DNOW && !TARGET_64BIT"
21296{
21297  if (INTVAL (operands[1]) == 0)
21298    return "prefetch\t%a0";
21299  else
21300    return "prefetchw\t%a0";
21301}
21302  [(set_attr "type" "mmx")
21303   (set_attr "memory" "none")])
21304
21305(define_insn "*prefetch_3dnow_rex"
21306  [(prefetch (match_operand:DI 0 "address_operand" "p")
21307	     (match_operand:SI 1 "const_int_operand" "n")
21308	     (const_int 3))]
21309  "TARGET_3DNOW && TARGET_64BIT"
21310{
21311  if (INTVAL (operands[1]) == 0)
21312    return "prefetch\t%a0";
21313  else
21314    return "prefetchw\t%a0";
21315}
21316  [(set_attr "type" "mmx")
21317   (set_attr "memory" "none")])
21318
21319;; SSE2 support
21320
21321(define_insn "addv2df3"
21322  [(set (match_operand:V2DF 0 "register_operand" "=x")
21323        (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21324	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21325  "TARGET_SSE2"
21326  "addpd\t{%2, %0|%0, %2}"
21327  [(set_attr "type" "sseadd")
21328   (set_attr "mode" "V2DF")])
21329
21330(define_insn "vmaddv2df3"
21331  [(set (match_operand:V2DF 0 "register_operand" "=x")
21332	(vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21333	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21334                        (match_dup 1)
21335			(const_int 1)))]
21336  "TARGET_SSE2"
21337  "addsd\t{%2, %0|%0, %2}"
21338  [(set_attr "type" "sseadd")
21339   (set_attr "mode" "DF")])
21340
21341(define_insn "subv2df3"
21342  [(set (match_operand:V2DF 0 "register_operand" "=x")
21343        (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21344	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21345  "TARGET_SSE2"
21346  "subpd\t{%2, %0|%0, %2}"
21347  [(set_attr "type" "sseadd")
21348   (set_attr "mode" "V2DF")])
21349
21350(define_insn "vmsubv2df3"
21351  [(set (match_operand:V2DF 0 "register_operand" "=x")
21352	(vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21353	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21354                        (match_dup 1)
21355			(const_int 1)))]
21356  "TARGET_SSE2"
21357  "subsd\t{%2, %0|%0, %2}"
21358  [(set_attr "type" "sseadd")
21359   (set_attr "mode" "DF")])
21360
21361(define_insn "mulv2df3"
21362  [(set (match_operand:V2DF 0 "register_operand" "=x")
21363        (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21364	           (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21365  "TARGET_SSE2"
21366  "mulpd\t{%2, %0|%0, %2}"
21367  [(set_attr "type" "ssemul")
21368   (set_attr "mode" "V2DF")])
21369
21370(define_insn "vmmulv2df3"
21371  [(set (match_operand:V2DF 0 "register_operand" "=x")
21372	(vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21373	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21374                        (match_dup 1)
21375			(const_int 1)))]
21376  "TARGET_SSE2"
21377  "mulsd\t{%2, %0|%0, %2}"
21378  [(set_attr "type" "ssemul")
21379   (set_attr "mode" "DF")])
21380
21381(define_insn "divv2df3"
21382  [(set (match_operand:V2DF 0 "register_operand" "=x")
21383        (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21384	          (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21385  "TARGET_SSE2"
21386  "divpd\t{%2, %0|%0, %2}"
21387  [(set_attr "type" "ssediv")
21388   (set_attr "mode" "V2DF")])
21389
21390(define_insn "vmdivv2df3"
21391  [(set (match_operand:V2DF 0 "register_operand" "=x")
21392	(vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21393				  (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21394                        (match_dup 1)
21395			(const_int 1)))]
21396  "TARGET_SSE2"
21397  "divsd\t{%2, %0|%0, %2}"
21398  [(set_attr "type" "ssediv")
21399   (set_attr "mode" "DF")])
21400
21401;; SSE min/max
21402
21403(define_insn "smaxv2df3"
21404  [(set (match_operand:V2DF 0 "register_operand" "=x")
21405        (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21406		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21407  "TARGET_SSE2"
21408  "maxpd\t{%2, %0|%0, %2}"
21409  [(set_attr "type" "sseadd")
21410   (set_attr "mode" "V2DF")])
21411
21412(define_insn "vmsmaxv2df3"
21413  [(set (match_operand:V2DF 0 "register_operand" "=x")
21414	(vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21415	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21416                        (match_dup 1)
21417			(const_int 1)))]
21418  "TARGET_SSE2"
21419  "maxsd\t{%2, %0|%0, %2}"
21420  [(set_attr "type" "sseadd")
21421   (set_attr "mode" "DF")])
21422
21423(define_insn "sminv2df3"
21424  [(set (match_operand:V2DF 0 "register_operand" "=x")
21425        (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21426		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21427  "TARGET_SSE2"
21428  "minpd\t{%2, %0|%0, %2}"
21429  [(set_attr "type" "sseadd")
21430   (set_attr "mode" "V2DF")])
21431
21432(define_insn "vmsminv2df3"
21433  [(set (match_operand:V2DF 0 "register_operand" "=x")
21434	(vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21435	                           (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21436                        (match_dup 1)
21437			(const_int 1)))]
21438  "TARGET_SSE2"
21439  "minsd\t{%2, %0|%0, %2}"
21440  [(set_attr "type" "sseadd")
21441   (set_attr "mode" "DF")])
21442;; SSE2 square root.  There doesn't appear to be an extension for the
21443;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21444
21445(define_insn "sqrtv2df2"
21446  [(set (match_operand:V2DF 0 "register_operand" "=x")
21447        (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21448  "TARGET_SSE2"
21449  "sqrtpd\t{%1, %0|%0, %1}"
21450  [(set_attr "type" "sse")
21451   (set_attr "mode" "V2DF")])
21452
21453(define_insn "vmsqrtv2df2"
21454  [(set (match_operand:V2DF 0 "register_operand" "=x")
21455	(vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21456                        (match_operand:V2DF 2 "register_operand" "0")
21457			(const_int 1)))]
21458  "TARGET_SSE2"
21459  "sqrtsd\t{%1, %0|%0, %1}"
21460  [(set_attr "type" "sse")
21461   (set_attr "mode" "SF")])
21462
21463;; SSE mask-generating compares
21464
21465(define_insn "maskcmpv2df3"
21466  [(set (match_operand:V2DI 0 "register_operand" "=x")
21467        (match_operator:V2DI 3 "sse_comparison_operator"
21468			     [(match_operand:V2DF 1 "register_operand" "0")
21469			      (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21470  "TARGET_SSE2"
21471  "cmp%D3pd\t{%2, %0|%0, %2}"
21472  [(set_attr "type" "ssecmp")
21473   (set_attr "mode" "V2DF")])
21474
21475(define_insn "maskncmpv2df3"
21476  [(set (match_operand:V2DI 0 "register_operand" "=x")
21477        (not:V2DI
21478	 (match_operator:V2DI 3 "sse_comparison_operator"
21479			      [(match_operand:V2DF 1 "register_operand" "0")
21480			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21481  "TARGET_SSE2"
21482{
21483  if (GET_CODE (operands[3]) == UNORDERED)
21484    return "cmpordps\t{%2, %0|%0, %2}";
21485  else
21486    return "cmpn%D3pd\t{%2, %0|%0, %2}";
21487}
21488  [(set_attr "type" "ssecmp")
21489   (set_attr "mode" "V2DF")])
21490
21491(define_insn "vmmaskcmpv2df3"
21492  [(set (match_operand:V2DI 0 "register_operand" "=x")
21493	(vec_merge:V2DI
21494	 (match_operator:V2DI 3 "sse_comparison_operator"
21495			      [(match_operand:V2DF 1 "register_operand" "0")
21496			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21497	 (subreg:V2DI (match_dup 1) 0)
21498	 (const_int 1)))]
21499  "TARGET_SSE2"
21500  "cmp%D3sd\t{%2, %0|%0, %2}"
21501  [(set_attr "type" "ssecmp")
21502   (set_attr "mode" "DF")])
21503
21504(define_insn "vmmaskncmpv2df3"
21505  [(set (match_operand:V2DI 0 "register_operand" "=x")
21506	(vec_merge:V2DI
21507	 (not:V2DI
21508	  (match_operator:V2DI 3 "sse_comparison_operator"
21509			       [(match_operand:V2DF 1 "register_operand" "0")
21510				(match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21511	 (subreg:V2DI (match_dup 1) 0)
21512	 (const_int 1)))]
21513  "TARGET_SSE2"
21514{
21515  if (GET_CODE (operands[3]) == UNORDERED)
21516    return "cmpordsd\t{%2, %0|%0, %2}";
21517  else
21518    return "cmpn%D3sd\t{%2, %0|%0, %2}";
21519}
21520  [(set_attr "type" "ssecmp")
21521   (set_attr "mode" "DF")])
21522
21523(define_insn "sse2_comi"
21524  [(set (reg:CCFP 17)
21525        (compare:CCFP (vec_select:DF
21526		       (match_operand:V2DF 0 "register_operand" "x")
21527		       (parallel [(const_int 0)]))
21528		      (vec_select:DF
21529		       (match_operand:V2DF 1 "register_operand" "x")
21530		       (parallel [(const_int 0)]))))]
21531  "TARGET_SSE2"
21532  "comisd\t{%1, %0|%0, %1}"
21533  [(set_attr "type" "ssecomi")
21534   (set_attr "mode" "DF")])
21535
21536(define_insn "sse2_ucomi"
21537  [(set (reg:CCFPU 17)
21538	(compare:CCFPU (vec_select:DF
21539			 (match_operand:V2DF 0 "register_operand" "x")
21540			 (parallel [(const_int 0)]))
21541			(vec_select:DF
21542			 (match_operand:V2DF 1 "register_operand" "x")
21543			 (parallel [(const_int 0)]))))]
21544  "TARGET_SSE2"
21545  "ucomisd\t{%1, %0|%0, %1}"
21546  [(set_attr "type" "ssecomi")
21547   (set_attr "mode" "DF")])
21548
21549;; SSE Strange Moves.
21550
21551(define_insn "sse2_movmskpd"
21552  [(set (match_operand:SI 0 "register_operand" "=r")
21553	(unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21554		   UNSPEC_MOVMSK))]
21555  "TARGET_SSE2"
21556  "movmskpd\t{%1, %0|%0, %1}"
21557  [(set_attr "type" "ssecvt")
21558   (set_attr "mode" "V2DF")])
21559
21560(define_insn "sse2_pmovmskb"
21561  [(set (match_operand:SI 0 "register_operand" "=r")
21562	(unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21563		   UNSPEC_MOVMSK))]
21564  "TARGET_SSE2"
21565  "pmovmskb\t{%1, %0|%0, %1}"
21566  [(set_attr "type" "ssecvt")
21567   (set_attr "mode" "V2DF")])
21568
21569(define_insn "sse2_maskmovdqu"
21570  [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21571	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21572		       (match_operand:V16QI 2 "register_operand" "x")]
21573		      UNSPEC_MASKMOV))]
21574  "TARGET_SSE2"
21575  ;; @@@ check ordering of operands in intel/nonintel syntax
21576  "maskmovdqu\t{%2, %1|%1, %2}"
21577  [(set_attr "type" "ssecvt")
21578   (set_attr "mode" "TI")])
21579
21580(define_insn "sse2_maskmovdqu_rex64"
21581  [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21582	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21583		       (match_operand:V16QI 2 "register_operand" "x")]
21584		      UNSPEC_MASKMOV))]
21585  "TARGET_SSE2"
21586  ;; @@@ check ordering of operands in intel/nonintel syntax
21587  "maskmovdqu\t{%2, %1|%1, %2}"
21588  [(set_attr "type" "ssecvt")
21589   (set_attr "mode" "TI")])
21590
21591(define_insn "sse2_movntv2df"
21592  [(set (match_operand:V2DF 0 "memory_operand" "=m")
21593	(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21594		     UNSPEC_MOVNT))]
21595  "TARGET_SSE2"
21596  "movntpd\t{%1, %0|%0, %1}"
21597  [(set_attr "type" "ssecvt")
21598   (set_attr "mode" "V2DF")])
21599
21600(define_insn "sse2_movntv2di"
21601  [(set (match_operand:V2DI 0 "memory_operand" "=m")
21602	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21603		     UNSPEC_MOVNT))]
21604  "TARGET_SSE2"
21605  "movntdq\t{%1, %0|%0, %1}"
21606  [(set_attr "type" "ssecvt")
21607   (set_attr "mode" "TI")])
21608
21609(define_insn "sse2_movntsi"
21610  [(set (match_operand:SI 0 "memory_operand" "=m")
21611	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21612		   UNSPEC_MOVNT))]
21613  "TARGET_SSE2"
21614  "movnti\t{%1, %0|%0, %1}"
21615  [(set_attr "type" "ssecvt")
21616   (set_attr "mode" "V2DF")])
21617
21618;; SSE <-> integer/MMX conversions
21619
21620;; Conversions between SI and SF
21621
21622(define_insn "cvtdq2ps"
21623  [(set (match_operand:V4SF 0 "register_operand" "=x")
21624	(float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21625  "TARGET_SSE2"
21626  "cvtdq2ps\t{%1, %0|%0, %1}"
21627  [(set_attr "type" "ssecvt")
21628   (set_attr "mode" "V2DF")])
21629
21630(define_insn "cvtps2dq"
21631  [(set (match_operand:V4SI 0 "register_operand" "=x")
21632	(fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21633  "TARGET_SSE2"
21634  "cvtps2dq\t{%1, %0|%0, %1}"
21635  [(set_attr "type" "ssecvt")
21636   (set_attr "mode" "TI")])
21637
21638(define_insn "cvttps2dq"
21639  [(set (match_operand:V4SI 0 "register_operand" "=x")
21640	(unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21641		     UNSPEC_FIX))]
21642  "TARGET_SSE2"
21643  "cvttps2dq\t{%1, %0|%0, %1}"
21644  [(set_attr "type" "ssecvt")
21645   (set_attr "mode" "TI")])
21646
21647;; Conversions between SI and DF
21648
21649(define_insn "cvtdq2pd"
21650  [(set (match_operand:V2DF 0 "register_operand" "=x")
21651	(float:V2DF (vec_select:V2SI
21652		     (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21653		     (parallel
21654		      [(const_int 0)
21655		       (const_int 1)]))))]
21656  "TARGET_SSE2"
21657  "cvtdq2pd\t{%1, %0|%0, %1}"
21658  [(set_attr "type" "ssecvt")
21659   (set_attr "mode" "V2DF")])
21660
21661(define_insn "cvtpd2dq"
21662  [(set (match_operand:V4SI 0 "register_operand" "=x")
21663	(vec_concat:V4SI
21664	 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21665	 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21666  "TARGET_SSE2"
21667  "cvtpd2dq\t{%1, %0|%0, %1}"
21668  [(set_attr "type" "ssecvt")
21669   (set_attr "mode" "TI")])
21670
21671(define_insn "cvttpd2dq"
21672  [(set (match_operand:V4SI 0 "register_operand" "=x")
21673	(vec_concat:V4SI
21674	 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21675		      UNSPEC_FIX)
21676	 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21677  "TARGET_SSE2"
21678  "cvttpd2dq\t{%1, %0|%0, %1}"
21679  [(set_attr "type" "ssecvt")
21680   (set_attr "mode" "TI")])
21681
21682(define_insn "cvtpd2pi"
21683  [(set (match_operand:V2SI 0 "register_operand" "=y")
21684	(fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21685  "TARGET_SSE2"
21686  "cvtpd2pi\t{%1, %0|%0, %1}"
21687  [(set_attr "type" "ssecvt")
21688   (set_attr "mode" "TI")])
21689
21690(define_insn "cvttpd2pi"
21691  [(set (match_operand:V2SI 0 "register_operand" "=y")
21692	(unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21693		     UNSPEC_FIX))]
21694  "TARGET_SSE2"
21695  "cvttpd2pi\t{%1, %0|%0, %1}"
21696  [(set_attr "type" "ssecvt")
21697   (set_attr "mode" "TI")])
21698
21699(define_insn "cvtpi2pd"
21700  [(set (match_operand:V2DF 0 "register_operand" "=x")
21701	(float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21702  "TARGET_SSE2"
21703  "cvtpi2pd\t{%1, %0|%0, %1}"
21704  [(set_attr "type" "ssecvt")
21705   (set_attr "mode" "TI")])
21706
21707;; Conversions between SI and DF
21708
21709(define_insn "cvtsd2si"
21710  [(set (match_operand:SI 0 "register_operand" "=r,r")
21711	(fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21712			       (parallel [(const_int 0)]))))]
21713  "TARGET_SSE2"
21714  "cvtsd2si\t{%1, %0|%0, %1}"
21715  [(set_attr "type" "sseicvt")
21716   (set_attr "athlon_decode" "double,vector")
21717   (set_attr "mode" "SI")])
21718
21719(define_insn "cvtsd2siq"
21720  [(set (match_operand:DI 0 "register_operand" "=r,r")
21721	(fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21722			       (parallel [(const_int 0)]))))]
21723  "TARGET_SSE2 && TARGET_64BIT"
21724  "cvtsd2siq\t{%1, %0|%0, %1}"
21725  [(set_attr "type" "sseicvt")
21726   (set_attr "athlon_decode" "double,vector")
21727   (set_attr "mode" "DI")])
21728
21729(define_insn "cvttsd2si"
21730  [(set (match_operand:SI 0 "register_operand" "=r,r")
21731	(unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21732				   (parallel [(const_int 0)]))] UNSPEC_FIX))]
21733  "TARGET_SSE2"
21734  "cvttsd2si\t{%1, %0|%0, %1}"
21735  [(set_attr "type" "sseicvt")
21736   (set_attr "mode" "SI")
21737   (set_attr "athlon_decode" "double,vector")])
21738
21739(define_insn "cvttsd2siq"
21740  [(set (match_operand:DI 0 "register_operand" "=r,r")
21741	(unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21742				   (parallel [(const_int 0)]))] UNSPEC_FIX))]
21743  "TARGET_SSE2 && TARGET_64BIT"
21744  "cvttsd2siq\t{%1, %0|%0, %1}"
21745  [(set_attr "type" "sseicvt")
21746   (set_attr "mode" "DI")
21747   (set_attr "athlon_decode" "double,vector")])
21748
21749(define_insn "cvtsi2sd"
21750  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21751	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21752	 		(vec_duplicate:V2DF
21753			  (float:DF
21754			    (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21755			(const_int 2)))]
21756  "TARGET_SSE2"
21757  "cvtsi2sd\t{%2, %0|%0, %2}"
21758  [(set_attr "type" "sseicvt")
21759   (set_attr "mode" "DF")
21760   (set_attr "athlon_decode" "double,direct")])
21761
21762(define_insn "cvtsi2sdq"
21763  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21764	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21765	 		(vec_duplicate:V2DF
21766			  (float:DF
21767			    (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21768			(const_int 2)))]
21769  "TARGET_SSE2 && TARGET_64BIT"
21770  "cvtsi2sdq\t{%2, %0|%0, %2}"
21771  [(set_attr "type" "sseicvt")
21772   (set_attr "mode" "DF")
21773   (set_attr "athlon_decode" "double,direct")])
21774
21775;; Conversions between SF and DF
21776
21777(define_insn "cvtsd2ss"
21778  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21779	(vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21780	 		(vec_duplicate:V4SF
21781			  (float_truncate:V2SF
21782			    (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21783			(const_int 14)))]
21784  "TARGET_SSE2"
21785  "cvtsd2ss\t{%2, %0|%0, %2}"
21786  [(set_attr "type" "ssecvt")
21787   (set_attr "athlon_decode" "vector,double")
21788   (set_attr "mode" "SF")])
21789
21790(define_insn "cvtss2sd"
21791  [(set (match_operand:V2DF 0 "register_operand" "=x")
21792	(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21793	 		(float_extend:V2DF
21794			  (vec_select:V2SF
21795			    (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21796			    (parallel [(const_int 0)
21797				       (const_int 1)])))
21798			(const_int 2)))]
21799  "TARGET_SSE2"
21800  "cvtss2sd\t{%2, %0|%0, %2}"
21801  [(set_attr "type" "ssecvt")
21802   (set_attr "mode" "DF")])
21803
21804(define_insn "cvtpd2ps"
21805  [(set (match_operand:V4SF 0 "register_operand" "=x")
21806	(subreg:V4SF
21807	  (vec_concat:V4SI
21808	    (subreg:V2SI (float_truncate:V2SF
21809			   (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21810	    (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21811  "TARGET_SSE2"
21812  "cvtpd2ps\t{%1, %0|%0, %1}"
21813  [(set_attr "type" "ssecvt")
21814   (set_attr "mode" "V4SF")])
21815
21816(define_insn "cvtps2pd"
21817  [(set (match_operand:V2DF 0 "register_operand" "=x")
21818	(float_extend:V2DF
21819	  (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21820			   (parallel [(const_int 0)
21821				      (const_int 1)]))))]
21822  "TARGET_SSE2"
21823  "cvtps2pd\t{%1, %0|%0, %1}"
21824  [(set_attr "type" "ssecvt")
21825   (set_attr "mode" "V2DF")])
21826
21827;; SSE2 variants of MMX insns
21828
21829;; MMX arithmetic
21830
21831(define_insn "addv16qi3"
21832  [(set (match_operand:V16QI 0 "register_operand" "=x")
21833        (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21834		    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21835  "TARGET_SSE2"
21836  "paddb\t{%2, %0|%0, %2}"
21837  [(set_attr "type" "sseiadd")
21838   (set_attr "mode" "TI")])
21839
21840(define_insn "addv8hi3"
21841  [(set (match_operand:V8HI 0 "register_operand" "=x")
21842        (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21843	           (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21844  "TARGET_SSE2"
21845  "paddw\t{%2, %0|%0, %2}"
21846  [(set_attr "type" "sseiadd")
21847   (set_attr "mode" "TI")])
21848
21849(define_insn "addv4si3"
21850  [(set (match_operand:V4SI 0 "register_operand" "=x")
21851        (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21852	           (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21853  "TARGET_SSE2"
21854  "paddd\t{%2, %0|%0, %2}"
21855  [(set_attr "type" "sseiadd")
21856   (set_attr "mode" "TI")])
21857
21858(define_insn "addv2di3"
21859  [(set (match_operand:V2DI 0 "register_operand" "=x")
21860        (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21861	           (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21862  "TARGET_SSE2"
21863  "paddq\t{%2, %0|%0, %2}"
21864  [(set_attr "type" "sseiadd")
21865   (set_attr "mode" "TI")])
21866
21867(define_insn "ssaddv16qi3"
21868  [(set (match_operand:V16QI 0 "register_operand" "=x")
21869        (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21870		       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21871  "TARGET_SSE2"
21872  "paddsb\t{%2, %0|%0, %2}"
21873  [(set_attr "type" "sseiadd")
21874   (set_attr "mode" "TI")])
21875
21876(define_insn "ssaddv8hi3"
21877  [(set (match_operand:V8HI 0 "register_operand" "=x")
21878        (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21879		      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21880  "TARGET_SSE2"
21881  "paddsw\t{%2, %0|%0, %2}"
21882  [(set_attr "type" "sseiadd")
21883   (set_attr "mode" "TI")])
21884
21885(define_insn "usaddv16qi3"
21886  [(set (match_operand:V16QI 0 "register_operand" "=x")
21887        (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21888		       (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21889  "TARGET_SSE2"
21890  "paddusb\t{%2, %0|%0, %2}"
21891  [(set_attr "type" "sseiadd")
21892   (set_attr "mode" "TI")])
21893
21894(define_insn "usaddv8hi3"
21895  [(set (match_operand:V8HI 0 "register_operand" "=x")
21896        (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21897		      (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21898  "TARGET_SSE2"
21899  "paddusw\t{%2, %0|%0, %2}"
21900  [(set_attr "type" "sseiadd")
21901   (set_attr "mode" "TI")])
21902
21903(define_insn "subv16qi3"
21904  [(set (match_operand:V16QI 0 "register_operand" "=x")
21905        (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21906		     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21907  "TARGET_SSE2"
21908  "psubb\t{%2, %0|%0, %2}"
21909  [(set_attr "type" "sseiadd")
21910   (set_attr "mode" "TI")])
21911
21912(define_insn "subv8hi3"
21913  [(set (match_operand:V8HI 0 "register_operand" "=x")
21914        (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21915		    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21916  "TARGET_SSE2"
21917  "psubw\t{%2, %0|%0, %2}"
21918  [(set_attr "type" "sseiadd")
21919   (set_attr "mode" "TI")])
21920
21921(define_insn "subv4si3"
21922  [(set (match_operand:V4SI 0 "register_operand" "=x")
21923        (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21924		    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21925  "TARGET_SSE2"
21926  "psubd\t{%2, %0|%0, %2}"
21927  [(set_attr "type" "sseiadd")
21928   (set_attr "mode" "TI")])
21929
21930(define_insn "subv2di3"
21931  [(set (match_operand:V2DI 0 "register_operand" "=x")
21932        (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21933		    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21934  "TARGET_SSE2"
21935  "psubq\t{%2, %0|%0, %2}"
21936  [(set_attr "type" "sseiadd")
21937   (set_attr "mode" "TI")])
21938
21939(define_insn "sssubv16qi3"
21940  [(set (match_operand:V16QI 0 "register_operand" "=x")
21941        (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21942			(match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21943  "TARGET_SSE2"
21944  "psubsb\t{%2, %0|%0, %2}"
21945  [(set_attr "type" "sseiadd")
21946   (set_attr "mode" "TI")])
21947
21948(define_insn "sssubv8hi3"
21949  [(set (match_operand:V8HI 0 "register_operand" "=x")
21950        (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21951		       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21952  "TARGET_SSE2"
21953  "psubsw\t{%2, %0|%0, %2}"
21954  [(set_attr "type" "sseiadd")
21955   (set_attr "mode" "TI")])
21956
21957(define_insn "ussubv16qi3"
21958  [(set (match_operand:V16QI 0 "register_operand" "=x")
21959        (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21960			(match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21961  "TARGET_SSE2"
21962  "psubusb\t{%2, %0|%0, %2}"
21963  [(set_attr "type" "sseiadd")
21964   (set_attr "mode" "TI")])
21965
21966(define_insn "ussubv8hi3"
21967  [(set (match_operand:V8HI 0 "register_operand" "=x")
21968        (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21969		       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21970  "TARGET_SSE2"
21971  "psubusw\t{%2, %0|%0, %2}"
21972  [(set_attr "type" "sseiadd")
21973   (set_attr "mode" "TI")])
21974
21975(define_insn "mulv8hi3"
21976  [(set (match_operand:V8HI 0 "register_operand" "=x")
21977        (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21978		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21979  "TARGET_SSE2"
21980  "pmullw\t{%2, %0|%0, %2}"
21981  [(set_attr "type" "sseimul")
21982   (set_attr "mode" "TI")])
21983
21984(define_insn "smulv8hi3_highpart"
21985  [(set (match_operand:V8HI 0 "register_operand" "=x")
21986	(truncate:V8HI
21987	 (lshiftrt:V8SI
21988	  (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21989		     (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21990	  (const_int 16))))]
21991  "TARGET_SSE2"
21992  "pmulhw\t{%2, %0|%0, %2}"
21993  [(set_attr "type" "sseimul")
21994   (set_attr "mode" "TI")])
21995
21996(define_insn "umulv8hi3_highpart"
21997  [(set (match_operand:V8HI 0 "register_operand" "=x")
21998	(truncate:V8HI
21999	 (lshiftrt:V8SI
22000	  (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22001		     (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22002	  (const_int 16))))]
22003  "TARGET_SSE2"
22004  "pmulhuw\t{%2, %0|%0, %2}"
22005  [(set_attr "type" "sseimul")
22006   (set_attr "mode" "TI")])
22007
22008(define_insn "sse2_umulsidi3"
22009  [(set (match_operand:DI 0 "register_operand" "=y")
22010        (mult:DI (zero_extend:DI (vec_select:SI
22011				  (match_operand:V2SI 1 "register_operand" "0")
22012				  (parallel [(const_int 0)])))
22013		 (zero_extend:DI (vec_select:SI
22014				  (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22015				  (parallel [(const_int 0)])))))]
22016  "TARGET_SSE2"
22017  "pmuludq\t{%2, %0|%0, %2}"
22018  [(set_attr "type" "sseimul")
22019   (set_attr "mode" "TI")])
22020
22021(define_insn "sse2_umulv2siv2di3"
22022  [(set (match_operand:V2DI 0 "register_operand" "=x")
22023        (mult:V2DI (zero_extend:V2DI
22024		     (vec_select:V2SI
22025		       (match_operand:V4SI 1 "register_operand" "0")
22026		       (parallel [(const_int 0) (const_int 2)])))
22027		   (zero_extend:V2DI
22028		     (vec_select:V2SI
22029		       (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22030		       (parallel [(const_int 0) (const_int 2)])))))]
22031  "TARGET_SSE2"
22032  "pmuludq\t{%2, %0|%0, %2}"
22033  [(set_attr "type" "sseimul")
22034   (set_attr "mode" "TI")])
22035
22036(define_insn "sse2_pmaddwd"
22037  [(set (match_operand:V4SI 0 "register_operand" "=x")
22038        (plus:V4SI
22039	 (mult:V4SI
22040	  (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22041					     (parallel [(const_int 0)
22042							(const_int 2)
22043							(const_int 4)
22044							(const_int 6)])))
22045	  (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22046					     (parallel [(const_int 0)
22047							(const_int 2)
22048							(const_int 4)
22049							(const_int 6)]))))
22050	 (mult:V4SI
22051	  (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22052					     (parallel [(const_int 1)
22053							(const_int 3)
22054							(const_int 5)
22055							(const_int 7)])))
22056	  (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22057					     (parallel [(const_int 1)
22058							(const_int 3)
22059							(const_int 5)
22060							(const_int 7)]))))))]
22061  "TARGET_SSE2"
22062  "pmaddwd\t{%2, %0|%0, %2}"
22063  [(set_attr "type" "sseiadd")
22064   (set_attr "mode" "TI")])
22065
22066;; Same as pxor, but don't show input operands so that we don't think
22067;; they are live.
22068(define_insn "sse2_clrti"
22069  [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22070  "TARGET_SSE2"
22071{
22072  if (get_attr_mode (insn) == MODE_TI)
22073    return "pxor\t%0, %0";
22074  else
22075    return "xorps\t%0, %0";
22076}
22077  [(set_attr "type" "ssemov")
22078   (set_attr "memory" "none")
22079   (set (attr "mode")
22080	      (if_then_else
22081		(ne (symbol_ref "optimize_size")
22082		    (const_int 0))
22083		(const_string "V4SF")
22084		(const_string "TI")))])
22085
22086;; MMX unsigned averages/sum of absolute differences
22087
22088(define_insn "sse2_uavgv16qi3"
22089  [(set (match_operand:V16QI 0 "register_operand" "=x")
22090        (ashiftrt:V16QI
22091	 (plus:V16QI (plus:V16QI
22092		     (match_operand:V16QI 1 "register_operand" "0")
22093		     (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22094		     (const_vector:V16QI [(const_int 1) (const_int 1)
22095					  (const_int 1) (const_int 1)
22096					  (const_int 1) (const_int 1)
22097					  (const_int 1) (const_int 1)
22098					  (const_int 1) (const_int 1)
22099					  (const_int 1) (const_int 1)
22100					  (const_int 1) (const_int 1)
22101					  (const_int 1) (const_int 1)]))
22102	 (const_int 1)))]
22103  "TARGET_SSE2"
22104  "pavgb\t{%2, %0|%0, %2}"
22105  [(set_attr "type" "sseiadd")
22106   (set_attr "mode" "TI")])
22107
22108(define_insn "sse2_uavgv8hi3"
22109  [(set (match_operand:V8HI 0 "register_operand" "=x")
22110        (ashiftrt:V8HI
22111	 (plus:V8HI (plus:V8HI
22112		     (match_operand:V8HI 1 "register_operand" "0")
22113		     (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22114		    (const_vector:V8HI [(const_int 1) (const_int 1)
22115				        (const_int 1) (const_int 1)
22116				        (const_int 1) (const_int 1)
22117				        (const_int 1) (const_int 1)]))
22118	 (const_int 1)))]
22119  "TARGET_SSE2"
22120  "pavgw\t{%2, %0|%0, %2}"
22121  [(set_attr "type" "sseiadd")
22122   (set_attr "mode" "TI")])
22123
22124;; @@@ this isn't the right representation.
22125(define_insn "sse2_psadbw"
22126  [(set (match_operand:V2DI 0 "register_operand" "=x")
22127        (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22128		      (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22129		     UNSPEC_PSADBW))]
22130  "TARGET_SSE2"
22131  "psadbw\t{%2, %0|%0, %2}"
22132  [(set_attr "type" "sseiadd")
22133   (set_attr "mode" "TI")])
22134
22135
22136;; MMX insert/extract/shuffle
22137
22138(define_insn "sse2_pinsrw"
22139  [(set (match_operand:V8HI 0 "register_operand" "=x")
22140        (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22141			(vec_duplicate:V8HI
22142			 (truncate:HI
22143			   (match_operand:SI 2 "nonimmediate_operand" "rm")))
22144			(match_operand:SI 3 "const_0_to_255_operand" "N")))]
22145  "TARGET_SSE2"
22146  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22147  [(set_attr "type" "ssecvt")
22148   (set_attr "mode" "TI")])
22149
22150(define_insn "sse2_pextrw"
22151  [(set (match_operand:SI 0 "register_operand" "=r")
22152        (zero_extend:SI
22153	  (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22154			 (parallel
22155			  [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22156  "TARGET_SSE2"
22157  "pextrw\t{%2, %1, %0|%0, %1, %2}"
22158  [(set_attr "type" "ssecvt")
22159   (set_attr "mode" "TI")])
22160
22161(define_insn "sse2_pshufd"
22162  [(set (match_operand:V4SI 0 "register_operand" "=x")
22163        (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22164		      (match_operand:SI 2 "immediate_operand" "i")]
22165		     UNSPEC_SHUFFLE))]
22166  "TARGET_SSE2"
22167  "pshufd\t{%2, %1, %0|%0, %1, %2}"
22168  [(set_attr "type" "ssecvt")
22169   (set_attr "mode" "TI")])
22170
22171(define_insn "sse2_pshuflw"
22172  [(set (match_operand:V8HI 0 "register_operand" "=x")
22173        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22174		      (match_operand:SI 2 "immediate_operand" "i")]
22175		     UNSPEC_PSHUFLW))]
22176  "TARGET_SSE2"
22177  "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22178  [(set_attr "type" "ssecvt")
22179   (set_attr "mode" "TI")])
22180
22181(define_insn "sse2_pshufhw"
22182  [(set (match_operand:V8HI 0 "register_operand" "=x")
22183        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22184		      (match_operand:SI 2 "immediate_operand" "i")]
22185		     UNSPEC_PSHUFHW))]
22186  "TARGET_SSE2"
22187  "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22188  [(set_attr "type" "ssecvt")
22189   (set_attr "mode" "TI")])
22190
22191;; MMX mask-generating comparisons
22192
22193(define_insn "eqv16qi3"
22194  [(set (match_operand:V16QI 0 "register_operand" "=x")
22195        (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22196		 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22197  "TARGET_SSE2"
22198  "pcmpeqb\t{%2, %0|%0, %2}"
22199  [(set_attr "type" "ssecmp")
22200   (set_attr "mode" "TI")])
22201
22202(define_insn "eqv8hi3"
22203  [(set (match_operand:V8HI 0 "register_operand" "=x")
22204        (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22205		 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22206  "TARGET_SSE2"
22207  "pcmpeqw\t{%2, %0|%0, %2}"
22208  [(set_attr "type" "ssecmp")
22209   (set_attr "mode" "TI")])
22210
22211(define_insn "eqv4si3"
22212  [(set (match_operand:V4SI 0 "register_operand" "=x")
22213        (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22214		 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22215  "TARGET_SSE2"
22216  "pcmpeqd\t{%2, %0|%0, %2}"
22217  [(set_attr "type" "ssecmp")
22218   (set_attr "mode" "TI")])
22219
22220(define_insn "gtv16qi3"
22221  [(set (match_operand:V16QI 0 "register_operand" "=x")
22222        (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22223		 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22224  "TARGET_SSE2"
22225  "pcmpgtb\t{%2, %0|%0, %2}"
22226  [(set_attr "type" "ssecmp")
22227   (set_attr "mode" "TI")])
22228
22229(define_insn "gtv8hi3"
22230  [(set (match_operand:V8HI 0 "register_operand" "=x")
22231        (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22232		 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22233  "TARGET_SSE2"
22234  "pcmpgtw\t{%2, %0|%0, %2}"
22235  [(set_attr "type" "ssecmp")
22236   (set_attr "mode" "TI")])
22237
22238(define_insn "gtv4si3"
22239  [(set (match_operand:V4SI 0 "register_operand" "=x")
22240        (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22241		 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22242  "TARGET_SSE2"
22243  "pcmpgtd\t{%2, %0|%0, %2}"
22244  [(set_attr "type" "ssecmp")
22245   (set_attr "mode" "TI")])
22246
22247
22248;; MMX max/min insns
22249
22250(define_insn "umaxv16qi3"
22251  [(set (match_operand:V16QI 0 "register_operand" "=x")
22252        (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22253		   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22254  "TARGET_SSE2"
22255  "pmaxub\t{%2, %0|%0, %2}"
22256  [(set_attr "type" "sseiadd")
22257   (set_attr "mode" "TI")])
22258
22259(define_insn "smaxv8hi3"
22260  [(set (match_operand:V8HI 0 "register_operand" "=x")
22261        (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22262		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22263  "TARGET_SSE2"
22264  "pmaxsw\t{%2, %0|%0, %2}"
22265  [(set_attr "type" "sseiadd")
22266   (set_attr "mode" "TI")])
22267
22268(define_insn "uminv16qi3"
22269  [(set (match_operand:V16QI 0 "register_operand" "=x")
22270        (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22271		   (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22272  "TARGET_SSE2"
22273  "pminub\t{%2, %0|%0, %2}"
22274  [(set_attr "type" "sseiadd")
22275   (set_attr "mode" "TI")])
22276
22277(define_insn "sminv8hi3"
22278  [(set (match_operand:V8HI 0 "register_operand" "=x")
22279        (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22280		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22281  "TARGET_SSE2"
22282  "pminsw\t{%2, %0|%0, %2}"
22283  [(set_attr "type" "sseiadd")
22284   (set_attr "mode" "TI")])
22285
22286
22287;; MMX shifts
22288
22289(define_insn "ashrv8hi3"
22290  [(set (match_operand:V8HI 0 "register_operand" "=x")
22291        (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22292		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22293  "TARGET_SSE2"
22294  "psraw\t{%2, %0|%0, %2}"
22295  [(set_attr "type" "sseishft")
22296   (set_attr "mode" "TI")])
22297
22298(define_insn "ashrv4si3"
22299  [(set (match_operand:V4SI 0 "register_operand" "=x")
22300        (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22301		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22302  "TARGET_SSE2"
22303  "psrad\t{%2, %0|%0, %2}"
22304  [(set_attr "type" "sseishft")
22305   (set_attr "mode" "TI")])
22306
22307(define_insn "lshrv8hi3"
22308  [(set (match_operand:V8HI 0 "register_operand" "=x")
22309        (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22310		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22311  "TARGET_SSE2"
22312  "psrlw\t{%2, %0|%0, %2}"
22313  [(set_attr "type" "sseishft")
22314   (set_attr "mode" "TI")])
22315
22316(define_insn "lshrv4si3"
22317  [(set (match_operand:V4SI 0 "register_operand" "=x")
22318        (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22319		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22320  "TARGET_SSE2"
22321  "psrld\t{%2, %0|%0, %2}"
22322  [(set_attr "type" "sseishft")
22323   (set_attr "mode" "TI")])
22324
22325(define_insn "lshrv2di3"
22326  [(set (match_operand:V2DI 0 "register_operand" "=x")
22327        (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22328		       (match_operand:SI 2 "nonmemory_operand" "xi")))]
22329  "TARGET_SSE2"
22330  "psrlq\t{%2, %0|%0, %2}"
22331  [(set_attr "type" "sseishft")
22332   (set_attr "mode" "TI")])
22333
22334(define_insn "ashlv8hi3"
22335  [(set (match_operand:V8HI 0 "register_operand" "=x")
22336        (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22337		     (match_operand:SI 2 "nonmemory_operand" "xi")))]
22338  "TARGET_SSE2"
22339  "psllw\t{%2, %0|%0, %2}"
22340  [(set_attr "type" "sseishft")
22341   (set_attr "mode" "TI")])
22342
22343(define_insn "ashlv4si3"
22344  [(set (match_operand:V4SI 0 "register_operand" "=x")
22345        (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22346		     (match_operand:SI 2 "nonmemory_operand" "xi")))]
22347  "TARGET_SSE2"
22348  "pslld\t{%2, %0|%0, %2}"
22349  [(set_attr "type" "sseishft")
22350   (set_attr "mode" "TI")])
22351
22352(define_insn "ashlv2di3"
22353  [(set (match_operand:V2DI 0 "register_operand" "=x")
22354        (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22355		     (match_operand:SI 2 "nonmemory_operand" "xi")))]
22356  "TARGET_SSE2"
22357  "psllq\t{%2, %0|%0, %2}"
22358  [(set_attr "type" "sseishft")
22359   (set_attr "mode" "TI")])
22360
22361(define_insn "ashrv8hi3_ti"
22362  [(set (match_operand:V8HI 0 "register_operand" "=x")
22363        (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22364		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22365  "TARGET_SSE2"
22366  "psraw\t{%2, %0|%0, %2}"
22367  [(set_attr "type" "sseishft")
22368   (set_attr "mode" "TI")])
22369
22370(define_insn "ashrv4si3_ti"
22371  [(set (match_operand:V4SI 0 "register_operand" "=x")
22372        (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22373		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22374  "TARGET_SSE2"
22375  "psrad\t{%2, %0|%0, %2}"
22376  [(set_attr "type" "sseishft")
22377   (set_attr "mode" "TI")])
22378
22379(define_insn "lshrv8hi3_ti"
22380  [(set (match_operand:V8HI 0 "register_operand" "=x")
22381        (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22382		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22383  "TARGET_SSE2"
22384  "psrlw\t{%2, %0|%0, %2}"
22385  [(set_attr "type" "sseishft")
22386   (set_attr "mode" "TI")])
22387
22388(define_insn "lshrv4si3_ti"
22389  [(set (match_operand:V4SI 0 "register_operand" "=x")
22390        (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22391		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22392  "TARGET_SSE2"
22393  "psrld\t{%2, %0|%0, %2}"
22394  [(set_attr "type" "sseishft")
22395   (set_attr "mode" "TI")])
22396
22397(define_insn "lshrv2di3_ti"
22398  [(set (match_operand:V2DI 0 "register_operand" "=x")
22399        (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22400		       (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22401  "TARGET_SSE2"
22402  "psrlq\t{%2, %0|%0, %2}"
22403  [(set_attr "type" "sseishft")
22404   (set_attr "mode" "TI")])
22405
22406(define_insn "ashlv8hi3_ti"
22407  [(set (match_operand:V8HI 0 "register_operand" "=x")
22408        (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22409		     (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22410  "TARGET_SSE2"
22411  "psllw\t{%2, %0|%0, %2}"
22412  [(set_attr "type" "sseishft")
22413   (set_attr "mode" "TI")])
22414
22415(define_insn "ashlv4si3_ti"
22416  [(set (match_operand:V4SI 0 "register_operand" "=x")
22417        (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22418		     (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22419  "TARGET_SSE2"
22420  "pslld\t{%2, %0|%0, %2}"
22421  [(set_attr "type" "sseishft")
22422   (set_attr "mode" "TI")])
22423
22424(define_insn "ashlv2di3_ti"
22425  [(set (match_operand:V2DI 0 "register_operand" "=x")
22426        (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22427		     (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22428  "TARGET_SSE2"
22429  "psllq\t{%2, %0|%0, %2}"
22430  [(set_attr "type" "sseishft")
22431   (set_attr "mode" "TI")])
22432
22433;; See logical MMX insns for the reason for the unspec.  Strictly speaking
22434;; we wouldn't need here it since we never generate TImode arithmetic.
22435
22436;; There has to be some kind of prize for the weirdest new instruction...
22437(define_insn "sse2_ashlti3"
22438  [(set (match_operand:TI 0 "register_operand" "=x")
22439        (unspec:TI
22440	 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22441		     (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22442			       (const_int 8)))] UNSPEC_NOP))]
22443  "TARGET_SSE2"
22444  "pslldq\t{%2, %0|%0, %2}"
22445  [(set_attr "type" "sseishft")
22446   (set_attr "mode" "TI")])
22447
22448(define_insn "sse2_lshrti3"
22449  [(set (match_operand:TI 0 "register_operand" "=x")
22450        (unspec:TI
22451	 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22452		       (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22453				(const_int 8)))] UNSPEC_NOP))]
22454  "TARGET_SSE2"
22455  "psrldq\t{%2, %0|%0, %2}"
22456  [(set_attr "type" "sseishft")
22457   (set_attr "mode" "TI")])
22458
22459;; SSE unpack
22460
22461(define_insn "sse2_unpckhpd"
22462  [(set (match_operand:V2DF 0 "register_operand" "=x")
22463	(vec_concat:V2DF
22464	 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22465			(parallel [(const_int 1)]))
22466	 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22467			(parallel [(const_int 1)]))))]
22468  "TARGET_SSE2"
22469  "unpckhpd\t{%2, %0|%0, %2}"
22470  [(set_attr "type" "ssecvt")
22471   (set_attr "mode" "V2DF")])
22472
22473(define_insn "sse2_unpcklpd"
22474  [(set (match_operand:V2DF 0 "register_operand" "=x")
22475	(vec_concat:V2DF
22476	 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22477			(parallel [(const_int 0)]))
22478	 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22479			(parallel [(const_int 0)]))))]
22480  "TARGET_SSE2"
22481  "unpcklpd\t{%2, %0|%0, %2}"
22482  [(set_attr "type" "ssecvt")
22483   (set_attr "mode" "V2DF")])
22484
22485;; MMX pack/unpack insns.
22486
22487(define_insn "sse2_packsswb"
22488  [(set (match_operand:V16QI 0 "register_operand" "=x")
22489	(vec_concat:V16QI
22490	 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22491	 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22492  "TARGET_SSE2"
22493  "packsswb\t{%2, %0|%0, %2}"
22494  [(set_attr "type" "ssecvt")
22495   (set_attr "mode" "TI")])
22496
22497(define_insn "sse2_packssdw"
22498  [(set (match_operand:V8HI 0 "register_operand" "=x")
22499	(vec_concat:V8HI
22500	 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22501	 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22502  "TARGET_SSE2"
22503  "packssdw\t{%2, %0|%0, %2}"
22504  [(set_attr "type" "ssecvt")
22505   (set_attr "mode" "TI")])
22506
22507(define_insn "sse2_packuswb"
22508  [(set (match_operand:V16QI 0 "register_operand" "=x")
22509	(vec_concat:V16QI
22510	 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22511	 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22512  "TARGET_SSE2"
22513  "packuswb\t{%2, %0|%0, %2}"
22514  [(set_attr "type" "ssecvt")
22515   (set_attr "mode" "TI")])
22516
22517(define_insn "sse2_punpckhbw"
22518  [(set (match_operand:V16QI 0 "register_operand" "=x")
22519	(vec_merge:V16QI
22520	 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22521			   (parallel [(const_int 8) (const_int 0)
22522				      (const_int 9) (const_int 1)
22523				      (const_int 10) (const_int 2)
22524				      (const_int 11) (const_int 3)
22525				      (const_int 12) (const_int 4)
22526				      (const_int 13) (const_int 5)
22527				      (const_int 14) (const_int 6)
22528				      (const_int 15) (const_int 7)]))
22529	 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22530			   (parallel [(const_int 0) (const_int 8)
22531				      (const_int 1) (const_int 9)
22532				      (const_int 2) (const_int 10)
22533				      (const_int 3) (const_int 11)
22534				      (const_int 4) (const_int 12)
22535				      (const_int 5) (const_int 13)
22536				      (const_int 6) (const_int 14)
22537				      (const_int 7) (const_int 15)]))
22538	 (const_int 21845)))]
22539  "TARGET_SSE2"
22540  "punpckhbw\t{%2, %0|%0, %2}"
22541  [(set_attr "type" "ssecvt")
22542   (set_attr "mode" "TI")])
22543
22544(define_insn "sse2_punpckhwd"
22545  [(set (match_operand:V8HI 0 "register_operand" "=x")
22546	(vec_merge:V8HI
22547	 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22548			  (parallel [(const_int 4) (const_int 0)
22549				     (const_int 5) (const_int 1)
22550				     (const_int 6) (const_int 2)
22551				     (const_int 7) (const_int 3)]))
22552	 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22553			  (parallel [(const_int 0) (const_int 4)
22554				     (const_int 1) (const_int 5)
22555				     (const_int 2) (const_int 6)
22556				     (const_int 3) (const_int 7)]))
22557	 (const_int 85)))]
22558  "TARGET_SSE2"
22559  "punpckhwd\t{%2, %0|%0, %2}"
22560  [(set_attr "type" "ssecvt")
22561   (set_attr "mode" "TI")])
22562
22563(define_insn "sse2_punpckhdq"
22564  [(set (match_operand:V4SI 0 "register_operand" "=x")
22565	(vec_merge:V4SI
22566	 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22567			  (parallel [(const_int 2) (const_int 0)
22568				     (const_int 3) (const_int 1)]))
22569	 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22570			  (parallel [(const_int 0) (const_int 2)
22571				     (const_int 1) (const_int 3)]))
22572	 (const_int 5)))]
22573  "TARGET_SSE2"
22574  "punpckhdq\t{%2, %0|%0, %2}"
22575  [(set_attr "type" "ssecvt")
22576   (set_attr "mode" "TI")])
22577
22578(define_insn "sse2_punpcklbw"
22579  [(set (match_operand:V16QI 0 "register_operand" "=x")
22580	(vec_merge:V16QI
22581	 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22582			   (parallel [(const_int 0) (const_int 8)
22583				      (const_int 1) (const_int 9)
22584				      (const_int 2) (const_int 10)
22585				      (const_int 3) (const_int 11)
22586				      (const_int 4) (const_int 12)
22587				      (const_int 5) (const_int 13)
22588				      (const_int 6) (const_int 14)
22589				      (const_int 7) (const_int 15)]))
22590	 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22591			   (parallel [(const_int 8) (const_int 0)
22592				      (const_int 9) (const_int 1)
22593				      (const_int 10) (const_int 2)
22594				      (const_int 11) (const_int 3)
22595				      (const_int 12) (const_int 4)
22596				      (const_int 13) (const_int 5)
22597				      (const_int 14) (const_int 6)
22598				      (const_int 15) (const_int 7)]))
22599	 (const_int 21845)))]
22600  "TARGET_SSE2"
22601  "punpcklbw\t{%2, %0|%0, %2}"
22602  [(set_attr "type" "ssecvt")
22603   (set_attr "mode" "TI")])
22604
22605(define_insn "sse2_punpcklwd"
22606  [(set (match_operand:V8HI 0 "register_operand" "=x")
22607	(vec_merge:V8HI
22608	 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22609			  (parallel [(const_int 0) (const_int 4)
22610				     (const_int 1) (const_int 5)
22611				     (const_int 2) (const_int 6)
22612				     (const_int 3) (const_int 7)]))
22613	 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22614			  (parallel [(const_int 4) (const_int 0)
22615				     (const_int 5) (const_int 1)
22616				     (const_int 6) (const_int 2)
22617				     (const_int 7) (const_int 3)]))
22618	 (const_int 85)))]
22619  "TARGET_SSE2"
22620  "punpcklwd\t{%2, %0|%0, %2}"
22621  [(set_attr "type" "ssecvt")
22622   (set_attr "mode" "TI")])
22623
22624(define_insn "sse2_punpckldq"
22625  [(set (match_operand:V4SI 0 "register_operand" "=x")
22626	(vec_merge:V4SI
22627	 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22628			  (parallel [(const_int 0) (const_int 2)
22629				     (const_int 1) (const_int 3)]))
22630	 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22631			  (parallel [(const_int 2) (const_int 0)
22632				     (const_int 3) (const_int 1)]))
22633	 (const_int 5)))]
22634  "TARGET_SSE2"
22635  "punpckldq\t{%2, %0|%0, %2}"
22636  [(set_attr "type" "ssecvt")
22637   (set_attr "mode" "TI")])
22638
22639(define_insn "sse2_punpcklqdq"
22640  [(set (match_operand:V2DI 0 "register_operand" "=x")
22641	(vec_merge:V2DI
22642	 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22643			  (parallel [(const_int 1)
22644				     (const_int 0)]))
22645	 (match_operand:V2DI 1 "register_operand" "0")
22646	 (const_int 1)))]
22647  "TARGET_SSE2"
22648  "punpcklqdq\t{%2, %0|%0, %2}"
22649  [(set_attr "type" "ssecvt")
22650   (set_attr "mode" "TI")])
22651
22652(define_insn "sse2_punpckhqdq"
22653  [(set (match_operand:V2DI 0 "register_operand" "=x")
22654	(vec_merge:V2DI
22655	 (match_operand:V2DI 1 "register_operand" "0")
22656	 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22657			  (parallel [(const_int 1)
22658				     (const_int 0)]))
22659	 (const_int 1)))]
22660  "TARGET_SSE2"
22661  "punpckhqdq\t{%2, %0|%0, %2}"
22662  [(set_attr "type" "ssecvt")
22663   (set_attr "mode" "TI")])
22664
22665;; SSE2 moves
22666
22667(define_insn "sse2_movapd"
22668  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22669	(unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22670		     UNSPEC_MOVA))]
22671  "TARGET_SSE2
22672   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22673  "movapd\t{%1, %0|%0, %1}"
22674  [(set_attr "type" "ssemov")
22675   (set_attr "mode" "V2DF")])
22676
22677(define_insn "sse2_movupd"
22678  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22679	(unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22680		     UNSPEC_MOVU))]
22681  "TARGET_SSE2
22682   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22683  "movupd\t{%1, %0|%0, %1}"
22684  [(set_attr "type" "ssecvt")
22685   (set_attr "mode" "V2DF")])
22686
22687(define_insn "sse2_movdqa"
22688  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22689	(unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22690		       UNSPEC_MOVA))]
22691  "TARGET_SSE2
22692   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22693  "movdqa\t{%1, %0|%0, %1}"
22694  [(set_attr "type" "ssemov")
22695   (set_attr "mode" "TI")])
22696
22697(define_insn "sse2_movdqu"
22698  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22699	(unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22700		       UNSPEC_MOVU))]
22701  "TARGET_SSE2
22702   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22703  "movdqu\t{%1, %0|%0, %1}"
22704  [(set_attr "type" "ssecvt")
22705   (set_attr "mode" "TI")])
22706
22707(define_insn "sse2_movdq2q"
22708  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22709	(vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22710		       (parallel [(const_int 0)])))]
22711  "TARGET_SSE2 && !TARGET_64BIT"
22712  "@
22713   movq\t{%1, %0|%0, %1}
22714   movdq2q\t{%1, %0|%0, %1}"
22715  [(set_attr "type" "ssecvt")
22716   (set_attr "mode" "TI")])
22717
22718(define_insn "sse2_movdq2q_rex64"
22719  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22720	(vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22721		       (parallel [(const_int 0)])))]
22722  "TARGET_SSE2 && TARGET_64BIT"
22723  "@
22724   movq\t{%1, %0|%0, %1}
22725   movdq2q\t{%1, %0|%0, %1}
22726   movd\t{%1, %0|%0, %1}"
22727  [(set_attr "type" "ssecvt")
22728   (set_attr "mode" "TI")])
22729
22730(define_insn "sse2_movq2dq"
22731  [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22732	(vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22733			 (const_int 0)))]
22734  "TARGET_SSE2 && !TARGET_64BIT"
22735  "@
22736   movq\t{%1, %0|%0, %1}
22737   movq2dq\t{%1, %0|%0, %1}"
22738  [(set_attr "type" "ssecvt,ssemov")
22739   (set_attr "mode" "TI")])
22740
22741(define_insn "sse2_movq2dq_rex64"
22742  [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22743	(vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22744			 (const_int 0)))]
22745  "TARGET_SSE2 && TARGET_64BIT"
22746  "@
22747   movq\t{%1, %0|%0, %1}
22748   movq2dq\t{%1, %0|%0, %1}
22749   movd\t{%1, %0|%0, %1}"
22750  [(set_attr "type" "ssecvt,ssemov,ssecvt")
22751   (set_attr "mode" "TI")])
22752
22753(define_insn "sse2_movq"
22754  [(set (match_operand:V2DI 0 "register_operand" "=x")
22755	(vec_concat:V2DI (vec_select:DI
22756			  (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22757			  (parallel [(const_int 0)]))
22758			 (const_int 0)))]
22759  "TARGET_SSE2"
22760  "movq\t{%1, %0|%0, %1}"
22761  [(set_attr "type" "ssemov")
22762   (set_attr "mode" "TI")])
22763
22764(define_insn "sse2_loadd"
22765  [(set (match_operand:V4SI 0 "register_operand" "=x")
22766	(vec_merge:V4SI
22767	 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22768	 (const_vector:V4SI [(const_int 0)
22769			     (const_int 0)
22770			     (const_int 0)
22771			     (const_int 0)])
22772	 (const_int 1)))]
22773  "TARGET_SSE2"
22774  "movd\t{%1, %0|%0, %1}"
22775  [(set_attr "type" "ssemov")
22776   (set_attr "mode" "TI")])
22777
22778(define_insn "sse2_stored"
22779  [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22780	(vec_select:SI
22781	 (match_operand:V4SI 1 "register_operand" "x")
22782	 (parallel [(const_int 0)])))]
22783  "TARGET_SSE2"
22784  "movd\t{%1, %0|%0, %1}"
22785  [(set_attr "type" "ssemov")
22786   (set_attr "mode" "TI")])
22787
22788(define_insn "sse2_movhpd"
22789  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22790	(vec_merge:V2DF
22791	 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22792	 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22793	 (const_int 2)))]
22794  "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22795  "movhpd\t{%2, %0|%0, %2}"
22796  [(set_attr "type" "ssecvt")
22797   (set_attr "mode" "V2DF")])
22798
22799(define_expand "sse2_loadsd"
22800  [(match_operand:V2DF 0 "register_operand" "")
22801   (match_operand:DF 1 "memory_operand" "")]
22802  "TARGET_SSE2"
22803{
22804  emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22805			        CONST0_RTX (V2DFmode)));
22806  DONE;
22807})
22808
22809(define_insn "sse2_loadsd_1"
22810  [(set (match_operand:V2DF 0 "register_operand" "=x")
22811	(vec_merge:V2DF
22812	 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22813	 (match_operand:V2DF 2 "const0_operand" "X")
22814	 (const_int 1)))]
22815  "TARGET_SSE2"
22816  "movsd\t{%1, %0|%0, %1}"
22817  [(set_attr "type" "ssecvt")
22818   (set_attr "mode" "DF")])
22819
22820(define_insn "sse2_movsd"
22821  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22822	(vec_merge:V2DF
22823	 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22824	 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22825	 (const_int 1)))]
22826  "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22827  "@movsd\t{%2, %0|%0, %2}
22828    movlpd\t{%2, %0|%0, %2}
22829    movlpd\t{%2, %0|%0, %2}"
22830  [(set_attr "type" "ssecvt")
22831   (set_attr "mode" "DF,V2DF,V2DF")])
22832
22833(define_insn "sse2_storesd"
22834  [(set (match_operand:DF 0 "memory_operand" "=m")
22835	(vec_select:DF
22836	 (match_operand:V2DF 1 "register_operand" "x")
22837	 (parallel [(const_int 0)])))]
22838  "TARGET_SSE2"
22839  "movsd\t{%1, %0|%0, %1}"
22840  [(set_attr "type" "ssecvt")
22841   (set_attr "mode" "DF")])
22842
22843(define_insn "sse2_shufpd"
22844  [(set (match_operand:V2DF 0 "register_operand" "=x")
22845        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22846		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22847		      (match_operand:SI 3 "immediate_operand" "i")]
22848		     UNSPEC_SHUFFLE))]
22849  "TARGET_SSE2"
22850  ;; @@@ check operand order for intel/nonintel syntax
22851  "shufpd\t{%3, %2, %0|%0, %2, %3}"
22852  [(set_attr "type" "ssecvt")
22853   (set_attr "mode" "V2DF")])
22854
22855(define_insn "sse2_clflush"
22856  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22857		    UNSPECV_CLFLUSH)]
22858  "TARGET_SSE2"
22859  "clflush %0"
22860  [(set_attr "type" "sse")
22861   (set_attr "memory" "unknown")])
22862
22863(define_expand "sse2_mfence"
22864  [(set (match_dup 0)
22865	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22866  "TARGET_SSE2"
22867{
22868  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22869  MEM_VOLATILE_P (operands[0]) = 1;
22870})
22871
22872(define_insn "*mfence_insn"
22873  [(set (match_operand:BLK 0 "" "")
22874	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22875  "TARGET_SSE2"
22876  "mfence"
22877  [(set_attr "type" "sse")
22878   (set_attr "memory" "unknown")])
22879
22880(define_expand "sse2_lfence"
22881  [(set (match_dup 0)
22882	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22883  "TARGET_SSE2"
22884{
22885  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22886  MEM_VOLATILE_P (operands[0]) = 1;
22887})
22888
22889(define_insn "*lfence_insn"
22890  [(set (match_operand:BLK 0 "" "")
22891	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22892  "TARGET_SSE2"
22893  "lfence"
22894  [(set_attr "type" "sse")
22895   (set_attr "memory" "unknown")])
22896
22897;; SSE3
22898
22899(define_insn "mwait"
22900  [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22901		     (match_operand:SI 1 "register_operand" "c")]
22902		    UNSPECV_MWAIT)]
22903  "TARGET_SSE3"
22904  "mwait\t%0, %1"
22905  [(set_attr "length" "3")])
22906
22907(define_insn "monitor"
22908  [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22909		     (match_operand:SI 1 "register_operand" "c")
22910		     (match_operand:SI 2 "register_operand" "d")]
22911		    UNSPECV_MONITOR)]
22912  "TARGET_SSE3"
22913  "monitor\t%0, %1, %2"
22914  [(set_attr "length" "3")])
22915
22916;; SSE3 arithmetic
22917
22918(define_insn "addsubv4sf3"
22919  [(set (match_operand:V4SF 0 "register_operand" "=x")
22920        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22921		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22922		     UNSPEC_ADDSUB))]
22923  "TARGET_SSE3"
22924  "addsubps\t{%2, %0|%0, %2}"
22925  [(set_attr "type" "sseadd")
22926   (set_attr "mode" "V4SF")])
22927
22928(define_insn "addsubv2df3"
22929  [(set (match_operand:V2DF 0 "register_operand" "=x")
22930        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22931		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22932		     UNSPEC_ADDSUB))]
22933  "TARGET_SSE3"
22934  "addsubpd\t{%2, %0|%0, %2}"
22935  [(set_attr "type" "sseadd")
22936   (set_attr "mode" "V2DF")])
22937
22938(define_insn "haddv4sf3"
22939  [(set (match_operand:V4SF 0 "register_operand" "=x")
22940        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22941		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22942		     UNSPEC_HADD))]
22943  "TARGET_SSE3"
22944  "haddps\t{%2, %0|%0, %2}"
22945  [(set_attr "type" "sseadd")
22946   (set_attr "mode" "V4SF")])
22947
22948(define_insn "haddv2df3"
22949  [(set (match_operand:V2DF 0 "register_operand" "=x")
22950        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22951		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22952		     UNSPEC_HADD))]
22953  "TARGET_SSE3"
22954  "haddpd\t{%2, %0|%0, %2}"
22955  [(set_attr "type" "sseadd")
22956   (set_attr "mode" "V2DF")])
22957
22958(define_insn "hsubv4sf3"
22959  [(set (match_operand:V4SF 0 "register_operand" "=x")
22960        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22961		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22962		     UNSPEC_HSUB))]
22963  "TARGET_SSE3"
22964  "hsubps\t{%2, %0|%0, %2}"
22965  [(set_attr "type" "sseadd")
22966   (set_attr "mode" "V4SF")])
22967
22968(define_insn "hsubv2df3"
22969  [(set (match_operand:V2DF 0 "register_operand" "=x")
22970        (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22971		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22972		     UNSPEC_HSUB))]
22973  "TARGET_SSE3"
22974  "hsubpd\t{%2, %0|%0, %2}"
22975  [(set_attr "type" "sseadd")
22976   (set_attr "mode" "V2DF")])
22977
22978(define_insn "movshdup"
22979  [(set (match_operand:V4SF 0 "register_operand" "=x")
22980        (unspec:V4SF
22981	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22982  "TARGET_SSE3"
22983  "movshdup\t{%1, %0|%0, %1}"
22984  [(set_attr "type" "sse")
22985   (set_attr "mode" "V4SF")])
22986
22987(define_insn "movsldup"
22988  [(set (match_operand:V4SF 0 "register_operand" "=x")
22989        (unspec:V4SF
22990	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22991  "TARGET_SSE3"
22992  "movsldup\t{%1, %0|%0, %1}"
22993  [(set_attr "type" "sse")
22994   (set_attr "mode" "V4SF")])
22995
22996(define_insn "lddqu"
22997  [(set (match_operand:V16QI 0 "register_operand" "=x")
22998	(unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22999		       UNSPEC_LDQQU))]
23000  "TARGET_SSE3"
23001  "lddqu\t{%1, %0|%0, %1}"
23002  [(set_attr "type" "ssecvt")
23003   (set_attr "mode" "TI")])
23004
23005(define_insn "loadddup"
23006  [(set (match_operand:V2DF 0 "register_operand" "=x")
23007	(vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23008  "TARGET_SSE3"
23009  "movddup\t{%1, %0|%0, %1}"
23010  [(set_attr "type" "ssecvt")
23011   (set_attr "mode" "DF")])
23012
23013(define_insn "movddup"
23014  [(set (match_operand:V2DF 0 "register_operand" "=x")
23015	(vec_duplicate:V2DF
23016	 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23017			(parallel [(const_int 0)]))))]
23018  "TARGET_SSE3"
23019  "movddup\t{%1, %0|%0, %1}"
23020  [(set_attr "type" "ssecvt")
23021   (set_attr "mode" "DF")])
23022