i386.md revision 107605
1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3;; Free Software Foundation, Inc.
4;; Mostly by William Schelter.
5;; x86_64 support added by Jan Hubicka
6;;
7;; This file is part of GNU CC.
8;;
9;; GNU CC is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; GNU CC is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GNU CC; see the file COPYING.  If not, write to
21;; the Free Software Foundation, 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.  */
23;;
24;; The original PO technology requires these to be ordered by speed,
25;; so that assigner will pick the fastest.
26;;
27;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28;;
29;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30;; updates for most instructions.
31;;
32;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33;; constraint letters.
34;;
35;; The special asm out single letter directives following a '%' are:
36;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37;;     operands[1].
38;; 'L' Print the opcode suffix for a 32-bit integer opcode.
39;; 'W' Print the opcode suffix for a 16-bit integer opcode.
40;; 'B' Print the opcode suffix for an 8-bit integer opcode.
41;; 'Q' Print the opcode suffix for a 64-bit float opcode.
42;; 'S' Print the opcode suffix for a 32-bit float opcode.
43;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44;; 'J' Print the appropriate jump operand.
45;;
46;; 'b' Print the QImode name of the register for the indicated operand.
47;;     %b0 would print %al if operands[0] is reg 0.
48;; 'w' Likewise, print the HImode name of the register.
49;; 'k' Likewise, print the SImode name of the register.
50;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
51;; 'y' Print "st(0)" instead of "st" as a register.
52;;
53;; UNSPEC usage:
54;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
55;;    operand 0 is the memory address to scan.
56;;    operand 1 is a register containing the value to scan for.  The mode
57;;       of the scas opcode will be the same as the mode of this operand.
58;;    operand 2 is the known alignment of operand 0.
59;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
60;;    operand 0 is the argument for `sin'.
61;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
62;;    operand 0 is the argument for `cos'.
63;; 3  This is part of a `stack probe' operation.  The mode of the UNSPEC is 
64;;    always SImode.  operand 0 is the size of the stack allocation.
65;; 4  This is the source of a fake SET of the frame pointer which is used to
66;;    prevent insns referencing it being scheduled across the initial
67;;    decrement of the stack pointer.
68;; 5  This is a `bsf' operation.
69;; 6  This is the @GOT offset of a PIC address.
70;; 7  This is the @GOTOFF offset of a PIC address.
71;; 8  This is a reference to a symbol's @PLT address.
72;; 9  This is an `fnstsw' operation.
73;; 10 This is a `sahf' operation.
74;; 11 This is a `fstcw' operation
75;; 12 This is behaviour of add when setting carry flag.
76;; 13 This is a `eh_return' placeholder.
77
78;; For SSE/MMX support:
79;; 30 This is `fix', guaranteed to be truncating.
80;; 31 This is a `emms' operation.
81;; 32 This is a `maskmov' operation.
82;; 33 This is a `movmsk' operation.
83;; 34 This is a `non-temporal' move.
84;; 36 This is used to distinguish COMISS from UCOMISS.
85;; 37 This is a `ldmxcsr' operation.
86;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
87;; 39 This is a forced `movups' instruction (rather than whatever movti does)
88;; 40 This is a `stmxcsr' operation.
89;; 41 This is a `shuffle' operation.
90;; 42 This is a `rcp' operation.
91;; 43 This is a `rsqsrt' operation.
92;; 44 This is a `sfence' operation.
93;; 45 This is a noop to prevent excessive combiner cleverness.
94;; 46 This is a `femms' operation.
95;; 49 This is a 'pavgusb' operation.
96;; 50 This is a `pfrcp' operation.
97;; 51 This is a `pfrcpit1' operation.
98;; 52 This is a `pfrcpit2' operation.
99;; 53 This is a `pfrsqrt' operation.
100;; 54 This is a `pfrsqrit1' operation.
101
102;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
103;; from i386.c.
104
105;; In C guard expressions, put expressions which may be compile-time
106;; constants first.  This allows for better optimization.  For
107;; example, write "TARGET_64BIT && reload_completed", not
108;; "reload_completed && TARGET_64BIT".
109
110
111;; Processor type.  This attribute must exactly match the processor_type
112;; enumeration in i386.h.
113(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
114  (const (symbol_ref "ix86_cpu")))
115
116;; A basic instruction type.  Refinements due to arguments to be
117;; provided in other attributes.
118(define_attr "type"
119  "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
120  (const_string "other"))
121
122;; Main data type used by the insn
123(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
124  (const_string "unknown"))
125
126;; Set for i387 operations.
127(define_attr "i387" ""
128  (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
129    (const_int 1)
130    (const_int 0)))
131
132;; The (bounding maximum) length of an instruction immediate.
133(define_attr "length_immediate" ""
134  (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
135	   (const_int 0)
136	 (eq_attr "i387" "1")
137	   (const_int 0)
138	 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
139	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
140	 (eq_attr "type" "imov,test")
141	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
142	 (eq_attr "type" "call")
143	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
144	     (const_int 4)
145	     (const_int 0))
146	 (eq_attr "type" "callv")
147	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
148	     (const_int 4)
149	     (const_int 0))
150	 (eq_attr "type" "ibr")
151	   (if_then_else (and (ge (minus (match_dup 0) (pc))
152				  (const_int -128))
153			      (lt (minus (match_dup 0) (pc))
154				  (const_int 124)))
155	     (const_int 1)
156	     (const_int 4))
157	 ]
158	 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
159
160;; The (bounding maximum) length of an instruction address.
161(define_attr "length_address" ""
162  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
163	   (const_int 0)
164	 (and (eq_attr "type" "call")
165	      (match_operand 1 "constant_call_address_operand" ""))
166	     (const_int 0)
167	 (and (eq_attr "type" "callv")
168	      (match_operand 1 "constant_call_address_operand" ""))
169	     (const_int 0)
170	 ]
171	 (symbol_ref "ix86_attr_length_address_default (insn)")))
172
173;; Set when length prefix is used.
174(define_attr "prefix_data16" ""
175  (if_then_else (eq_attr "mode" "HI")
176    (const_int 1)
177    (const_int 0)))
178
179;; Set when string REP prefix is used.
180(define_attr "prefix_rep" "" (const_int 0))
181
182;; Set when 0f opcode prefix is used.
183(define_attr "prefix_0f" ""
184  (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
185    (const_int 1)
186    (const_int 0)))
187
188;; Set when modrm byte is used.
189(define_attr "modrm" ""
190  (cond [(eq_attr "type" "str,cld")
191	   (const_int 0)
192	 (eq_attr "i387" "1")
193	   (const_int 0)
194         (and (eq_attr "type" "incdec")
195	      (ior (match_operand:SI 1 "register_operand" "")
196		   (match_operand:HI 1 "register_operand" "")))
197	   (const_int 0)
198	 (and (eq_attr "type" "push")
199	      (not (match_operand 1 "memory_operand" "")))
200	   (const_int 0)
201	 (and (eq_attr "type" "pop")
202	      (not (match_operand 0 "memory_operand" "")))
203	   (const_int 0)
204	 (and (eq_attr "type" "imov")
205	      (and (match_operand 0 "register_operand" "")
206	           (match_operand 1 "immediate_operand" "")))
207	   (const_int 0)
208	 ]
209	 (const_int 1)))
210
211;; The (bounding maximum) length of an instruction in bytes.
212;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
213;; to split it and compute proper length as for other insns.
214(define_attr "length" ""
215  (cond [(eq_attr "type" "other,multi,fistp")
216	   (const_int 16)
217	 ]
218	 (plus (plus (attr "modrm")
219		     (plus (attr "prefix_0f")
220			   (plus (attr "i387")
221				 (const_int 1))))
222	       (plus (attr "prefix_rep")
223		     (plus (attr "prefix_data16")
224			   (plus (attr "length_immediate")
225				 (attr "length_address")))))))
226
227;; The `memory' attribute is `none' if no memory is referenced, `load' or
228;; `store' if there is a simple memory reference therein, or `unknown'
229;; if the instruction is complex.
230
231(define_attr "memory" "none,load,store,both,unknown"
232  (cond [(eq_attr "type" "other,multi,str")
233	   (const_string "unknown")
234	 (eq_attr "type" "lea,fcmov,fpspc,cld")
235	   (const_string "none")
236	 (eq_attr "type" "fistp")
237	   (const_string "both")
238	 (eq_attr "type" "push")
239	   (if_then_else (match_operand 1 "memory_operand" "")
240	     (const_string "both")
241	     (const_string "store"))
242	 (eq_attr "type" "pop,setcc")
243	   (if_then_else (match_operand 0 "memory_operand" "")
244	     (const_string "both")
245	     (const_string "load"))
246	 (eq_attr "type" "icmp,test")
247	   (if_then_else (ior (match_operand 0 "memory_operand" "")
248			      (match_operand 1 "memory_operand" ""))
249	     (const_string "load")
250	     (const_string "none"))
251	 (eq_attr "type" "ibr")
252	   (if_then_else (match_operand 0 "memory_operand" "")
253	     (const_string "load")
254	     (const_string "none"))
255	 (eq_attr "type" "call")
256	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
257	     (const_string "none")
258	     (const_string "load"))
259	 (eq_attr "type" "callv")
260	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
261	     (const_string "none")
262	     (const_string "load"))
263	 (and (eq_attr "type" "alu1,negnot")
264	      (match_operand 1 "memory_operand" ""))
265	   (const_string "both")
266	 (and (match_operand 0 "memory_operand" "")
267	      (match_operand 1 "memory_operand" ""))
268	   (const_string "both")
269	 (match_operand 0 "memory_operand" "")
270	   (const_string "store")
271	 (match_operand 1 "memory_operand" "")
272	   (const_string "load")
273	 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
274	      (match_operand 2 "memory_operand" ""))
275	   (const_string "load")
276	 (and (eq_attr "type" "icmov")
277	      (match_operand 3 "memory_operand" ""))
278	   (const_string "load")
279	]
280	(const_string "none")))
281
282;; Indicates if an instruction has both an immediate and a displacement.
283
284(define_attr "imm_disp" "false,true,unknown"
285  (cond [(eq_attr "type" "other,multi")
286	   (const_string "unknown")
287	 (and (eq_attr "type" "icmp,test,imov")
288	      (and (match_operand 0 "memory_displacement_operand" "")
289		   (match_operand 1 "immediate_operand" "")))
290	   (const_string "true")
291	 (and (eq_attr "type" "alu,ishift,imul,idiv")
292	      (and (match_operand 0 "memory_displacement_operand" "")
293		   (match_operand 2 "immediate_operand" "")))
294	   (const_string "true")
295	]
296	(const_string "false")))
297
298;; Indicates if an FP operation has an integer source.
299
300(define_attr "fp_int_src" "false,true"
301  (const_string "false"))
302
303;; Describe a user's asm statement.
304(define_asm_attributes
305  [(set_attr "length" "128")
306   (set_attr "type" "multi")])
307
308;; Pentium Scheduling
309;;
310;; The Pentium is an in-order core with two integer pipelines.
311
312;; True for insns that behave like prefixed insns on the Pentium.
313(define_attr "pent_prefix" "false,true"
314  (if_then_else (ior (eq_attr "prefix_0f" "1")
315  		     (ior (eq_attr "prefix_data16" "1")
316			  (eq_attr "prefix_rep" "1")))
317    (const_string "true")
318    (const_string "false")))
319
320;; Categorize how an instruction slots.
321
322;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
323;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium
324;; rules, because it results in noticeably better code on non-MMX Pentium
325;; and doesn't hurt much on MMX.  (Prefixed instructions are not very
326;; common, so the scheduler usualy has a non-prefixed insn to pair).
327
328(define_attr "pent_pair" "uv,pu,pv,np"
329  (cond [(eq_attr "imm_disp" "true")
330	   (const_string "np")
331	 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
332	      (and (eq_attr "type" "pop,push")
333		   (eq_attr "memory" "!both")))
334	   (if_then_else (eq_attr "pent_prefix" "true")
335	     (const_string "pu")
336	     (const_string "uv"))
337	 (eq_attr "type" "ibr")
338	   (const_string "pv")
339	 (and (eq_attr "type" "ishift")
340	      (match_operand 2 "const_int_operand" ""))
341	   (const_string "pu")
342	 (and (eq_attr "type" "call")
343	      (match_operand 0 "constant_call_address_operand" ""))
344	   (const_string "pv")
345	 (and (eq_attr "type" "callv")
346	      (match_operand 1 "constant_call_address_operand" ""))
347	   (const_string "pv")
348	]
349	(const_string "np")))
350
351;; Rough readiness numbers.  Fine tuning happens in i386.c.
352;;
353;; u	describes pipe U
354;; v	describes pipe V
355;; uv	describes either pipe U or V for those that can issue to either
356;; np	describes not paring
357;; fpu	describes fpu
358;; fpm	describes fp insns of different types are not pipelined.
359;;
360;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
361
362(define_function_unit "pent_np" 1 0
363  (and (eq_attr "cpu" "pentium")
364       (eq_attr "type" "imul"))
365  11 11)
366
367(define_function_unit "pent_mul" 1 1
368  (and (eq_attr "cpu" "pentium")
369       (eq_attr "type" "imul"))
370  11 11)
371
372;; Rep movs takes minimally 12 cycles.
373(define_function_unit "pent_np" 1 0
374  (and (eq_attr "cpu" "pentium")
375       (eq_attr "type" "str"))
376  12 12)
377
378; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
379(define_function_unit "pent_np" 1 0
380  (and (eq_attr "cpu" "pentium")
381       (eq_attr "type" "idiv"))
382  46 46)
383
384; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
385; 3 cycles for XFmode.  Stores takes 2 cycles for SF/DF and 3 for XF.
386; fldz and fld1 takes 2 cycles.  Only reg-reg moves are pairable.
387; The integer <-> fp conversion is not modeled correctly. Fild behaves
388; like normal fp operation and fist takes 6 cycles.
389
390(define_function_unit "fpu" 1 0
391  (and (eq_attr "cpu" "pentium")
392       (and (eq_attr "type" "fmov")
393	    (and (eq_attr "memory" "load,store")
394		 (eq_attr "mode" "XF"))))
395  3 3)
396
397(define_function_unit "pent_np" 1 0
398  (and (eq_attr "cpu" "pentium")
399       (and (eq_attr "type" "fmov")
400	    (and (eq_attr "memory" "load,store")
401		 (eq_attr "mode" "XF"))))
402  3 3)
403
404(define_function_unit "fpu" 1 0
405  (and (eq_attr "cpu" "pentium")
406       (and (eq_attr "type" "fmov")
407            (ior (match_operand 1 "immediate_operand" "")
408	         (eq_attr "memory" "store"))))
409  2 2)
410
411(define_function_unit "pent_np" 1 0
412  (and (eq_attr "cpu" "pentium")
413       (and (eq_attr "type" "fmov")
414            (ior (match_operand 1 "immediate_operand" "")
415	         (eq_attr "memory" "store"))))
416  2 2)
417
418(define_function_unit "pent_np" 1 0
419  (and (eq_attr "cpu" "pentium")
420       (eq_attr "type" "cld"))
421  2 2)
422
423(define_function_unit "fpu" 1 0
424  (and (eq_attr "cpu" "pentium")
425       (and (eq_attr "type" "fmov")
426	    (eq_attr "memory" "none,load")))
427  1 1)
428
429; Read/Modify/Write instructions usually take 3 cycles.
430(define_function_unit "pent_u" 1 0
431  (and (eq_attr "cpu" "pentium")
432       (and (eq_attr "type" "alu,alu1,ishift")
433	    (and (eq_attr "pent_pair" "pu")
434		 (eq_attr "memory" "both"))))
435  3 3)
436
437(define_function_unit "pent_uv" 2 0
438  (and (eq_attr "cpu" "pentium")
439       (and (eq_attr "type" "alu,alu1,ishift")
440	    (and (eq_attr "pent_pair" "!np")
441		 (eq_attr "memory" "both"))))
442  3 3)
443
444(define_function_unit "pent_np" 1 0
445  (and (eq_attr "cpu" "pentium")
446       (and (eq_attr "type" "alu,alu1,negnot,ishift")
447	    (and (eq_attr "pent_pair" "np")
448		 (eq_attr "memory" "both"))))
449  3 3)
450
451; Read/Modify or Modify/Write instructions usually take 2 cycles.
452(define_function_unit "pent_u" 1 0
453  (and (eq_attr "cpu" "pentium")
454       (and (eq_attr "type" "alu,ishift")
455	    (and (eq_attr "pent_pair" "pu")
456		 (eq_attr "memory" "load,store"))))
457  2 2)
458
459(define_function_unit "pent_uv" 2 0
460  (and (eq_attr "cpu" "pentium")
461       (and (eq_attr "type" "alu,ishift")
462	    (and (eq_attr "pent_pair" "!np")
463		 (eq_attr "memory" "load,store"))))
464  2 2)
465
466(define_function_unit "pent_np" 1 0
467  (and (eq_attr "cpu" "pentium")
468       (and (eq_attr "type" "alu,ishift")
469	    (and (eq_attr "pent_pair" "np")
470		 (eq_attr "memory" "load,store"))))
471  2 2)
472
473; Insns w/o memory operands and move instructions usually take one cycle.
474(define_function_unit "pent_u" 1 0
475  (and (eq_attr "cpu" "pentium")
476       (eq_attr "pent_pair" "pu"))
477  1 1)
478
479(define_function_unit "pent_v" 1 0
480  (and (eq_attr "cpu" "pentium")
481       (eq_attr "pent_pair" "pv"))
482  1 1)
483
484(define_function_unit "pent_uv" 2 0
485  (and (eq_attr "cpu" "pentium")
486       (eq_attr "pent_pair" "!np"))
487  1 1)
488
489(define_function_unit "pent_np" 1 0
490  (and (eq_attr "cpu" "pentium")
491       (eq_attr "pent_pair" "np"))
492  1 1)
493
494; Pairable insns only conflict with other non-pairable insns.
495(define_function_unit "pent_np" 1 0
496  (and (eq_attr "cpu" "pentium")
497       (and (eq_attr "type" "alu,alu1,ishift")
498	    (and (eq_attr "pent_pair" "!np")
499		 (eq_attr "memory" "both"))))
500  3 3
501  [(eq_attr "pent_pair" "np")])
502
503(define_function_unit "pent_np" 1 0
504  (and (eq_attr "cpu" "pentium")
505       (and (eq_attr "type" "alu,alu1,ishift")
506	    (and (eq_attr "pent_pair" "!np")
507		 (eq_attr "memory" "load,store"))))
508  2 2
509  [(eq_attr "pent_pair" "np")])
510
511(define_function_unit "pent_np" 1 0
512  (and (eq_attr "cpu" "pentium")
513       (eq_attr "pent_pair" "!np"))
514  1 1
515  [(eq_attr "pent_pair" "np")])
516
517; Floating point instructions usually blocks cycle longer when combined with
518; integer instructions, because of the inpaired fxch instruction.
519(define_function_unit "pent_np" 1 0
520  (and (eq_attr "cpu" "pentium")
521       (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
522  2 2
523  [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
524
525(define_function_unit "fpu" 1 0
526  (and (eq_attr "cpu" "pentium")
527       (eq_attr "type" "fcmp,fxch,fsgn"))
528  1 1)
529
530; Addition takes 3 cycles; assume other random cruft does as well.
531; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
532(define_function_unit "fpu" 1 0
533  (and (eq_attr "cpu" "pentium")
534       (eq_attr "type" "fop,fop1,fistp"))
535  3 1)
536
537; Multiplication takes 3 cycles and is only half pipelined.
538(define_function_unit "fpu" 1 0
539  (and (eq_attr "cpu" "pentium")
540       (eq_attr "type" "fmul"))
541  3 1)
542
543(define_function_unit "pent_mul" 1 1
544  (and (eq_attr "cpu" "pentium")
545       (eq_attr "type" "fmul"))
546  2 2)
547
548; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles. 
549; They can overlap with integer insns.  Only the last two cycles can overlap
550; with other fp insns.  Only fsin/fcos can overlap with multiplies.
551; Only last two cycles of fsin/fcos can overlap with other instructions.
552(define_function_unit "fpu" 1 0
553  (and (eq_attr "cpu" "pentium")
554       (eq_attr "type" "fdiv"))
555  39 37)
556
557(define_function_unit "pent_mul" 1 1
558  (and (eq_attr "cpu" "pentium")
559       (eq_attr "type" "fdiv"))
560  39 39)
561
562(define_function_unit "fpu" 1 0
563  (and (eq_attr "cpu" "pentium")
564       (eq_attr "type" "fpspc"))
565  70 68)
566
567(define_function_unit "pent_mul" 1 1
568  (and (eq_attr "cpu" "pentium")
569       (eq_attr "type" "fpspc"))
570  70 70)
571
572;; Pentium Pro/PII Scheduling
573;;
574;; The PPro has an out-of-order core, but the instruction decoders are
575;; naturally in-order and asymmetric.  We get best performance by scheduling
576;; for the decoders, for in doing so we give the oo execution unit the 
577;; most choices.
578
579;; Categorize how many uops an ia32 instruction evaluates to:
580;;   one --  an instruction with 1 uop can be decoded by any of the
581;;           three decoders.
582;;   few --  an instruction with 1 to 4 uops can be decoded only by 
583;;	     decoder 0.
584;;   many -- a complex instruction may take an unspecified number of
585;;	     cycles to decode in decoder 0.
586
587(define_attr "ppro_uops" "one,few,many"
588  (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
589	   (const_string "many")
590	 (eq_attr "type" "icmov,fcmov,str,cld")
591	   (const_string "few")
592	 (eq_attr "type" "imov")
593	   (if_then_else (eq_attr "memory" "store,both")
594	     (const_string "few")
595	     (const_string "one"))
596	 (eq_attr "memory" "!none")
597	   (const_string "few")
598	]
599	(const_string "one")))
600
601;; Rough readiness numbers.  Fine tuning happens in i386.c.
602;;
603;; p0	describes port 0.
604;; p01	describes ports 0 and 1 as a pair; alu insns can issue to either.
605;; p2	describes port 2 for loads.
606;; p34	describes ports 3 and 4 for stores.
607;; fpu	describes the fpu accessed via port 0. 
608;;	??? It is less than clear if there are separate fadd and fmul units
609;;	that could operate in parallel.
610;;
611;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
612
613(define_function_unit "ppro_p0" 1 0
614  (and (eq_attr "cpu" "pentiumpro")
615       (eq_attr "type" "ishift,lea,ibr,cld"))
616  1 1)
617
618(define_function_unit "ppro_p0" 1 0
619  (and (eq_attr "cpu" "pentiumpro")
620       (eq_attr "type" "imul"))
621  4 1)
622
623;; ??? Does the divider lock out the pipe while it works,
624;; or is there a disconnected unit?
625(define_function_unit "ppro_p0" 1 0
626  (and (eq_attr "cpu" "pentiumpro")
627       (eq_attr "type" "idiv"))
628  17 17)
629
630(define_function_unit "ppro_p0" 1 0
631  (and (eq_attr "cpu" "pentiumpro")
632       (eq_attr "type" "fop,fop1,fsgn,fistp"))
633  3 1)
634
635(define_function_unit "ppro_p0" 1 0
636  (and (eq_attr "cpu" "pentiumpro")
637       (eq_attr "type" "fcmov"))
638  2 1)
639
640(define_function_unit "ppro_p0" 1 0
641  (and (eq_attr "cpu" "pentiumpro")
642       (eq_attr "type" "fcmp"))
643  1 1)
644
645(define_function_unit "ppro_p0" 1 0
646  (and (eq_attr "cpu" "pentiumpro")
647       (eq_attr "type" "fmov"))
648  1 1)
649
650(define_function_unit "ppro_p0" 1 0
651  (and (eq_attr "cpu" "pentiumpro")
652       (eq_attr "type" "fmul"))
653  5 1)
654
655(define_function_unit "ppro_p0" 1 0
656  (and (eq_attr "cpu" "pentiumpro")
657       (eq_attr "type" "fdiv,fpspc"))
658  56 1)
659
660(define_function_unit "ppro_p01" 2 0
661  (and (eq_attr "cpu" "pentiumpro")
662       (eq_attr "type" "!imov,fmov"))
663  1 1)
664
665(define_function_unit "ppro_p01" 2 0
666  (and (and (eq_attr "cpu" "pentiumpro")
667            (eq_attr "type" "imov,fmov"))
668       (eq_attr "memory" "none"))
669  1 1)
670
671(define_function_unit "ppro_p2" 1 0
672  (and (eq_attr "cpu" "pentiumpro")
673       (ior (eq_attr "type" "pop")
674	    (eq_attr "memory" "load,both")))
675  3 1)
676
677(define_function_unit "ppro_p34" 1 0
678  (and (eq_attr "cpu" "pentiumpro")
679       (ior (eq_attr "type" "push")
680	    (eq_attr "memory" "store,both")))
681  1 1)
682
683(define_function_unit "fpu" 1 0
684  (and (eq_attr "cpu" "pentiumpro")
685       (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
686  1 1)
687
688(define_function_unit "fpu" 1 0
689  (and (eq_attr "cpu" "pentiumpro")
690       (eq_attr "type" "fmul"))
691  5 2)
692
693(define_function_unit "fpu" 1 0
694  (and (eq_attr "cpu" "pentiumpro")
695       (eq_attr "type" "fdiv,fpspc"))
696  56 56)
697
698;; imul uses the fpu.  ??? does it have the same throughput as fmul?
699(define_function_unit "fpu" 1 0
700  (and (eq_attr "cpu" "pentiumpro")
701       (eq_attr "type" "imul"))
702  4 1)
703
704;; AMD K6/K6-2 Scheduling
705;;
706;; The K6 has similar architecture to PPro.  Important difference is, that
707;; there are only two decoders and they seems to be much slower than execution
708;; units.  So we have to pay much more attention to proper decoding for
709;; schedulers.  We share most of scheduler code for PPro in i386.c
710;;
711;; The fp unit is not pipelined and do one operation per two cycles including
712;; the FXCH.
713;;
714;; alu	  describes both ALU units (ALU-X and ALU-Y).
715;; alux   describes X alu unit
716;; fpu    describes FPU unit
717;; load   describes load unit.
718;; branch describes branch unit.
719;; store  decsribes store unit.  This unit is not modelled completely and only
720;;        used to model lea operation.  Otherwise it lie outside of the critical
721;;        path.
722;;
723;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
724
725;; The decoder specification is in the PPro section above!
726
727;; Shift instructions and certain arithmetic are issued only to X pipe.
728(define_function_unit "k6_alux" 1 0
729  (and (eq_attr "cpu" "k6")
730       (eq_attr "type" "ishift,alu1,negnot,cld"))
731  1 1)
732
733;; The QI mode arithmetic is issued to X pipe only.
734(define_function_unit "k6_alux" 1 0
735  (and (eq_attr "cpu" "k6")
736       (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
737	    (match_operand:QI 0 "general_operand" "")))
738  1 1)
739
740(define_function_unit "k6_alu" 2 0
741  (and (eq_attr "cpu" "k6")
742       (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
743  1 1)
744
745(define_function_unit "k6_alu" 2 0
746  (and (eq_attr "cpu" "k6")
747       (and (eq_attr "type" "imov")
748       	    (eq_attr "memory" "none")))
749  1 1)
750
751(define_function_unit "k6_branch" 1 0
752  (and (eq_attr "cpu" "k6")
753       (eq_attr "type" "call,callv,ibr"))
754  1 1)
755
756;; Load unit have two cycle latency, but we take care for it in adjust_cost
757(define_function_unit "k6_load" 1 0
758  (and (eq_attr "cpu" "k6")
759       (ior (eq_attr "type" "pop")
760	    (eq_attr "memory" "load,both")))
761  1 1)
762
763(define_function_unit "k6_load" 1 0
764  (and (eq_attr "cpu" "k6")
765       (and (eq_attr "type" "str")
766	    (eq_attr "memory" "load,both")))
767  10 10)
768
769;; Lea have two instructions, so latency is probably 2
770(define_function_unit "k6_store" 1 0
771  (and (eq_attr "cpu" "k6")
772       (eq_attr "type" "lea"))
773  2 1)
774
775(define_function_unit "k6_store" 1 0
776  (and (eq_attr "cpu" "k6")
777       (eq_attr "type" "str"))
778  10 10)
779
780(define_function_unit "k6_store" 1 0
781  (and (eq_attr "cpu" "k6")
782       (ior (eq_attr "type" "push")
783	    (eq_attr "memory" "store,both")))
784  1 1)
785
786(define_function_unit "k6_fpu" 1 1
787  (and (eq_attr "cpu" "k6")
788       (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
789  2 2)
790
791(define_function_unit "k6_fpu" 1 1
792  (and (eq_attr "cpu" "k6")
793       (eq_attr "type" "fmul"))
794  2 2)
795
796;; ??? Guess
797(define_function_unit "k6_fpu" 1 1
798  (and (eq_attr "cpu" "k6")
799       (eq_attr "type" "fdiv,fpspc"))
800  56 56)
801
802(define_function_unit "k6_alu" 2 0
803  (and (eq_attr "cpu" "k6")
804       (eq_attr "type" "imul"))
805  2 2)
806
807(define_function_unit "k6_alux" 1 0
808  (and (eq_attr "cpu" "k6")
809       (eq_attr "type" "imul"))
810  2 2)
811
812;; ??? Guess
813(define_function_unit "k6_alu" 2 0
814  (and (eq_attr "cpu" "k6")
815       (eq_attr "type" "idiv"))
816  17 17)
817
818(define_function_unit "k6_alux" 1 0
819  (and (eq_attr "cpu" "k6")
820       (eq_attr "type" "idiv"))
821  17 17)
822
823;; AMD Athlon Scheduling
824;;
825;; The Athlon does contain three pipelined FP units, three integer units and
826;; three address generation units. 
827;;
828;; The predecode logic is determining boundaries of instructions in the 64
829;; byte cache line. So the cache line straddling problem of K6 might be issue
830;; here as well, but it is not noted in the documentation.
831;;
832;; Three DirectPath instructions decoders and only one VectorPath decoder
833;; is available. They can decode three DirectPath instructions or one VectorPath
834;; instruction per cycle.
835;; Decoded macro instructions are then passed to 72 entry instruction control
836;; unit, that passes
837;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
838;;
839;; The load/store queue unit is not attached to the schedulers but
840;; communicates with all the execution units separately instead.
841
842(define_attr "athlon_decode" "direct,vector"
843  (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
844	   (const_string "vector")
845         (and (eq_attr "type" "push")
846              (match_operand 1 "memory_operand" ""))
847	   (const_string "vector")
848         (and (eq_attr "type" "fmov")
849	      (and (eq_attr "memory" "load,store")
850		   (eq_attr "mode" "XF")))
851	   (const_string "vector")]
852	(const_string "direct")))
853
854(define_function_unit "athlon_vectordec" 1 0
855  (and (eq_attr "cpu" "athlon")
856       (eq_attr "athlon_decode" "vector"))
857  1 1)
858
859(define_function_unit "athlon_directdec" 3 0
860  (and (eq_attr "cpu" "athlon")
861       (eq_attr "athlon_decode" "direct"))
862  1 1)
863
864(define_function_unit "athlon_vectordec" 1 0
865  (and (eq_attr "cpu" "athlon")
866       (eq_attr "athlon_decode" "direct"))
867  1 1 [(eq_attr "athlon_decode" "vector")])
868
869(define_function_unit "athlon_ieu" 3 0
870  (and (eq_attr "cpu" "athlon")
871       (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
872  1 1)
873
874(define_function_unit "athlon_ieu" 3 0
875  (and (eq_attr "cpu" "athlon")
876       (eq_attr "type" "str"))
877  15 15)
878
879(define_function_unit "athlon_ieu" 3 0
880  (and (eq_attr "cpu" "athlon")
881       (eq_attr "type" "imul"))
882  5 0)
883
884(define_function_unit "athlon_ieu" 3 0
885  (and (eq_attr "cpu" "athlon")
886       (eq_attr "type" "idiv"))
887  42 0)
888
889(define_function_unit "athlon_muldiv" 1 0
890  (and (eq_attr "cpu" "athlon")
891       (eq_attr "type" "imul"))
892  5 0)
893
894(define_function_unit "athlon_muldiv" 1 0
895  (and (eq_attr "cpu" "athlon")
896       (eq_attr "type" "idiv"))
897  42 42)
898
899(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
900  (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
901	   (const_string "add")
902         (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
903	   (const_string "mul")
904	 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
905	   (const_string "store")
906	 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
907	   (const_string "any")
908         (and (eq_attr "type" "fmov")
909              (ior (match_operand:SI 1 "register_operand" "")
910                   (match_operand 1 "immediate_operand" "")))
911	   (const_string "store")
912         (eq_attr "type" "fmov")
913	   (const_string "muladd")]
914	(const_string "none")))
915
916;; We use latencies 1 for definitions.  This is OK to model colisions
917;; in execution units.  The real latencies are modeled in the "fp" pipeline.
918
919;; fsin, fcos: 96-192
920;; fsincos: 107-211
921;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
922(define_function_unit "athlon_fp" 3 0
923  (and (eq_attr "cpu" "athlon")
924       (eq_attr "type" "fpspc"))
925  100 1)
926
927;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
928(define_function_unit "athlon_fp" 3 0
929  (and (eq_attr "cpu" "athlon")
930       (eq_attr "type" "fdiv"))
931  24 1)
932
933(define_function_unit "athlon_fp" 3 0
934  (and (eq_attr "cpu" "athlon")
935       (eq_attr "type" "fop,fop1,fmul,fistp"))
936  4 1)
937
938;; XFmode loads are slow.
939;; XFmode store is slow too (8 cycles), but we don't need to model it, because
940;; there are no dependent instructions.
941
942(define_function_unit "athlon_fp" 3 0
943  (and (eq_attr "cpu" "athlon")
944       (and (eq_attr "type" "fmov")
945	    (and (eq_attr "memory" "load")
946		 (eq_attr "mode" "XF"))))
947  10 1)
948
949(define_function_unit "athlon_fp" 3 0
950  (and (eq_attr "cpu" "athlon")
951       (eq_attr "type" "fmov,fsgn"))
952  2 1)
953
954;; fcmp and ftst instructions
955(define_function_unit "athlon_fp" 3 0
956  (and (eq_attr "cpu" "athlon")
957       (and (eq_attr "type" "fcmp")
958	    (eq_attr "athlon_decode" "direct")))
959  3 1)
960
961;; fcmpi instructions.
962(define_function_unit "athlon_fp" 3 0
963  (and (eq_attr "cpu" "athlon")
964       (and (eq_attr "type" "fcmp")
965	    (eq_attr "athlon_decode" "vector")))
966  3 1)
967
968(define_function_unit "athlon_fp" 3 0
969  (and (eq_attr "cpu" "athlon")
970       (eq_attr "type" "fcmov"))
971  7 1)
972
973(define_function_unit "athlon_fp_mul" 1 0
974  (and (eq_attr "cpu" "athlon")
975       (eq_attr "athlon_fpunits" "mul"))
976  1 1)
977
978(define_function_unit "athlon_fp_add" 1 0
979  (and (eq_attr "cpu" "athlon")
980       (eq_attr "athlon_fpunits" "add"))
981  1 1)
982
983(define_function_unit "athlon_fp_muladd" 2 0
984  (and (eq_attr "cpu" "athlon")
985       (eq_attr "athlon_fpunits" "muladd,mul,add"))
986  1 1)
987
988(define_function_unit "athlon_fp_store" 1 0
989  (and (eq_attr "cpu" "athlon")
990       (eq_attr "athlon_fpunits" "store"))
991  1 1)
992
993;; We don't need to model the Address Generation Unit, since we don't model
994;; the re-order buffer yet and thus we never schedule more than three operations
995;; at time.  Later we may want to experiment with MD_SCHED macros modeling the
996;; decoders independently on the functional units.
997
998;(define_function_unit "athlon_agu" 3 0
999;  (and (eq_attr "cpu" "athlon")
1000;       (and (eq_attr "memory" "!none")
1001;            (eq_attr "athlon_fpunits" "none")))
1002;  1 1)
1003
1004;; Model load unit to avoid too long sequences of loads.  We don't need to
1005;; model store queue, since it is hardly going to be bottleneck.
1006
1007(define_function_unit "athlon_load" 2 0
1008  (and (eq_attr "cpu" "athlon")
1009       (eq_attr "memory" "load,both"))
1010  1 1)
1011
1012
1013;; Compare instructions.
1014
1015;; All compare insns have expanders that save the operands away without
1016;; actually generating RTL.  The bCOND or sCOND (emitted immediately
1017;; after the cmp) will actually emit the cmpM.
1018
1019(define_expand "cmpdi"
1020  [(set (reg:CC 17)
1021	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1022		    (match_operand:DI 1 "x86_64_general_operand" "")))]
1023  ""
1024{
1025  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1026    operands[0] = force_reg (DImode, operands[0]);
1027  ix86_compare_op0 = operands[0];
1028  ix86_compare_op1 = operands[1];
1029  DONE;
1030})
1031
1032(define_expand "cmpsi"
1033  [(set (reg:CC 17)
1034	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1035		    (match_operand:SI 1 "general_operand" "")))]
1036  ""
1037{
1038  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1039    operands[0] = force_reg (SImode, operands[0]);
1040  ix86_compare_op0 = operands[0];
1041  ix86_compare_op1 = operands[1];
1042  DONE;
1043})
1044
1045(define_expand "cmphi"
1046  [(set (reg:CC 17)
1047	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
1048		    (match_operand:HI 1 "general_operand" "")))]
1049  ""
1050{
1051  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1052    operands[0] = force_reg (HImode, operands[0]);
1053  ix86_compare_op0 = operands[0];
1054  ix86_compare_op1 = operands[1];
1055  DONE;
1056})
1057
1058(define_expand "cmpqi"
1059  [(set (reg:CC 17)
1060	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
1061		    (match_operand:QI 1 "general_operand" "")))]
1062  "TARGET_QIMODE_MATH"
1063{
1064  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1065    operands[0] = force_reg (QImode, operands[0]);
1066  ix86_compare_op0 = operands[0];
1067  ix86_compare_op1 = operands[1];
1068  DONE;
1069})
1070
1071(define_insn "cmpdi_ccno_1_rex64"
1072  [(set (reg 17)
1073	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1074		 (match_operand:DI 1 "const0_operand" "n,n")))]
1075  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1076  "@
1077   test{q}\t{%0, %0|%0, %0}
1078   cmp{q}\t{%1, %0|%0, %1}"
1079  [(set_attr "type" "test,icmp")
1080   (set_attr "length_immediate" "0,1")
1081   (set_attr "mode" "DI")])
1082
1083(define_insn "*cmpdi_minus_1_rex64"
1084  [(set (reg 17)
1085	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1086			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1087		 (const_int 0)))]
1088  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
1089  "cmp{q}\t{%1, %0|%0, %1}"
1090  [(set_attr "type" "icmp")
1091   (set_attr "mode" "DI")])
1092
1093(define_expand "cmpdi_1_rex64"
1094  [(set (reg:CC 17)
1095	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1096		    (match_operand:DI 1 "general_operand" "")))]
1097  "TARGET_64BIT"
1098  "")
1099
1100(define_insn "cmpdi_1_insn_rex64"
1101  [(set (reg 17)
1102	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1103		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1104  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1105  "cmp{q}\t{%1, %0|%0, %1}"
1106  [(set_attr "type" "icmp")
1107   (set_attr "mode" "DI")])
1108
1109
1110(define_insn "*cmpsi_ccno_1"
1111  [(set (reg 17)
1112	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1113		 (match_operand:SI 1 "const0_operand" "n,n")))]
1114  "ix86_match_ccmode (insn, CCNOmode)"
1115  "@
1116   test{l}\t{%0, %0|%0, %0}
1117   cmp{l}\t{%1, %0|%0, %1}"
1118  [(set_attr "type" "test,icmp")
1119   (set_attr "length_immediate" "0,1")
1120   (set_attr "mode" "SI")])
1121
1122(define_insn "*cmpsi_minus_1"
1123  [(set (reg 17)
1124	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1125			   (match_operand:SI 1 "general_operand" "ri,mr"))
1126		 (const_int 0)))]
1127  "ix86_match_ccmode (insn, CCGOCmode)"
1128  "cmp{l}\t{%1, %0|%0, %1}"
1129  [(set_attr "type" "icmp")
1130   (set_attr "mode" "SI")])
1131
1132(define_expand "cmpsi_1"
1133  [(set (reg:CC 17)
1134	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1135		    (match_operand:SI 1 "general_operand" "ri,mr")))]
1136  ""
1137  "")
1138
1139(define_insn "*cmpsi_1_insn"
1140  [(set (reg 17)
1141	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1142		 (match_operand:SI 1 "general_operand" "ri,mr")))]
1143  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1144    && ix86_match_ccmode (insn, CCmode)"
1145  "cmp{l}\t{%1, %0|%0, %1}"
1146  [(set_attr "type" "icmp")
1147   (set_attr "mode" "SI")])
1148
1149(define_insn "*cmphi_ccno_1"
1150  [(set (reg 17)
1151	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1152		 (match_operand:HI 1 "const0_operand" "n,n")))]
1153  "ix86_match_ccmode (insn, CCNOmode)"
1154  "@
1155   test{w}\t{%0, %0|%0, %0}
1156   cmp{w}\t{%1, %0|%0, %1}"
1157  [(set_attr "type" "test,icmp")
1158   (set_attr "length_immediate" "0,1")
1159   (set_attr "mode" "HI")])
1160
1161(define_insn "*cmphi_minus_1"
1162  [(set (reg 17)
1163	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1164			   (match_operand:HI 1 "general_operand" "ri,mr"))
1165		 (const_int 0)))]
1166  "ix86_match_ccmode (insn, CCGOCmode)"
1167  "cmp{w}\t{%1, %0|%0, %1}"
1168  [(set_attr "type" "icmp")
1169   (set_attr "mode" "HI")])
1170
1171(define_insn "*cmphi_1"
1172  [(set (reg 17)
1173	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1174		 (match_operand:HI 1 "general_operand" "ri,mr")))]
1175  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1176   && ix86_match_ccmode (insn, CCmode)"
1177  "cmp{w}\t{%1, %0|%0, %1}"
1178  [(set_attr "type" "icmp")
1179   (set_attr "mode" "HI")])
1180
1181(define_insn "*cmpqi_ccno_1"
1182  [(set (reg 17)
1183	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1184		 (match_operand:QI 1 "const0_operand" "n,n")))]
1185  "ix86_match_ccmode (insn, CCNOmode)"
1186  "@
1187   test{b}\t{%0, %0|%0, %0}
1188   cmp{b}\t{$0, %0|%0, 0}"
1189  [(set_attr "type" "test,icmp")
1190   (set_attr "length_immediate" "0,1")
1191   (set_attr "mode" "QI")])
1192
1193(define_insn "*cmpqi_1"
1194  [(set (reg 17)
1195	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1196		 (match_operand:QI 1 "general_operand" "qi,mq")))]
1197  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1198    && ix86_match_ccmode (insn, CCmode)"
1199  "cmp{b}\t{%1, %0|%0, %1}"
1200  [(set_attr "type" "icmp")
1201   (set_attr "mode" "QI")])
1202
1203(define_insn "*cmpqi_minus_1"
1204  [(set (reg 17)
1205	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1206			   (match_operand:QI 1 "general_operand" "qi,mq"))
1207		 (const_int 0)))]
1208  "ix86_match_ccmode (insn, CCGOCmode)"
1209  "cmp{b}\t{%1, %0|%0, %1}"
1210  [(set_attr "type" "icmp")
1211   (set_attr "mode" "QI")])
1212
1213(define_insn "*cmpqi_ext_1"
1214  [(set (reg 17)
1215	(compare
1216	  (match_operand:QI 0 "general_operand" "Qm")
1217	  (subreg:QI
1218	    (zero_extract:SI
1219	      (match_operand 1 "ext_register_operand" "Q")
1220	      (const_int 8)
1221	      (const_int 8)) 0)))]
1222  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1223  "cmp{b}\t{%h1, %0|%0, %h1}"
1224  [(set_attr "type" "icmp")
1225   (set_attr "mode" "QI")])
1226
1227(define_insn "*cmpqi_ext_1_rex64"
1228  [(set (reg 17)
1229	(compare
1230	  (match_operand:QI 0 "register_operand" "Q")
1231	  (subreg:QI
1232	    (zero_extract:SI
1233	      (match_operand 1 "ext_register_operand" "Q")
1234	      (const_int 8)
1235	      (const_int 8)) 0)))]
1236  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1237  "cmp{b}\t{%h1, %0|%0, %h1}"
1238  [(set_attr "type" "icmp")
1239   (set_attr "mode" "QI")])
1240
1241(define_insn "*cmpqi_ext_2"
1242  [(set (reg 17)
1243	(compare
1244	  (subreg:QI
1245	    (zero_extract:SI
1246	      (match_operand 0 "ext_register_operand" "Q")
1247	      (const_int 8)
1248	      (const_int 8)) 0)
1249	  (match_operand:QI 1 "const0_operand" "n")))]
1250  "ix86_match_ccmode (insn, CCNOmode)"
1251  "test{b}\t%h0, %h0"
1252  [(set_attr "type" "test")
1253   (set_attr "length_immediate" "0")
1254   (set_attr "mode" "QI")])
1255
1256(define_expand "cmpqi_ext_3"
1257  [(set (reg:CC 17)
1258	(compare:CC
1259	  (subreg:QI
1260	    (zero_extract:SI
1261	      (match_operand 0 "ext_register_operand" "")
1262	      (const_int 8)
1263	      (const_int 8)) 0)
1264	  (match_operand:QI 1 "general_operand" "")))]
1265  ""
1266  "")
1267
1268(define_insn "cmpqi_ext_3_insn"
1269  [(set (reg 17)
1270	(compare
1271	  (subreg:QI
1272	    (zero_extract:SI
1273	      (match_operand 0 "ext_register_operand" "Q")
1274	      (const_int 8)
1275	      (const_int 8)) 0)
1276	  (match_operand:QI 1 "general_operand" "Qmn")))]
1277  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1278  "cmp{b}\t{%1, %h0|%h0, %1}"
1279  [(set_attr "type" "icmp")
1280   (set_attr "mode" "QI")])
1281
1282(define_insn "cmpqi_ext_3_insn_rex64"
1283  [(set (reg 17)
1284	(compare
1285	  (subreg:QI
1286	    (zero_extract:SI
1287	      (match_operand 0 "ext_register_operand" "Q")
1288	      (const_int 8)
1289	      (const_int 8)) 0)
1290	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1291  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1292  "cmp{b}\t{%1, %h0|%h0, %1}"
1293  [(set_attr "type" "icmp")
1294   (set_attr "mode" "QI")])
1295
1296(define_insn "*cmpqi_ext_4"
1297  [(set (reg 17)
1298	(compare
1299	  (subreg:QI
1300	    (zero_extract:SI
1301	      (match_operand 0 "ext_register_operand" "Q")
1302	      (const_int 8)
1303	      (const_int 8)) 0)
1304	  (subreg:QI
1305	    (zero_extract:SI
1306	      (match_operand 1 "ext_register_operand" "Q")
1307	      (const_int 8)
1308	      (const_int 8)) 0)))]
1309  "ix86_match_ccmode (insn, CCmode)"
1310  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1311  [(set_attr "type" "icmp")
1312   (set_attr "mode" "QI")])
1313
1314;; These implement float point compares.
1315;; %%% See if we can get away with VOIDmode operands on the actual insns,
1316;; which would allow mix and match FP modes on the compares.  Which is what
1317;; the old patterns did, but with many more of them.
1318
1319(define_expand "cmpxf"
1320  [(set (reg:CC 17)
1321	(compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1322		    (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1323  "!TARGET_64BIT && TARGET_80387"
1324{
1325  ix86_compare_op0 = operands[0];
1326  ix86_compare_op1 = operands[1];
1327  DONE;
1328})
1329
1330(define_expand "cmptf"
1331  [(set (reg:CC 17)
1332	(compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1333		    (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1334  "TARGET_80387"
1335{
1336  ix86_compare_op0 = operands[0];
1337  ix86_compare_op1 = operands[1];
1338  DONE;
1339})
1340
1341(define_expand "cmpdf"
1342  [(set (reg:CC 17)
1343	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1344		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1345  "TARGET_80387 || TARGET_SSE2"
1346{
1347  ix86_compare_op0 = operands[0];
1348  ix86_compare_op1 = operands[1];
1349  DONE;
1350})
1351
1352(define_expand "cmpsf"
1353  [(set (reg:CC 17)
1354	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1355		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1356  "TARGET_80387 || TARGET_SSE"
1357{
1358  ix86_compare_op0 = operands[0];
1359  ix86_compare_op1 = operands[1];
1360  DONE;
1361})
1362
1363;; FP compares, step 1:
1364;; Set the FP condition codes.
1365;;
1366;; CCFPmode	compare with exceptions
1367;; CCFPUmode	compare with no exceptions
1368
1369;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1370;; and that fp moves clobber the condition codes, and that there is
1371;; currently no way to describe this fact to reg-stack.  So there are
1372;; no splitters yet for this.
1373
1374;; %%% YIKES!  This scheme does not retain a strong connection between 
1375;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1376;; work!  Only allow tos/mem with tos in op 0.
1377;;
1378;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
1379;; things aren't as bad as they sound...
1380
1381(define_insn "*cmpfp_0"
1382  [(set (match_operand:HI 0 "register_operand" "=a")
1383	(unspec:HI
1384	  [(compare:CCFP (match_operand 1 "register_operand" "f")
1385		         (match_operand 2 "const0_operand" "X"))] 9))]
1386  "TARGET_80387
1387   && FLOAT_MODE_P (GET_MODE (operands[1]))
1388   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1389{
1390  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1391    return "ftst\;fnstsw\t%0\;fstp\t%y0";
1392  else
1393    return "ftst\;fnstsw\t%0";
1394}
1395  [(set_attr "type" "multi")
1396   (set_attr "mode" "unknownfp")])
1397
1398;; We may not use "#" to split and emit these, since the REG_DEAD notes
1399;; used to manage the reg stack popping would not be preserved.
1400
1401(define_insn "*cmpfp_2_sf"
1402  [(set (reg:CCFP 18)
1403	(compare:CCFP
1404	  (match_operand:SF 0 "register_operand" "f")
1405	  (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1406  "TARGET_80387"
1407  "* return output_fp_compare (insn, operands, 0, 0);"
1408  [(set_attr "type" "fcmp")
1409   (set_attr "mode" "SF")])
1410
1411(define_insn "*cmpfp_2_sf_1"
1412  [(set (match_operand:HI 0 "register_operand" "=a")
1413	(unspec:HI
1414	  [(compare:CCFP
1415	     (match_operand:SF 1 "register_operand" "f")
1416	     (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1417  "TARGET_80387"
1418  "* return output_fp_compare (insn, operands, 2, 0);"
1419  [(set_attr "type" "fcmp")
1420   (set_attr "mode" "SF")])
1421
1422(define_insn "*cmpfp_2_df"
1423  [(set (reg:CCFP 18)
1424	(compare:CCFP
1425	  (match_operand:DF 0 "register_operand" "f")
1426	  (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1427  "TARGET_80387"
1428  "* return output_fp_compare (insn, operands, 0, 0);"
1429  [(set_attr "type" "fcmp")
1430   (set_attr "mode" "DF")])
1431
1432(define_insn "*cmpfp_2_df_1"
1433  [(set (match_operand:HI 0 "register_operand" "=a")
1434	(unspec:HI
1435	  [(compare:CCFP
1436	     (match_operand:DF 1 "register_operand" "f")
1437	     (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1438  "TARGET_80387"
1439  "* return output_fp_compare (insn, operands, 2, 0);"
1440  [(set_attr "type" "multi")
1441   (set_attr "mode" "DF")])
1442
1443(define_insn "*cmpfp_2_xf"
1444  [(set (reg:CCFP 18)
1445	(compare:CCFP
1446	  (match_operand:XF 0 "register_operand" "f")
1447	  (match_operand:XF 1 "register_operand" "f")))]
1448  "!TARGET_64BIT && TARGET_80387"
1449  "* return output_fp_compare (insn, operands, 0, 0);"
1450  [(set_attr "type" "fcmp")
1451   (set_attr "mode" "XF")])
1452
1453(define_insn "*cmpfp_2_tf"
1454  [(set (reg:CCFP 18)
1455	(compare:CCFP
1456	  (match_operand:TF 0 "register_operand" "f")
1457	  (match_operand:TF 1 "register_operand" "f")))]
1458  "TARGET_80387"
1459  "* return output_fp_compare (insn, operands, 0, 0);"
1460  [(set_attr "type" "fcmp")
1461   (set_attr "mode" "XF")])
1462
1463(define_insn "*cmpfp_2_xf_1"
1464  [(set (match_operand:HI 0 "register_operand" "=a")
1465	(unspec:HI
1466	  [(compare:CCFP
1467	     (match_operand:XF 1 "register_operand" "f")
1468	     (match_operand:XF 2 "register_operand" "f"))] 9))]
1469  "!TARGET_64BIT && TARGET_80387"
1470  "* return output_fp_compare (insn, operands, 2, 0);"
1471  [(set_attr "type" "multi")
1472   (set_attr "mode" "XF")])
1473
1474(define_insn "*cmpfp_2_tf_1"
1475  [(set (match_operand:HI 0 "register_operand" "=a")
1476	(unspec:HI
1477	  [(compare:CCFP
1478	     (match_operand:TF 1 "register_operand" "f")
1479	     (match_operand:TF 2 "register_operand" "f"))] 9))]
1480  "TARGET_80387"
1481  "* return output_fp_compare (insn, operands, 2, 0);"
1482  [(set_attr "type" "multi")
1483   (set_attr "mode" "XF")])
1484
1485(define_insn "*cmpfp_2u"
1486  [(set (reg:CCFPU 18)
1487	(compare:CCFPU
1488	  (match_operand 0 "register_operand" "f")
1489	  (match_operand 1 "register_operand" "f")))]
1490  "TARGET_80387
1491   && FLOAT_MODE_P (GET_MODE (operands[0]))
1492   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1493  "* return output_fp_compare (insn, operands, 0, 1);"
1494  [(set_attr "type" "fcmp")
1495   (set_attr "mode" "unknownfp")])
1496
1497(define_insn "*cmpfp_2u_1"
1498  [(set (match_operand:HI 0 "register_operand" "=a")
1499	(unspec:HI
1500	  [(compare:CCFPU
1501	     (match_operand 1 "register_operand" "f")
1502	     (match_operand 2 "register_operand" "f"))] 9))]
1503  "TARGET_80387
1504   && FLOAT_MODE_P (GET_MODE (operands[1]))
1505   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1506  "* return output_fp_compare (insn, operands, 2, 1);"
1507  [(set_attr "type" "multi")
1508   (set_attr "mode" "unknownfp")])
1509
1510;; Patterns to match the SImode-in-memory ficom instructions.
1511;;
1512;; %%% Play games with accepting gp registers, as otherwise we have to
1513;; force them to memory during rtl generation, which is no good.  We
1514;; can get rid of this once we teach reload to do memory input reloads 
1515;; via pushes.
1516
1517(define_insn "*ficom_1"
1518  [(set (reg:CCFP 18)
1519	(compare:CCFP
1520	  (match_operand 0 "register_operand" "f,f")
1521	  (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1522  "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1523   && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1524  "#")
1525
1526;; Split the not-really-implemented gp register case into a
1527;; push-op-pop sequence.
1528;;
1529;; %%% This is most efficient, but am I gonna get in trouble
1530;; for separating cc0_setter and cc0_user?
1531
1532(define_split
1533  [(set (reg:CCFP 18)
1534	(compare:CCFP
1535	  (match_operand:SF 0 "register_operand" "")
1536	  (float (match_operand:SI 1 "register_operand" ""))))]
1537  "0 && TARGET_80387 && reload_completed"
1538  [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1539   (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1540   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1541              (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1542  "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1543   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1544
1545;; FP compares, step 2
1546;; Move the fpsw to ax.
1547
1548(define_insn "x86_fnstsw_1"
1549  [(set (match_operand:HI 0 "register_operand" "=a")
1550	(unspec:HI [(reg 18)] 9))]
1551  "TARGET_80387"
1552  "fnstsw\t%0"
1553  [(set_attr "length" "2")
1554   (set_attr "mode" "SI")
1555   (set_attr "i387" "1")
1556   (set_attr "ppro_uops" "few")])
1557
1558;; FP compares, step 3
1559;; Get ax into flags, general case.
1560
1561(define_insn "x86_sahf_1"
1562  [(set (reg:CC 17)
1563	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1564  "!TARGET_64BIT"
1565  "sahf"
1566  [(set_attr "length" "1")
1567   (set_attr "athlon_decode" "vector")
1568   (set_attr "mode" "SI")
1569   (set_attr "ppro_uops" "one")])
1570
1571;; Pentium Pro can do steps 1 through 3 in one go.
1572
1573(define_insn "*cmpfp_i"
1574  [(set (reg:CCFP 17)
1575	(compare:CCFP (match_operand 0 "register_operand" "f")
1576		      (match_operand 1 "register_operand" "f")))]
1577  "TARGET_80387 && TARGET_CMOVE
1578   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579   && FLOAT_MODE_P (GET_MODE (operands[0]))
1580   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1581  "* return output_fp_compare (insn, operands, 1, 0);"
1582  [(set_attr "type" "fcmp")
1583   (set_attr "mode" "unknownfp")
1584   (set_attr "athlon_decode" "vector")])
1585
1586(define_insn "*cmpfp_i_sse"
1587  [(set (reg:CCFP 17)
1588	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1589		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1590  "TARGET_80387
1591   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1592   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1593  "* return output_fp_compare (insn, operands, 1, 0);"
1594  [(set_attr "type" "fcmp,sse")
1595   (set_attr "mode" "unknownfp")
1596   (set_attr "athlon_decode" "vector")])
1597
1598(define_insn "*cmpfp_i_sse_only"
1599  [(set (reg:CCFP 17)
1600	(compare:CCFP (match_operand 0 "register_operand" "x")
1601		      (match_operand 1 "nonimmediate_operand" "xm")))]
1602  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1603   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1604  "* return output_fp_compare (insn, operands, 1, 0);"
1605  [(set_attr "type" "sse")
1606   (set_attr "mode" "unknownfp")
1607   (set_attr "athlon_decode" "vector")])
1608
1609(define_insn "*cmpfp_iu"
1610  [(set (reg:CCFPU 17)
1611	(compare:CCFPU (match_operand 0 "register_operand" "f")
1612		       (match_operand 1 "register_operand" "f")))]
1613  "TARGET_80387 && TARGET_CMOVE
1614   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1615   && FLOAT_MODE_P (GET_MODE (operands[0]))
1616   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1617  "* return output_fp_compare (insn, operands, 1, 1);"
1618  [(set_attr "type" "fcmp")
1619   (set_attr "mode" "unknownfp")
1620   (set_attr "athlon_decode" "vector")])
1621
1622(define_insn "*cmpfp_iu_sse"
1623  [(set (reg:CCFPU 17)
1624	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1625		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1626  "TARGET_80387
1627   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1628   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629  "* return output_fp_compare (insn, operands, 1, 1);"
1630  [(set_attr "type" "fcmp,sse")
1631   (set_attr "mode" "unknownfp")
1632   (set_attr "athlon_decode" "vector")])
1633
1634(define_insn "*cmpfp_iu_sse_only"
1635  [(set (reg:CCFPU 17)
1636	(compare:CCFPU (match_operand 0 "register_operand" "x")
1637		       (match_operand 1 "nonimmediate_operand" "xm")))]
1638  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1639   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1640  "* return output_fp_compare (insn, operands, 1, 1);"
1641  [(set_attr "type" "sse")
1642   (set_attr "mode" "unknownfp")
1643   (set_attr "athlon_decode" "vector")])
1644
1645;; Move instructions.
1646
1647;; General case of fullword move.
1648
1649(define_expand "movsi"
1650  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1651	(match_operand:SI 1 "general_operand" ""))]
1652  ""
1653  "ix86_expand_move (SImode, operands); DONE;")
1654
1655;; Push/pop instructions.  They are separate since autoinc/dec is not a
1656;; general_operand.
1657;;
1658;; %%% We don't use a post-inc memory reference because x86 is not a 
1659;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1660;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1661;; targets without our curiosities, and it is just as easy to represent
1662;; this differently.
1663
1664(define_insn "*pushsi2"
1665  [(set (match_operand:SI 0 "push_operand" "=<")
1666	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1667  "!TARGET_64BIT"
1668  "push{l}\t%1"
1669  [(set_attr "type" "push")
1670   (set_attr "mode" "SI")])
1671
1672;; For 64BIT abi we always round up to 8 bytes.
1673(define_insn "*pushsi2_rex64"
1674  [(set (match_operand:SI 0 "push_operand" "=X")
1675	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1676  "TARGET_64BIT"
1677  "push{q}\t%q1"
1678  [(set_attr "type" "push")
1679   (set_attr "mode" "SI")])
1680
1681(define_insn "*pushsi2_prologue"
1682  [(set (match_operand:SI 0 "push_operand" "=<")
1683	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1684   (clobber (mem:BLK (scratch)))]
1685  "!TARGET_64BIT"
1686  "push{l}\t%1"
1687  [(set_attr "type" "push")
1688   (set_attr "mode" "SI")])
1689
1690(define_insn "*popsi1_epilogue"
1691  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1692	(mem:SI (reg:SI 7)))
1693   (set (reg:SI 7)
1694	(plus:SI (reg:SI 7) (const_int 4)))
1695   (clobber (mem:BLK (scratch)))]
1696  "!TARGET_64BIT"
1697  "pop{l}\t%0"
1698  [(set_attr "type" "pop")
1699   (set_attr "mode" "SI")])
1700
1701(define_insn "popsi1"
1702  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1703	(mem:SI (reg:SI 7)))
1704   (set (reg:SI 7)
1705	(plus:SI (reg:SI 7) (const_int 4)))]
1706  "!TARGET_64BIT"
1707  "pop{l}\t%0"
1708  [(set_attr "type" "pop")
1709   (set_attr "mode" "SI")])
1710
1711(define_insn "*movsi_xor"
1712  [(set (match_operand:SI 0 "register_operand" "=r")
1713	(match_operand:SI 1 "const0_operand" "i"))
1714   (clobber (reg:CC 17))]
1715  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1716  "xor{l}\t{%0, %0|%0, %0}"
1717  [(set_attr "type" "alu1")
1718   (set_attr "mode" "SI")
1719   (set_attr "length_immediate" "0")])
1720
1721(define_insn "*movsi_or"
1722  [(set (match_operand:SI 0 "register_operand" "=r")
1723	(match_operand:SI 1 "immediate_operand" "i"))
1724   (clobber (reg:CC 17))]
1725  "reload_completed && GET_CODE (operands[1]) == CONST_INT
1726   && INTVAL (operands[1]) == -1
1727   && (TARGET_PENTIUM || optimize_size)"
1728{
1729  operands[1] = constm1_rtx;
1730  return "or{l}\t{%1, %0|%0, %1}";
1731}
1732  [(set_attr "type" "alu1")
1733   (set_attr "mode" "SI")
1734   (set_attr "length_immediate" "1")])
1735
1736; The first alternative is used only to compute proper length of instruction.
1737; Reload's algorithm does not take into account the cost of spill instructions
1738; needed to free register in given class, so avoid it from choosing the first
1739; alternative when eax is not available.
1740
1741(define_insn "*movsi_1"
1742  [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1743	(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
1744  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1745{
1746  switch (get_attr_type (insn))
1747    {
1748    case TYPE_SSE:
1749      if (get_attr_mode (insn) == TImode)
1750        return "movdqa\t{%1, %0|%0, %1}";
1751      return "movd\t{%1, %0|%0, %1}";
1752
1753    case TYPE_MMX:
1754      if (get_attr_mode (insn) == DImode)
1755	return "movq\t{%1, %0|%0, %1}";
1756      return "movd\t{%1, %0|%0, %1}";
1757
1758    case TYPE_LEA:
1759      return "lea{l}\t{%1, %0|%0, %1}";
1760
1761    default:
1762      if (flag_pic && SYMBOLIC_CONST (operands[1]))
1763	abort();
1764      return "mov{l}\t{%1, %0|%0, %1}";
1765    }
1766}
1767  [(set (attr "type")
1768     (cond [(eq_attr "alternative" "4,5,6")
1769	      (const_string "mmx")
1770	    (eq_attr "alternative" "7,8,9")
1771	      (const_string "sse")
1772	    (and (ne (symbol_ref "flag_pic") (const_int 0))
1773		 (match_operand:SI 1 "symbolic_operand" ""))
1774	      (const_string "lea")
1775	   ]
1776	   (const_string "imov")))
1777   (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
1778   (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
1779
1780;; Stores and loads of ax to arbitary constant address.
1781;; We fake an second form of instruction to force reload to load address
1782;; into register when rax is not available
1783(define_insn "*movabssi_1_rex64"
1784  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1785	(match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1786  "TARGET_64BIT"
1787  "@
1788   movabs{l}\t{%1, %P0|%P0, %1}
1789   mov{l}\t{%1, %a0|%a0, %1}
1790   movabs{l}\t{%1, %a0|%a0, %1}"
1791  [(set_attr "type" "imov")
1792   (set_attr "modrm" "0,*,*")
1793   (set_attr "length_address" "8,0,0")
1794   (set_attr "length_immediate" "0,*,*")
1795   (set_attr "memory" "store")
1796   (set_attr "mode" "SI")])
1797
1798(define_insn "*movabssi_2_rex64"
1799  [(set (match_operand:SI 0 "register_operand" "=a,r")
1800        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1801  "TARGET_64BIT"
1802  "@
1803   movabs{l}\t{%P1, %0|%0, %P1}
1804   mov{l}\t{%a1, %0|%0, %a1}"
1805  [(set_attr "type" "imov")
1806   (set_attr "modrm" "0,*")
1807   (set_attr "length_address" "8,0")
1808   (set_attr "length_immediate" "0")
1809   (set_attr "memory" "load")
1810   (set_attr "mode" "SI")])
1811
1812(define_insn "*swapsi"
1813  [(set (match_operand:SI 0 "register_operand" "+r")
1814	(match_operand:SI 1 "register_operand" "+r"))
1815   (set (match_dup 1)
1816	(match_dup 0))]
1817  ""
1818  "xchg{l}\t%1, %0"
1819  [(set_attr "type" "imov")
1820   (set_attr "pent_pair" "np")
1821   (set_attr "athlon_decode" "vector")
1822   (set_attr "mode" "SI")
1823   (set_attr "modrm" "0")
1824   (set_attr "ppro_uops" "few")])
1825
1826(define_expand "movhi"
1827  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1828        (match_operand:HI 1 "general_operand" ""))]
1829  ""
1830  "ix86_expand_move (HImode, operands); DONE;")
1831
1832(define_insn "*pushhi2"
1833  [(set (match_operand:HI 0 "push_operand" "=<,<")
1834	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1835  "!TARGET_64BIT"
1836  "@
1837   push{w}\t{|WORD PTR }%1
1838   push{w}\t%1"
1839  [(set_attr "type" "push")
1840   (set_attr "mode" "HI")])
1841
1842;; For 64BIT abi we always round up to 8 bytes.
1843(define_insn "*pushhi2_rex64"
1844  [(set (match_operand:HI 0 "push_operand" "=X")
1845	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1846  "TARGET_64BIT"
1847  "push{q}\t%q1"
1848  [(set_attr "type" "push")
1849   (set_attr "mode" "QI")])
1850
1851; The first alternative is used only to compute proper length of instruction.
1852; Reload's algorithm does not take into account the cost of spill instructions
1853; needed to free register in given class, so avoid it from choosing the first
1854; alternative when eax is not available.
1855
1856(define_insn "*movhi_1"
1857  [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
1858	(match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1859  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1860{
1861  switch (get_attr_type (insn))
1862    {
1863    case TYPE_IMOVX:
1864      /* movzwl is faster than movw on p2 due to partial word stalls,
1865	 though not as fast as an aligned movl.  */
1866      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1867    default:
1868      if (get_attr_mode (insn) == MODE_SI)
1869        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1870      else
1871        return "mov{w}\t{%1, %0|%0, %1}";
1872    }
1873}
1874  [(set (attr "type")
1875     (cond [(and (eq_attr "alternative" "0,1")
1876		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1877			  (const_int 0))
1878		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1879			  (const_int 0))))
1880	      (const_string "imov")
1881	    (and (eq_attr "alternative" "2,3,4")
1882		 (match_operand:HI 1 "aligned_operand" ""))
1883	      (const_string "imov")
1884	    (and (ne (symbol_ref "TARGET_MOVX")
1885		     (const_int 0))
1886		 (eq_attr "alternative" "0,1,3,4"))
1887	      (const_string "imovx")
1888	   ]
1889	   (const_string "imov")))
1890    (set (attr "mode")
1891      (cond [(eq_attr "type" "imovx")
1892	       (const_string "SI")
1893	     (and (eq_attr "alternative" "2,3,4")
1894		  (match_operand:HI 1 "aligned_operand" ""))
1895	       (const_string "SI")
1896	     (and (eq_attr "alternative" "0,1")
1897		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1898			   (const_int 0))
1899		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1900			   (const_int 0))))
1901	       (const_string "SI")
1902	    ]
1903	    (const_string "HI")))
1904   (set_attr "modrm" "0,*,*,0,*,*")])
1905
1906;; Stores and loads of ax to arbitary constant address.
1907;; We fake an second form of instruction to force reload to load address
1908;; into register when rax is not available
1909(define_insn "*movabshi_1_rex64"
1910  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1911	(match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1912  "TARGET_64BIT"
1913  "@
1914   movabs{w}\t{%1, %P0|%P0, %1}
1915   mov{w}\t{%1, %a0|%a0, %1}
1916   movabs{w}\t{%1, %a0|%a0, %1}"
1917  [(set_attr "type" "imov")
1918   (set_attr "modrm" "0,*,*")
1919   (set_attr "length_address" "8,0,0")
1920   (set_attr "length_immediate" "0,*,*")
1921   (set_attr "memory" "store")
1922   (set_attr "mode" "HI")])
1923
1924(define_insn "*movabshi_2_rex64"
1925  [(set (match_operand:HI 0 "register_operand" "=a,r")
1926        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1927  "TARGET_64BIT"
1928  "@
1929   movabs{w}\t{%P1, %0|%0, %P1}
1930   mov{w}\t{%a1, %0|%0, %a1}"
1931  [(set_attr "type" "imov")
1932   (set_attr "modrm" "0,*")
1933   (set_attr "length_address" "8,0")
1934   (set_attr "length_immediate" "0")
1935   (set_attr "memory" "load")
1936   (set_attr "mode" "HI")])
1937
1938(define_insn "*swaphi_1"
1939  [(set (match_operand:HI 0 "register_operand" "+r")
1940	(match_operand:HI 1 "register_operand" "+r"))
1941   (set (match_dup 1)
1942	(match_dup 0))]
1943  "TARGET_PARTIAL_REG_STALL"
1944  "xchg{w}\t%1, %0"
1945  [(set_attr "type" "imov")
1946   (set_attr "pent_pair" "np")
1947   (set_attr "mode" "HI")
1948   (set_attr "modrm" "0")
1949   (set_attr "ppro_uops" "few")])
1950
1951(define_insn "*swaphi_2"
1952  [(set (match_operand:HI 0 "register_operand" "+r")
1953	(match_operand:HI 1 "register_operand" "+r"))
1954   (set (match_dup 1)
1955	(match_dup 0))]
1956  "! TARGET_PARTIAL_REG_STALL"
1957  "xchg{l}\t%k1, %k0"
1958  [(set_attr "type" "imov")
1959   (set_attr "pent_pair" "np")
1960   (set_attr "mode" "SI")
1961   (set_attr "modrm" "0")
1962   (set_attr "ppro_uops" "few")])
1963
1964(define_expand "movstricthi"
1965  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1966	(match_operand:HI 1 "general_operand" ""))]
1967  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1968{
1969  /* Don't generate memory->memory moves, go through a register */
1970  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1971    operands[1] = force_reg (HImode, operands[1]);
1972})
1973
1974(define_insn "*movstricthi_1"
1975  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1976	(match_operand:HI 1 "general_operand" "rn,m"))]
1977  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1978   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1979  "mov{w}\t{%1, %0|%0, %1}"
1980  [(set_attr "type" "imov")
1981   (set_attr "mode" "HI")])
1982
1983(define_insn "*movstricthi_xor"
1984  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1985	(match_operand:HI 1 "const0_operand" "i"))
1986   (clobber (reg:CC 17))]
1987  "reload_completed
1988   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1989  "xor{w}\t{%0, %0|%0, %0}"
1990  [(set_attr "type" "alu1")
1991   (set_attr "mode" "HI")
1992   (set_attr "length_immediate" "0")])
1993
1994(define_expand "movqi"
1995  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1996	(match_operand:QI 1 "general_operand" ""))]
1997  ""
1998  "ix86_expand_move (QImode, operands); DONE;")
1999
2000;; emit_push_insn when it calls move_by_pieces requires an insn to
2001;; "push a byte".  But actually we use pushw, which has the effect
2002;; of rounding the amount pushed up to a halfword.
2003
2004(define_insn "*pushqi2"
2005  [(set (match_operand:QI 0 "push_operand" "=X,X")
2006	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
2007  "!TARGET_64BIT"
2008  "@
2009   push{w}\t{|word ptr }%1
2010   push{w}\t%w1"
2011  [(set_attr "type" "push")
2012   (set_attr "mode" "HI")])
2013
2014;; For 64BIT abi we always round up to 8 bytes.
2015(define_insn "*pushqi2_rex64"
2016  [(set (match_operand:QI 0 "push_operand" "=X")
2017	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
2018  "TARGET_64BIT"
2019  "push{q}\t%q1"
2020  [(set_attr "type" "push")
2021   (set_attr "mode" "QI")])
2022
2023;; Situation is quite tricky about when to choose full sized (SImode) move
2024;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2025;; partial register dependency machines (such as AMD Athlon), where QImode
2026;; moves issue extra dependency and for partial register stalls machines
2027;; that don't use QImode patterns (and QImode move cause stall on the next
2028;; instruction).
2029;;
2030;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2031;; register stall machines with, where we use QImode instructions, since
2032;; partial register stall can be caused there.  Then we use movzx.
2033(define_insn "*movqi_1"
2034  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2035	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2036  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2037{
2038  switch (get_attr_type (insn))
2039    {
2040    case TYPE_IMOVX:
2041      if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
2042	abort ();
2043      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2044    default:
2045      if (get_attr_mode (insn) == MODE_SI)
2046        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2047      else
2048        return "mov{b}\t{%1, %0|%0, %1}";
2049    }
2050}
2051  [(set (attr "type")
2052     (cond [(and (eq_attr "alternative" "3")
2053		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2054			  (const_int 0))
2055		      (eq (symbol_ref "TARGET_QIMODE_MATH")
2056			  (const_int 0))))
2057	      (const_string "imov")
2058	    (eq_attr "alternative" "3,5")
2059	      (const_string "imovx")
2060	    (and (ne (symbol_ref "TARGET_MOVX")
2061		     (const_int 0))
2062		 (eq_attr "alternative" "2"))
2063	      (const_string "imovx")
2064	   ]
2065	   (const_string "imov")))
2066   (set (attr "mode")
2067      (cond [(eq_attr "alternative" "3,4,5")
2068	       (const_string "SI")
2069	     (eq_attr "alternative" "6")
2070	       (const_string "QI")
2071	     (eq_attr "type" "imovx")
2072	       (const_string "SI")
2073	     (and (eq_attr "type" "imov")
2074		  (and (eq_attr "alternative" "0,1,2")
2075		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2076			   (const_int 0))))
2077	       (const_string "SI")
2078	     ;; Avoid partial register stalls when not using QImode arithmetic
2079	     (and (eq_attr "type" "imov")
2080		  (and (eq_attr "alternative" "0,1,2")
2081		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2082				(const_int 0))
2083			    (eq (symbol_ref "TARGET_QIMODE_MATH")
2084				(const_int 0)))))
2085	       (const_string "SI")
2086	   ]
2087	   (const_string "QI")))])
2088
2089(define_expand "reload_outqi"
2090  [(parallel [(match_operand:QI 0 "" "=m")
2091              (match_operand:QI 1 "register_operand" "r")
2092              (match_operand:QI 2 "register_operand" "=&q")])]
2093  ""
2094{
2095  rtx op0, op1, op2;
2096  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
2097
2098  if (reg_overlap_mentioned_p (op2, op0))
2099    abort ();
2100  if (! q_regs_operand (op1, QImode))
2101    {
2102      emit_insn (gen_movqi (op2, op1));
2103      op1 = op2;
2104    }
2105  emit_insn (gen_movqi (op0, op1));
2106  DONE;
2107})
2108
2109(define_insn "*swapqi"
2110  [(set (match_operand:QI 0 "register_operand" "+r")
2111	(match_operand:QI 1 "register_operand" "+r"))
2112   (set (match_dup 1)
2113	(match_dup 0))]
2114  ""
2115  "xchg{b}\t%1, %0"
2116  [(set_attr "type" "imov")
2117   (set_attr "pent_pair" "np")
2118   (set_attr "mode" "QI")
2119   (set_attr "modrm" "0")
2120   (set_attr "ppro_uops" "few")])
2121
2122(define_expand "movstrictqi"
2123  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2124	(match_operand:QI 1 "general_operand" ""))]
2125  "! TARGET_PARTIAL_REG_STALL"
2126{
2127  /* Don't generate memory->memory moves, go through a register.  */
2128  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2129    operands[1] = force_reg (QImode, operands[1]);
2130})
2131
2132(define_insn "*movstrictqi_1"
2133  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2134	(match_operand:QI 1 "general_operand" "*qn,m"))]
2135  "! TARGET_PARTIAL_REG_STALL
2136   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2137  "mov{b}\t{%1, %0|%0, %1}"
2138  [(set_attr "type" "imov")
2139   (set_attr "mode" "QI")])
2140
2141(define_insn "*movstrictqi_xor"
2142  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2143	(match_operand:QI 1 "const0_operand" "i"))
2144   (clobber (reg:CC 17))]
2145  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
2146  "xor{b}\t{%0, %0|%0, %0}"
2147  [(set_attr "type" "alu1")
2148   (set_attr "mode" "QI")
2149   (set_attr "length_immediate" "0")])
2150
2151(define_insn "*movsi_extv_1"
2152  [(set (match_operand:SI 0 "register_operand" "=R")
2153	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2154			 (const_int 8)
2155			 (const_int 8)))]
2156  ""
2157  "movs{bl|x}\t{%h1, %0|%0, %h1}"
2158  [(set_attr "type" "imovx")
2159   (set_attr "mode" "SI")])
2160
2161(define_insn "*movhi_extv_1"
2162  [(set (match_operand:HI 0 "register_operand" "=R")
2163	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2164			 (const_int 8)
2165			 (const_int 8)))]
2166  ""
2167  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2168  [(set_attr "type" "imovx")
2169   (set_attr "mode" "SI")])
2170
2171(define_insn "*movqi_extv_1"
2172  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2173        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2174                         (const_int 8)
2175                         (const_int 8)))]
2176  "!TARGET_64BIT"
2177{
2178  switch (get_attr_type (insn))
2179    {
2180    case TYPE_IMOVX:
2181      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2182    default:
2183      return "mov{b}\t{%h1, %0|%0, %h1}";
2184    }
2185}
2186  [(set (attr "type")
2187     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2188			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
2189			     (ne (symbol_ref "TARGET_MOVX")
2190				 (const_int 0))))
2191	(const_string "imovx")
2192	(const_string "imov")))
2193   (set (attr "mode")
2194     (if_then_else (eq_attr "type" "imovx")
2195	(const_string "SI")
2196	(const_string "QI")))])
2197
2198(define_insn "*movqi_extv_1_rex64"
2199  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2200        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2201                         (const_int 8)
2202                         (const_int 8)))]
2203  "TARGET_64BIT"
2204{
2205  switch (get_attr_type (insn))
2206    {
2207    case TYPE_IMOVX:
2208      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2209    default:
2210      return "mov{b}\t{%h1, %0|%0, %h1}";
2211    }
2212}
2213  [(set (attr "type")
2214     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2215			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
2216			     (ne (symbol_ref "TARGET_MOVX")
2217				 (const_int 0))))
2218	(const_string "imovx")
2219	(const_string "imov")))
2220   (set (attr "mode")
2221     (if_then_else (eq_attr "type" "imovx")
2222	(const_string "SI")
2223	(const_string "QI")))])
2224
2225;; Stores and loads of ax to arbitary constant address.
2226;; We fake an second form of instruction to force reload to load address
2227;; into register when rax is not available
2228(define_insn "*movabsqi_1_rex64"
2229  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2230	(match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
2231  "TARGET_64BIT"
2232  "@
2233   movabs{b}\t{%1, %P0|%P0, %1}
2234   mov{b}\t{%1, %a0|%a0, %1}
2235   movabs{b}\t{%1, %a0|%a0, %1}"
2236  [(set_attr "type" "imov")
2237   (set_attr "modrm" "0,*,*")
2238   (set_attr "length_address" "8,0,0")
2239   (set_attr "length_immediate" "0,*,*")
2240   (set_attr "memory" "store")
2241   (set_attr "mode" "QI")])
2242
2243(define_insn "*movabsqi_2_rex64"
2244  [(set (match_operand:QI 0 "register_operand" "=a,r")
2245        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2246  "TARGET_64BIT"
2247  "@
2248   movabs{b}\t{%P1, %0|%0, %P1}
2249   mov{b}\t{%a1, %0|%0, %a1}"
2250  [(set_attr "type" "imov")
2251   (set_attr "modrm" "0,*")
2252   (set_attr "length_address" "8,0")
2253   (set_attr "length_immediate" "0")
2254   (set_attr "memory" "load")
2255   (set_attr "mode" "QI")])
2256
2257(define_insn "*movsi_extzv_1"
2258  [(set (match_operand:SI 0 "register_operand" "=R")
2259	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2260			 (const_int 8)
2261			 (const_int 8)))]
2262  ""
2263  "movz{bl|x}\t{%h1, %0|%0, %h1}"
2264  [(set_attr "type" "imovx")
2265   (set_attr "mode" "SI")])
2266
2267(define_insn "*movqi_extzv_2"
2268  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2269        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2270				    (const_int 8)
2271				    (const_int 8)) 0))]
2272  "!TARGET_64BIT"
2273{
2274  switch (get_attr_type (insn))
2275    {
2276    case TYPE_IMOVX:
2277      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2278    default:
2279      return "mov{b}\t{%h1, %0|%0, %h1}";
2280    }
2281}
2282  [(set (attr "type")
2283     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2284			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
2285			     (ne (symbol_ref "TARGET_MOVX")
2286				 (const_int 0))))
2287	(const_string "imovx")
2288	(const_string "imov")))
2289   (set (attr "mode")
2290     (if_then_else (eq_attr "type" "imovx")
2291	(const_string "SI")
2292	(const_string "QI")))])
2293
2294(define_insn "*movqi_extzv_2_rex64"
2295  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2296        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2297				    (const_int 8)
2298				    (const_int 8)) 0))]
2299  "TARGET_64BIT"
2300{
2301  switch (get_attr_type (insn))
2302    {
2303    case TYPE_IMOVX:
2304      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2305    default:
2306      return "mov{b}\t{%h1, %0|%0, %h1}";
2307    }
2308}
2309  [(set (attr "type")
2310     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2311			(ne (symbol_ref "TARGET_MOVX")
2312			    (const_int 0)))
2313	(const_string "imovx")
2314	(const_string "imov")))
2315   (set (attr "mode")
2316     (if_then_else (eq_attr "type" "imovx")
2317	(const_string "SI")
2318	(const_string "QI")))])
2319
2320(define_insn "movsi_insv_1"
2321  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2322			 (const_int 8)
2323			 (const_int 8))
2324	(match_operand:SI 1 "general_operand" "Qmn"))]
2325  "!TARGET_64BIT"
2326  "mov{b}\t{%b1, %h0|%h0, %b1}"
2327  [(set_attr "type" "imov")
2328   (set_attr "mode" "QI")])
2329
2330(define_insn "*movsi_insv_1_rex64"
2331  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2332			 (const_int 8)
2333			 (const_int 8))
2334	(match_operand:SI 1 "nonmemory_operand" "Qn"))]
2335  "TARGET_64BIT"
2336  "mov{b}\t{%b1, %h0|%h0, %b1}"
2337  [(set_attr "type" "imov")
2338   (set_attr "mode" "QI")])
2339
2340(define_insn "*movqi_insv_2"
2341  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2342			 (const_int 8)
2343			 (const_int 8))
2344	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2345			     (const_int 8))
2346		(const_int 255)))]
2347  ""
2348  "mov{b}\t{%h1, %h0|%h0, %h1}"
2349  [(set_attr "type" "imov")
2350   (set_attr "mode" "QI")])
2351
2352(define_expand "movdi"
2353  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2354	(match_operand:DI 1 "general_operand" ""))]
2355  ""
2356  "ix86_expand_move (DImode, operands); DONE;")
2357
2358(define_insn "*pushdi"
2359  [(set (match_operand:DI 0 "push_operand" "=<")
2360	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2361  "!TARGET_64BIT"
2362  "#")
2363
2364(define_insn "pushdi2_rex64"
2365  [(set (match_operand:DI 0 "push_operand" "=<,!<")
2366	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2367  "TARGET_64BIT"
2368  "@
2369   push{q}\t%1
2370   #"
2371  [(set_attr "type" "push,multi")
2372   (set_attr "mode" "DI")])
2373
2374;; Convert impossible pushes of immediate to existing instructions.
2375;; First try to get scratch register and go through it.  In case this
2376;; fails, push sign extended lower part first and then overwrite
2377;; upper part by 32bit move.
2378(define_peephole2
2379  [(match_scratch:DI 2 "r")
2380   (set (match_operand:DI 0 "push_operand" "")
2381        (match_operand:DI 1 "immediate_operand" ""))]
2382  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2383   && !x86_64_immediate_operand (operands[1], DImode)"
2384  [(set (match_dup 2) (match_dup 1))
2385   (set (match_dup 0) (match_dup 2))]
2386  "")
2387
2388;; We need to define this as both peepholer and splitter for case
2389;; peephole2 pass is not run.
2390(define_peephole2
2391  [(set (match_operand:DI 0 "push_operand" "")
2392        (match_operand:DI 1 "immediate_operand" ""))]
2393  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2394   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2395  [(set (match_dup 0) (match_dup 1))
2396   (set (match_dup 2) (match_dup 3))]
2397  "split_di (operands + 1, 1, operands + 2, operands + 3);
2398   operands[1] = gen_lowpart (DImode, operands[2]);
2399   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2400						    GEN_INT (4)));
2401  ")
2402
2403(define_split
2404  [(set (match_operand:DI 0 "push_operand" "")
2405        (match_operand:DI 1 "immediate_operand" ""))]
2406  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2407   && !symbolic_operand (operands[1], DImode)
2408   && !x86_64_immediate_operand (operands[1], DImode)"
2409  [(set (match_dup 0) (match_dup 1))
2410   (set (match_dup 2) (match_dup 3))]
2411  "split_di (operands + 1, 1, operands + 2, operands + 3);
2412   operands[1] = gen_lowpart (DImode, operands[2]);
2413   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2414						    GEN_INT (4)));
2415  ")
2416
2417(define_insn "*pushdi2_prologue_rex64"
2418  [(set (match_operand:DI 0 "push_operand" "=<")
2419	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
2420   (clobber (mem:BLK (scratch)))]
2421  "TARGET_64BIT"
2422  "push{q}\t%1"
2423  [(set_attr "type" "push")
2424   (set_attr "mode" "DI")])
2425
2426(define_insn "*popdi1_epilogue_rex64"
2427  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2428	(mem:DI (reg:DI 7)))
2429   (set (reg:DI 7)
2430	(plus:DI (reg:DI 7) (const_int 8)))
2431   (clobber (mem:BLK (scratch)))]
2432  "TARGET_64BIT"
2433  "pop{q}\t%0"
2434  [(set_attr "type" "pop")
2435   (set_attr "mode" "DI")])
2436
2437(define_insn "popdi1"
2438  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2439	(mem:DI (reg:DI 7)))
2440   (set (reg:DI 7)
2441	(plus:DI (reg:DI 7) (const_int 8)))]
2442  "TARGET_64BIT"
2443  "pop{q}\t%0"
2444  [(set_attr "type" "pop")
2445   (set_attr "mode" "DI")])
2446
2447(define_insn "*movdi_xor_rex64"
2448  [(set (match_operand:DI 0 "register_operand" "=r")
2449	(match_operand:DI 1 "const0_operand" "i"))
2450   (clobber (reg:CC 17))]
2451  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2452   && reload_completed"
2453  "xor{l}\t{%k0, %k0|%k0, %k0}"
2454  [(set_attr "type" "alu1")
2455   (set_attr "mode" "SI")
2456   (set_attr "length_immediate" "0")])
2457
2458(define_insn "*movdi_or_rex64"
2459  [(set (match_operand:DI 0 "register_operand" "=r")
2460	(match_operand:DI 1 "const_int_operand" "i"))
2461   (clobber (reg:CC 17))]
2462  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
2463   && reload_completed
2464   && GET_CODE (operands[1]) == CONST_INT
2465   && INTVAL (operands[1]) == -1"
2466{
2467  operands[1] = constm1_rtx;
2468  return "or{q}\t{%1, %0|%0, %1}";
2469}
2470  [(set_attr "type" "alu1")
2471   (set_attr "mode" "DI")
2472   (set_attr "length_immediate" "1")])
2473
2474(define_insn "*movdi_2"
2475  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
2476	(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
2477  "!TARGET_64BIT
2478   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2479  "@
2480   #
2481   #
2482   movq\t{%1, %0|%0, %1}
2483   movq\t{%1, %0|%0, %1}
2484   movq\t{%1, %0|%0, %1}
2485   movdqa\t{%1, %0|%0, %1}
2486   movq\t{%1, %0|%0, %1}"
2487  [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
2488   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
2489
2490(define_split
2491  [(set (match_operand:DI 0 "push_operand" "")
2492        (match_operand:DI 1 "general_operand" ""))]
2493  "!TARGET_64BIT && reload_completed
2494   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2495  [(const_int 0)]
2496  "ix86_split_long_move (operands); DONE;")
2497
2498;; %%% This multiword shite has got to go.
2499(define_split
2500  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2501        (match_operand:DI 1 "general_operand" ""))]
2502  "!TARGET_64BIT && reload_completed
2503   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2504   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2505  [(const_int 0)]
2506  "ix86_split_long_move (operands); DONE;")
2507
2508(define_insn "*movdi_1_rex64"
2509  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
2510	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
2511  "TARGET_64BIT
2512   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2513{
2514  switch (get_attr_type (insn))
2515    {
2516    case TYPE_SSE:
2517      if (register_operand (operands[0], DImode)
2518	  && register_operand (operands[1], DImode))
2519	  return "movdqa\t{%1, %0|%0, %1}";
2520      /* FALLTHRU */
2521    case TYPE_MMX:
2522      return "movq\t{%1, %0|%0, %1}";
2523    case TYPE_MULTI:
2524      return "#";
2525    case TYPE_LEA:
2526      return "lea{q}\t{%a1, %0|%0, %a1}";
2527    default:
2528      if (flag_pic && SYMBOLIC_CONST (operands[1]))
2529	abort ();
2530      if (get_attr_mode (insn) == MODE_SI)
2531	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2532      else if (which_alternative == 2)
2533	return "movabs{q}\t{%1, %0|%0, %1}";
2534      else
2535	return "mov{q}\t{%1, %0|%0, %1}";
2536    }
2537}
2538  [(set (attr "type")
2539     (cond [(eq_attr "alternative" "5,6")
2540	      (const_string "mmx")
2541	    (eq_attr "alternative" "7,8")
2542	      (const_string "sse")
2543	    (eq_attr "alternative" "4")
2544	      (const_string "multi")
2545 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
2546		 (match_operand:DI 1 "symbolic_operand" ""))
2547	      (const_string "lea")
2548	   ]
2549	   (const_string "imov")))
2550   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
2551   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
2552   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
2553
2554;; Stores and loads of ax to arbitary constant address.
2555;; We fake an second form of instruction to force reload to load address
2556;; into register when rax is not available
2557(define_insn "*movabsdi_1_rex64"
2558  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2559	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2560  "TARGET_64BIT"
2561  "@
2562   movabs{q}\t{%1, %P0|%P0, %1}
2563   mov{q}\t{%1, %a0|%a0, %1}"
2564  [(set_attr "type" "imov")
2565   (set_attr "modrm" "0,*")
2566   (set_attr "length_address" "8,0")
2567   (set_attr "length_immediate" "0,*")
2568   (set_attr "memory" "store")
2569   (set_attr "mode" "DI")])
2570
2571(define_insn "*movabsdi_2_rex64"
2572  [(set (match_operand:DI 0 "register_operand" "=a,r")
2573        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2574  "TARGET_64BIT"
2575  "@
2576   movabs{q}\t{%P1, %0|%0, %P1}
2577   mov{q}\t{%a1, %0|%0, %a1}"
2578  [(set_attr "type" "imov")
2579   (set_attr "modrm" "0,*")
2580   (set_attr "length_address" "8,0")
2581   (set_attr "length_immediate" "0")
2582   (set_attr "memory" "load")
2583   (set_attr "mode" "DI")])
2584
2585;; Convert impossible stores of immediate to existing instructions.
2586;; First try to get scratch register and go through it.  In case this
2587;; fails, move by 32bit parts.
2588(define_peephole2
2589  [(match_scratch:DI 2 "r")
2590   (set (match_operand:DI 0 "memory_operand" "")
2591        (match_operand:DI 1 "immediate_operand" ""))]
2592  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2593   && !x86_64_immediate_operand (operands[1], DImode)"
2594  [(set (match_dup 2) (match_dup 1))
2595   (set (match_dup 0) (match_dup 2))]
2596  "")
2597
2598;; We need to define this as both peepholer and splitter for case
2599;; peephole2 pass is not run.
2600(define_peephole2
2601  [(set (match_operand:DI 0 "memory_operand" "")
2602        (match_operand:DI 1 "immediate_operand" ""))]
2603  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2604   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2605  [(set (match_dup 2) (match_dup 3))
2606   (set (match_dup 4) (match_dup 5))]
2607  "split_di (operands, 2, operands + 2, operands + 4);")
2608
2609(define_split
2610  [(set (match_operand:DI 0 "memory_operand" "")
2611        (match_operand:DI 1 "immediate_operand" ""))]
2612  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2613   && !symbolic_operand (operands[1], DImode)
2614   && !x86_64_immediate_operand (operands[1], DImode)"
2615  [(set (match_dup 2) (match_dup 3))
2616   (set (match_dup 4) (match_dup 5))]
2617  "split_di (operands, 2, operands + 2, operands + 4);")
2618
2619(define_insn "*swapdi_rex64"
2620  [(set (match_operand:DI 0 "register_operand" "+r")
2621	(match_operand:DI 1 "register_operand" "+r"))
2622   (set (match_dup 1)
2623	(match_dup 0))]
2624  "TARGET_64BIT"
2625  "xchg{q}\t%1, %0"
2626  [(set_attr "type" "imov")
2627   (set_attr "pent_pair" "np")
2628   (set_attr "athlon_decode" "vector")
2629   (set_attr "mode" "DI")
2630   (set_attr "modrm" "0")
2631   (set_attr "ppro_uops" "few")])
2632
2633  
2634(define_expand "movsf"
2635  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2636	(match_operand:SF 1 "general_operand" ""))]
2637  ""
2638  "ix86_expand_move (SFmode, operands); DONE;")
2639
2640(define_insn "*pushsf"
2641  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2642	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2643  "!TARGET_64BIT"
2644{
2645  switch (which_alternative)
2646    {
2647    case 0:
2648      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2649      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2650      operands[2] = stack_pointer_rtx;
2651      operands[3] = GEN_INT (4);
2652      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2653	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2654      else
2655	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2656
2657    case 1:
2658      return "push{l}\t%1";
2659    case 2:
2660      return "#";
2661
2662    default:
2663      abort ();
2664    }
2665}
2666  [(set_attr "type" "multi,push,multi")
2667   (set_attr "mode" "SF,SI,SF")])
2668
2669(define_insn "*pushsf_rex64"
2670  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2671	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2672  "TARGET_64BIT"
2673{
2674  switch (which_alternative)
2675    {
2676    case 0:
2677      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2678      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2679      operands[2] = stack_pointer_rtx;
2680      operands[3] = GEN_INT (8);
2681      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2682	return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2683      else
2684	return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2685
2686    case 1:
2687      return "push{q}\t%q1";
2688
2689    case 2:
2690      return "#";
2691
2692    default:
2693      abort ();
2694    }
2695}
2696  [(set_attr "type" "multi,push,multi")
2697   (set_attr "mode" "SF,DI,SF")])
2698
2699(define_split
2700  [(set (match_operand:SF 0 "push_operand" "")
2701	(match_operand:SF 1 "memory_operand" ""))]
2702  "reload_completed
2703   && GET_CODE (operands[1]) == MEM
2704   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2705   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2706  [(set (match_dup 0)
2707	(match_dup 1))]
2708  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2709
2710
2711;; %%% Kill this when call knows how to work this out.
2712(define_split
2713  [(set (match_operand:SF 0 "push_operand" "")
2714	(match_operand:SF 1 "register_operand" ""))]
2715  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2716  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2717   (set (mem:SF (reg:SI 7)) (match_dup 1))])
2718
2719(define_split
2720  [(set (match_operand:SF 0 "push_operand" "")
2721	(match_operand:SF 1 "register_operand" ""))]
2722  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2723  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2724   (set (mem:SF (reg:DI 7)) (match_dup 1))])
2725
2726(define_insn "*movsf_1"
2727  [(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")
2728	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
2729  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2730   && (reload_in_progress || reload_completed
2731       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2732       || GET_CODE (operands[1]) != CONST_DOUBLE
2733       || memory_operand (operands[0], SFmode))" 
2734{
2735  switch (which_alternative)
2736    {
2737    case 0:
2738      if (REG_P (operands[1])
2739          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2740        return "fstp\t%y0";
2741      else if (STACK_TOP_P (operands[0]))
2742        return "fld%z1\t%y1";
2743      else
2744        return "fst\t%y0";
2745
2746    case 1:
2747      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2748        return "fstp%z0\t%y0";
2749      else
2750        return "fst%z0\t%y0";
2751
2752    case 2:
2753      switch (standard_80387_constant_p (operands[1]))
2754        {
2755        case 1:
2756	  return "fldz";
2757	case 2:
2758	  return "fld1";
2759	}
2760      abort();
2761
2762    case 3:
2763    case 4:
2764      return "mov{l}\t{%1, %0|%0, %1}";
2765    case 5:
2766      if (TARGET_SSE2)
2767	return "pxor\t%0, %0";
2768      else
2769	return "xorps\t%0, %0";
2770    case 6:
2771      if (TARGET_PARTIAL_REG_DEPENDENCY)
2772	return "movaps\t{%1, %0|%0, %1}";
2773      else
2774	return "movss\t{%1, %0|%0, %1}";
2775    case 7:
2776    case 8:
2777      return "movss\t{%1, %0|%0, %1}";
2778
2779    case 9:
2780    case 10:
2781      return "movd\t{%1, %0|%0, %1}";
2782
2783    case 11:
2784      return "movq\t{%1, %0|%0, %1}";
2785
2786    default:
2787      abort();
2788    }
2789}
2790  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
2791   (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
2792
2793(define_insn "*swapsf"
2794  [(set (match_operand:SF 0 "register_operand" "+f")
2795	(match_operand:SF 1 "register_operand" "+f"))
2796   (set (match_dup 1)
2797	(match_dup 0))]
2798  "reload_completed || !TARGET_SSE"
2799{
2800  if (STACK_TOP_P (operands[0]))
2801    return "fxch\t%1";
2802  else
2803    return "fxch\t%0";
2804}
2805  [(set_attr "type" "fxch")
2806   (set_attr "mode" "SF")])
2807
2808(define_expand "movdf"
2809  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2810	(match_operand:DF 1 "general_operand" ""))]
2811  ""
2812  "ix86_expand_move (DFmode, operands); DONE;")
2813
2814;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2815;; Size of pushdf using integer insturctions is 2+2*memory operand size
2816;; On the average, pushdf using integers can be still shorter.  Allow this
2817;; pattern for optimize_size too.
2818
2819(define_insn "*pushdf_nointeger"
2820  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2821	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2822  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2823{
2824  switch (which_alternative)
2825    {
2826    case 0:
2827      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2828      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2829      operands[2] = stack_pointer_rtx;
2830      operands[3] = GEN_INT (8);
2831      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2832	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2833      else
2834	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2835
2836    case 1:
2837    case 2:
2838    case 3:
2839      return "#";
2840
2841    default:
2842      abort ();
2843    }
2844}
2845  [(set_attr "type" "multi")
2846   (set_attr "mode" "DF,SI,SI,DF")])
2847
2848(define_insn "*pushdf_integer"
2849  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2850	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2851  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2852{
2853  switch (which_alternative)
2854    {
2855    case 0:
2856      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2857      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2858      operands[2] = stack_pointer_rtx;
2859      operands[3] = GEN_INT (8);
2860      if (TARGET_64BIT)
2861	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2862	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2863	else
2864	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2865      else
2866	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2867	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2868	else
2869	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2870
2871
2872    case 1:
2873    case 2:
2874      return "#";
2875
2876    default:
2877      abort ();
2878    }
2879}
2880  [(set_attr "type" "multi")
2881   (set_attr "mode" "DF,SI,DF")])
2882
2883;; %%% Kill this when call knows how to work this out.
2884(define_split
2885  [(set (match_operand:DF 0 "push_operand" "")
2886	(match_operand:DF 1 "register_operand" ""))]
2887  "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2888  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2889   (set (mem:DF (reg:SI 7)) (match_dup 1))]
2890  "")
2891
2892(define_split
2893  [(set (match_operand:DF 0 "push_operand" "")
2894	(match_operand:DF 1 "register_operand" ""))]
2895  "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2896  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2897   (set (mem:DF (reg:DI 7)) (match_dup 1))]
2898  "")
2899
2900(define_split
2901  [(set (match_operand:DF 0 "push_operand" "")
2902	(match_operand:DF 1 "general_operand" ""))]
2903  "reload_completed"
2904  [(const_int 0)]
2905  "ix86_split_long_move (operands); DONE;")
2906
2907;; Moving is usually shorter when only FP registers are used. This separate
2908;; movdf pattern avoids the use of integer registers for FP operations
2909;; when optimizing for size.
2910
2911(define_insn "*movdf_nointeger"
2912  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2913	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2914  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2915   && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2916   && (reload_in_progress || reload_completed
2917       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2918       || GET_CODE (operands[1]) != CONST_DOUBLE
2919       || memory_operand (operands[0], DFmode))" 
2920{
2921  switch (which_alternative)
2922    {
2923    case 0:
2924      if (REG_P (operands[1])
2925          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2926        return "fstp\t%y0";
2927      else if (STACK_TOP_P (operands[0]))
2928        return "fld%z1\t%y1";
2929      else
2930        return "fst\t%y0";
2931
2932    case 1:
2933      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2934        return "fstp%z0\t%y0";
2935      else
2936        return "fst%z0\t%y0";
2937
2938    case 2:
2939      switch (standard_80387_constant_p (operands[1]))
2940        {
2941        case 1:
2942	  return "fldz";
2943	case 2:
2944	  return "fld1";
2945	}
2946      abort();
2947
2948    case 3:
2949    case 4:
2950      return "#";
2951    case 5:
2952      return "pxor\t%0, %0";
2953    case 6:
2954      if (TARGET_PARTIAL_REG_DEPENDENCY)
2955	return "movapd\t{%1, %0|%0, %1}";
2956      else
2957	return "movsd\t{%1, %0|%0, %1}";
2958    case 7:
2959    case 8:
2960        return "movsd\t{%1, %0|%0, %1}";
2961
2962    default:
2963      abort();
2964    }
2965}
2966  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2967   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2968
2969(define_insn "*movdf_integer"
2970  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2971	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2972  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2973   && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2974   && (reload_in_progress || reload_completed
2975       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2976       || GET_CODE (operands[1]) != CONST_DOUBLE
2977       || memory_operand (operands[0], DFmode))" 
2978{
2979  switch (which_alternative)
2980    {
2981    case 0:
2982      if (REG_P (operands[1])
2983          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2984        return "fstp\t%y0";
2985      else if (STACK_TOP_P (operands[0]))
2986        return "fld%z1\t%y1";
2987      else
2988        return "fst\t%y0";
2989
2990    case 1:
2991      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2992        return "fstp%z0\t%y0";
2993      else
2994        return "fst%z0\t%y0";
2995
2996    case 2:
2997      switch (standard_80387_constant_p (operands[1]))
2998        {
2999        case 1:
3000	  return "fldz";
3001	case 2:
3002	  return "fld1";
3003	}
3004      abort();
3005
3006    case 3:
3007    case 4:
3008      return "#";
3009
3010    case 5:
3011      return "pxor\t%0, %0";
3012    case 6:
3013      if (TARGET_PARTIAL_REG_DEPENDENCY)
3014	return "movapd\t{%1, %0|%0, %1}";
3015      else
3016	return "movsd\t{%1, %0|%0, %1}";
3017    case 7:
3018    case 8:
3019      return "movsd\t{%1, %0|%0, %1}";
3020
3021    default:
3022      abort();
3023    }
3024}
3025  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
3026   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
3027
3028(define_split
3029  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3030	(match_operand:DF 1 "general_operand" ""))]
3031  "reload_completed
3032   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3033   && ! (ANY_FP_REG_P (operands[0]) || 
3034	 (GET_CODE (operands[0]) == SUBREG
3035	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3036   && ! (ANY_FP_REG_P (operands[1]) || 
3037	 (GET_CODE (operands[1]) == SUBREG
3038	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3039  [(const_int 0)]
3040  "ix86_split_long_move (operands); DONE;")
3041
3042(define_insn "*swapdf"
3043  [(set (match_operand:DF 0 "register_operand" "+f")
3044	(match_operand:DF 1 "register_operand" "+f"))
3045   (set (match_dup 1)
3046	(match_dup 0))]
3047  "reload_completed || !TARGET_SSE2"
3048{
3049  if (STACK_TOP_P (operands[0]))
3050    return "fxch\t%1";
3051  else
3052    return "fxch\t%0";
3053}
3054  [(set_attr "type" "fxch")
3055   (set_attr "mode" "DF")])
3056
3057(define_expand "movxf"
3058  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3059	(match_operand:XF 1 "general_operand" ""))]
3060  "!TARGET_64BIT"
3061  "ix86_expand_move (XFmode, operands); DONE;")
3062
3063(define_expand "movtf"
3064  [(set (match_operand:TF 0 "nonimmediate_operand" "")
3065	(match_operand:TF 1 "general_operand" ""))]
3066  ""
3067  "ix86_expand_move (TFmode, operands); DONE;")
3068
3069;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3070;; Size of pushdf using integer insturctions is 3+3*memory operand size
3071;; Pushing using integer instructions is longer except for constants
3072;; and direct memory references.
3073;; (assuming that any given constant is pushed only once, but this ought to be
3074;;  handled elsewhere).
3075
3076(define_insn "*pushxf_nointeger"
3077  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3078	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3079  "!TARGET_64BIT && optimize_size"
3080{
3081  switch (which_alternative)
3082    {
3083    case 0:
3084      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
3085      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3086      operands[2] = stack_pointer_rtx;
3087      operands[3] = GEN_INT (12);
3088      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3089	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3090      else
3091	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3092
3093    case 1:
3094    case 2:
3095      return "#";
3096
3097    default:
3098      abort ();
3099    }
3100}
3101  [(set_attr "type" "multi")
3102   (set_attr "mode" "XF,SI,SI")])
3103
3104(define_insn "*pushtf_nointeger"
3105  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3106	(match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
3107  "optimize_size"
3108{
3109  switch (which_alternative)
3110    {
3111    case 0:
3112      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
3113      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3114      operands[2] = stack_pointer_rtx;
3115      operands[3] = GEN_INT (16);
3116      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3117	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3118      else
3119	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3120
3121    case 1:
3122    case 2:
3123      return "#";
3124
3125    default:
3126      abort ();
3127    }
3128}
3129  [(set_attr "type" "multi")
3130   (set_attr "mode" "XF,SI,SI")])
3131
3132(define_insn "*pushxf_integer"
3133  [(set (match_operand:XF 0 "push_operand" "=<,<")
3134	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
3135  "!TARGET_64BIT && !optimize_size"
3136{
3137  switch (which_alternative)
3138    {
3139    case 0:
3140      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
3141      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3142      operands[2] = stack_pointer_rtx;
3143      operands[3] = GEN_INT (12);
3144      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3145	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3146      else
3147	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3148
3149    case 1:
3150      return "#";
3151
3152    default:
3153      abort ();
3154    }
3155}
3156  [(set_attr "type" "multi")
3157   (set_attr "mode" "XF,SI")])
3158
3159(define_insn "*pushtf_integer"
3160  [(set (match_operand:TF 0 "push_operand" "=<,<")
3161	(match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
3162  "!optimize_size"
3163{
3164  switch (which_alternative)
3165    {
3166    case 0:
3167      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
3168      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3169      operands[2] = stack_pointer_rtx;
3170      operands[3] = GEN_INT (16);
3171      if (TARGET_64BIT)
3172	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3173	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3174	else
3175	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3176      else
3177	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3178	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3179	else
3180	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3181
3182    case 1:
3183      return "#";
3184
3185    default:
3186      abort ();
3187    }
3188}
3189  [(set_attr "type" "multi")
3190   (set_attr "mode" "XF,SI")])
3191
3192(define_split
3193  [(set (match_operand 0 "push_operand" "")
3194	(match_operand 1 "general_operand" ""))]
3195  "reload_completed
3196   && (GET_MODE (operands[0]) == XFmode
3197       || GET_MODE (operands[0]) == TFmode
3198       || GET_MODE (operands[0]) == DFmode)
3199   && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
3200  [(const_int 0)]
3201  "ix86_split_long_move (operands); DONE;")
3202
3203(define_split
3204  [(set (match_operand:XF 0 "push_operand" "")
3205	(match_operand:XF 1 "register_operand" ""))]
3206  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3207  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3208   (set (mem:XF (reg:SI 7)) (match_dup 1))])
3209
3210(define_split
3211  [(set (match_operand:TF 0 "push_operand" "")
3212	(match_operand:TF 1 "register_operand" ""))]
3213  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3214  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3215   (set (mem:TF (reg:SI 7)) (match_dup 1))])
3216
3217(define_split
3218  [(set (match_operand:TF 0 "push_operand" "")
3219	(match_operand:TF 1 "register_operand" ""))]
3220  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3221  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3222   (set (mem:TF (reg:DI 7)) (match_dup 1))])
3223
3224;; Do not use integer registers when optimizing for size
3225(define_insn "*movxf_nointeger"
3226  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3227	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3228  "!TARGET_64BIT
3229   && optimize_size
3230   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3231   && (reload_in_progress || reload_completed
3232       || GET_CODE (operands[1]) != CONST_DOUBLE
3233       || memory_operand (operands[0], XFmode))" 
3234{
3235  switch (which_alternative)
3236    {
3237    case 0:
3238      if (REG_P (operands[1])
3239          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3240        return "fstp\t%y0";
3241      else if (STACK_TOP_P (operands[0]))
3242        return "fld%z1\t%y1";
3243      else
3244        return "fst\t%y0";
3245
3246    case 1:
3247      /* There is no non-popping store to memory for XFmode.  So if
3248	 we need one, follow the store with a load.  */
3249      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3250        return "fstp%z0\t%y0\;fld%z0\t%y0";
3251      else
3252        return "fstp%z0\t%y0";
3253
3254    case 2:
3255      switch (standard_80387_constant_p (operands[1]))
3256        {
3257        case 1:
3258	  return "fldz";
3259	case 2:
3260	  return "fld1";
3261	}
3262      break;
3263
3264    case 3: case 4:
3265      return "#";
3266    }
3267  abort();
3268}
3269  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3270   (set_attr "mode" "XF,XF,XF,SI,SI")])
3271
3272(define_insn "*movtf_nointeger"
3273  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3274	(match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3275  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3276   && optimize_size
3277   && (reload_in_progress || reload_completed
3278       || GET_CODE (operands[1]) != CONST_DOUBLE
3279       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3280       || memory_operand (operands[0], TFmode))" 
3281{
3282  switch (which_alternative)
3283    {
3284    case 0:
3285      if (REG_P (operands[1])
3286          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3287        return "fstp\t%y0";
3288      else if (STACK_TOP_P (operands[0]))
3289        return "fld%z1\t%y1";
3290      else
3291        return "fst\t%y0";
3292
3293    case 1:
3294      /* There is no non-popping store to memory for XFmode.  So if
3295	 we need one, follow the store with a load.  */
3296      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3297        return "fstp%z0\t%y0\;fld%z0\t%y0";
3298      else
3299        return "fstp%z0\t%y0";
3300
3301    case 2:
3302      switch (standard_80387_constant_p (operands[1]))
3303        {
3304        case 1:
3305	  return "fldz";
3306	case 2:
3307	  return "fld1";
3308	}
3309      break;
3310
3311    case 3: case 4:
3312      return "#";
3313    }
3314  abort();
3315}
3316  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3317   (set_attr "mode" "XF,XF,XF,SI,SI")])
3318
3319(define_insn "*movxf_integer"
3320  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3321	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3322  "!TARGET_64BIT
3323   && !optimize_size
3324   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3325   && (reload_in_progress || reload_completed
3326       || GET_CODE (operands[1]) != CONST_DOUBLE
3327       || memory_operand (operands[0], XFmode))" 
3328{
3329  switch (which_alternative)
3330    {
3331    case 0:
3332      if (REG_P (operands[1])
3333          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3334        return "fstp\t%y0";
3335      else if (STACK_TOP_P (operands[0]))
3336        return "fld%z1\t%y1";
3337      else
3338        return "fst\t%y0";
3339
3340    case 1:
3341      /* There is no non-popping store to memory for XFmode.  So if
3342	 we need one, follow the store with a load.  */
3343      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3344        return "fstp%z0\t%y0\;fld%z0\t%y0";
3345      else
3346        return "fstp%z0\t%y0";
3347
3348    case 2:
3349      switch (standard_80387_constant_p (operands[1]))
3350        {
3351        case 1:
3352	  return "fldz";
3353	case 2:
3354	  return "fld1";
3355	}
3356      break;
3357
3358    case 3: case 4:
3359      return "#";
3360    }
3361  abort();
3362}
3363  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3364   (set_attr "mode" "XF,XF,XF,SI,SI")])
3365
3366(define_insn "*movtf_integer"
3367  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3368	(match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3369  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3370   && !optimize_size
3371   && (reload_in_progress || reload_completed
3372       || GET_CODE (operands[1]) != CONST_DOUBLE
3373       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3374       || memory_operand (operands[0], TFmode))" 
3375{
3376  switch (which_alternative)
3377    {
3378    case 0:
3379      if (REG_P (operands[1])
3380          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3381        return "fstp\t%y0";
3382      else if (STACK_TOP_P (operands[0]))
3383        return "fld%z1\t%y1";
3384      else
3385        return "fst\t%y0";
3386
3387    case 1:
3388      /* There is no non-popping store to memory for XFmode.  So if
3389	 we need one, follow the store with a load.  */
3390      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3391        return "fstp%z0\t%y0\;fld%z0\t%y0";
3392      else
3393        return "fstp%z0\t%y0";
3394
3395    case 2:
3396      switch (standard_80387_constant_p (operands[1]))
3397        {
3398        case 1:
3399	  return "fldz";
3400	case 2:
3401	  return "fld1";
3402	}
3403      break;
3404
3405    case 3: case 4:
3406      return "#";
3407    }
3408  abort();
3409}
3410  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3411   (set_attr "mode" "XF,XF,XF,SI,SI")])
3412
3413(define_split
3414  [(set (match_operand 0 "nonimmediate_operand" "")
3415	(match_operand 1 "general_operand" ""))]
3416  "reload_completed
3417   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3418   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3419   && ! (ANY_FP_REG_P (operands[0]) || 
3420	 (GET_CODE (operands[0]) == SUBREG
3421	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3422   && ! (ANY_FP_REG_P (operands[1]) || 
3423	 (GET_CODE (operands[1]) == SUBREG
3424	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3425  [(const_int 0)]
3426  "ix86_split_long_move (operands); DONE;")
3427
3428(define_split
3429  [(set (match_operand 0 "register_operand" "")
3430	(match_operand 1 "memory_operand" ""))]
3431  "reload_completed
3432   && GET_CODE (operands[1]) == MEM
3433   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3434       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3435   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3436   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3437   && (!(SSE_REG_P (operands[0]) || 
3438	 (GET_CODE (operands[0]) == SUBREG
3439	  && SSE_REG_P (SUBREG_REG (operands[0]))))
3440       || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3441   && (!(FP_REG_P (operands[0]) || 
3442	 (GET_CODE (operands[0]) == SUBREG
3443	  && FP_REG_P (SUBREG_REG (operands[0]))))
3444       || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3445  [(set (match_dup 0)
3446	(match_dup 1))]
3447  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3448
3449(define_insn "swapxf"
3450  [(set (match_operand:XF 0 "register_operand" "+f")
3451	(match_operand:XF 1 "register_operand" "+f"))
3452   (set (match_dup 1)
3453	(match_dup 0))]
3454  ""
3455{
3456  if (STACK_TOP_P (operands[0]))
3457    return "fxch\t%1";
3458  else
3459    return "fxch\t%0";
3460}
3461  [(set_attr "type" "fxch")
3462   (set_attr "mode" "XF")])
3463
3464(define_insn "swaptf"
3465  [(set (match_operand:TF 0 "register_operand" "+f")
3466	(match_operand:TF 1 "register_operand" "+f"))
3467   (set (match_dup 1)
3468	(match_dup 0))]
3469  ""
3470{
3471  if (STACK_TOP_P (operands[0]))
3472    return "fxch\t%1";
3473  else
3474    return "fxch\t%0";
3475}
3476  [(set_attr "type" "fxch")
3477   (set_attr "mode" "XF")])
3478
3479;; Zero extension instructions
3480
3481(define_expand "zero_extendhisi2"
3482  [(set (match_operand:SI 0 "register_operand" "")
3483     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3484  ""
3485{
3486  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3487    {
3488      operands[1] = force_reg (HImode, operands[1]);
3489      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3490      DONE;
3491    }
3492})
3493
3494(define_insn "zero_extendhisi2_and"
3495  [(set (match_operand:SI 0 "register_operand" "=r")
3496     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3497   (clobber (reg:CC 17))]
3498  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3499  "#"
3500  [(set_attr "type" "alu1")
3501   (set_attr "mode" "SI")])
3502
3503(define_split
3504  [(set (match_operand:SI 0 "register_operand" "")
3505	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3506   (clobber (reg:CC 17))]
3507  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3508  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3509	      (clobber (reg:CC 17))])]
3510  "")
3511
3512(define_insn "*zero_extendhisi2_movzwl"
3513  [(set (match_operand:SI 0 "register_operand" "=r")
3514     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3515  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3516  "movz{wl|x}\t{%1, %0|%0, %1}"
3517  [(set_attr "type" "imovx")
3518   (set_attr "mode" "SI")])
3519
3520(define_expand "zero_extendqihi2"
3521  [(parallel
3522    [(set (match_operand:HI 0 "register_operand" "")
3523       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3524     (clobber (reg:CC 17))])]
3525  ""
3526  "")
3527
3528(define_insn "*zero_extendqihi2_and"
3529  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3530     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3531   (clobber (reg:CC 17))]
3532  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3533  "#"
3534  [(set_attr "type" "alu1")
3535   (set_attr "mode" "HI")])
3536
3537(define_insn "*zero_extendqihi2_movzbw_and"
3538  [(set (match_operand:HI 0 "register_operand" "=r,r")
3539     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3540   (clobber (reg:CC 17))]
3541  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3542  "#"
3543  [(set_attr "type" "imovx,alu1")
3544   (set_attr "mode" "HI")])
3545
3546(define_insn "*zero_extendqihi2_movzbw"
3547  [(set (match_operand:HI 0 "register_operand" "=r")
3548     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3549  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3550  "movz{bw|x}\t{%1, %0|%0, %1}"
3551  [(set_attr "type" "imovx")
3552   (set_attr "mode" "HI")])
3553
3554;; For the movzbw case strip only the clobber
3555(define_split
3556  [(set (match_operand:HI 0 "register_operand" "")
3557	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3558   (clobber (reg:CC 17))]
3559  "reload_completed 
3560   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3561   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3562  [(set (match_operand:HI 0 "register_operand" "")
3563	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3564
3565;; When source and destination does not overlap, clear destination
3566;; first and then do the movb
3567(define_split
3568  [(set (match_operand:HI 0 "register_operand" "")
3569	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3570   (clobber (reg:CC 17))]
3571  "reload_completed
3572   && ANY_QI_REG_P (operands[0])
3573   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3574   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3575  [(set (match_dup 0) (const_int 0))
3576   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3577  "operands[2] = gen_lowpart (QImode, operands[0]);")
3578
3579;; Rest is handled by single and.
3580(define_split
3581  [(set (match_operand:HI 0 "register_operand" "")
3582	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3583   (clobber (reg:CC 17))]
3584  "reload_completed
3585   && true_regnum (operands[0]) == true_regnum (operands[1])"
3586  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3587	      (clobber (reg:CC 17))])]
3588  "")
3589
3590(define_expand "zero_extendqisi2"
3591  [(parallel
3592    [(set (match_operand:SI 0 "register_operand" "")
3593       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3594     (clobber (reg:CC 17))])]
3595  ""
3596  "")
3597
3598(define_insn "*zero_extendqisi2_and"
3599  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3600     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3601   (clobber (reg:CC 17))]
3602  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3603  "#"
3604  [(set_attr "type" "alu1")
3605   (set_attr "mode" "SI")])
3606
3607(define_insn "*zero_extendqisi2_movzbw_and"
3608  [(set (match_operand:SI 0 "register_operand" "=r,r")
3609     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3610   (clobber (reg:CC 17))]
3611  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3612  "#"
3613  [(set_attr "type" "imovx,alu1")
3614   (set_attr "mode" "SI")])
3615
3616(define_insn "*zero_extendqisi2_movzbw"
3617  [(set (match_operand:SI 0 "register_operand" "=r")
3618     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3619  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3620  "movz{bl|x}\t{%1, %0|%0, %1}"
3621  [(set_attr "type" "imovx")
3622   (set_attr "mode" "SI")])
3623
3624;; For the movzbl case strip only the clobber
3625(define_split
3626  [(set (match_operand:SI 0 "register_operand" "")
3627	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3628   (clobber (reg:CC 17))]
3629  "reload_completed 
3630   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3631   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3632  [(set (match_dup 0)
3633	(zero_extend:SI (match_dup 1)))])
3634
3635;; When source and destination does not overlap, clear destination
3636;; first and then do the movb
3637(define_split
3638  [(set (match_operand:SI 0 "register_operand" "")
3639	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3640   (clobber (reg:CC 17))]
3641  "reload_completed
3642   && ANY_QI_REG_P (operands[0])
3643   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3644   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3645   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3646  [(set (match_dup 0) (const_int 0))
3647   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3648  "operands[2] = gen_lowpart (QImode, operands[0]);")
3649
3650;; Rest is handled by single and.
3651(define_split
3652  [(set (match_operand:SI 0 "register_operand" "")
3653	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3654   (clobber (reg:CC 17))]
3655  "reload_completed
3656   && true_regnum (operands[0]) == true_regnum (operands[1])"
3657  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3658	      (clobber (reg:CC 17))])]
3659  "")
3660
3661;; %%% Kill me once multi-word ops are sane.
3662(define_expand "zero_extendsidi2"
3663  [(set (match_operand:DI 0 "register_operand" "=r")
3664     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3665  ""
3666  "if (!TARGET_64BIT)
3667     {
3668       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3669       DONE;
3670     }
3671  ")
3672
3673(define_insn "zero_extendsidi2_32"
3674  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3675	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3676   (clobber (reg:CC 17))]
3677  "!TARGET_64BIT"
3678  "#"
3679  [(set_attr "mode" "SI")])
3680
3681(define_insn "zero_extendsidi2_rex64"
3682  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3683     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3684  "TARGET_64BIT"
3685  "@
3686   mov\t{%k1, %k0|%k0, %k1}
3687   #"
3688  [(set_attr "type" "imovx,imov")
3689   (set_attr "mode" "SI,DI")])
3690
3691(define_split
3692  [(set (match_operand:DI 0 "memory_operand" "")
3693     (zero_extend:DI (match_dup 0)))]
3694  "TARGET_64BIT"
3695  [(set (match_dup 4) (const_int 0))]
3696  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3697
3698(define_split 
3699  [(set (match_operand:DI 0 "register_operand" "")
3700	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3701   (clobber (reg:CC 17))]
3702  "!TARGET_64BIT && reload_completed
3703   && true_regnum (operands[0]) == true_regnum (operands[1])"
3704  [(set (match_dup 4) (const_int 0))]
3705  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3706
3707(define_split 
3708  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3709	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3710   (clobber (reg:CC 17))]
3711  "!TARGET_64BIT && reload_completed"
3712  [(set (match_dup 3) (match_dup 1))
3713   (set (match_dup 4) (const_int 0))]
3714  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3715
3716(define_insn "zero_extendhidi2"
3717  [(set (match_operand:DI 0 "register_operand" "=r,r")
3718     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3719  "TARGET_64BIT"
3720  "@
3721   movz{wl|x}\t{%1, %k0|%k0, %1} 
3722   movz{wq|x}\t{%1, %0|%0, %1}"
3723  [(set_attr "type" "imovx")
3724   (set_attr "mode" "SI,DI")])
3725
3726(define_insn "zero_extendqidi2"
3727  [(set (match_operand:DI 0 "register_operand" "=r,r")
3728     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3729  "TARGET_64BIT"
3730  "@
3731   movz{bl|x}\t{%1, %k0|%k0, %1} 
3732   movz{bq|x}\t{%1, %0|%0, %1}"
3733  [(set_attr "type" "imovx")
3734   (set_attr "mode" "SI,DI")])
3735
3736;; Sign extension instructions
3737
3738(define_expand "extendsidi2"
3739  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3740		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3741	      (clobber (reg:CC 17))
3742	      (clobber (match_scratch:SI 2 ""))])]
3743  ""
3744{
3745  if (TARGET_64BIT)
3746    {
3747      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3748      DONE;
3749    }
3750})
3751
3752(define_insn "*extendsidi2_1"
3753  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3754	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3755   (clobber (reg:CC 17))
3756   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3757  "!TARGET_64BIT"
3758  "#")
3759
3760(define_insn "extendsidi2_rex64"
3761  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3762	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3763  "TARGET_64BIT"
3764  "@
3765   {cltq|cdqe}
3766   movs{lq|x}\t{%1,%0|%0, %1}"
3767  [(set_attr "type" "imovx")
3768   (set_attr "mode" "DI")
3769   (set_attr "prefix_0f" "0")
3770   (set_attr "modrm" "0,1")])
3771
3772(define_insn "extendhidi2"
3773  [(set (match_operand:DI 0 "register_operand" "=r")
3774	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3775  "TARGET_64BIT"
3776  "movs{wq|x}\t{%1,%0|%0, %1}"
3777  [(set_attr "type" "imovx")
3778   (set_attr "mode" "DI")])
3779
3780(define_insn "extendqidi2"
3781  [(set (match_operand:DI 0 "register_operand" "=r")
3782	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3783  "TARGET_64BIT"
3784  "movs{bq|x}\t{%1,%0|%0, %1}"
3785   [(set_attr "type" "imovx")
3786    (set_attr "mode" "DI")])
3787
3788;; Extend to memory case when source register does die.
3789(define_split 
3790  [(set (match_operand:DI 0 "memory_operand" "")
3791	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3792   (clobber (reg:CC 17))
3793   (clobber (match_operand:SI 2 "register_operand" ""))]
3794  "(reload_completed
3795    && dead_or_set_p (insn, operands[1])
3796    && !reg_mentioned_p (operands[1], operands[0]))"
3797  [(set (match_dup 3) (match_dup 1))
3798   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3799	      (clobber (reg:CC 17))])
3800   (set (match_dup 4) (match_dup 1))]
3801  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3802
3803;; Extend to memory case when source register does not die.
3804(define_split 
3805  [(set (match_operand:DI 0 "memory_operand" "")
3806	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807   (clobber (reg:CC 17))
3808   (clobber (match_operand:SI 2 "register_operand" ""))]
3809  "reload_completed"
3810  [(const_int 0)]
3811{
3812  split_di (&operands[0], 1, &operands[3], &operands[4]);
3813
3814  emit_move_insn (operands[3], operands[1]);
3815
3816  /* Generate a cltd if possible and doing so it profitable.  */
3817  if (true_regnum (operands[1]) == 0
3818      && true_regnum (operands[2]) == 1
3819      && (optimize_size || TARGET_USE_CLTD))
3820    {
3821      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3822    }
3823  else
3824    {
3825      emit_move_insn (operands[2], operands[1]);
3826      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3827    }
3828  emit_move_insn (operands[4], operands[2]);
3829  DONE;
3830})
3831
3832;; Extend to register case.  Optimize case where source and destination
3833;; registers match and cases where we can use cltd.
3834(define_split 
3835  [(set (match_operand:DI 0 "register_operand" "")
3836	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3837   (clobber (reg:CC 17))
3838   (clobber (match_scratch:SI 2 ""))]
3839  "reload_completed"
3840  [(const_int 0)]
3841{
3842  split_di (&operands[0], 1, &operands[3], &operands[4]);
3843
3844  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3845    emit_move_insn (operands[3], operands[1]);
3846
3847  /* Generate a cltd if possible and doing so it profitable.  */
3848  if (true_regnum (operands[3]) == 0
3849      && (optimize_size || TARGET_USE_CLTD))
3850    {
3851      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3852      DONE;
3853    }
3854
3855  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3856    emit_move_insn (operands[4], operands[1]);
3857
3858  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3859  DONE;
3860})
3861
3862(define_insn "extendhisi2"
3863  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3864	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3865  ""
3866{
3867  switch (get_attr_prefix_0f (insn))
3868    {
3869    case 0:
3870      return "{cwtl|cwde}";
3871    default:
3872      return "movs{wl|x}\t{%1,%0|%0, %1}";
3873    }
3874}
3875  [(set_attr "type" "imovx")
3876   (set_attr "mode" "SI")
3877   (set (attr "prefix_0f")
3878     ;; movsx is short decodable while cwtl is vector decoded.
3879     (if_then_else (and (eq_attr "cpu" "!k6")
3880			(eq_attr "alternative" "0"))
3881	(const_string "0")
3882	(const_string "1")))
3883   (set (attr "modrm")
3884     (if_then_else (eq_attr "prefix_0f" "0")
3885	(const_string "0")
3886	(const_string "1")))])
3887
3888(define_insn "*extendhisi2_zext"
3889  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3890	(zero_extend:DI
3891	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3892  "TARGET_64BIT"
3893{
3894  switch (get_attr_prefix_0f (insn))
3895    {
3896    case 0:
3897      return "{cwtl|cwde}";
3898    default:
3899      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3900    }
3901}
3902  [(set_attr "type" "imovx")
3903   (set_attr "mode" "SI")
3904   (set (attr "prefix_0f")
3905     ;; movsx is short decodable while cwtl is vector decoded.
3906     (if_then_else (and (eq_attr "cpu" "!k6")
3907			(eq_attr "alternative" "0"))
3908	(const_string "0")
3909	(const_string "1")))
3910   (set (attr "modrm")
3911     (if_then_else (eq_attr "prefix_0f" "0")
3912	(const_string "0")
3913	(const_string "1")))])
3914
3915(define_insn "extendqihi2"
3916  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3917	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3918  ""
3919{
3920  switch (get_attr_prefix_0f (insn))
3921    {
3922    case 0:
3923      return "{cbtw|cbw}";
3924    default:
3925      return "movs{bw|x}\t{%1,%0|%0, %1}";
3926    }
3927}
3928  [(set_attr "type" "imovx")
3929   (set_attr "mode" "HI")
3930   (set (attr "prefix_0f")
3931     ;; movsx is short decodable while cwtl is vector decoded.
3932     (if_then_else (and (eq_attr "cpu" "!k6")
3933			(eq_attr "alternative" "0"))
3934	(const_string "0")
3935	(const_string "1")))
3936   (set (attr "modrm")
3937     (if_then_else (eq_attr "prefix_0f" "0")
3938	(const_string "0")
3939	(const_string "1")))])
3940
3941(define_insn "extendqisi2"
3942  [(set (match_operand:SI 0 "register_operand" "=r")
3943	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3944  ""
3945  "movs{bl|x}\t{%1,%0|%0, %1}"
3946   [(set_attr "type" "imovx")
3947    (set_attr "mode" "SI")])
3948
3949(define_insn "*extendqisi2_zext"
3950  [(set (match_operand:DI 0 "register_operand" "=r")
3951	(zero_extend:DI
3952	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3953  "TARGET_64BIT"
3954  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3955   [(set_attr "type" "imovx")
3956    (set_attr "mode" "SI")])
3957
3958;; Conversions between float and double.
3959
3960;; These are all no-ops in the model used for the 80387.  So just
3961;; emit moves.
3962
3963;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3964(define_insn "*dummy_extendsfdf2"
3965  [(set (match_operand:DF 0 "push_operand" "=<")
3966	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3967  "0"
3968  "#")
3969
3970(define_split
3971  [(set (match_operand:DF 0 "push_operand" "")
3972	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3973  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3974  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3975   (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3976
3977(define_split
3978  [(set (match_operand:DF 0 "push_operand" "")
3979	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3980  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3981  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3982   (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3983
3984(define_insn "*dummy_extendsfxf2"
3985  [(set (match_operand:XF 0 "push_operand" "=<")
3986	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3987  "0"
3988  "#")
3989
3990(define_split
3991  [(set (match_operand:XF 0 "push_operand" "")
3992	(float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3993  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3994  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3995   (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3996
3997(define_insn "*dummy_extendsftf2"
3998  [(set (match_operand:TF 0 "push_operand" "=<")
3999	(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4000  "0"
4001  "#")
4002
4003(define_split
4004  [(set (match_operand:TF 0 "push_operand" "")
4005	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
4006  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4007  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4008   (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
4009
4010(define_split
4011  [(set (match_operand:TF 0 "push_operand" "")
4012	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
4013  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4014  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4015   (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4016
4017(define_insn "*dummy_extenddfxf2"
4018  [(set (match_operand:XF 0 "push_operand" "=<")
4019	(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4020  "0"
4021  "#")
4022
4023(define_split
4024  [(set (match_operand:XF 0 "push_operand" "")
4025	(float_extend:XF (match_operand:DF 1 "register_operand" "")))]
4026  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4027  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
4028   (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4029
4030(define_insn "*dummy_extenddftf2"
4031  [(set (match_operand:TF 0 "push_operand" "=<")
4032	(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4033  "0"
4034  "#")
4035
4036(define_split
4037  [(set (match_operand:TF 0 "push_operand" "")
4038	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4039  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4040  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4041   (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4042
4043(define_split
4044  [(set (match_operand:TF 0 "push_operand" "")
4045	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4046  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4047  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4048   (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4049
4050(define_expand "extendsfdf2"
4051  [(set (match_operand:DF 0 "nonimmediate_operand" "")
4052        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
4053  "TARGET_80387 || TARGET_SSE2"
4054{
4055  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4056    operands[1] = force_reg (SFmode, operands[1]);
4057})
4058
4059(define_insn "*extendsfdf2_1"
4060  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
4061        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
4062  "(TARGET_80387 || TARGET_SSE2)
4063   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4064{
4065  switch (which_alternative)
4066    {
4067    case 0:
4068      if (REG_P (operands[1])
4069          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4070        return "fstp\t%y0";
4071      else if (STACK_TOP_P (operands[0]))
4072        return "fld%z1\t%y1";
4073      else
4074        return "fst\t%y0";
4075
4076    case 1:
4077      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4078        return "fstp%z0\t%y0";
4079
4080      else
4081        return "fst%z0\t%y0";
4082    case 2:
4083      return "cvtss2sd\t{%1, %0|%0, %1}";
4084
4085    default:
4086      abort ();
4087    }
4088}
4089  [(set_attr "type" "fmov,fmov,sse")
4090   (set_attr "mode" "SF,XF,DF")])
4091
4092(define_insn "*extendsfdf2_1_sse_only"
4093  [(set (match_operand:DF 0 "register_operand" "=Y")
4094        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
4095  "!TARGET_80387 && TARGET_SSE2
4096   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4097  "cvtss2sd\t{%1, %0|%0, %1}"
4098  [(set_attr "type" "sse")
4099   (set_attr "mode" "DF")])
4100
4101(define_expand "extendsfxf2"
4102  [(set (match_operand:XF 0 "nonimmediate_operand" "")
4103        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
4104  "!TARGET_64BIT && TARGET_80387"
4105{
4106  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4107    operands[1] = force_reg (SFmode, operands[1]);
4108})
4109
4110(define_insn "*extendsfxf2_1"
4111  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4112        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4113  "!TARGET_64BIT && TARGET_80387
4114   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4115{
4116  switch (which_alternative)
4117    {
4118    case 0:
4119      if (REG_P (operands[1])
4120          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4121        return "fstp\t%y0";
4122      else if (STACK_TOP_P (operands[0]))
4123        return "fld%z1\t%y1";
4124      else
4125        return "fst\t%y0";
4126
4127    case 1:
4128      /* There is no non-popping store to memory for XFmode.  So if
4129	 we need one, follow the store with a load.  */
4130      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4131        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4132      else
4133        return "fstp%z0\t%y0";
4134
4135    default:
4136      abort ();
4137    }
4138}
4139  [(set_attr "type" "fmov")
4140   (set_attr "mode" "SF,XF")])
4141
4142(define_expand "extendsftf2"
4143  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4144        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
4145  "TARGET_80387"
4146{
4147  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4148    operands[1] = force_reg (SFmode, operands[1]);
4149})
4150
4151(define_insn "*extendsftf2_1"
4152  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4153        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4154  "TARGET_80387
4155   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4156{
4157  switch (which_alternative)
4158    {
4159    case 0:
4160      if (REG_P (operands[1])
4161          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4162        return "fstp\t%y0";
4163      else if (STACK_TOP_P (operands[0]))
4164        return "fld%z1\t%y1";
4165      else
4166        return "fst\t%y0";
4167
4168    case 1:
4169      /* There is no non-popping store to memory for XFmode.  So if
4170	 we need one, follow the store with a load.  */
4171      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4172        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4173      else
4174        return "fstp%z0\t%y0";
4175
4176    default:
4177      abort ();
4178    }
4179}
4180  [(set_attr "type" "fmov")
4181   (set_attr "mode" "SF,XF")])
4182
4183(define_expand "extenddfxf2"
4184  [(set (match_operand:XF 0 "nonimmediate_operand" "")
4185        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
4186  "!TARGET_64BIT && TARGET_80387"
4187{
4188  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4189    operands[1] = force_reg (DFmode, operands[1]);
4190})
4191
4192(define_insn "*extenddfxf2_1"
4193  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4194        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4195  "!TARGET_64BIT && TARGET_80387
4196   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4197{
4198  switch (which_alternative)
4199    {
4200    case 0:
4201      if (REG_P (operands[1])
4202          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4203        return "fstp\t%y0";
4204      else if (STACK_TOP_P (operands[0]))
4205        return "fld%z1\t%y1";
4206      else
4207        return "fst\t%y0";
4208
4209    case 1:
4210      /* There is no non-popping store to memory for XFmode.  So if
4211	 we need one, follow the store with a load.  */
4212      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4213        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4214      else
4215        return "fstp%z0\t%y0";
4216
4217    default:
4218      abort ();
4219    }
4220}
4221  [(set_attr "type" "fmov")
4222   (set_attr "mode" "DF,XF")])
4223
4224(define_expand "extenddftf2"
4225  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4226        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
4227  "TARGET_80387"
4228{
4229  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4230    operands[1] = force_reg (DFmode, operands[1]);
4231})
4232
4233(define_insn "*extenddftf2_1"
4234  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4235        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4236  "TARGET_80387
4237   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4238{
4239  switch (which_alternative)
4240    {
4241    case 0:
4242      if (REG_P (operands[1])
4243          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4244        return "fstp\t%y0";
4245      else if (STACK_TOP_P (operands[0]))
4246        return "fld%z1\t%y1";
4247      else
4248        return "fst\t%y0";
4249
4250    case 1:
4251      /* There is no non-popping store to memory for XFmode.  So if
4252	 we need one, follow the store with a load.  */
4253      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4254        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4255      else
4256        return "fstp%z0\t%y0";
4257
4258    default:
4259      abort ();
4260    }
4261}
4262  [(set_attr "type" "fmov")
4263   (set_attr "mode" "DF,XF")])
4264
4265;; %%% This seems bad bad news.
4266;; This cannot output into an f-reg because there is no way to be sure
4267;; of truncating in that case.  Otherwise this is just like a simple move
4268;; insn.  So we pretend we can output to a reg in order to get better
4269;; register preferencing, but we really use a stack slot.
4270
4271(define_expand "truncdfsf2"
4272  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4273		   (float_truncate:SF
4274		    (match_operand:DF 1 "register_operand" "")))
4275	      (clobber (match_dup 2))])]
4276  "TARGET_80387 || TARGET_SSE2"
4277  "
4278   if (TARGET_80387)
4279     operands[2] = assign_386_stack_local (SFmode, 0);
4280   else
4281     {
4282	emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4283	DONE;
4284     }
4285")
4286
4287(define_insn "*truncdfsf2_1"
4288  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4289	(float_truncate:SF
4290	 (match_operand:DF 1 "register_operand" "f,f,f,f")))
4291   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4292  "TARGET_80387 && !TARGET_SSE2"
4293{
4294  switch (which_alternative)
4295    {
4296    case 0:
4297      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4298	return "fstp%z0\t%y0";
4299      else
4300	return "fst%z0\t%y0";
4301    default:
4302      abort ();
4303    }
4304}
4305  [(set_attr "type" "fmov,multi,multi,multi")
4306   (set_attr "mode" "SF,SF,SF,SF")])
4307
4308(define_insn "*truncdfsf2_1_sse"
4309  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
4310	(float_truncate:SF
4311	 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
4312   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
4313  "TARGET_80387 && TARGET_SSE2"
4314{
4315  switch (which_alternative)
4316    {
4317    case 0:
4318      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4319	return "fstp%z0\t%y0";
4320      else
4321	return "fst%z0\t%y0";
4322    case 4:
4323      return "cvtsd2ss\t{%1, %0|%0, %1}";
4324    default:
4325      abort ();
4326    }
4327}
4328  [(set_attr "type" "fmov,multi,multi,multi,sse")
4329   (set_attr "mode" "SF,SF,SF,SF,DF")])
4330
4331(define_insn "*truncdfsf2_2"
4332  [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
4333	(float_truncate:SF
4334	 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4335  "TARGET_80387 && TARGET_SSE2
4336   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4337{
4338  switch (which_alternative)
4339    {
4340    case 0:
4341      return "cvtsd2ss\t{%1, %0|%0, %1}";
4342    case 1:
4343      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4344	return "fstp%z0\t%y0";
4345      else
4346	return "fst%z0\t%y0";
4347    default:
4348      abort ();
4349    }
4350}
4351  [(set_attr "type" "sse,fmov")
4352   (set_attr "mode" "DF,SF")])
4353
4354(define_insn "truncdfsf2_3"
4355  [(set (match_operand:SF 0 "memory_operand" "=m")
4356	(float_truncate:SF
4357	 (match_operand:DF 1 "register_operand" "f")))]
4358  "TARGET_80387"
4359{
4360  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4361    return "fstp%z0\t%y0";
4362  else
4363    return "fst%z0\t%y0";
4364}
4365  [(set_attr "type" "fmov")
4366   (set_attr "mode" "SF")])
4367
4368(define_insn "truncdfsf2_sse_only"
4369  [(set (match_operand:SF 0 "register_operand" "=Y")
4370	(float_truncate:SF
4371	 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4372  "!TARGET_80387 && TARGET_SSE2"
4373  "cvtsd2ss\t{%1, %0|%0, %1}"
4374  [(set_attr "type" "sse")
4375   (set_attr "mode" "DF")])
4376
4377(define_split
4378  [(set (match_operand:SF 0 "memory_operand" "")
4379	(float_truncate:SF
4380	 (match_operand:DF 1 "register_operand" "")))
4381   (clobber (match_operand:SF 2 "memory_operand" ""))]
4382  "TARGET_80387"
4383  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4384  "")
4385
4386(define_split
4387  [(set (match_operand:SF 0 "nonimmediate_operand" "")
4388	(float_truncate:SF
4389	 (match_operand:DF 1 "nonimmediate_operand" "")))
4390   (clobber (match_operand 2 "" ""))]
4391  "TARGET_80387 && reload_completed
4392   && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
4393  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4394  "")
4395
4396(define_split
4397  [(set (match_operand:SF 0 "register_operand" "")
4398	(float_truncate:SF
4399	 (match_operand:DF 1 "register_operand" "")))
4400   (clobber (match_operand:SF 2 "memory_operand" ""))]
4401  "TARGET_80387 && reload_completed
4402   && FP_REG_P (operands[1])"
4403  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4404   (set (match_dup 0) (match_dup 2))]
4405  "")
4406
4407(define_expand "truncxfsf2"
4408  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4409		   (float_truncate:SF
4410		    (match_operand:XF 1 "register_operand" "")))
4411	      (clobber (match_dup 2))])]
4412  "!TARGET_64BIT && TARGET_80387"
4413  "operands[2] = assign_386_stack_local (SFmode, 0);")
4414
4415(define_insn "*truncxfsf2_1"
4416  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4417	(float_truncate:SF
4418	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4419   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4420  "!TARGET_64BIT && TARGET_80387"
4421{
4422  switch (which_alternative)
4423    {
4424    case 0:
4425      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4426	return "fstp%z0\t%y0";
4427      else
4428	return "fst%z0\t%y0";
4429    default:
4430      abort();
4431    }
4432}
4433  [(set_attr "type" "fmov,multi,multi,multi")
4434   (set_attr "mode" "SF")])
4435
4436(define_insn "*truncxfsf2_2"
4437  [(set (match_operand:SF 0 "memory_operand" "=m")
4438	(float_truncate:SF
4439	 (match_operand:XF 1 "register_operand" "f")))]
4440  "!TARGET_64BIT && TARGET_80387"
4441{
4442  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4443    return "fstp%z0\t%y0";
4444  else
4445    return "fst%z0\t%y0";
4446}
4447  [(set_attr "type" "fmov")
4448   (set_attr "mode" "SF")])
4449
4450(define_split
4451  [(set (match_operand:SF 0 "memory_operand" "")
4452	(float_truncate:SF
4453	 (match_operand:XF 1 "register_operand" "")))
4454   (clobber (match_operand:SF 2 "memory_operand" ""))]
4455  "TARGET_80387"
4456  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4457  "")
4458
4459(define_split
4460  [(set (match_operand:SF 0 "register_operand" "")
4461	(float_truncate:SF
4462	 (match_operand:XF 1 "register_operand" "")))
4463   (clobber (match_operand:SF 2 "memory_operand" ""))]
4464  "TARGET_80387 && reload_completed"
4465  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4466   (set (match_dup 0) (match_dup 2))]
4467  "")
4468
4469(define_expand "trunctfsf2"
4470  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4471		   (float_truncate:SF
4472		    (match_operand:TF 1 "register_operand" "")))
4473	      (clobber (match_dup 2))])]
4474  "TARGET_80387"
4475  "operands[2] = assign_386_stack_local (SFmode, 0);")
4476
4477(define_insn "*trunctfsf2_1"
4478  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4479	(float_truncate:SF
4480	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4481   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4482  "TARGET_80387"
4483{
4484  switch (which_alternative)
4485    {
4486    case 0:
4487      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4488	return "fstp%z0\t%y0";
4489      else
4490	return "fst%z0\t%y0";
4491    default:
4492      abort();
4493    }
4494}
4495  [(set_attr "type" "fmov,multi,multi,multi")
4496   (set_attr "mode" "SF")])
4497
4498(define_insn "*trunctfsf2_2"
4499  [(set (match_operand:SF 0 "memory_operand" "=m")
4500	(float_truncate:SF
4501	 (match_operand:TF 1 "register_operand" "f")))]
4502  "TARGET_80387"
4503{
4504  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4505    return "fstp%z0\t%y0";
4506  else
4507    return "fst%z0\t%y0";
4508}
4509  [(set_attr "type" "fmov")
4510   (set_attr "mode" "SF")])
4511
4512(define_split
4513  [(set (match_operand:SF 0 "memory_operand" "")
4514	(float_truncate:SF
4515	 (match_operand:TF 1 "register_operand" "")))
4516   (clobber (match_operand:SF 2 "memory_operand" ""))]
4517  "TARGET_80387"
4518  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4519  "")
4520
4521(define_split
4522  [(set (match_operand:SF 0 "register_operand" "")
4523	(float_truncate:SF
4524	 (match_operand:TF 1 "register_operand" "")))
4525   (clobber (match_operand:SF 2 "memory_operand" ""))]
4526  "TARGET_80387 && reload_completed"
4527  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4528   (set (match_dup 0) (match_dup 2))]
4529  "")
4530
4531
4532(define_expand "truncxfdf2"
4533  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4534		   (float_truncate:DF
4535		    (match_operand:XF 1 "register_operand" "")))
4536	      (clobber (match_dup 2))])]
4537  "!TARGET_64BIT && TARGET_80387"
4538  "operands[2] = assign_386_stack_local (DFmode, 0);")
4539
4540(define_insn "*truncxfdf2_1"
4541  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4542	(float_truncate:DF
4543	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4544   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4545  "!TARGET_64BIT && TARGET_80387"
4546{
4547  switch (which_alternative)
4548    {
4549    case 0:
4550      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4551	return "fstp%z0\t%y0";
4552      else
4553	return "fst%z0\t%y0";
4554    default:
4555      abort();
4556    }
4557  abort ();
4558}
4559  [(set_attr "type" "fmov,multi,multi,multi")
4560   (set_attr "mode" "DF")])
4561
4562(define_insn "*truncxfdf2_2"
4563  [(set (match_operand:DF 0 "memory_operand" "=m")
4564	(float_truncate:DF
4565	  (match_operand:XF 1 "register_operand" "f")))]
4566  "!TARGET_64BIT && TARGET_80387"
4567{
4568  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4569    return "fstp%z0\t%y0";
4570  else
4571    return "fst%z0\t%y0";
4572}
4573  [(set_attr "type" "fmov")
4574   (set_attr "mode" "DF")])
4575
4576(define_split
4577  [(set (match_operand:DF 0 "memory_operand" "")
4578	(float_truncate:DF
4579	 (match_operand:XF 1 "register_operand" "")))
4580   (clobber (match_operand:DF 2 "memory_operand" ""))]
4581  "TARGET_80387"
4582  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4583  "")
4584
4585(define_split
4586  [(set (match_operand:DF 0 "register_operand" "")
4587	(float_truncate:DF
4588	 (match_operand:XF 1 "register_operand" "")))
4589   (clobber (match_operand:DF 2 "memory_operand" ""))]
4590  "TARGET_80387 && reload_completed"
4591  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4592   (set (match_dup 0) (match_dup 2))]
4593  "")
4594
4595(define_expand "trunctfdf2"
4596  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4597		   (float_truncate:DF
4598		    (match_operand:TF 1 "register_operand" "")))
4599	      (clobber (match_dup 2))])]
4600  "TARGET_80387"
4601  "operands[2] = assign_386_stack_local (DFmode, 0);")
4602
4603(define_insn "*trunctfdf2_1"
4604  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4605	(float_truncate:DF
4606	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4607   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4608  "TARGET_80387"
4609{
4610  switch (which_alternative)
4611    {
4612    case 0:
4613      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4614	return "fstp%z0\t%y0";
4615      else
4616	return "fst%z0\t%y0";
4617    default:
4618      abort();
4619    }
4620  abort ();
4621}
4622  [(set_attr "type" "fmov,multi,multi,multi")
4623   (set_attr "mode" "DF")])
4624
4625	(define_insn "*trunctfdf2_2"
4626  [(set (match_operand:DF 0 "memory_operand" "=m")
4627	(float_truncate:DF
4628	  (match_operand:TF 1 "register_operand" "f")))]
4629  "TARGET_80387"
4630{
4631  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4632    return "fstp%z0\t%y0";
4633  else
4634    return "fst%z0\t%y0";
4635}
4636  [(set_attr "type" "fmov")
4637   (set_attr "mode" "DF")])
4638
4639(define_split
4640  [(set (match_operand:DF 0 "memory_operand" "")
4641	(float_truncate:DF
4642	 (match_operand:TF 1 "register_operand" "")))
4643   (clobber (match_operand:DF 2 "memory_operand" ""))]
4644  "TARGET_80387"
4645  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4646  "")
4647
4648(define_split
4649  [(set (match_operand:DF 0 "register_operand" "")
4650	(float_truncate:DF
4651	 (match_operand:TF 1 "register_operand" "")))
4652   (clobber (match_operand:DF 2 "memory_operand" ""))]
4653  "TARGET_80387 && reload_completed"
4654  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4655   (set (match_dup 0) (match_dup 2))]
4656  "")
4657
4658
4659;; %%% Break up all these bad boys.
4660
4661;; Signed conversion to DImode.
4662
4663(define_expand "fix_truncxfdi2"
4664  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4665        (fix:DI (match_operand:XF 1 "register_operand" "")))]
4666  "!TARGET_64BIT && TARGET_80387"
4667  "")
4668
4669(define_expand "fix_trunctfdi2"
4670  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4671	(fix:DI (match_operand:TF 1 "register_operand" "")))]
4672  "TARGET_80387"
4673  "")
4674
4675(define_expand "fix_truncdfdi2"
4676  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4677        (fix:DI (match_operand:DF 1 "register_operand" "")))]
4678  "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4679{
4680  if (TARGET_64BIT && TARGET_SSE2)
4681   {
4682     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4683     emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4684     if (out != operands[0])
4685	emit_move_insn (operands[0], out);
4686     DONE;
4687   }
4688})
4689
4690(define_expand "fix_truncsfdi2"
4691  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4692	(fix:DI (match_operand:SF 1 "register_operand" "")))]
4693  "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4694{
4695  if (TARGET_SSE && TARGET_64BIT)
4696   {
4697     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4698     emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4699     if (out != operands[0])
4700	emit_move_insn (operands[0], out);
4701     DONE;
4702   }
4703})
4704
4705;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4706;; of the machinery.
4707(define_insn_and_split "*fix_truncdi_1"
4708  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4709	(fix:DI (match_operand 1 "register_operand" "f,f")))]
4710  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4711   && !reload_completed && !reload_in_progress
4712   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4713  "#"
4714  "&& 1"
4715  [(const_int 0)]
4716{
4717  operands[2] = assign_386_stack_local (HImode, 1);
4718  operands[3] = assign_386_stack_local (HImode, 2);
4719  if (memory_operand (operands[0], VOIDmode))
4720    emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4721				       operands[2], operands[3]));
4722  else
4723    {
4724      operands[4] = assign_386_stack_local (DImode, 0);
4725      emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4726					   operands[2], operands[3],
4727					   operands[4]));
4728    }
4729  DONE;
4730}
4731  [(set_attr "type" "fistp")])
4732
4733(define_insn "fix_truncdi_nomemory"
4734  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4735	(fix:DI (match_operand 1 "register_operand" "f,f")))
4736   (use (match_operand:HI 2 "memory_operand" "m,m"))
4737   (use (match_operand:HI 3 "memory_operand" "m,m"))
4738   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4739   (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4740  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4741   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4742  "#"
4743  [(set_attr "type" "fistp")])
4744
4745(define_insn "fix_truncdi_memory"
4746  [(set (match_operand:DI 0 "memory_operand" "=m")
4747	(fix:DI (match_operand 1 "register_operand" "f")))
4748   (use (match_operand:HI 2 "memory_operand" "m"))
4749   (use (match_operand:HI 3 "memory_operand" "m"))
4750   (clobber (match_scratch:DF 4 "=&1f"))]
4751  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4752   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4753  "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4754  [(set_attr "type" "fistp")])
4755
4756(define_split 
4757  [(set (match_operand:DI 0 "register_operand" "")
4758	(fix:DI (match_operand 1 "register_operand" "")))
4759   (use (match_operand:HI 2 "memory_operand" ""))
4760   (use (match_operand:HI 3 "memory_operand" ""))
4761   (clobber (match_operand:DI 4 "memory_operand" ""))
4762   (clobber (match_scratch 5 ""))]
4763  "reload_completed"
4764  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4765	      (use (match_dup 2))
4766	      (use (match_dup 3))
4767	      (clobber (match_dup 5))])
4768   (set (match_dup 0) (match_dup 4))]
4769  "")
4770
4771(define_split 
4772  [(set (match_operand:DI 0 "memory_operand" "")
4773	(fix:DI (match_operand 1 "register_operand" "")))
4774   (use (match_operand:HI 2 "memory_operand" ""))
4775   (use (match_operand:HI 3 "memory_operand" ""))
4776   (clobber (match_operand:DI 4 "memory_operand" ""))
4777   (clobber (match_scratch 5 ""))]
4778  "reload_completed"
4779  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4780	      (use (match_dup 2))
4781	      (use (match_dup 3))
4782	      (clobber (match_dup 5))])]
4783  "")
4784
4785;; When SSE available, it is always faster to use it!
4786(define_insn "fix_truncsfdi_sse"
4787  [(set (match_operand:DI 0 "register_operand" "=r")
4788	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4789  "TARGET_64BIT && TARGET_SSE"
4790  "cvttss2si{q}\t{%1, %0|%0, %1}"
4791  [(set_attr "type" "sse")])
4792
4793(define_insn "fix_truncdfdi_sse"
4794  [(set (match_operand:DI 0 "register_operand" "=r")
4795	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4796  "TARGET_64BIT && TARGET_SSE2"
4797  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4798  [(set_attr "type" "sse")])
4799
4800;; Signed conversion to SImode.
4801
4802(define_expand "fix_truncxfsi2"
4803  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4804	(fix:SI (match_operand:XF 1 "register_operand" "")))]
4805  "!TARGET_64BIT && TARGET_80387"
4806  "")
4807
4808(define_expand "fix_trunctfsi2"
4809  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4810	(fix:SI (match_operand:TF 1 "register_operand" "")))]
4811  "TARGET_80387"
4812  "")
4813
4814(define_expand "fix_truncdfsi2"
4815  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4816	(fix:SI (match_operand:DF 1 "register_operand" "")))]
4817  "TARGET_80387 || TARGET_SSE2"
4818{
4819  if (TARGET_SSE2)
4820   {
4821     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4822     emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4823     if (out != operands[0])
4824	emit_move_insn (operands[0], out);
4825     DONE;
4826   }
4827})
4828
4829(define_expand "fix_truncsfsi2"
4830  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4831	(fix:SI (match_operand:SF 1 "register_operand" "")))]
4832  "TARGET_80387 || TARGET_SSE"
4833{
4834  if (TARGET_SSE)
4835   {
4836     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4837     emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4838     if (out != operands[0])
4839	emit_move_insn (operands[0], out);
4840     DONE;
4841   }
4842})
4843
4844;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4845;; of the machinery.
4846(define_insn_and_split "*fix_truncsi_1"
4847  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4848	(fix:SI (match_operand 1 "register_operand" "f,f")))]
4849  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4850   && !reload_completed && !reload_in_progress
4851   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4852  "#"
4853  "&& 1"
4854  [(const_int 0)]
4855{
4856  operands[2] = assign_386_stack_local (HImode, 1);
4857  operands[3] = assign_386_stack_local (HImode, 2);
4858  if (memory_operand (operands[0], VOIDmode))
4859    emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4860				       operands[2], operands[3]));
4861  else
4862    {
4863      operands[4] = assign_386_stack_local (SImode, 0);
4864      emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4865					   operands[2], operands[3],
4866					   operands[4]));
4867    }
4868  DONE;
4869}
4870  [(set_attr "type" "fistp")])
4871
4872(define_insn "fix_truncsi_nomemory"
4873  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4874	(fix:SI (match_operand 1 "register_operand" "f,f")))
4875   (use (match_operand:HI 2 "memory_operand" "m,m"))
4876   (use (match_operand:HI 3 "memory_operand" "m,m"))
4877   (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4878  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4879   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4880  "#"
4881  [(set_attr "type" "fistp")])
4882
4883(define_insn "fix_truncsi_memory"
4884  [(set (match_operand:SI 0 "memory_operand" "=m")
4885	(fix:SI (match_operand 1 "register_operand" "f")))
4886   (use (match_operand:HI 2 "memory_operand" "m"))
4887   (use (match_operand:HI 3 "memory_operand" "m"))]
4888  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4889   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4890  "* return output_fix_trunc (insn, operands);"
4891  [(set_attr "type" "fistp")])
4892
4893;; When SSE available, it is always faster to use it!
4894(define_insn "fix_truncsfsi_sse"
4895  [(set (match_operand:SI 0 "register_operand" "=r")
4896	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4897  "TARGET_SSE"
4898  "cvttss2si\t{%1, %0|%0, %1}"
4899  [(set_attr "type" "sse")])
4900
4901(define_insn "fix_truncdfsi_sse"
4902  [(set (match_operand:SI 0 "register_operand" "=r")
4903	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4904  "TARGET_SSE2"
4905  "cvttsd2si\t{%1, %0|%0, %1}"
4906  [(set_attr "type" "sse")])
4907
4908(define_split 
4909  [(set (match_operand:SI 0 "register_operand" "")
4910	(fix:SI (match_operand 1 "register_operand" "")))
4911   (use (match_operand:HI 2 "memory_operand" ""))
4912   (use (match_operand:HI 3 "memory_operand" ""))
4913   (clobber (match_operand:SI 4 "memory_operand" ""))]
4914  "reload_completed"
4915  [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4916	      (use (match_dup 2))
4917	      (use (match_dup 3))])
4918   (set (match_dup 0) (match_dup 4))]
4919  "")
4920
4921(define_split 
4922  [(set (match_operand:SI 0 "memory_operand" "")
4923	(fix:SI (match_operand 1 "register_operand" "")))
4924   (use (match_operand:HI 2 "memory_operand" ""))
4925   (use (match_operand:HI 3 "memory_operand" ""))
4926   (clobber (match_operand:SI 4 "memory_operand" ""))]
4927  "reload_completed"
4928  [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4929	      (use (match_dup 2))
4930	      (use (match_dup 3))])]
4931  "")
4932
4933;; Signed conversion to HImode.
4934
4935(define_expand "fix_truncxfhi2"
4936  [(set (match_operand:HI 0 "nonimmediate_operand" "")
4937        (fix:HI (match_operand:XF 1 "register_operand" "")))]
4938  "!TARGET_64BIT && TARGET_80387"
4939  "")
4940
4941(define_expand "fix_trunctfhi2"
4942  [(set (match_operand:HI 0 "nonimmediate_operand" "")
4943	(fix:HI (match_operand:TF 1 "register_operand" "")))]
4944  "TARGET_80387"
4945  "")
4946
4947(define_expand "fix_truncdfhi2"
4948  [(set (match_operand:HI 0 "nonimmediate_operand" "")
4949	(fix:HI (match_operand:DF 1 "register_operand" "")))]
4950  "TARGET_80387 && !TARGET_SSE2"
4951  "")
4952
4953(define_expand "fix_truncsfhi2"
4954  [(set (match_operand:HI 0 "nonimmediate_operand" "")
4955	(fix:HI (match_operand:SF 1 "register_operand" "")))]
4956  "TARGET_80387 && !TARGET_SSE"
4957  "")
4958
4959;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4960;; of the machinery.
4961(define_insn_and_split "*fix_trunchi_1"
4962  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4963	(fix:HI (match_operand 1 "register_operand" "f,f")))]
4964  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4965   && !reload_completed && !reload_in_progress
4966   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4967  "#"
4968  ""
4969  [(const_int 0)]
4970{
4971  operands[2] = assign_386_stack_local (HImode, 1);
4972  operands[3] = assign_386_stack_local (HImode, 2);
4973  if (memory_operand (operands[0], VOIDmode))
4974    emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4975				       operands[2], operands[3]));
4976  else
4977    {
4978      operands[4] = assign_386_stack_local (HImode, 0);
4979      emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4980					   operands[2], operands[3],
4981					   operands[4]));
4982    }
4983  DONE;
4984}
4985  [(set_attr "type" "fistp")])
4986
4987(define_insn "fix_trunchi_nomemory"
4988  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4989	(fix:HI (match_operand 1 "register_operand" "f,f")))
4990   (use (match_operand:HI 2 "memory_operand" "m,m"))
4991   (use (match_operand:HI 3 "memory_operand" "m,m"))
4992   (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4993  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4994   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4995  "#"
4996  [(set_attr "type" "fistp")])
4997
4998(define_insn "fix_trunchi_memory"
4999  [(set (match_operand:HI 0 "memory_operand" "=m")
5000	(fix:HI (match_operand 1 "register_operand" "f")))
5001   (use (match_operand:HI 2 "memory_operand" "m"))
5002   (use (match_operand:HI 3 "memory_operand" "m"))]
5003  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
5004   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5005  "* return output_fix_trunc (insn, operands);"
5006  [(set_attr "type" "fistp")])
5007
5008(define_split 
5009  [(set (match_operand:HI 0 "memory_operand" "")
5010	(fix:HI (match_operand 1 "register_operand" "")))
5011   (use (match_operand:HI 2 "memory_operand" ""))
5012   (use (match_operand:HI 3 "memory_operand" ""))
5013   (clobber (match_operand:HI 4 "memory_operand" ""))]
5014  "reload_completed"
5015  [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
5016	      (use (match_dup 2))
5017	      (use (match_dup 3))])]
5018  "")
5019
5020(define_split 
5021  [(set (match_operand:HI 0 "register_operand" "")
5022	(fix:HI (match_operand 1 "register_operand" "")))
5023   (use (match_operand:HI 2 "memory_operand" ""))
5024   (use (match_operand:HI 3 "memory_operand" ""))
5025   (clobber (match_operand:HI 4 "memory_operand" ""))]
5026  "reload_completed"
5027  [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
5028	      (use (match_dup 2))
5029	      (use (match_dup 3))
5030	      (clobber (match_dup 4))])
5031   (set (match_dup 0) (match_dup 4))]
5032  "")
5033
5034;; %% Not used yet.
5035(define_insn "x86_fnstcw_1"
5036  [(set (match_operand:HI 0 "memory_operand" "=m")
5037	(unspec:HI [(reg:HI 18)] 11))]
5038  "TARGET_80387"
5039  "fnstcw\t%0"
5040  [(set_attr "length" "2")
5041   (set_attr "mode" "HI")
5042   (set_attr "i387" "1")
5043   (set_attr "ppro_uops" "few")])
5044
5045(define_insn "x86_fldcw_1"
5046  [(set (reg:HI 18)
5047	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
5048  "TARGET_80387"
5049  "fldcw\t%0"
5050  [(set_attr "length" "2")
5051   (set_attr "mode" "HI")
5052   (set_attr "i387" "1")
5053   (set_attr "athlon_decode" "vector")
5054   (set_attr "ppro_uops" "few")])
5055
5056;; Conversion between fixed point and floating point.
5057
5058;; Even though we only accept memory inputs, the backend _really_
5059;; wants to be able to do this between registers.
5060
5061(define_insn "floathisf2"
5062  [(set (match_operand:SF 0 "register_operand" "=f,f")
5063	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5064  "TARGET_80387 && !TARGET_SSE"
5065  "@
5066   fild%z1\t%1
5067   #"
5068  [(set_attr "type" "fmov,multi")
5069   (set_attr "mode" "SF")
5070   (set_attr "fp_int_src" "true")])
5071
5072(define_expand "floatsisf2"
5073  [(set (match_operand:SF 0 "register_operand" "")
5074	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5075  "TARGET_SSE || TARGET_80387"
5076  "")
5077
5078(define_insn "*floatsisf2_i387"
5079  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5080	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5081  "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5082  "@
5083   fild%z1\t%1
5084   #
5085   cvtsi2ss\t{%1, %0|%0, %1}"
5086  [(set_attr "type" "fmov,multi,sse")
5087   (set_attr "mode" "SF")
5088   (set_attr "fp_int_src" "true")])
5089
5090(define_insn "*floatsisf2_sse"
5091  [(set (match_operand:SF 0 "register_operand" "=x")
5092	(float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5093  "TARGET_SSE"
5094  "cvtsi2ss\t{%1, %0|%0, %1}"
5095  [(set_attr "type" "sse")
5096   (set_attr "mode" "SF")
5097   (set_attr "fp_int_src" "true")])
5098
5099(define_expand "floatdisf2"
5100  [(set (match_operand:SF 0 "register_operand" "")
5101	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5102  "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
5103  "")
5104
5105(define_insn "*floatdisf2_i387_only"
5106  [(set (match_operand:SF 0 "register_operand" "=f,?f")
5107	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5108  "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5109  "@
5110   fild%z1\t%1
5111   #"
5112  [(set_attr "type" "fmov,multi")
5113   (set_attr "mode" "SF")
5114   (set_attr "fp_int_src" "true")])
5115
5116(define_insn "*floatdisf2_i387"
5117  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5118	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5119  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5120  "@
5121   fild%z1\t%1
5122   #
5123   cvtsi2ss{q}\t{%1, %0|%0, %1}"
5124  [(set_attr "type" "fmov,multi,sse")
5125   (set_attr "mode" "SF")
5126   (set_attr "fp_int_src" "true")])
5127
5128(define_insn "*floatdisf2_sse"
5129  [(set (match_operand:SF 0 "register_operand" "=x")
5130	(float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5131  "TARGET_64BIT && TARGET_SSE"
5132  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5133  [(set_attr "type" "sse")
5134   (set_attr "mode" "SF")
5135   (set_attr "fp_int_src" "true")])
5136
5137(define_insn "floathidf2"
5138  [(set (match_operand:DF 0 "register_operand" "=f,f")
5139	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5140  "TARGET_80387 && !TARGET_SSE2"
5141  "@
5142   fild%z1\t%1
5143   #"
5144  [(set_attr "type" "fmov,multi")
5145   (set_attr "mode" "DF")
5146   (set_attr "fp_int_src" "true")])
5147
5148(define_expand "floatsidf2"
5149  [(set (match_operand:DF 0 "register_operand" "")
5150	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5151  "TARGET_80387 || TARGET_SSE2"
5152  "")
5153
5154(define_insn "*floatsidf2_i387"
5155  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5156	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5157  "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5158  "@
5159   fild%z1\t%1
5160   #
5161   cvtsi2sd\t{%1, %0|%0, %1}"
5162  [(set_attr "type" "fmov,multi,sse")
5163   (set_attr "mode" "DF")
5164   (set_attr "fp_int_src" "true")])
5165
5166(define_insn "*floatsidf2_sse"
5167  [(set (match_operand:DF 0 "register_operand" "=Y")
5168	(float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5169  "TARGET_SSE2"
5170  "cvtsi2sd\t{%1, %0|%0, %1}"
5171  [(set_attr "type" "sse")
5172   (set_attr "mode" "DF")
5173   (set_attr "fp_int_src" "true")])
5174
5175(define_expand "floatdidf2"
5176  [(set (match_operand:DF 0 "register_operand" "")
5177	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5178  "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5179  "")
5180
5181(define_insn "*floatdidf2_i387_only"
5182  [(set (match_operand:DF 0 "register_operand" "=f,?f")
5183	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5184  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5185  "@
5186   fild%z1\t%1
5187   #"
5188  [(set_attr "type" "fmov,multi")
5189   (set_attr "mode" "DF")
5190   (set_attr "fp_int_src" "true")])
5191
5192(define_insn "*floatdidf2_i387"
5193  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5194	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5195  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5196  "@
5197   fild%z1\t%1
5198   #
5199   cvtsi2sd{q}\t{%1, %0|%0, %1}"
5200  [(set_attr "type" "fmov,multi,sse")
5201   (set_attr "mode" "DF")
5202   (set_attr "fp_int_src" "true")])
5203
5204(define_insn "*floatdidf2_sse"
5205  [(set (match_operand:DF 0 "register_operand" "=Y")
5206	(float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5207  "TARGET_SSE2"
5208  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5209  [(set_attr "type" "sse")
5210   (set_attr "mode" "DF")
5211   (set_attr "fp_int_src" "true")])
5212
5213(define_insn "floathixf2"
5214  [(set (match_operand:XF 0 "register_operand" "=f,f")
5215	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5216  "!TARGET_64BIT && TARGET_80387"
5217  "@
5218   fild%z1\t%1
5219   #"
5220  [(set_attr "type" "fmov,multi")
5221   (set_attr "mode" "XF")
5222   (set_attr "fp_int_src" "true")])
5223
5224(define_insn "floathitf2"
5225  [(set (match_operand:TF 0 "register_operand" "=f,f")
5226	(float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5227  "TARGET_80387"
5228  "@
5229   fild%z1\t%1
5230   #"
5231  [(set_attr "type" "fmov,multi")
5232   (set_attr "mode" "XF")
5233   (set_attr "fp_int_src" "true")])
5234
5235(define_insn "floatsixf2"
5236  [(set (match_operand:XF 0 "register_operand" "=f,f")
5237	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5238  "!TARGET_64BIT && TARGET_80387"
5239  "@
5240   fild%z1\t%1
5241   #"
5242  [(set_attr "type" "fmov,multi")
5243   (set_attr "mode" "XF")
5244   (set_attr "fp_int_src" "true")])
5245
5246(define_insn "floatsitf2"
5247  [(set (match_operand:TF 0 "register_operand" "=f,f")
5248	(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5249  "TARGET_80387"
5250  "@
5251   fild%z1\t%1
5252   #"
5253  [(set_attr "type" "fmov,multi")
5254   (set_attr "mode" "XF")
5255   (set_attr "fp_int_src" "true")])
5256
5257(define_insn "floatdixf2"
5258  [(set (match_operand:XF 0 "register_operand" "=f,f")
5259	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5260  "!TARGET_64BIT && TARGET_80387"
5261  "@
5262   fild%z1\t%1
5263   #"
5264  [(set_attr "type" "fmov,multi")
5265   (set_attr "mode" "XF")
5266   (set_attr "fp_int_src" "true")])
5267
5268(define_insn "floatditf2"
5269  [(set (match_operand:TF 0 "register_operand" "=f,f")
5270	(float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5271  "TARGET_80387"
5272  "@
5273   fild%z1\t%1
5274   #"
5275  [(set_attr "type" "fmov,multi")
5276   (set_attr "mode" "XF")
5277   (set_attr "fp_int_src" "true")])
5278
5279;; %%% Kill these when reload knows how to do it.
5280(define_split
5281  [(set (match_operand 0 "register_operand" "")
5282	(float (match_operand 1 "register_operand" "")))]
5283  "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
5284   && FP_REG_P (operands[0])"
5285  [(const_int 0)]
5286{
5287  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5288  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5289  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5290  ix86_free_from_memory (GET_MODE (operands[1]));
5291  DONE;
5292})
5293
5294;; Add instructions
5295
5296;; %%% splits for addsidi3
5297;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5298;	(plus:DI (match_operand:DI 1 "general_operand" "")
5299;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5300
5301(define_expand "adddi3"
5302  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5303	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5304		 (match_operand:DI 2 "x86_64_general_operand" "")))
5305   (clobber (reg:CC 17))]
5306  ""
5307  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5308
5309(define_insn "*adddi3_1"
5310  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5311	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5312		 (match_operand:DI 2 "general_operand" "roiF,riF")))
5313   (clobber (reg:CC 17))]
5314  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5315  "#")
5316
5317(define_split
5318  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5319	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5320		 (match_operand:DI 2 "general_operand" "")))
5321   (clobber (reg:CC 17))]
5322  "!TARGET_64BIT && reload_completed"
5323  [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
5324	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5325   (parallel [(set (match_dup 3)
5326		   (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5327				     (match_dup 4))
5328			    (match_dup 5)))
5329	      (clobber (reg:CC 17))])]
5330  "split_di (operands+0, 1, operands+0, operands+3);
5331   split_di (operands+1, 1, operands+1, operands+4);
5332   split_di (operands+2, 1, operands+2, operands+5);")
5333
5334(define_insn "*adddi3_carry_rex64"
5335  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5336	  (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
5337			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5338		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5339   (clobber (reg:CC 17))]
5340  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5341  "adc{q}\t{%2, %0|%0, %2}"
5342  [(set_attr "type" "alu")
5343   (set_attr "pent_pair" "pu")
5344   (set_attr "mode" "DI")
5345   (set_attr "ppro_uops" "few")])
5346
5347(define_insn "*adddi3_cc_rex64"
5348  [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5349				(match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
5350   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5351	(plus:DI (match_dup 1) (match_dup 2)))]
5352  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5353  "add{q}\t{%2, %0|%0, %2}"
5354  [(set_attr "type" "alu")
5355   (set_attr "mode" "DI")])
5356
5357(define_insn "*addsi3_carry"
5358  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5359	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5360			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5361		   (match_operand:SI 2 "general_operand" "ri,rm")))
5362   (clobber (reg:CC 17))]
5363  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5364  "adc{l}\t{%2, %0|%0, %2}"
5365  [(set_attr "type" "alu")
5366   (set_attr "pent_pair" "pu")
5367   (set_attr "mode" "SI")
5368   (set_attr "ppro_uops" "few")])
5369
5370(define_insn "*addsi3_carry_zext"
5371  [(set (match_operand:DI 0 "register_operand" "=r")
5372	  (zero_extend:DI 
5373	    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5374			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
5375		     (match_operand:SI 2 "general_operand" "rim"))))
5376   (clobber (reg:CC 17))]
5377  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5378  "adc{l}\t{%2, %k0|%k0, %2}"
5379  [(set_attr "type" "alu")
5380   (set_attr "pent_pair" "pu")
5381   (set_attr "mode" "SI")
5382   (set_attr "ppro_uops" "few")])
5383
5384(define_insn "*addsi3_cc"
5385  [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5386			        (match_operand:SI 2 "general_operand" "ri,rm")] 12))
5387   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5388	(plus:SI (match_dup 1) (match_dup 2)))]
5389  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5390  "add{l}\t{%2, %0|%0, %2}"
5391  [(set_attr "type" "alu")
5392   (set_attr "mode" "SI")])
5393
5394(define_insn "addqi3_cc"
5395  [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5396			        (match_operand:QI 2 "general_operand" "qi,qm")] 12))
5397   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5398	(plus:QI (match_dup 1) (match_dup 2)))]
5399  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5400  "add{b}\t{%2, %0|%0, %2}"
5401  [(set_attr "type" "alu")
5402   (set_attr "mode" "QI")])
5403
5404(define_expand "addsi3"
5405  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5406		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5407			    (match_operand:SI 2 "general_operand" "")))
5408	      (clobber (reg:CC 17))])]
5409  ""
5410  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5411
5412(define_insn "*lea_1"
5413  [(set (match_operand:SI 0 "register_operand" "=r")
5414	(match_operand:SI 1 "address_operand" "p"))]
5415  "!TARGET_64BIT"
5416  "lea{l}\t{%a1, %0|%0, %a1}"
5417  [(set_attr "type" "lea")
5418   (set_attr "mode" "SI")])
5419
5420(define_insn "*lea_1_rex64"
5421  [(set (match_operand:SI 0 "register_operand" "=r")
5422	(subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5423  "TARGET_64BIT"
5424  "lea{l}\t{%a1, %0|%0, %a1}"
5425  [(set_attr "type" "lea")
5426   (set_attr "mode" "SI")])
5427
5428(define_insn "*lea_1_zext"
5429  [(set (match_operand:DI 0 "register_operand" "=r")
5430	(zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5431  "TARGET_64BIT"
5432  "lea{l}\t{%a1, %k0|%k0, %a1}"
5433  [(set_attr "type" "lea")
5434   (set_attr "mode" "SI")])
5435
5436(define_insn "*lea_2_rex64"
5437  [(set (match_operand:DI 0 "register_operand" "=r")
5438	(match_operand:DI 1 "address_operand" "p"))]
5439  "TARGET_64BIT"
5440  "lea{q}\t{%a1, %0|%0, %a1}"
5441  [(set_attr "type" "lea")
5442   (set_attr "mode" "DI")])
5443
5444;; The lea patterns for non-Pmodes needs to be matched by several
5445;; insns converted to real lea by splitters.
5446
5447(define_insn_and_split "*lea_general_1"
5448  [(set (match_operand 0 "register_operand" "=r")
5449	(plus (plus (match_operand 1 "register_operand" "r")
5450		    (match_operand 2 "register_operand" "r"))
5451	      (match_operand 3 "immediate_operand" "i")))]
5452  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5453    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5454   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5455   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5456   && GET_MODE (operands[0]) == GET_MODE (operands[2])
5457   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5458       || GET_MODE (operands[3]) == VOIDmode)"
5459  "#"
5460  "&& reload_completed"
5461  [(const_int 0)]
5462{
5463  rtx pat;
5464  operands[0] = gen_lowpart (SImode, operands[0]);
5465  operands[1] = gen_lowpart (Pmode, operands[1]);
5466  operands[2] = gen_lowpart (Pmode, operands[2]);
5467  operands[3] = gen_lowpart (Pmode, operands[3]);
5468  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5469  		      operands[3]);
5470  if (Pmode != SImode)
5471    pat = gen_rtx_SUBREG (SImode, pat, 0);
5472  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5473  DONE;
5474}
5475  [(set_attr "type" "lea")
5476   (set_attr "mode" "SI")])
5477
5478(define_insn_and_split "*lea_general_1_zext"
5479  [(set (match_operand:DI 0 "register_operand" "=r")
5480	(zero_extend:DI
5481	  (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5482			    (match_operand:SI 2 "register_operand" "r"))
5483		   (match_operand:SI 3 "immediate_operand" "i"))))]
5484  "TARGET_64BIT"
5485  "#"
5486  "&& reload_completed"
5487  [(set (match_dup 0)
5488	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5489						     (match_dup 2))
5490					    (match_dup 3)) 0)))]
5491{
5492  operands[1] = gen_lowpart (Pmode, operands[1]);
5493  operands[2] = gen_lowpart (Pmode, operands[2]);
5494  operands[3] = gen_lowpart (Pmode, operands[3]);
5495}
5496  [(set_attr "type" "lea")
5497   (set_attr "mode" "SI")])
5498
5499(define_insn_and_split "*lea_general_2"
5500  [(set (match_operand 0 "register_operand" "=r")
5501	(plus (mult (match_operand 1 "register_operand" "r")
5502		    (match_operand 2 "const248_operand" "i"))
5503	      (match_operand 3 "nonmemory_operand" "ri")))]
5504  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5505    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5506   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5507   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5508   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5509       || GET_MODE (operands[3]) == VOIDmode)"
5510  "#"
5511  "&& reload_completed"
5512  [(const_int 0)]
5513{
5514  rtx pat;
5515  operands[0] = gen_lowpart (SImode, operands[0]);
5516  operands[1] = gen_lowpart (Pmode, operands[1]);
5517  operands[3] = gen_lowpart (Pmode, operands[3]);
5518  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5519  		      operands[3]);
5520  if (Pmode != SImode)
5521    pat = gen_rtx_SUBREG (SImode, pat, 0);
5522  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5523  DONE;
5524}
5525  [(set_attr "type" "lea")
5526   (set_attr "mode" "SI")])
5527
5528(define_insn_and_split "*lea_general_2_zext"
5529  [(set (match_operand:DI 0 "register_operand" "=r")
5530	(zero_extend:DI
5531	  (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5532			    (match_operand:SI 2 "const248_operand" "n"))
5533		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5534  "TARGET_64BIT"
5535  "#"
5536  "&& reload_completed"
5537  [(set (match_dup 0)
5538	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5539						     (match_dup 2))
5540					    (match_dup 3)) 0)))]
5541{
5542  operands[1] = gen_lowpart (Pmode, operands[1]);
5543  operands[3] = gen_lowpart (Pmode, operands[3]);
5544}
5545  [(set_attr "type" "lea")
5546   (set_attr "mode" "SI")])
5547
5548(define_insn_and_split "*lea_general_3"
5549  [(set (match_operand 0 "register_operand" "=r")
5550	(plus (plus (mult (match_operand 1 "register_operand" "r")
5551			  (match_operand 2 "const248_operand" "i"))
5552		    (match_operand 3 "register_operand" "r"))
5553	      (match_operand 4 "immediate_operand" "i")))]
5554  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5555    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5556   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5557   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5558   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5559  "#"
5560  "&& reload_completed"
5561  [(const_int 0)]
5562{
5563  rtx pat;
5564  operands[0] = gen_lowpart (SImode, operands[0]);
5565  operands[1] = gen_lowpart (Pmode, operands[1]);
5566  operands[3] = gen_lowpart (Pmode, operands[3]);
5567  operands[4] = gen_lowpart (Pmode, operands[4]);
5568  pat = gen_rtx_PLUS (Pmode,
5569  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5570		      					 operands[2]),
5571				    operands[3]),
5572  		      operands[4]);
5573  if (Pmode != SImode)
5574    pat = gen_rtx_SUBREG (SImode, pat, 0);
5575  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5576  DONE;
5577}
5578  [(set_attr "type" "lea")
5579   (set_attr "mode" "SI")])
5580
5581(define_insn_and_split "*lea_general_3_zext"
5582  [(set (match_operand:DI 0 "register_operand" "=r")
5583	(zero_extend:DI
5584	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5585				     (match_operand:SI 2 "const248_operand" "n"))
5586			    (match_operand:SI 3 "register_operand" "r"))
5587		   (match_operand:SI 4 "immediate_operand" "i"))))]
5588  "TARGET_64BIT"
5589  "#"
5590  "&& reload_completed"
5591  [(set (match_dup 0)
5592	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5593							      (match_dup 2))
5594						     (match_dup 3))
5595					    (match_dup 4)) 0)))]
5596{
5597  operands[1] = gen_lowpart (Pmode, operands[1]);
5598  operands[3] = gen_lowpart (Pmode, operands[3]);
5599  operands[4] = gen_lowpart (Pmode, operands[4]);
5600}
5601  [(set_attr "type" "lea")
5602   (set_attr "mode" "SI")])
5603
5604(define_insn "*adddi_1_rex64"
5605  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5606	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5607		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5608   (clobber (reg:CC 17))]
5609  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5610{
5611  switch (get_attr_type (insn))
5612    {
5613    case TYPE_LEA:
5614      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5615      return "lea{q}\t{%a2, %0|%0, %a2}";
5616
5617    case TYPE_INCDEC:
5618      if (! rtx_equal_p (operands[0], operands[1]))
5619	abort ();
5620      if (operands[2] == const1_rtx)
5621        return "inc{q}\t%0";
5622      else if (operands[2] == constm1_rtx)
5623        return "dec{q}\t%0";
5624      else
5625	abort ();
5626
5627    default:
5628      if (! rtx_equal_p (operands[0], operands[1]))
5629	abort ();
5630
5631      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5632	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5633      if (GET_CODE (operands[2]) == CONST_INT
5634	  /* Avoid overflows.  */
5635	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5636          && (INTVAL (operands[2]) == 128
5637	      || (INTVAL (operands[2]) < 0
5638		  && INTVAL (operands[2]) != -128)))
5639        {
5640          operands[2] = GEN_INT (-INTVAL (operands[2]));
5641          return "sub{q}\t{%2, %0|%0, %2}";
5642        }
5643      return "add{q}\t{%2, %0|%0, %2}";
5644    }
5645}
5646  [(set (attr "type")
5647     (cond [(eq_attr "alternative" "2")
5648	      (const_string "lea")
5649	    ; Current assemblers are broken and do not allow @GOTOFF in
5650	    ; ought but a memory context.
5651	    (match_operand:DI 2 "pic_symbolic_operand" "")
5652	      (const_string "lea")
5653	    (match_operand:DI 2 "incdec_operand" "")
5654	      (const_string "incdec")
5655	   ]
5656	   (const_string "alu")))
5657   (set_attr "mode" "DI")])
5658
5659;; Convert lea to the lea pattern to avoid flags dependency.
5660(define_split
5661  [(set (match_operand:DI 0 "register_operand" "")
5662	(plus:DI (match_operand:DI 1 "register_operand" "")
5663		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5664   (clobber (reg:CC 17))]
5665  "TARGET_64BIT && reload_completed
5666   && true_regnum (operands[0]) != true_regnum (operands[1])"
5667  [(set (match_dup 0)
5668	(plus:DI (match_dup 1)
5669		 (match_dup 2)))]
5670  "")
5671
5672(define_insn "*adddi_2_rex64"
5673  [(set (reg 17)
5674	(compare
5675	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5676		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5677	  (const_int 0)))			
5678   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5679	(plus:DI (match_dup 1) (match_dup 2)))]
5680  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5681   && ix86_binary_operator_ok (PLUS, DImode, operands)
5682   /* Current assemblers are broken and do not allow @GOTOFF in
5683      ought but a memory context.  */
5684   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5685{
5686  switch (get_attr_type (insn))
5687    {
5688    case TYPE_INCDEC:
5689      if (! rtx_equal_p (operands[0], operands[1]))
5690	abort ();
5691      if (operands[2] == const1_rtx)
5692        return "inc{q}\t%0";
5693      else if (operands[2] == constm1_rtx)
5694        return "dec{q}\t%0";
5695      else
5696	abort ();
5697
5698    default:
5699      if (! rtx_equal_p (operands[0], operands[1]))
5700	abort ();
5701      /* ???? We ought to handle there the 32bit case too
5702	 - do we need new constrant?  */
5703      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705      if (GET_CODE (operands[2]) == CONST_INT
5706	  /* Avoid overflows.  */
5707	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5708          && (INTVAL (operands[2]) == 128
5709	      || (INTVAL (operands[2]) < 0
5710		  && INTVAL (operands[2]) != -128)))
5711        {
5712          operands[2] = GEN_INT (-INTVAL (operands[2]));
5713          return "sub{q}\t{%2, %0|%0, %2}";
5714        }
5715      return "add{q}\t{%2, %0|%0, %2}";
5716    }
5717}
5718  [(set (attr "type")
5719     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5720	(const_string "incdec")
5721	(const_string "alu")))
5722   (set_attr "mode" "DI")])
5723
5724(define_insn "*adddi_3_rex64"
5725  [(set (reg 17)
5726	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5727		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5728   (clobber (match_scratch:DI 0 "=r"))]
5729  "TARGET_64BIT
5730   && ix86_match_ccmode (insn, CCZmode)
5731   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732   /* Current assemblers are broken and do not allow @GOTOFF in
5733      ought but a memory context.  */
5734   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5735{
5736  switch (get_attr_type (insn))
5737    {
5738    case TYPE_INCDEC:
5739      if (! rtx_equal_p (operands[0], operands[1]))
5740	abort ();
5741      if (operands[2] == const1_rtx)
5742        return "inc{q}\t%0";
5743      else if (operands[2] == constm1_rtx)
5744        return "dec{q}\t%0";
5745      else
5746	abort ();
5747
5748    default:
5749      if (! rtx_equal_p (operands[0], operands[1]))
5750	abort ();
5751      /* ???? We ought to handle there the 32bit case too
5752	 - do we need new constrant?  */
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	  /* Avoid overflows.  */
5757	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5758          && (INTVAL (operands[2]) == 128
5759	      || (INTVAL (operands[2]) < 0
5760		  && INTVAL (operands[2]) != -128)))
5761        {
5762          operands[2] = GEN_INT (-INTVAL (operands[2]));
5763          return "sub{q}\t{%2, %0|%0, %2}";
5764        }
5765      return "add{q}\t{%2, %0|%0, %2}";
5766    }
5767}
5768  [(set (attr "type")
5769     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5770	(const_string "incdec")
5771	(const_string "alu")))
5772   (set_attr "mode" "DI")])
5773
5774; For comparisons against 1, -1 and 128, we may generate better code
5775; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5776; is matched then.  We can't accept general immediate, because for
5777; case of overflows,  the result is messed up.
5778; This pattern also don't hold of 0x8000000000000000, since the value overflows
5779; when negated.
5780; Also carry flag is reversed compared to cmp, so this conversion is valid
5781; only for comparisons not depending on it.
5782(define_insn "*adddi_4_rex64"
5783  [(set (reg 17)
5784	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5785		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5786   (clobber (match_scratch:DI 0 "=rm"))]
5787  "TARGET_64BIT
5788   &&  ix86_match_ccmode (insn, CCGCmode)"
5789{
5790  switch (get_attr_type (insn))
5791    {
5792    case TYPE_INCDEC:
5793      if (operands[2] == constm1_rtx)
5794        return "inc{q}\t%0";
5795      else if (operands[2] == const1_rtx)
5796        return "dec{q}\t%0";
5797      else
5798	abort();
5799
5800    default:
5801      if (! rtx_equal_p (operands[0], operands[1]))
5802	abort ();
5803      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5804	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5805      if ((INTVAL (operands[2]) == -128
5806	   || (INTVAL (operands[2]) > 0
5807	       && INTVAL (operands[2]) != 128))
5808	  /* Avoid overflows.  */
5809	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5810	return "sub{q}\t{%2, %0|%0, %2}";
5811      operands[2] = GEN_INT (-INTVAL (operands[2]));
5812      return "add{q}\t{%2, %0|%0, %2}";
5813    }
5814}
5815  [(set (attr "type")
5816     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5817	(const_string "incdec")
5818	(const_string "alu")))
5819   (set_attr "mode" "DI")])
5820
5821(define_insn "*adddi_5_rex64"
5822  [(set (reg 17)
5823	(compare
5824	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5825		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5826	  (const_int 0)))			
5827   (clobber (match_scratch:DI 0 "=r"))]
5828  "TARGET_64BIT
5829   && ix86_match_ccmode (insn, CCGOCmode)
5830   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5831   /* Current assemblers are broken and do not allow @GOTOFF in
5832      ought but a memory context.  */
5833   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5834{
5835  switch (get_attr_type (insn))
5836    {
5837    case TYPE_INCDEC:
5838      if (! rtx_equal_p (operands[0], operands[1]))
5839	abort ();
5840      if (operands[2] == const1_rtx)
5841        return "inc{q}\t%0";
5842      else if (operands[2] == constm1_rtx)
5843        return "dec{q}\t%0";
5844      else
5845	abort();
5846
5847    default:
5848      if (! rtx_equal_p (operands[0], operands[1]))
5849	abort ();
5850      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5851	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5852      if (GET_CODE (operands[2]) == CONST_INT
5853	  /* Avoid overflows.  */
5854	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5855          && (INTVAL (operands[2]) == 128
5856	      || (INTVAL (operands[2]) < 0
5857		  && INTVAL (operands[2]) != -128)))
5858        {
5859          operands[2] = GEN_INT (-INTVAL (operands[2]));
5860          return "sub{q}\t{%2, %0|%0, %2}";
5861        }
5862      return "add{q}\t{%2, %0|%0, %2}";
5863    }
5864}
5865  [(set (attr "type")
5866     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5867	(const_string "incdec")
5868	(const_string "alu")))
5869   (set_attr "mode" "DI")])
5870
5871
5872(define_insn "*addsi_1"
5873  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5874	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5875		 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5876   (clobber (reg:CC 17))]
5877  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5878{
5879  switch (get_attr_type (insn))
5880    {
5881    case TYPE_LEA:
5882      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5883      return "lea{l}\t{%a2, %0|%0, %a2}";
5884
5885    case TYPE_INCDEC:
5886      if (! rtx_equal_p (operands[0], operands[1]))
5887	abort ();
5888      if (operands[2] == const1_rtx)
5889        return "inc{l}\t%0";
5890      else if (operands[2] == constm1_rtx)
5891        return "dec{l}\t%0";
5892      else
5893	abort();
5894
5895    default:
5896      if (! rtx_equal_p (operands[0], operands[1]))
5897	abort ();
5898
5899      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5900	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5901      if (GET_CODE (operands[2]) == CONST_INT
5902          && (INTVAL (operands[2]) == 128
5903	      || (INTVAL (operands[2]) < 0
5904		  && INTVAL (operands[2]) != -128)))
5905        {
5906          operands[2] = GEN_INT (-INTVAL (operands[2]));
5907          return "sub{l}\t{%2, %0|%0, %2}";
5908        }
5909      return "add{l}\t{%2, %0|%0, %2}";
5910    }
5911}
5912  [(set (attr "type")
5913     (cond [(eq_attr "alternative" "2")
5914	      (const_string "lea")
5915	    ; Current assemblers are broken and do not allow @GOTOFF in
5916	    ; ought but a memory context.
5917	    (match_operand:SI 2 "pic_symbolic_operand" "")
5918	      (const_string "lea")
5919	    (match_operand:SI 2 "incdec_operand" "")
5920	      (const_string "incdec")
5921	   ]
5922	   (const_string "alu")))
5923   (set_attr "mode" "SI")])
5924
5925;; Convert lea to the lea pattern to avoid flags dependency.
5926(define_split
5927  [(set (match_operand 0 "register_operand" "")
5928	(plus (match_operand 1 "register_operand" "")
5929              (match_operand 2 "nonmemory_operand" "")))
5930   (clobber (reg:CC 17))]
5931  "reload_completed
5932   && true_regnum (operands[0]) != true_regnum (operands[1])"
5933  [(const_int 0)]
5934{
5935  rtx pat;
5936  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5937     may confuse gen_lowpart.  */
5938  if (GET_MODE (operands[0]) != Pmode)
5939    {
5940      operands[1] = gen_lowpart (Pmode, operands[1]);
5941      operands[2] = gen_lowpart (Pmode, operands[2]);
5942    }
5943  operands[0] = gen_lowpart (SImode, operands[0]);
5944  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5945  if (Pmode != SImode)
5946    pat = gen_rtx_SUBREG (SImode, pat, 0);
5947  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5948  DONE;
5949})
5950
5951;; It may seem that nonimmediate operand is proper one for operand 1.
5952;; The addsi_1 pattern allows nonimmediate operand at that place and
5953;; we take care in ix86_binary_operator_ok to not allow two memory
5954;; operands so proper swapping will be done in reload.  This allow
5955;; patterns constructed from addsi_1 to match.
5956(define_insn "addsi_1_zext"
5957  [(set (match_operand:DI 0 "register_operand" "=r,r")
5958	(zero_extend:DI
5959	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5960		   (match_operand:SI 2 "general_operand" "rmni,rni"))))
5961   (clobber (reg:CC 17))]
5962  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5963{
5964  switch (get_attr_type (insn))
5965    {
5966    case TYPE_LEA:
5967      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5968      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5969
5970    case TYPE_INCDEC:
5971      if (operands[2] == const1_rtx)
5972        return "inc{l}\t%k0";
5973      else if (operands[2] == constm1_rtx)
5974        return "dec{l}\t%k0";
5975      else
5976	abort();
5977
5978    default:
5979      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5980	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5981      if (GET_CODE (operands[2]) == CONST_INT
5982          && (INTVAL (operands[2]) == 128
5983	      || (INTVAL (operands[2]) < 0
5984		  && INTVAL (operands[2]) != -128)))
5985        {
5986          operands[2] = GEN_INT (-INTVAL (operands[2]));
5987          return "sub{l}\t{%2, %k0|%k0, %2}";
5988        }
5989      return "add{l}\t{%2, %k0|%k0, %2}";
5990    }
5991}
5992  [(set (attr "type")
5993     (cond [(eq_attr "alternative" "1")
5994	      (const_string "lea")
5995	    ; Current assemblers are broken and do not allow @GOTOFF in
5996	    ; ought but a memory context.
5997	    (match_operand:SI 2 "pic_symbolic_operand" "")
5998	      (const_string "lea")
5999	    (match_operand:SI 2 "incdec_operand" "")
6000	      (const_string "incdec")
6001	   ]
6002	   (const_string "alu")))
6003   (set_attr "mode" "SI")])
6004
6005;; Convert lea to the lea pattern to avoid flags dependency.
6006(define_split
6007  [(set (match_operand:DI 0 "register_operand" "")
6008	(zero_extend:DI
6009	  (plus:SI (match_operand:SI 1 "register_operand" "")
6010		   (match_operand:SI 2 "nonmemory_operand" ""))))
6011   (clobber (reg:CC 17))]
6012  "reload_completed
6013   && true_regnum (operands[0]) != true_regnum (operands[1])"
6014  [(set (match_dup 0)
6015	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6016{
6017  operands[1] = gen_lowpart (Pmode, operands[1]);
6018  operands[2] = gen_lowpart (Pmode, operands[2]);
6019})
6020
6021(define_insn "*addsi_2"
6022  [(set (reg 17)
6023	(compare
6024	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6025		   (match_operand:SI 2 "general_operand" "rmni,rni"))
6026	  (const_int 0)))			
6027   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6028	(plus:SI (match_dup 1) (match_dup 2)))]
6029  "ix86_match_ccmode (insn, CCGOCmode)
6030   && ix86_binary_operator_ok (PLUS, SImode, operands)
6031   /* Current assemblers are broken and do not allow @GOTOFF in
6032      ought but a memory context.  */
6033   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6034{
6035  switch (get_attr_type (insn))
6036    {
6037    case TYPE_INCDEC:
6038      if (! rtx_equal_p (operands[0], operands[1]))
6039	abort ();
6040      if (operands[2] == const1_rtx)
6041        return "inc{l}\t%0";
6042      else if (operands[2] == constm1_rtx)
6043        return "dec{l}\t%0";
6044      else
6045	abort();
6046
6047    default:
6048      if (! rtx_equal_p (operands[0], operands[1]))
6049	abort ();
6050      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6052      if (GET_CODE (operands[2]) == CONST_INT
6053          && (INTVAL (operands[2]) == 128
6054	      || (INTVAL (operands[2]) < 0
6055		  && INTVAL (operands[2]) != -128)))
6056        {
6057          operands[2] = GEN_INT (-INTVAL (operands[2]));
6058          return "sub{l}\t{%2, %0|%0, %2}";
6059        }
6060      return "add{l}\t{%2, %0|%0, %2}";
6061    }
6062}
6063  [(set (attr "type")
6064     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6065	(const_string "incdec")
6066	(const_string "alu")))
6067   (set_attr "mode" "SI")])
6068
6069;; See comment for addsi_1_zext why we do use nonimmediate_operand
6070(define_insn "*addsi_2_zext"
6071  [(set (reg 17)
6072	(compare
6073	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6074		   (match_operand:SI 2 "general_operand" "rmni"))
6075	  (const_int 0)))			
6076   (set (match_operand:DI 0 "register_operand" "=r")
6077	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6078  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6079   && ix86_binary_operator_ok (PLUS, SImode, operands)
6080   /* Current assemblers are broken and do not allow @GOTOFF in
6081      ought but a memory context.  */
6082   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6083{
6084  switch (get_attr_type (insn))
6085    {
6086    case TYPE_INCDEC:
6087      if (operands[2] == const1_rtx)
6088        return "inc{l}\t%k0";
6089      else if (operands[2] == constm1_rtx)
6090        return "dec{l}\t%k0";
6091      else
6092	abort();
6093
6094    default:
6095      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6096	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6097      if (GET_CODE (operands[2]) == CONST_INT
6098          && (INTVAL (operands[2]) == 128
6099	      || (INTVAL (operands[2]) < 0
6100		  && INTVAL (operands[2]) != -128)))
6101        {
6102          operands[2] = GEN_INT (-INTVAL (operands[2]));
6103          return "sub{l}\t{%2, %k0|%k0, %2}";
6104        }
6105      return "add{l}\t{%2, %k0|%k0, %2}";
6106    }
6107}
6108  [(set (attr "type")
6109     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6110	(const_string "incdec")
6111	(const_string "alu")))
6112   (set_attr "mode" "SI")])
6113
6114(define_insn "*addsi_3"
6115  [(set (reg 17)
6116	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6117		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6118   (clobber (match_scratch:SI 0 "=r"))]
6119  "ix86_match_ccmode (insn, CCZmode)
6120   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6121   /* Current assemblers are broken and do not allow @GOTOFF in
6122      ought but a memory context.  */
6123   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6124{
6125  switch (get_attr_type (insn))
6126    {
6127    case TYPE_INCDEC:
6128      if (! rtx_equal_p (operands[0], operands[1]))
6129	abort ();
6130      if (operands[2] == const1_rtx)
6131        return "inc{l}\t%0";
6132      else if (operands[2] == constm1_rtx)
6133        return "dec{l}\t%0";
6134      else
6135	abort();
6136
6137    default:
6138      if (! rtx_equal_p (operands[0], operands[1]))
6139	abort ();
6140      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6142      if (GET_CODE (operands[2]) == CONST_INT
6143          && (INTVAL (operands[2]) == 128
6144	      || (INTVAL (operands[2]) < 0
6145		  && INTVAL (operands[2]) != -128)))
6146        {
6147          operands[2] = GEN_INT (-INTVAL (operands[2]));
6148          return "sub{l}\t{%2, %0|%0, %2}";
6149        }
6150      return "add{l}\t{%2, %0|%0, %2}";
6151    }
6152}
6153  [(set (attr "type")
6154     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6155	(const_string "incdec")
6156	(const_string "alu")))
6157   (set_attr "mode" "SI")])
6158
6159;; See comment for addsi_1_zext why we do use nonimmediate_operand
6160(define_insn "*addsi_3_zext"
6161  [(set (reg 17)
6162	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6163		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6164   (set (match_operand:DI 0 "register_operand" "=r")
6165	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6166  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6167   && ix86_binary_operator_ok (PLUS, SImode, operands)
6168   /* Current assemblers are broken and do not allow @GOTOFF in
6169      ought but a memory context.  */
6170   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6171{
6172  switch (get_attr_type (insn))
6173    {
6174    case TYPE_INCDEC:
6175      if (operands[2] == const1_rtx)
6176        return "inc{l}\t%k0";
6177      else if (operands[2] == constm1_rtx)
6178        return "dec{l}\t%k0";
6179      else
6180	abort();
6181
6182    default:
6183      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6184	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6185      if (GET_CODE (operands[2]) == CONST_INT
6186          && (INTVAL (operands[2]) == 128
6187	      || (INTVAL (operands[2]) < 0
6188		  && INTVAL (operands[2]) != -128)))
6189        {
6190          operands[2] = GEN_INT (-INTVAL (operands[2]));
6191          return "sub{l}\t{%2, %k0|%k0, %2}";
6192        }
6193      return "add{l}\t{%2, %k0|%k0, %2}";
6194    }
6195}
6196  [(set (attr "type")
6197     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6198	(const_string "incdec")
6199	(const_string "alu")))
6200   (set_attr "mode" "SI")])
6201
6202; For comparisons agains 1, -1 and 128, we may generate better code
6203; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6204; is matched then.  We can't accept general immediate, because for
6205; case of overflows,  the result is messed up.
6206; This pattern also don't hold of 0x80000000, since the value overflows
6207; when negated.
6208; Also carry flag is reversed compared to cmp, so this conversion is valid
6209; only for comparisons not depending on it.
6210(define_insn "*addsi_4"
6211  [(set (reg 17)
6212	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
6213		 (match_operand:SI 2 "const_int_operand" "n")))
6214   (clobber (match_scratch:SI 0 "=rm"))]
6215  "ix86_match_ccmode (insn, CCGCmode)
6216   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6217{
6218  switch (get_attr_type (insn))
6219    {
6220    case TYPE_INCDEC:
6221      if (operands[2] == constm1_rtx)
6222        return "inc{l}\t%0";
6223      else if (operands[2] == const1_rtx)
6224        return "dec{l}\t%0";
6225      else
6226	abort();
6227
6228    default:
6229      if (! rtx_equal_p (operands[0], operands[1]))
6230	abort ();
6231      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6232	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6233      if ((INTVAL (operands[2]) == -128
6234	   || (INTVAL (operands[2]) > 0
6235	       && INTVAL (operands[2]) != 128)))
6236	return "sub{l}\t{%2, %0|%0, %2}";
6237      operands[2] = GEN_INT (-INTVAL (operands[2]));
6238      return "add{l}\t{%2, %0|%0, %2}";
6239    }
6240}
6241  [(set (attr "type")
6242     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6243	(const_string "incdec")
6244	(const_string "alu")))
6245   (set_attr "mode" "SI")])
6246
6247(define_insn "*addsi_5"
6248  [(set (reg 17)
6249	(compare
6250	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6251		   (match_operand:SI 2 "general_operand" "rmni"))
6252	  (const_int 0)))			
6253   (clobber (match_scratch:SI 0 "=r"))]
6254  "ix86_match_ccmode (insn, CCGOCmode)
6255   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6256   /* Current assemblers are broken and do not allow @GOTOFF in
6257      ought but a memory context.  */
6258   && ! pic_symbolic_operand (operands[2], VOIDmode)"
6259{
6260  switch (get_attr_type (insn))
6261    {
6262    case TYPE_INCDEC:
6263      if (! rtx_equal_p (operands[0], operands[1]))
6264	abort ();
6265      if (operands[2] == const1_rtx)
6266        return "inc{l}\t%0";
6267      else if (operands[2] == constm1_rtx)
6268        return "dec{l}\t%0";
6269      else
6270	abort();
6271
6272    default:
6273      if (! rtx_equal_p (operands[0], operands[1]))
6274	abort ();
6275      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6276	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6277      if (GET_CODE (operands[2]) == CONST_INT
6278          && (INTVAL (operands[2]) == 128
6279	      || (INTVAL (operands[2]) < 0
6280		  && INTVAL (operands[2]) != -128)))
6281        {
6282          operands[2] = GEN_INT (-INTVAL (operands[2]));
6283          return "sub{l}\t{%2, %0|%0, %2}";
6284        }
6285      return "add{l}\t{%2, %0|%0, %2}";
6286    }
6287}
6288  [(set (attr "type")
6289     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6290	(const_string "incdec")
6291	(const_string "alu")))
6292   (set_attr "mode" "SI")])
6293
6294(define_expand "addhi3"
6295  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6296		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6297			    (match_operand:HI 2 "general_operand" "")))
6298	      (clobber (reg:CC 17))])]
6299  "TARGET_HIMODE_MATH"
6300  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6301
6302;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6303;; type optimizations enabled by define-splits.  This is not important
6304;; for PII, and in fact harmful because of partial register stalls.
6305
6306(define_insn "*addhi_1_lea"
6307  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6308	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6309		 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6310   (clobber (reg:CC 17))]
6311  "!TARGET_PARTIAL_REG_STALL
6312   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6313{
6314  switch (get_attr_type (insn))
6315    {
6316    case TYPE_LEA:
6317      return "#";
6318    case TYPE_INCDEC:
6319      if (operands[2] == const1_rtx)
6320	return "inc{w}\t%0";
6321      else if (operands[2] == constm1_rtx
6322	       || (GET_CODE (operands[2]) == CONST_INT
6323		   && INTVAL (operands[2]) == 65535))
6324	return "dec{w}\t%0";
6325      abort();
6326
6327    default:
6328      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6329	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6330      if (GET_CODE (operands[2]) == CONST_INT
6331          && (INTVAL (operands[2]) == 128
6332	      || (INTVAL (operands[2]) < 0
6333		  && INTVAL (operands[2]) != -128)))
6334	{
6335	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6336	  return "sub{w}\t{%2, %0|%0, %2}";
6337	}
6338      return "add{w}\t{%2, %0|%0, %2}";
6339    }
6340}
6341  [(set (attr "type")
6342     (if_then_else (eq_attr "alternative" "2")
6343	(const_string "lea")
6344	(if_then_else (match_operand:HI 2 "incdec_operand" "")
6345	   (const_string "incdec")
6346	   (const_string "alu"))))
6347   (set_attr "mode" "HI,HI,SI")])
6348
6349(define_insn "*addhi_1"
6350  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6351	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6352		 (match_operand:HI 2 "general_operand" "ri,rm")))
6353   (clobber (reg:CC 17))]
6354  "TARGET_PARTIAL_REG_STALL
6355   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6356{
6357  switch (get_attr_type (insn))
6358    {
6359    case TYPE_INCDEC:
6360      if (operands[2] == const1_rtx)
6361	return "inc{w}\t%0";
6362      else if (operands[2] == constm1_rtx
6363	       || (GET_CODE (operands[2]) == CONST_INT
6364		   && INTVAL (operands[2]) == 65535))
6365	return "dec{w}\t%0";
6366      abort();
6367
6368    default:
6369      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6370	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6371      if (GET_CODE (operands[2]) == CONST_INT
6372          && (INTVAL (operands[2]) == 128
6373	      || (INTVAL (operands[2]) < 0
6374		  && INTVAL (operands[2]) != -128)))
6375	{
6376	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6377	  return "sub{w}\t{%2, %0|%0, %2}";
6378	}
6379      return "add{w}\t{%2, %0|%0, %2}";
6380    }
6381}
6382  [(set (attr "type")
6383     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6384	(const_string "incdec")
6385	(const_string "alu")))
6386   (set_attr "mode" "HI")])
6387
6388(define_insn "*addhi_2"
6389  [(set (reg 17)
6390	(compare
6391	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6392		   (match_operand:HI 2 "general_operand" "rmni,rni"))
6393	  (const_int 0)))			
6394   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6395	(plus:HI (match_dup 1) (match_dup 2)))]
6396  "ix86_match_ccmode (insn, CCGOCmode)
6397   && ix86_binary_operator_ok (PLUS, HImode, operands)"
6398{
6399  switch (get_attr_type (insn))
6400    {
6401    case TYPE_INCDEC:
6402      if (operands[2] == const1_rtx)
6403	return "inc{w}\t%0";
6404      else if (operands[2] == constm1_rtx
6405	       || (GET_CODE (operands[2]) == CONST_INT
6406		   && INTVAL (operands[2]) == 65535))
6407	return "dec{w}\t%0";
6408      abort();
6409
6410    default:
6411      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6412	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6413      if (GET_CODE (operands[2]) == CONST_INT
6414          && (INTVAL (operands[2]) == 128
6415	      || (INTVAL (operands[2]) < 0
6416		  && INTVAL (operands[2]) != -128)))
6417	{
6418	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6419	  return "sub{w}\t{%2, %0|%0, %2}";
6420	}
6421      return "add{w}\t{%2, %0|%0, %2}";
6422    }
6423}
6424  [(set (attr "type")
6425     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6426	(const_string "incdec")
6427	(const_string "alu")))
6428   (set_attr "mode" "HI")])
6429
6430(define_insn "*addhi_3"
6431  [(set (reg 17)
6432	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6433		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6434   (clobber (match_scratch:HI 0 "=r"))]
6435  "ix86_match_ccmode (insn, CCZmode)
6436   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6437{
6438  switch (get_attr_type (insn))
6439    {
6440    case TYPE_INCDEC:
6441      if (operands[2] == const1_rtx)
6442	return "inc{w}\t%0";
6443      else if (operands[2] == constm1_rtx
6444	       || (GET_CODE (operands[2]) == CONST_INT
6445		   && INTVAL (operands[2]) == 65535))
6446	return "dec{w}\t%0";
6447      abort();
6448
6449    default:
6450      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6451	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6452      if (GET_CODE (operands[2]) == CONST_INT
6453          && (INTVAL (operands[2]) == 128
6454	      || (INTVAL (operands[2]) < 0
6455		  && INTVAL (operands[2]) != -128)))
6456	{
6457	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6458	  return "sub{w}\t{%2, %0|%0, %2}";
6459	}
6460      return "add{w}\t{%2, %0|%0, %2}";
6461    }
6462}
6463  [(set (attr "type")
6464     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6465	(const_string "incdec")
6466	(const_string "alu")))
6467   (set_attr "mode" "HI")])
6468
6469; See comments above addsi_3_imm for details.
6470(define_insn "*addhi_4"
6471  [(set (reg 17)
6472	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
6473		 (match_operand:HI 2 "const_int_operand" "n")))
6474   (clobber (match_scratch:HI 0 "=rm"))]
6475  "ix86_match_ccmode (insn, CCGCmode)
6476   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6477{
6478  switch (get_attr_type (insn))
6479    {
6480    case TYPE_INCDEC:
6481      if (operands[2] == constm1_rtx
6482	  || (GET_CODE (operands[2]) == CONST_INT
6483	      && INTVAL (operands[2]) == 65535))
6484        return "inc{w}\t%0";
6485      else if (operands[2] == const1_rtx)
6486        return "dec{w}\t%0";
6487      else
6488	abort();
6489
6490    default:
6491      if (! rtx_equal_p (operands[0], operands[1]))
6492	abort ();
6493      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6494	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6495      if ((INTVAL (operands[2]) == -128
6496	   || (INTVAL (operands[2]) > 0
6497	       && INTVAL (operands[2]) != 128)))
6498	return "sub{w}\t{%2, %0|%0, %2}";
6499      operands[2] = GEN_INT (-INTVAL (operands[2]));
6500      return "add{w}\t{%2, %0|%0, %2}";
6501    }
6502}
6503  [(set (attr "type")
6504     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6505	(const_string "incdec")
6506	(const_string "alu")))
6507   (set_attr "mode" "SI")])
6508
6509
6510(define_insn "*addhi_5"
6511  [(set (reg 17)
6512	(compare
6513	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6514		   (match_operand:HI 2 "general_operand" "rmni"))
6515	  (const_int 0)))			
6516   (clobber (match_scratch:HI 0 "=r"))]
6517  "ix86_match_ccmode (insn, CCGOCmode)
6518   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6519{
6520  switch (get_attr_type (insn))
6521    {
6522    case TYPE_INCDEC:
6523      if (operands[2] == const1_rtx)
6524	return "inc{w}\t%0";
6525      else if (operands[2] == constm1_rtx
6526	       || (GET_CODE (operands[2]) == CONST_INT
6527		   && INTVAL (operands[2]) == 65535))
6528	return "dec{w}\t%0";
6529      abort();
6530
6531    default:
6532      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6533	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6534      if (GET_CODE (operands[2]) == CONST_INT
6535          && (INTVAL (operands[2]) == 128
6536	      || (INTVAL (operands[2]) < 0
6537		  && INTVAL (operands[2]) != -128)))
6538	{
6539	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6540	  return "sub{w}\t{%2, %0|%0, %2}";
6541	}
6542      return "add{w}\t{%2, %0|%0, %2}";
6543    }
6544}
6545  [(set (attr "type")
6546     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6547	(const_string "incdec")
6548	(const_string "alu")))
6549   (set_attr "mode" "HI")])
6550
6551(define_expand "addqi3"
6552  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6553		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6554			    (match_operand:QI 2 "general_operand" "")))
6555	      (clobber (reg:CC 17))])]
6556  "TARGET_QIMODE_MATH"
6557  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6558
6559;; %%% Potential partial reg stall on alternative 2.  What to do?
6560(define_insn "*addqi_1_lea"
6561  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6562	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6563		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6564   (clobber (reg:CC 17))]
6565  "!TARGET_PARTIAL_REG_STALL
6566   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6567{
6568  int widen = (which_alternative == 2);
6569  switch (get_attr_type (insn))
6570    {
6571    case TYPE_LEA:
6572      return "#";
6573    case TYPE_INCDEC:
6574      if (operands[2] == const1_rtx)
6575	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6576      else if (operands[2] == constm1_rtx
6577	       || (GET_CODE (operands[2]) == CONST_INT
6578		   && INTVAL (operands[2]) == 255))
6579	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6580      abort();
6581
6582    default:
6583      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6584	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6585      if (GET_CODE (operands[2]) == CONST_INT
6586          && (INTVAL (operands[2]) == 128
6587	      || (INTVAL (operands[2]) < 0
6588		  && INTVAL (operands[2]) != -128)))
6589	{
6590	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6591	  if (widen)
6592	    return "sub{l}\t{%2, %k0|%k0, %2}";
6593	  else
6594	    return "sub{b}\t{%2, %0|%0, %2}";
6595	}
6596      if (widen)
6597        return "add{l}\t{%k2, %k0|%k0, %k2}";
6598      else
6599        return "add{b}\t{%2, %0|%0, %2}";
6600    }
6601}
6602  [(set (attr "type")
6603     (if_then_else (eq_attr "alternative" "3")
6604	(const_string "lea")
6605	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6606	   (const_string "incdec")
6607	   (const_string "alu"))))
6608   (set_attr "mode" "QI,QI,SI,SI")])
6609
6610(define_insn "*addqi_1"
6611  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6612	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6613		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6614   (clobber (reg:CC 17))]
6615  "TARGET_PARTIAL_REG_STALL
6616   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6617{
6618  int widen = (which_alternative == 2);
6619  switch (get_attr_type (insn))
6620    {
6621    case TYPE_INCDEC:
6622      if (operands[2] == const1_rtx)
6623	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6624      else if (operands[2] == constm1_rtx
6625	       || (GET_CODE (operands[2]) == CONST_INT
6626		   && INTVAL (operands[2]) == 255))
6627	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6628      abort();
6629
6630    default:
6631      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6632	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6633      if (GET_CODE (operands[2]) == CONST_INT
6634          && (INTVAL (operands[2]) == 128
6635	      || (INTVAL (operands[2]) < 0
6636		  && INTVAL (operands[2]) != -128)))
6637	{
6638	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6639	  if (widen)
6640	    return "sub{l}\t{%2, %k0|%k0, %2}";
6641	  else
6642	    return "sub{b}\t{%2, %0|%0, %2}";
6643	}
6644      if (widen)
6645        return "add{l}\t{%k2, %k0|%k0, %k2}";
6646      else
6647        return "add{b}\t{%2, %0|%0, %2}";
6648    }
6649}
6650  [(set (attr "type")
6651     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6652	(const_string "incdec")
6653	(const_string "alu")))
6654   (set_attr "mode" "QI,QI,SI")])
6655
6656(define_insn "*addqi_2"
6657  [(set (reg 17)
6658	(compare
6659	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6660		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6661	  (const_int 0)))
6662   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6663	(plus:QI (match_dup 1) (match_dup 2)))]
6664  "ix86_match_ccmode (insn, CCGOCmode)
6665   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6666{
6667  switch (get_attr_type (insn))
6668    {
6669    case TYPE_INCDEC:
6670      if (operands[2] == const1_rtx)
6671	return "inc{b}\t%0";
6672      else if (operands[2] == constm1_rtx
6673	       || (GET_CODE (operands[2]) == CONST_INT
6674		   && INTVAL (operands[2]) == 255))
6675	return "dec{b}\t%0";
6676      abort();
6677
6678    default:
6679      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6680      if (GET_CODE (operands[2]) == CONST_INT
6681          && INTVAL (operands[2]) < 0)
6682	{
6683	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6684	  return "sub{b}\t{%2, %0|%0, %2}";
6685	}
6686      return "add{b}\t{%2, %0|%0, %2}";
6687    }
6688}
6689  [(set (attr "type")
6690     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6691	(const_string "incdec")
6692	(const_string "alu")))
6693   (set_attr "mode" "QI")])
6694
6695(define_insn "*addqi_3"
6696  [(set (reg 17)
6697	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6698		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6699   (clobber (match_scratch:QI 0 "=q"))]
6700  "ix86_match_ccmode (insn, CCZmode)
6701   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6702{
6703  switch (get_attr_type (insn))
6704    {
6705    case TYPE_INCDEC:
6706      if (operands[2] == const1_rtx)
6707	return "inc{b}\t%0";
6708      else if (operands[2] == constm1_rtx
6709	       || (GET_CODE (operands[2]) == CONST_INT
6710		   && INTVAL (operands[2]) == 255))
6711	return "dec{b}\t%0";
6712      abort();
6713
6714    default:
6715      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6716      if (GET_CODE (operands[2]) == CONST_INT
6717          && INTVAL (operands[2]) < 0)
6718	{
6719	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6720	  return "sub{b}\t{%2, %0|%0, %2}";
6721	}
6722      return "add{b}\t{%2, %0|%0, %2}";
6723    }
6724}
6725  [(set (attr "type")
6726     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6727	(const_string "incdec")
6728	(const_string "alu")))
6729   (set_attr "mode" "QI")])
6730
6731; See comments above addsi_3_imm for details.
6732(define_insn "*addqi_4"
6733  [(set (reg 17)
6734	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6735		 (match_operand:QI 2 "const_int_operand" "n")))
6736   (clobber (match_scratch:QI 0 "=qm"))]
6737  "ix86_match_ccmode (insn, CCGCmode)
6738   && (INTVAL (operands[2]) & 0xff) != 0x80"
6739{
6740  switch (get_attr_type (insn))
6741    {
6742    case TYPE_INCDEC:
6743      if (operands[2] == constm1_rtx
6744	  || (GET_CODE (operands[2]) == CONST_INT
6745	      && INTVAL (operands[2]) == 255))
6746        return "inc{b}\t%0";
6747      else if (operands[2] == const1_rtx)
6748        return "dec{b}\t%0";
6749      else
6750	abort();
6751
6752    default:
6753      if (! rtx_equal_p (operands[0], operands[1]))
6754	abort ();
6755      if (INTVAL (operands[2]) < 0)
6756        {
6757          operands[2] = GEN_INT (-INTVAL (operands[2]));
6758          return "add{b}\t{%2, %0|%0, %2}";
6759        }
6760      return "sub{b}\t{%2, %0|%0, %2}";
6761    }
6762}
6763  [(set (attr "type")
6764     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6765	(const_string "incdec")
6766	(const_string "alu")))
6767   (set_attr "mode" "QI")])
6768
6769
6770(define_insn "*addqi_5"
6771  [(set (reg 17)
6772	(compare
6773	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6774		   (match_operand:QI 2 "general_operand" "qmni"))
6775	  (const_int 0)))
6776   (clobber (match_scratch:QI 0 "=q"))]
6777  "ix86_match_ccmode (insn, CCGOCmode)
6778   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6779{
6780  switch (get_attr_type (insn))
6781    {
6782    case TYPE_INCDEC:
6783      if (operands[2] == const1_rtx)
6784	return "inc{b}\t%0";
6785      else if (operands[2] == constm1_rtx
6786	       || (GET_CODE (operands[2]) == CONST_INT
6787		   && INTVAL (operands[2]) == 255))
6788	return "dec{b}\t%0";
6789      abort();
6790
6791    default:
6792      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6793      if (GET_CODE (operands[2]) == CONST_INT
6794          && INTVAL (operands[2]) < 0)
6795	{
6796	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6797	  return "sub{b}\t{%2, %0|%0, %2}";
6798	}
6799      return "add{b}\t{%2, %0|%0, %2}";
6800    }
6801}
6802  [(set (attr "type")
6803     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6804	(const_string "incdec")
6805	(const_string "alu")))
6806   (set_attr "mode" "QI")])
6807
6808
6809(define_insn "addqi_ext_1"
6810  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6811			 (const_int 8)
6812			 (const_int 8))
6813	(plus:SI
6814	  (zero_extract:SI
6815	    (match_operand 1 "ext_register_operand" "0")
6816	    (const_int 8)
6817	    (const_int 8))
6818	  (match_operand:QI 2 "general_operand" "Qmn")))
6819   (clobber (reg:CC 17))]
6820  "!TARGET_64BIT"
6821{
6822  switch (get_attr_type (insn))
6823    {
6824    case TYPE_INCDEC:
6825      if (operands[2] == const1_rtx)
6826	return "inc{b}\t%h0";
6827      else if (operands[2] == constm1_rtx
6828	       || (GET_CODE (operands[2]) == CONST_INT
6829		   && INTVAL (operands[2]) == 255))
6830	return "dec{b}\t%h0";
6831      abort();
6832
6833    default:
6834      return "add{b}\t{%2, %h0|%h0, %2}";
6835    }
6836}
6837  [(set (attr "type")
6838     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6839	(const_string "incdec")
6840	(const_string "alu")))
6841   (set_attr "mode" "QI")])
6842
6843(define_insn "*addqi_ext_1_rex64"
6844  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6845			 (const_int 8)
6846			 (const_int 8))
6847	(plus:SI
6848	  (zero_extract:SI
6849	    (match_operand 1 "ext_register_operand" "0")
6850	    (const_int 8)
6851	    (const_int 8))
6852	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6853   (clobber (reg:CC 17))]
6854  "TARGET_64BIT"
6855{
6856  switch (get_attr_type (insn))
6857    {
6858    case TYPE_INCDEC:
6859      if (operands[2] == const1_rtx)
6860	return "inc{b}\t%h0";
6861      else if (operands[2] == constm1_rtx
6862	       || (GET_CODE (operands[2]) == CONST_INT
6863		   && INTVAL (operands[2]) == 255))
6864	return "dec{b}\t%h0";
6865      abort();
6866
6867    default:
6868      return "add{b}\t{%2, %h0|%h0, %2}";
6869    }
6870}
6871  [(set (attr "type")
6872     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6873	(const_string "incdec")
6874	(const_string "alu")))
6875   (set_attr "mode" "QI")])
6876
6877(define_insn "*addqi_ext_2"
6878  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6879			 (const_int 8)
6880			 (const_int 8))
6881	(plus:SI
6882	  (zero_extract:SI
6883	    (match_operand 1 "ext_register_operand" "%0")
6884	    (const_int 8)
6885	    (const_int 8))
6886	  (zero_extract:SI
6887	    (match_operand 2 "ext_register_operand" "Q")
6888	    (const_int 8)
6889	    (const_int 8))))
6890   (clobber (reg:CC 17))]
6891  ""
6892  "add{b}\t{%h2, %h0|%h0, %h2}"
6893  [(set_attr "type" "alu")
6894   (set_attr "mode" "QI")])
6895
6896;; The patterns that match these are at the end of this file.
6897
6898(define_expand "addxf3"
6899  [(set (match_operand:XF 0 "register_operand" "")
6900	(plus:XF (match_operand:XF 1 "register_operand" "")
6901		 (match_operand:XF 2 "register_operand" "")))]
6902  "!TARGET_64BIT && TARGET_80387"
6903  "")
6904
6905(define_expand "addtf3"
6906  [(set (match_operand:TF 0 "register_operand" "")
6907	(plus:TF (match_operand:TF 1 "register_operand" "")
6908		 (match_operand:TF 2 "register_operand" "")))]
6909  "TARGET_80387"
6910  "")
6911
6912(define_expand "adddf3"
6913  [(set (match_operand:DF 0 "register_operand" "")
6914	(plus:DF (match_operand:DF 1 "register_operand" "")
6915		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6916  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6917  "")
6918
6919(define_expand "addsf3"
6920  [(set (match_operand:SF 0 "register_operand" "")
6921	(plus:SF (match_operand:SF 1 "register_operand" "")
6922		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6923  "TARGET_80387 || TARGET_SSE_MATH"
6924  "")
6925
6926;; Subtract instructions
6927
6928;; %%% splits for subsidi3
6929
6930(define_expand "subdi3"
6931  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6932		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6933			     (match_operand:DI 2 "x86_64_general_operand" "")))
6934	      (clobber (reg:CC 17))])]
6935  ""
6936  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6937
6938(define_insn "*subdi3_1"
6939  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6940	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6941		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6942   (clobber (reg:CC 17))]
6943  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6944  "#")
6945
6946(define_split
6947  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6948	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6949		  (match_operand:DI 2 "general_operand" "")))
6950   (clobber (reg:CC 17))]
6951  "!TARGET_64BIT && reload_completed"
6952  [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6953	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6954   (parallel [(set (match_dup 3)
6955		   (minus:SI (match_dup 4)
6956			     (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6957				      (match_dup 5))))
6958	      (clobber (reg:CC 17))])]
6959  "split_di (operands+0, 1, operands+0, operands+3);
6960   split_di (operands+1, 1, operands+1, operands+4);
6961   split_di (operands+2, 1, operands+2, operands+5);")
6962
6963(define_insn "subdi3_carry_rex64"
6964  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6965	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6966	    (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6967	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6968   (clobber (reg:CC 17))]
6969  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6970  "sbb{q}\t{%2, %0|%0, %2}"
6971  [(set_attr "type" "alu")
6972   (set_attr "pent_pair" "pu")
6973   (set_attr "ppro_uops" "few")
6974   (set_attr "mode" "DI")])
6975
6976(define_insn "*subdi_1_rex64"
6977  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6978	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6979		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6980   (clobber (reg:CC 17))]
6981  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6982  "sub{q}\t{%2, %0|%0, %2}"
6983  [(set_attr "type" "alu")
6984   (set_attr "mode" "DI")])
6985
6986(define_insn "*subdi_2_rex64"
6987  [(set (reg 17)
6988	(compare
6989	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6990		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6991	  (const_int 0)))
6992   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6993	(minus:DI (match_dup 1) (match_dup 2)))]
6994  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6995   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6996  "sub{q}\t{%2, %0|%0, %2}"
6997  [(set_attr "type" "alu")
6998   (set_attr "mode" "DI")])
6999
7000(define_insn "*subdi_3_rex63"
7001  [(set (reg 17)
7002	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7003		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7004   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7005	(minus:DI (match_dup 1) (match_dup 2)))]
7006  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7007   && ix86_binary_operator_ok (MINUS, SImode, operands)"
7008  "sub{q}\t{%2, %0|%0, %2}"
7009  [(set_attr "type" "alu")
7010   (set_attr "mode" "DI")])
7011
7012
7013(define_insn "subsi3_carry"
7014  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7015	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7016	    (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7017	       (match_operand:SI 2 "general_operand" "ri,rm"))))
7018   (clobber (reg:CC 17))]
7019  "ix86_binary_operator_ok (MINUS, SImode, operands)"
7020  "sbb{l}\t{%2, %0|%0, %2}"
7021  [(set_attr "type" "alu")
7022   (set_attr "pent_pair" "pu")
7023   (set_attr "ppro_uops" "few")
7024   (set_attr "mode" "SI")])
7025
7026(define_insn "subsi3_carry_zext"
7027  [(set (match_operand:DI 0 "register_operand" "=rm,r")
7028	  (zero_extend:DI
7029	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
7030	      (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7031		 (match_operand:SI 2 "general_operand" "ri,rm")))))
7032   (clobber (reg:CC 17))]
7033  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7034  "sbb{l}\t{%2, %k0|%k0, %2}"
7035  [(set_attr "type" "alu")
7036   (set_attr "pent_pair" "pu")
7037   (set_attr "ppro_uops" "few")
7038   (set_attr "mode" "SI")])
7039
7040(define_expand "subsi3"
7041  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7042		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7043			     (match_operand:SI 2 "general_operand" "")))
7044	      (clobber (reg:CC 17))])]
7045  ""
7046  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7047
7048(define_insn "*subsi_1"
7049  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7050	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7051		  (match_operand:SI 2 "general_operand" "ri,rm")))
7052   (clobber (reg:CC 17))]
7053  "ix86_binary_operator_ok (MINUS, SImode, operands)"
7054  "sub{l}\t{%2, %0|%0, %2}"
7055  [(set_attr "type" "alu")
7056   (set_attr "mode" "SI")])
7057
7058(define_insn "*subsi_1_zext"
7059  [(set (match_operand:DI 0 "register_operand" "=r")
7060	(zero_extend:DI
7061	  (minus:SI (match_operand:SI 1 "register_operand" "0")
7062		    (match_operand:SI 2 "general_operand" "rim"))))
7063   (clobber (reg:CC 17))]
7064  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7065  "sub{l}\t{%2, %k0|%k0, %2}"
7066  [(set_attr "type" "alu")
7067   (set_attr "mode" "SI")])
7068
7069(define_insn "*subsi_2"
7070  [(set (reg 17)
7071	(compare
7072	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7073		    (match_operand:SI 2 "general_operand" "ri,rm"))
7074	  (const_int 0)))
7075   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7076	(minus:SI (match_dup 1) (match_dup 2)))]
7077  "ix86_match_ccmode (insn, CCGOCmode)
7078   && ix86_binary_operator_ok (MINUS, SImode, operands)"
7079  "sub{l}\t{%2, %0|%0, %2}"
7080  [(set_attr "type" "alu")
7081   (set_attr "mode" "SI")])
7082
7083(define_insn "*subsi_2_zext"
7084  [(set (reg 17)
7085	(compare
7086	  (minus:SI (match_operand:SI 1 "register_operand" "0")
7087		    (match_operand:SI 2 "general_operand" "rim"))
7088	  (const_int 0)))
7089   (set (match_operand:DI 0 "register_operand" "=r")
7090	(zero_extend:DI
7091	  (minus:SI (match_dup 1)
7092		    (match_dup 2))))]
7093  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7094   && ix86_binary_operator_ok (MINUS, SImode, operands)"
7095  "sub{l}\t{%2, %k0|%k0, %2}"
7096  [(set_attr "type" "alu")
7097   (set_attr "mode" "SI")])
7098
7099(define_insn "*subsi_3"
7100  [(set (reg 17)
7101	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7102		 (match_operand:SI 2 "general_operand" "ri,rm")))
7103   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7104	(minus:SI (match_dup 1) (match_dup 2)))]
7105  "ix86_match_ccmode (insn, CCmode)
7106   && ix86_binary_operator_ok (MINUS, SImode, operands)"
7107  "sub{l}\t{%2, %0|%0, %2}"
7108  [(set_attr "type" "alu")
7109   (set_attr "mode" "SI")])
7110
7111(define_insn "*subsi_3_zext"
7112  [(set (reg 17)
7113	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
7114		 (match_operand:SI 2 "general_operand" "rim")))
7115   (set (match_operand:DI 0 "register_operand" "=r")
7116	(zero_extend:DI
7117	  (minus:SI (match_dup 1)
7118		    (match_dup 2))))]
7119  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7120   && ix86_binary_operator_ok (MINUS, SImode, operands)"
7121  "sub{q}\t{%2, %0|%0, %2}"
7122  [(set_attr "type" "alu")
7123   (set_attr "mode" "DI")])
7124
7125(define_expand "subhi3"
7126  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7127		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7128			     (match_operand:HI 2 "general_operand" "")))
7129	      (clobber (reg:CC 17))])]
7130  "TARGET_HIMODE_MATH"
7131  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7132
7133(define_insn "*subhi_1"
7134  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7135	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7136		  (match_operand:HI 2 "general_operand" "ri,rm")))
7137   (clobber (reg:CC 17))]
7138  "ix86_binary_operator_ok (MINUS, HImode, operands)"
7139  "sub{w}\t{%2, %0|%0, %2}"
7140  [(set_attr "type" "alu")
7141   (set_attr "mode" "HI")])
7142
7143(define_insn "*subhi_2"
7144  [(set (reg 17)
7145	(compare
7146	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7147		    (match_operand:HI 2 "general_operand" "ri,rm"))
7148	  (const_int 0)))
7149   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7150	(minus:HI (match_dup 1) (match_dup 2)))]
7151  "ix86_match_ccmode (insn, CCGOCmode)
7152   && ix86_binary_operator_ok (MINUS, HImode, operands)"
7153  "sub{w}\t{%2, %0|%0, %2}"
7154  [(set_attr "type" "alu")
7155   (set_attr "mode" "HI")])
7156
7157(define_insn "*subhi_3"
7158  [(set (reg 17)
7159	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7160		 (match_operand:HI 2 "general_operand" "ri,rm")))
7161   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7162	(minus:HI (match_dup 1) (match_dup 2)))]
7163  "ix86_match_ccmode (insn, CCmode)
7164   && ix86_binary_operator_ok (MINUS, HImode, operands)"
7165  "sub{w}\t{%2, %0|%0, %2}"
7166  [(set_attr "type" "alu")
7167   (set_attr "mode" "HI")])
7168
7169(define_expand "subqi3"
7170  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7171		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7172			     (match_operand:QI 2 "general_operand" "")))
7173	      (clobber (reg:CC 17))])]
7174  "TARGET_QIMODE_MATH"
7175  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7176
7177(define_insn "*subqi_1"
7178  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7179	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7180		  (match_operand:QI 2 "general_operand" "qn,qmn")))
7181   (clobber (reg:CC 17))]
7182  "ix86_binary_operator_ok (MINUS, QImode, operands)"
7183  "sub{b}\t{%2, %0|%0, %2}"
7184  [(set_attr "type" "alu")
7185   (set_attr "mode" "QI")])
7186
7187(define_insn "*subqi_2"
7188  [(set (reg 17)
7189	(compare
7190	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7191		    (match_operand:QI 2 "general_operand" "qi,qm"))
7192	  (const_int 0)))
7193   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7194	(minus:HI (match_dup 1) (match_dup 2)))]
7195  "ix86_match_ccmode (insn, CCGOCmode)
7196   && ix86_binary_operator_ok (MINUS, QImode, operands)"
7197  "sub{b}\t{%2, %0|%0, %2}"
7198  [(set_attr "type" "alu")
7199   (set_attr "mode" "QI")])
7200
7201(define_insn "*subqi_3"
7202  [(set (reg 17)
7203	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7204		 (match_operand:QI 2 "general_operand" "qi,qm")))
7205   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7206	(minus:HI (match_dup 1) (match_dup 2)))]
7207  "ix86_match_ccmode (insn, CCmode)
7208   && ix86_binary_operator_ok (MINUS, QImode, operands)"
7209  "sub{b}\t{%2, %0|%0, %2}"
7210  [(set_attr "type" "alu")
7211   (set_attr "mode" "QI")])
7212
7213;; The patterns that match these are at the end of this file.
7214
7215(define_expand "subxf3"
7216  [(set (match_operand:XF 0 "register_operand" "")
7217	(minus:XF (match_operand:XF 1 "register_operand" "")
7218		  (match_operand:XF 2 "register_operand" "")))]
7219  "!TARGET_64BIT && TARGET_80387"
7220  "")
7221
7222(define_expand "subtf3"
7223  [(set (match_operand:TF 0 "register_operand" "")
7224	(minus:TF (match_operand:TF 1 "register_operand" "")
7225		  (match_operand:TF 2 "register_operand" "")))]
7226  "TARGET_80387"
7227  "")
7228
7229(define_expand "subdf3"
7230  [(set (match_operand:DF 0 "register_operand" "")
7231	(minus:DF (match_operand:DF 1 "register_operand" "")
7232		  (match_operand:DF 2 "nonimmediate_operand" "")))]
7233  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7234  "")
7235
7236(define_expand "subsf3"
7237  [(set (match_operand:SF 0 "register_operand" "")
7238	(minus:SF (match_operand:SF 1 "register_operand" "")
7239		  (match_operand:SF 2 "nonimmediate_operand" "")))]
7240  "TARGET_80387 || TARGET_SSE_MATH"
7241  "")
7242
7243;; Multiply instructions
7244
7245(define_expand "muldi3"
7246  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7247		   (mult:DI (match_operand:DI 1 "register_operand" "")
7248			    (match_operand:DI 2 "x86_64_general_operand" "")))
7249	      (clobber (reg:CC 17))])]
7250  "TARGET_64BIT"
7251  "")
7252
7253(define_insn "*muldi3_1_rex64"
7254  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7255	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
7256		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7257   (clobber (reg:CC 17))]
7258  "TARGET_64BIT
7259   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7260  "@
7261   imul{q}\t{%2, %1, %0|%0, %1, %2}
7262   imul{q}\t{%2, %1, %0|%0, %1, %2}
7263   imul{q}\t{%2, %0|%0, %2}"
7264  [(set_attr "type" "imul")
7265   (set_attr "prefix_0f" "0,0,1")
7266   (set_attr "mode" "DI")])
7267
7268(define_expand "mulsi3"
7269  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7270		   (mult:SI (match_operand:SI 1 "register_operand" "")
7271			    (match_operand:SI 2 "general_operand" "")))
7272	      (clobber (reg:CC 17))])]
7273  ""
7274  "")
7275
7276(define_insn "*mulsi3_1"
7277  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7278	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7279		 (match_operand:SI 2 "general_operand" "K,i,mr")))
7280   (clobber (reg:CC 17))]
7281  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7282  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7283  ; there are two ways of writing the exact same machine instruction
7284  ; in assembly language.  One, for example, is:
7285  ;
7286  ;   imul $12, %eax
7287  ;
7288  ; while the other is:
7289  ;
7290  ;   imul $12, %eax, %eax
7291  ;
7292  ; The first is simply short-hand for the latter.  But, some assemblers,
7293  ; like the SCO OSR5 COFF assembler, don't handle the first form.
7294  "@
7295   imul{l}\t{%2, %1, %0|%0, %1, %2}
7296   imul{l}\t{%2, %1, %0|%0, %1, %2}
7297   imul{l}\t{%2, %0|%0, %2}"
7298  [(set_attr "type" "imul")
7299   (set_attr "prefix_0f" "0,0,1")
7300   (set_attr "mode" "SI")])
7301
7302(define_insn "*mulsi3_1_zext"
7303  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7304	(zero_extend:DI
7305	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7306		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
7307   (clobber (reg:CC 17))]
7308  "TARGET_64BIT
7309   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7310  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7311  ; there are two ways of writing the exact same machine instruction
7312  ; in assembly language.  One, for example, is:
7313  ;
7314  ;   imul $12, %eax
7315  ;
7316  ; while the other is:
7317  ;
7318  ;   imul $12, %eax, %eax
7319  ;
7320  ; The first is simply short-hand for the latter.  But, some assemblers,
7321  ; like the SCO OSR5 COFF assembler, don't handle the first form.
7322  "@
7323   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7324   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7325   imul{l}\t{%2, %k0|%k0, %2}"
7326  [(set_attr "type" "imul")
7327   (set_attr "prefix_0f" "0,0,1")
7328   (set_attr "mode" "SI")])
7329
7330(define_expand "mulhi3"
7331  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7332		   (mult:HI (match_operand:HI 1 "register_operand" "")
7333			    (match_operand:HI 2 "general_operand" "")))
7334	      (clobber (reg:CC 17))])]
7335  "TARGET_HIMODE_MATH"
7336  "")
7337
7338(define_insn "*mulhi3_1"
7339  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7340	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
7341		 (match_operand:HI 2 "general_operand" "K,i,mr")))
7342   (clobber (reg:CC 17))]
7343  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7344  ; %%% There was a note about "Assembler has weird restrictions",
7345  ; concerning alternative 1 when op1 == op0.  True?
7346  "@
7347   imul{w}\t{%2, %1, %0|%0, %1, %2}
7348   imul{w}\t{%2, %1, %0|%0, %1, %2}
7349   imul{w}\t{%2, %0|%0, %2}"
7350  [(set_attr "type" "imul")
7351   (set_attr "prefix_0f" "0,0,1")
7352   (set_attr "mode" "HI")])
7353
7354(define_expand "mulqi3"
7355  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7356		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7357			    (match_operand:QI 2 "register_operand" "")))
7358	      (clobber (reg:CC 17))])]
7359  "TARGET_QIMODE_MATH"
7360  "")
7361
7362(define_insn "*mulqi3_1"
7363  [(set (match_operand:QI 0 "register_operand" "=a")
7364	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7365		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7366   (clobber (reg:CC 17))]
7367  "TARGET_QIMODE_MATH
7368   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7369  "mul{b}\t%2"
7370  [(set_attr "type" "imul")
7371   (set_attr "length_immediate" "0")
7372   (set_attr "mode" "QI")])
7373
7374(define_expand "umulqihi3"
7375  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7376		   (mult:HI (zero_extend:HI
7377			      (match_operand:QI 1 "nonimmediate_operand" ""))
7378			    (zero_extend:HI
7379			      (match_operand:QI 2 "register_operand" ""))))
7380	      (clobber (reg:CC 17))])]
7381  "TARGET_QIMODE_MATH"
7382  "")
7383
7384(define_insn "*umulqihi3_1"
7385  [(set (match_operand:HI 0 "register_operand" "=a")
7386	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7387		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7388   (clobber (reg:CC 17))]
7389  "TARGET_QIMODE_MATH
7390   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7391  "mul{b}\t%2"
7392  [(set_attr "type" "imul")
7393   (set_attr "length_immediate" "0")
7394   (set_attr "mode" "QI")])
7395
7396(define_expand "mulqihi3"
7397  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7398		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7399			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7400	      (clobber (reg:CC 17))])]
7401  "TARGET_QIMODE_MATH"
7402  "")
7403
7404(define_insn "*mulqihi3_insn"
7405  [(set (match_operand:HI 0 "register_operand" "=a")
7406	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7407		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7408   (clobber (reg:CC 17))]
7409  "TARGET_QIMODE_MATH
7410   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7411  "imul{b}\t%2"
7412  [(set_attr "type" "imul")
7413   (set_attr "length_immediate" "0")
7414   (set_attr "mode" "QI")])
7415
7416(define_expand "umulditi3"
7417  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7418		   (mult:TI (zero_extend:TI
7419			      (match_operand:DI 1 "nonimmediate_operand" ""))
7420			    (zero_extend:TI
7421			      (match_operand:DI 2 "register_operand" ""))))
7422	      (clobber (reg:CC 17))])]
7423  "TARGET_64BIT"
7424  "")
7425
7426(define_insn "*umulditi3_insn"
7427  [(set (match_operand:TI 0 "register_operand" "=A")
7428	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7429		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7430   (clobber (reg:CC 17))]
7431  "TARGET_64BIT
7432   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7433  "mul{q}\t%2"
7434  [(set_attr "type" "imul")
7435   (set_attr "ppro_uops" "few")
7436   (set_attr "length_immediate" "0")
7437   (set_attr "mode" "DI")])
7438
7439;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7440(define_expand "umulsidi3"
7441  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7442		   (mult:DI (zero_extend:DI
7443			      (match_operand:SI 1 "nonimmediate_operand" ""))
7444			    (zero_extend:DI
7445			      (match_operand:SI 2 "register_operand" ""))))
7446	      (clobber (reg:CC 17))])]
7447  "!TARGET_64BIT"
7448  "")
7449
7450(define_insn "*umulsidi3_insn"
7451  [(set (match_operand:DI 0 "register_operand" "=A")
7452	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7453		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7454   (clobber (reg:CC 17))]
7455  "!TARGET_64BIT
7456   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7457  "mul{l}\t%2"
7458  [(set_attr "type" "imul")
7459   (set_attr "ppro_uops" "few")
7460   (set_attr "length_immediate" "0")
7461   (set_attr "mode" "SI")])
7462
7463(define_expand "mulditi3"
7464  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7465		   (mult:TI (sign_extend:TI
7466			      (match_operand:DI 1 "nonimmediate_operand" ""))
7467			    (sign_extend:TI
7468			      (match_operand:DI 2 "register_operand" ""))))
7469	      (clobber (reg:CC 17))])]
7470  "TARGET_64BIT"
7471  "")
7472
7473(define_insn "*mulditi3_insn"
7474  [(set (match_operand:TI 0 "register_operand" "=A")
7475	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7476		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7477   (clobber (reg:CC 17))]
7478  "TARGET_64BIT
7479   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7480  "imul{q}\t%2"
7481  [(set_attr "type" "imul")
7482   (set_attr "length_immediate" "0")
7483   (set_attr "mode" "DI")])
7484
7485(define_expand "mulsidi3"
7486  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7487		   (mult:DI (sign_extend:DI
7488			      (match_operand:SI 1 "nonimmediate_operand" ""))
7489			    (sign_extend:DI
7490			      (match_operand:SI 2 "register_operand" ""))))
7491	      (clobber (reg:CC 17))])]
7492  "!TARGET_64BIT"
7493  "")
7494
7495(define_insn "*mulsidi3_insn"
7496  [(set (match_operand:DI 0 "register_operand" "=A")
7497	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7498		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7499   (clobber (reg:CC 17))]
7500  "!TARGET_64BIT
7501   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7502  "imul{l}\t%2"
7503  [(set_attr "type" "imul")
7504   (set_attr "length_immediate" "0")
7505   (set_attr "mode" "SI")])
7506
7507(define_expand "umuldi3_highpart"
7508  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7509		   (truncate:DI
7510		     (lshiftrt:TI
7511		       (mult:TI (zero_extend:TI
7512				  (match_operand:DI 1 "nonimmediate_operand" ""))
7513				(zero_extend:TI
7514				  (match_operand:DI 2 "register_operand" "")))
7515		       (const_int 64))))
7516	      (clobber (match_scratch:DI 3 ""))
7517	      (clobber (reg:CC 17))])]
7518  "TARGET_64BIT"
7519  "")
7520
7521(define_insn "*umuldi3_highpart_rex64"
7522  [(set (match_operand:DI 0 "register_operand" "=d")
7523	(truncate:DI
7524	  (lshiftrt:TI
7525	    (mult:TI (zero_extend:TI
7526		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7527		     (zero_extend:TI
7528		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7529	    (const_int 64))))
7530   (clobber (match_scratch:DI 3 "=1"))
7531   (clobber (reg:CC 17))]
7532  "TARGET_64BIT
7533   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7534  "mul{q}\t%2"
7535  [(set_attr "type" "imul")
7536   (set_attr "ppro_uops" "few")
7537   (set_attr "length_immediate" "0")
7538   (set_attr "mode" "DI")])
7539
7540(define_expand "umulsi3_highpart"
7541  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7542		   (truncate:SI
7543		     (lshiftrt:DI
7544		       (mult:DI (zero_extend:DI
7545				  (match_operand:SI 1 "nonimmediate_operand" ""))
7546				(zero_extend:DI
7547				  (match_operand:SI 2 "register_operand" "")))
7548		       (const_int 32))))
7549	      (clobber (match_scratch:SI 3 ""))
7550	      (clobber (reg:CC 17))])]
7551  ""
7552  "")
7553
7554(define_insn "*umulsi3_highpart_insn"
7555  [(set (match_operand:SI 0 "register_operand" "=d")
7556	(truncate:SI
7557	  (lshiftrt:DI
7558	    (mult:DI (zero_extend:DI
7559		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7560		     (zero_extend:DI
7561		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7562	    (const_int 32))))
7563   (clobber (match_scratch:SI 3 "=1"))
7564   (clobber (reg:CC 17))]
7565  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7566  "mul{l}\t%2"
7567  [(set_attr "type" "imul")
7568   (set_attr "ppro_uops" "few")
7569   (set_attr "length_immediate" "0")
7570   (set_attr "mode" "SI")])
7571
7572(define_insn "*umulsi3_highpart_zext"
7573  [(set (match_operand:DI 0 "register_operand" "=d")
7574	(zero_extend:DI (truncate:SI
7575	  (lshiftrt:DI
7576	    (mult:DI (zero_extend:DI
7577		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7578		     (zero_extend:DI
7579		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7580	    (const_int 32)))))
7581   (clobber (match_scratch:SI 3 "=1"))
7582   (clobber (reg:CC 17))]
7583  "TARGET_64BIT
7584   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7585  "mul{l}\t%2"
7586  [(set_attr "type" "imul")
7587   (set_attr "ppro_uops" "few")
7588   (set_attr "length_immediate" "0")
7589   (set_attr "mode" "SI")])
7590
7591(define_expand "smuldi3_highpart"
7592  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7593		   (truncate:DI
7594		     (lshiftrt:TI
7595		       (mult:TI (sign_extend:TI
7596				  (match_operand:DI 1 "nonimmediate_operand" ""))
7597				(sign_extend:TI
7598				  (match_operand:DI 2 "register_operand" "")))
7599		       (const_int 64))))
7600	      (clobber (match_scratch:DI 3 ""))
7601	      (clobber (reg:CC 17))])]
7602  "TARGET_64BIT"
7603  "")
7604
7605(define_insn "*smuldi3_highpart_rex64"
7606  [(set (match_operand:DI 0 "register_operand" "=d")
7607	(truncate:DI
7608	  (lshiftrt:TI
7609	    (mult:TI (sign_extend:TI
7610		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7611		     (sign_extend:TI
7612		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7613	    (const_int 64))))
7614   (clobber (match_scratch:DI 3 "=1"))
7615   (clobber (reg:CC 17))]
7616  "TARGET_64BIT
7617   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7618  "imul{q}\t%2"
7619  [(set_attr "type" "imul")
7620   (set_attr "ppro_uops" "few")
7621   (set_attr "mode" "DI")])
7622
7623(define_expand "smulsi3_highpart"
7624  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7625		   (truncate:SI
7626		     (lshiftrt:DI
7627		       (mult:DI (sign_extend:DI
7628				  (match_operand:SI 1 "nonimmediate_operand" ""))
7629				(sign_extend:DI
7630				  (match_operand:SI 2 "register_operand" "")))
7631		       (const_int 32))))
7632	      (clobber (match_scratch:SI 3 ""))
7633	      (clobber (reg:CC 17))])]
7634  ""
7635  "")
7636
7637(define_insn "*smulsi3_highpart_insn"
7638  [(set (match_operand:SI 0 "register_operand" "=d")
7639	(truncate:SI
7640	  (lshiftrt:DI
7641	    (mult:DI (sign_extend:DI
7642		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7643		     (sign_extend:DI
7644		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7645	    (const_int 32))))
7646   (clobber (match_scratch:SI 3 "=1"))
7647   (clobber (reg:CC 17))]
7648  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7649  "imul{l}\t%2"
7650  [(set_attr "type" "imul")
7651   (set_attr "ppro_uops" "few")
7652   (set_attr "mode" "SI")])
7653
7654(define_insn "*smulsi3_highpart_zext"
7655  [(set (match_operand:DI 0 "register_operand" "=d")
7656	(zero_extend:DI (truncate:SI
7657	  (lshiftrt:DI
7658	    (mult:DI (sign_extend:DI
7659		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7660		     (sign_extend:DI
7661		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7662	    (const_int 32)))))
7663   (clobber (match_scratch:SI 3 "=1"))
7664   (clobber (reg:CC 17))]
7665  "TARGET_64BIT
7666   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7667  "imul{l}\t%2"
7668  [(set_attr "type" "imul")
7669   (set_attr "ppro_uops" "few")
7670   (set_attr "mode" "SI")])
7671
7672;; The patterns that match these are at the end of this file.
7673
7674(define_expand "mulxf3"
7675  [(set (match_operand:XF 0 "register_operand" "")
7676	(mult:XF (match_operand:XF 1 "register_operand" "")
7677		 (match_operand:XF 2 "register_operand" "")))]
7678  "!TARGET_64BIT && TARGET_80387"
7679  "")
7680
7681(define_expand "multf3"
7682  [(set (match_operand:TF 0 "register_operand" "")
7683	(mult:TF (match_operand:TF 1 "register_operand" "")
7684		 (match_operand:TF 2 "register_operand" "")))]
7685  "TARGET_80387"
7686  "")
7687
7688(define_expand "muldf3"
7689  [(set (match_operand:DF 0 "register_operand" "")
7690	(mult:DF (match_operand:DF 1 "register_operand" "")
7691		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7692  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7693  "")
7694
7695(define_expand "mulsf3"
7696  [(set (match_operand:SF 0 "register_operand" "")
7697	(mult:SF (match_operand:SF 1 "register_operand" "")
7698		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7699  "TARGET_80387 || TARGET_SSE_MATH"
7700  "")
7701
7702;; Divide instructions
7703
7704(define_insn "divqi3"
7705  [(set (match_operand:QI 0 "register_operand" "=a")
7706	(div:QI (match_operand:HI 1 "register_operand" "0")
7707		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7708   (clobber (reg:CC 17))]
7709  "TARGET_QIMODE_MATH"
7710  "idiv{b}\t%2"
7711  [(set_attr "type" "idiv")
7712   (set_attr "mode" "QI")
7713   (set_attr "ppro_uops" "few")])
7714
7715(define_insn "udivqi3"
7716  [(set (match_operand:QI 0 "register_operand" "=a")
7717	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7718		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7719   (clobber (reg:CC 17))]
7720  "TARGET_QIMODE_MATH"
7721  "div{b}\t%2"
7722  [(set_attr "type" "idiv")
7723   (set_attr "mode" "QI")
7724   (set_attr "ppro_uops" "few")])
7725
7726;; The patterns that match these are at the end of this file.
7727
7728(define_expand "divxf3"
7729  [(set (match_operand:XF 0 "register_operand" "")
7730	(div:XF (match_operand:XF 1 "register_operand" "")
7731		(match_operand:XF 2 "register_operand" "")))]
7732  "!TARGET_64BIT && TARGET_80387"
7733  "")
7734
7735(define_expand "divtf3"
7736  [(set (match_operand:TF 0 "register_operand" "")
7737	(div:TF (match_operand:TF 1 "register_operand" "")
7738		(match_operand:TF 2 "register_operand" "")))]
7739  "TARGET_80387"
7740  "")
7741
7742(define_expand "divdf3"
7743  [(set (match_operand:DF 0 "register_operand" "")
7744 	(div:DF (match_operand:DF 1 "register_operand" "")
7745 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7746   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7747   "")
7748 
7749(define_expand "divsf3"
7750  [(set (match_operand:SF 0 "register_operand" "")
7751	(div:SF (match_operand:SF 1 "register_operand" "")
7752		(match_operand:SF 2 "nonimmediate_operand" "")))]
7753  "TARGET_80387 || TARGET_SSE_MATH"
7754  "")
7755
7756;; Remainder instructions.
7757
7758(define_expand "divmoddi4"
7759  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7760		   (div:DI (match_operand:DI 1 "register_operand" "")
7761			   (match_operand:DI 2 "nonimmediate_operand" "")))
7762	      (set (match_operand:DI 3 "register_operand" "")
7763		   (mod:DI (match_dup 1) (match_dup 2)))
7764	      (clobber (reg:CC 17))])]
7765  "TARGET_64BIT"
7766  "")
7767
7768;; Allow to come the parameter in eax or edx to avoid extra moves.
7769;; Penalize eax case sligthly because it results in worse scheduling
7770;; of code.
7771(define_insn "*divmoddi4_nocltd_rex64"
7772  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7773	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7774		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7775   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7776	(mod:DI (match_dup 2) (match_dup 3)))
7777   (clobber (reg:CC 17))]
7778  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7779  "#"
7780  [(set_attr "type" "multi")])
7781
7782(define_insn "*divmoddi4_cltd_rex64"
7783  [(set (match_operand:DI 0 "register_operand" "=a")
7784	(div:DI (match_operand:DI 2 "register_operand" "a")
7785		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7786   (set (match_operand:DI 1 "register_operand" "=&d")
7787	(mod:DI (match_dup 2) (match_dup 3)))
7788   (clobber (reg:CC 17))]
7789  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7790  "#"
7791  [(set_attr "type" "multi")])
7792
7793(define_insn "*divmoddi_noext_rex64"
7794  [(set (match_operand:DI 0 "register_operand" "=a")
7795	(div:DI (match_operand:DI 1 "register_operand" "0")
7796		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7797   (set (match_operand:DI 3 "register_operand" "=d")
7798	(mod:DI (match_dup 1) (match_dup 2)))
7799   (use (match_operand:DI 4 "register_operand" "3"))
7800   (clobber (reg:CC 17))]
7801  "TARGET_64BIT"
7802  "idiv{q}\t%2"
7803  [(set_attr "type" "idiv")
7804   (set_attr "mode" "DI")
7805   (set_attr "ppro_uops" "few")])
7806
7807(define_split
7808  [(set (match_operand:DI 0 "register_operand" "")
7809	(div:DI (match_operand:DI 1 "register_operand" "")
7810		(match_operand:DI 2 "nonimmediate_operand" "")))
7811   (set (match_operand:DI 3 "register_operand" "")
7812	(mod:DI (match_dup 1) (match_dup 2)))
7813   (clobber (reg:CC 17))]
7814  "TARGET_64BIT && reload_completed"
7815  [(parallel [(set (match_dup 3)
7816		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7817	      (clobber (reg:CC 17))])
7818   (parallel [(set (match_dup 0)
7819	           (div:DI (reg:DI 0) (match_dup 2)))
7820	      (set (match_dup 3)
7821		   (mod:DI (reg:DI 0) (match_dup 2)))
7822	      (use (match_dup 3))
7823	      (clobber (reg:CC 17))])]
7824{
7825  /* Avoid use of cltd in favour of a mov+shift.  */
7826  if (!TARGET_USE_CLTD && !optimize_size)
7827    {
7828      if (true_regnum (operands[1]))
7829        emit_move_insn (operands[0], operands[1]);
7830      else
7831	emit_move_insn (operands[3], operands[1]);
7832      operands[4] = operands[3];
7833    }
7834  else
7835    {
7836      if (true_regnum (operands[1]))
7837	abort();
7838      operands[4] = operands[1];
7839    }
7840})
7841
7842
7843(define_expand "divmodsi4"
7844  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7845		   (div:SI (match_operand:SI 1 "register_operand" "")
7846			   (match_operand:SI 2 "nonimmediate_operand" "")))
7847	      (set (match_operand:SI 3 "register_operand" "")
7848		   (mod:SI (match_dup 1) (match_dup 2)))
7849	      (clobber (reg:CC 17))])]
7850  ""
7851  "")
7852
7853;; Allow to come the parameter in eax or edx to avoid extra moves.
7854;; Penalize eax case sligthly because it results in worse scheduling
7855;; of code.
7856(define_insn "*divmodsi4_nocltd"
7857  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7858	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7859		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7860   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7861	(mod:SI (match_dup 2) (match_dup 3)))
7862   (clobber (reg:CC 17))]
7863  "!optimize_size && !TARGET_USE_CLTD"
7864  "#"
7865  [(set_attr "type" "multi")])
7866
7867(define_insn "*divmodsi4_cltd"
7868  [(set (match_operand:SI 0 "register_operand" "=a")
7869	(div:SI (match_operand:SI 2 "register_operand" "a")
7870		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7871   (set (match_operand:SI 1 "register_operand" "=&d")
7872	(mod:SI (match_dup 2) (match_dup 3)))
7873   (clobber (reg:CC 17))]
7874  "optimize_size || TARGET_USE_CLTD"
7875  "#"
7876  [(set_attr "type" "multi")])
7877
7878(define_insn "*divmodsi_noext"
7879  [(set (match_operand:SI 0 "register_operand" "=a")
7880	(div:SI (match_operand:SI 1 "register_operand" "0")
7881		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7882   (set (match_operand:SI 3 "register_operand" "=d")
7883	(mod:SI (match_dup 1) (match_dup 2)))
7884   (use (match_operand:SI 4 "register_operand" "3"))
7885   (clobber (reg:CC 17))]
7886  ""
7887  "idiv{l}\t%2"
7888  [(set_attr "type" "idiv")
7889   (set_attr "mode" "SI")
7890   (set_attr "ppro_uops" "few")])
7891
7892(define_split
7893  [(set (match_operand:SI 0 "register_operand" "")
7894	(div:SI (match_operand:SI 1 "register_operand" "")
7895		(match_operand:SI 2 "nonimmediate_operand" "")))
7896   (set (match_operand:SI 3 "register_operand" "")
7897	(mod:SI (match_dup 1) (match_dup 2)))
7898   (clobber (reg:CC 17))]
7899  "reload_completed"
7900  [(parallel [(set (match_dup 3)
7901		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7902	      (clobber (reg:CC 17))])
7903   (parallel [(set (match_dup 0)
7904	           (div:SI (reg:SI 0) (match_dup 2)))
7905	      (set (match_dup 3)
7906		   (mod:SI (reg:SI 0) (match_dup 2)))
7907	      (use (match_dup 3))
7908	      (clobber (reg:CC 17))])]
7909{
7910  /* Avoid use of cltd in favour of a mov+shift.  */
7911  if (!TARGET_USE_CLTD && !optimize_size)
7912    {
7913      if (true_regnum (operands[1]))
7914        emit_move_insn (operands[0], operands[1]);
7915      else
7916	emit_move_insn (operands[3], operands[1]);
7917      operands[4] = operands[3];
7918    }
7919  else
7920    {
7921      if (true_regnum (operands[1]))
7922	abort();
7923      operands[4] = operands[1];
7924    }
7925})
7926;; %%% Split me.
7927(define_insn "divmodhi4"
7928  [(set (match_operand:HI 0 "register_operand" "=a")
7929	(div:HI (match_operand:HI 1 "register_operand" "0")
7930		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7931   (set (match_operand:HI 3 "register_operand" "=&d")
7932	(mod:HI (match_dup 1) (match_dup 2)))
7933   (clobber (reg:CC 17))]
7934  "TARGET_HIMODE_MATH"
7935  "cwtd\;idiv{w}\t%2"
7936  [(set_attr "type" "multi")
7937   (set_attr "length_immediate" "0")
7938   (set_attr "mode" "SI")])
7939
7940(define_insn "udivmoddi4"
7941  [(set (match_operand:DI 0 "register_operand" "=a")
7942	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7943		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7944   (set (match_operand:DI 3 "register_operand" "=&d")
7945	(umod:DI (match_dup 1) (match_dup 2)))
7946   (clobber (reg:CC 17))]
7947  "TARGET_64BIT"
7948  "xor{q}\t%3, %3\;div{q}\t%2"
7949  [(set_attr "type" "multi")
7950   (set_attr "length_immediate" "0")
7951   (set_attr "mode" "DI")])
7952
7953(define_insn "*udivmoddi4_noext"
7954  [(set (match_operand:DI 0 "register_operand" "=a")
7955	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7956		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7957   (set (match_operand:DI 3 "register_operand" "=d")
7958	(umod:DI (match_dup 1) (match_dup 2)))
7959   (use (match_dup 3))
7960   (clobber (reg:CC 17))]
7961  "TARGET_64BIT"
7962  "div{q}\t%2"
7963  [(set_attr "type" "idiv")
7964   (set_attr "ppro_uops" "few")
7965   (set_attr "mode" "DI")])
7966
7967(define_split
7968  [(set (match_operand:DI 0 "register_operand" "")
7969	(udiv:DI (match_operand:DI 1 "register_operand" "")
7970		 (match_operand:DI 2 "nonimmediate_operand" "")))
7971   (set (match_operand:DI 3 "register_operand" "")
7972	(umod:DI (match_dup 1) (match_dup 2)))
7973   (clobber (reg:CC 17))]
7974  "TARGET_64BIT && reload_completed"
7975  [(set (match_dup 3) (const_int 0))
7976   (parallel [(set (match_dup 0)
7977		   (udiv:DI (match_dup 1) (match_dup 2)))
7978	      (set (match_dup 3)
7979		   (umod:DI (match_dup 1) (match_dup 2)))
7980	      (use (match_dup 3))
7981	      (clobber (reg:CC 17))])]
7982  "")
7983
7984(define_insn "udivmodsi4"
7985  [(set (match_operand:SI 0 "register_operand" "=a")
7986	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7987		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7988   (set (match_operand:SI 3 "register_operand" "=&d")
7989	(umod:SI (match_dup 1) (match_dup 2)))
7990   (clobber (reg:CC 17))]
7991  ""
7992  "xor{l}\t%3, %3\;div{l}\t%2"
7993  [(set_attr "type" "multi")
7994   (set_attr "length_immediate" "0")
7995   (set_attr "mode" "SI")])
7996
7997(define_insn "*udivmodsi4_noext"
7998  [(set (match_operand:SI 0 "register_operand" "=a")
7999	(udiv:SI (match_operand:SI 1 "register_operand" "0")
8000		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8001   (set (match_operand:SI 3 "register_operand" "=d")
8002	(umod:SI (match_dup 1) (match_dup 2)))
8003   (use (match_dup 3))
8004   (clobber (reg:CC 17))]
8005  ""
8006  "div{l}\t%2"
8007  [(set_attr "type" "idiv")
8008   (set_attr "ppro_uops" "few")
8009   (set_attr "mode" "SI")])
8010
8011(define_split
8012  [(set (match_operand:SI 0 "register_operand" "")
8013	(udiv:SI (match_operand:SI 1 "register_operand" "")
8014		 (match_operand:SI 2 "nonimmediate_operand" "")))
8015   (set (match_operand:SI 3 "register_operand" "")
8016	(umod:SI (match_dup 1) (match_dup 2)))
8017   (clobber (reg:CC 17))]
8018  "reload_completed"
8019  [(set (match_dup 3) (const_int 0))
8020   (parallel [(set (match_dup 0)
8021		   (udiv:SI (match_dup 1) (match_dup 2)))
8022	      (set (match_dup 3)
8023		   (umod:SI (match_dup 1) (match_dup 2)))
8024	      (use (match_dup 3))
8025	      (clobber (reg:CC 17))])]
8026  "")
8027
8028(define_expand "udivmodhi4"
8029  [(set (match_dup 4) (const_int 0))
8030   (parallel [(set (match_operand:HI 0 "register_operand" "")
8031		   (udiv:HI (match_operand:HI 1 "register_operand" "")
8032		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
8033	      (set (match_operand:HI 3 "register_operand" "")
8034	   	   (umod:HI (match_dup 1) (match_dup 2)))
8035	      (use (match_dup 4))
8036	      (clobber (reg:CC 17))])]
8037  "TARGET_HIMODE_MATH"
8038  "operands[4] = gen_reg_rtx (HImode);")
8039
8040(define_insn "*udivmodhi_noext"
8041  [(set (match_operand:HI 0 "register_operand" "=a")
8042	(udiv:HI (match_operand:HI 1 "register_operand" "0")
8043		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8044   (set (match_operand:HI 3 "register_operand" "=d")
8045	(umod:HI (match_dup 1) (match_dup 2)))
8046   (use (match_operand:HI 4 "register_operand" "3"))
8047   (clobber (reg:CC 17))]
8048  ""
8049  "div{w}\t%2"
8050  [(set_attr "type" "idiv")
8051   (set_attr "mode" "HI")
8052   (set_attr "ppro_uops" "few")])
8053
8054;; We can not use div/idiv for double division, because it causes
8055;; "division by zero" on the overflow and that's not what we expect
8056;; from truncate.  Because true (non truncating) double division is
8057;; never generated, we can't create this insn anyway.
8058;
8059;(define_insn ""
8060;  [(set (match_operand:SI 0 "register_operand" "=a")
8061;	(truncate:SI
8062;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
8063;		   (zero_extend:DI
8064;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8065;   (set (match_operand:SI 3 "register_operand" "=d")
8066;	(truncate:SI
8067;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8068;   (clobber (reg:CC 17))]
8069;  ""
8070;  "div{l}\t{%2, %0|%0, %2}"
8071;  [(set_attr "type" "idiv")
8072;   (set_attr "ppro_uops" "few")])
8073
8074;;- Logical AND instructions
8075
8076;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8077;; Note that this excludes ah.
8078
8079(define_insn "*testdi_1_rex64"
8080  [(set (reg 17)
8081	(compare
8082	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
8083		  (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
8084	  (const_int 0)))]
8085  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8086  "@
8087   test{l}\t{%k1, %k0|%k0, %k1} 
8088   test{l}\t{%k1, %k0|%k0, %k1} 
8089   test{q}\t{%1, %0|%0, %1} 
8090   test{q}\t{%1, %0|%0, %1} 
8091   test{q}\t{%1, %0|%0, %1}"
8092  [(set_attr "type" "test")
8093   (set_attr "modrm" "0,1,0,1,1")
8094   (set_attr "mode" "SI,SI,DI,DI,DI")
8095   (set_attr "pent_pair" "uv,np,uv,np,uv")])
8096
8097(define_insn "testsi_1"
8098  [(set (reg 17)
8099	(compare
8100	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
8101		  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
8102	  (const_int 0)))]
8103  "ix86_match_ccmode (insn, CCNOmode)"
8104  "test{l}\t{%1, %0|%0, %1}"
8105  [(set_attr "type" "test")
8106   (set_attr "modrm" "0,1,1")
8107   (set_attr "mode" "SI")
8108   (set_attr "pent_pair" "uv,np,uv")])
8109
8110(define_expand "testsi_ccno_1"
8111  [(set (reg:CCNO 17)
8112	(compare:CCNO
8113	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8114		  (match_operand:SI 1 "nonmemory_operand" ""))
8115	  (const_int 0)))]
8116  ""
8117  "")
8118
8119(define_insn "*testhi_1"
8120  [(set (reg 17)
8121        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
8122			 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
8123		 (const_int 0)))]
8124  "ix86_match_ccmode (insn, CCNOmode)"
8125  "test{w}\t{%1, %0|%0, %1}"
8126  [(set_attr "type" "test")
8127   (set_attr "modrm" "0,1,1")
8128   (set_attr "mode" "HI")
8129   (set_attr "pent_pair" "uv,np,uv")])
8130
8131(define_expand "testqi_ccz_1"
8132  [(set (reg:CCZ 17)
8133        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8134			     (match_operand:QI 1 "nonmemory_operand" ""))
8135		 (const_int 0)))]
8136  ""
8137  "")
8138
8139(define_insn "*testqi_1"
8140  [(set (reg 17)
8141        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
8142			 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
8143		 (const_int 0)))]
8144  "ix86_match_ccmode (insn, CCNOmode)"
8145{
8146  if (which_alternative == 3)
8147    {
8148      if (GET_CODE (operands[1]) == CONST_INT
8149	  && (INTVAL (operands[1]) & 0xffffff00))
8150	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8151      return "test{l}\t{%1, %k0|%k0, %1}";
8152    }
8153  return "test{b}\t{%1, %0|%0, %1}";
8154}
8155  [(set_attr "type" "test")
8156   (set_attr "modrm" "0,1,1,1")
8157   (set_attr "mode" "QI,QI,QI,SI")
8158   (set_attr "pent_pair" "uv,np,uv,np")])
8159
8160(define_expand "testqi_ext_ccno_0"
8161  [(set (reg:CCNO 17)
8162	(compare:CCNO
8163	  (and:SI
8164	    (zero_extract:SI
8165	      (match_operand 0 "ext_register_operand" "")
8166	      (const_int 8)
8167	      (const_int 8))
8168	    (match_operand 1 "const_int_operand" ""))
8169	  (const_int 0)))]
8170  ""
8171  "")
8172
8173(define_insn "*testqi_ext_0"
8174  [(set (reg 17)
8175	(compare
8176	  (and:SI
8177	    (zero_extract:SI
8178	      (match_operand 0 "ext_register_operand" "Q")
8179	      (const_int 8)
8180	      (const_int 8))
8181	    (match_operand 1 "const_int_operand" "n"))
8182	  (const_int 0)))]
8183  "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
8184   && ix86_match_ccmode (insn, CCNOmode)"
8185  "test{b}\t{%1, %h0|%h0, %1}"
8186  [(set_attr "type" "test")
8187   (set_attr "mode" "QI")
8188   (set_attr "length_immediate" "1")
8189   (set_attr "pent_pair" "np")])
8190
8191(define_insn "*testqi_ext_1"
8192  [(set (reg 17)
8193	(compare
8194	  (and:SI
8195	    (zero_extract:SI
8196	      (match_operand 0 "ext_register_operand" "Q")
8197	      (const_int 8)
8198	      (const_int 8))
8199	    (zero_extend:SI
8200	      (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8201	  (const_int 0)))]
8202  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8203  "test{b}\t{%1, %h0|%h0, %1}"
8204  [(set_attr "type" "test")
8205   (set_attr "mode" "QI")])
8206
8207(define_insn "*testqi_ext_1_rex64"
8208  [(set (reg 17)
8209	(compare
8210	  (and:SI
8211	    (zero_extract:SI
8212	      (match_operand 0 "ext_register_operand" "Q")
8213	      (const_int 8)
8214	      (const_int 8))
8215	    (zero_extend:SI
8216	      (match_operand:QI 1 "register_operand" "Q")))
8217	  (const_int 0)))]
8218  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8219  "test{b}\t{%1, %h0|%h0, %1}"
8220  [(set_attr "type" "test")
8221   (set_attr "mode" "QI")])
8222
8223(define_insn "*testqi_ext_2"
8224  [(set (reg 17)
8225	(compare
8226	  (and:SI
8227	    (zero_extract:SI
8228	      (match_operand 0 "ext_register_operand" "Q")
8229	      (const_int 8)
8230	      (const_int 8))
8231	    (zero_extract:SI
8232	      (match_operand 1 "ext_register_operand" "Q")
8233	      (const_int 8)
8234	      (const_int 8)))
8235	  (const_int 0)))]
8236  "ix86_match_ccmode (insn, CCNOmode)"
8237  "test{b}\t{%h1, %h0|%h0, %h1}"
8238  [(set_attr "type" "test")
8239   (set_attr "mode" "QI")])
8240
8241;; Combine likes to form bit extractions for some tests.  Humor it.
8242(define_insn "*testqi_ext_3"
8243  [(set (reg 17)
8244        (compare (zero_extract:SI
8245		   (match_operand 0 "nonimmediate_operand" "rm")
8246		   (match_operand:SI 1 "const_int_operand" "")
8247		   (match_operand:SI 2 "const_int_operand" ""))
8248		 (const_int 0)))]
8249  "ix86_match_ccmode (insn, CCNOmode)
8250   && (GET_MODE (operands[0]) == SImode
8251       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8252       || GET_MODE (operands[0]) == HImode
8253       || GET_MODE (operands[0]) == QImode)"
8254  "#")
8255
8256(define_insn "*testqi_ext_3_rex64"
8257  [(set (reg 17)
8258        (compare (zero_extract:DI
8259		   (match_operand 0 "nonimmediate_operand" "rm")
8260		   (match_operand:DI 1 "const_int_operand" "")
8261		   (match_operand:DI 2 "const_int_operand" ""))
8262		 (const_int 0)))]
8263  "TARGET_64BIT
8264   && ix86_match_ccmode (insn, CCNOmode)
8265   /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8266   && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8267   /* Ensure that resulting mask is zero or sign extended operand.  */
8268   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8269       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8270	   && INTVAL (operands[1]) > 32))
8271   && (GET_MODE (operands[0]) == SImode
8272       || GET_MODE (operands[0]) == DImode
8273       || GET_MODE (operands[0]) == HImode
8274       || GET_MODE (operands[0]) == QImode)"
8275  "#")
8276
8277(define_split
8278  [(set (reg 17)
8279        (compare (zero_extract
8280		   (match_operand 0 "nonimmediate_operand" "")
8281		   (match_operand 1 "const_int_operand" "")
8282		   (match_operand 2 "const_int_operand" ""))
8283		 (const_int 0)))]
8284  "ix86_match_ccmode (insn, CCNOmode)"
8285  [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8286{
8287  HOST_WIDE_INT len = INTVAL (operands[1]);
8288  HOST_WIDE_INT pos = INTVAL (operands[2]);
8289  HOST_WIDE_INT mask;
8290  enum machine_mode mode, submode;
8291
8292  mode = GET_MODE (operands[0]);
8293  if (GET_CODE (operands[0]) == MEM)
8294    {
8295      /* ??? Combine likes to put non-volatile mem extractions in QImode
8296	 no matter the size of the test.  So find a mode that works.  */
8297      if (! MEM_VOLATILE_P (operands[0]))
8298	{
8299	  mode = smallest_mode_for_size (pos + len, MODE_INT);
8300	  operands[0] = adjust_address (operands[0], mode, 0);
8301	}
8302    }
8303  else if (GET_CODE (operands[0]) == SUBREG
8304	   && (submode = GET_MODE (SUBREG_REG (operands[0])),
8305	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8306	   && pos + len <= GET_MODE_BITSIZE (submode))
8307    {
8308      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8309      mode = submode;
8310      operands[0] = SUBREG_REG (operands[0]);
8311    }
8312  else if (mode == HImode && pos + len <= 8)
8313    {
8314      /* Small HImode tests can be converted to QImode.  */
8315      mode = QImode;
8316      operands[0] = gen_lowpart (QImode, operands[0]);
8317    }
8318
8319  mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8320  mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8321
8322  operands[3] = gen_rtx_AND (mode, operands[0],
8323			     GEN_INT (trunc_int_for_mode (mask, mode)));
8324})
8325
8326;; %%% This used to optimize known byte-wide and operations to memory,
8327;; and sometimes to QImode registers.  If this is considered useful,
8328;; it should be done with splitters.
8329
8330(define_expand "anddi3"
8331  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8332	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8333		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8334   (clobber (reg:CC 17))]
8335  "TARGET_64BIT"
8336  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8337
8338(define_insn "*anddi_1_rex64"
8339  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8340	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8341		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8342   (clobber (reg:CC 17))]
8343  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8344{
8345  switch (get_attr_type (insn))
8346    {
8347    case TYPE_IMOVX:
8348      {
8349	enum machine_mode mode;
8350
8351	if (GET_CODE (operands[2]) != CONST_INT)
8352	  abort ();
8353        if (INTVAL (operands[2]) == 0xff)
8354	  mode = QImode;
8355	else if (INTVAL (operands[2]) == 0xffff)
8356	  mode = HImode;
8357	else
8358	  abort ();
8359	
8360	operands[1] = gen_lowpart (mode, operands[1]);
8361	if (mode == QImode)
8362	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8363	else
8364	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8365      }
8366
8367    default:
8368      if (! rtx_equal_p (operands[0], operands[1]))
8369	abort ();
8370      if (get_attr_mode (insn) == MODE_SI)
8371	return "and{l}\t{%k2, %k0|%k0, %k2}";
8372      else
8373	return "and{q}\t{%2, %0|%0, %2}";
8374    }
8375}
8376  [(set_attr "type" "alu,alu,alu,imovx")
8377   (set_attr "length_immediate" "*,*,*,0")
8378   (set_attr "mode" "SI,DI,DI,DI")])
8379
8380(define_insn "*anddi_2"
8381  [(set (reg 17)
8382	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8383			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8384		 (const_int 0)))
8385   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8386	(and:DI (match_dup 1) (match_dup 2)))]
8387  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8388   && ix86_binary_operator_ok (AND, DImode, operands)"
8389  "@
8390   and{l}\t{%k2, %k0|%k0, %k2} 
8391   and{q}\t{%2, %0|%0, %2} 
8392   and{q}\t{%2, %0|%0, %2}"
8393  [(set_attr "type" "alu")
8394   (set_attr "mode" "SI,DI,DI")])
8395
8396(define_expand "andsi3"
8397  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8398	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8399		(match_operand:SI 2 "general_operand" "")))
8400   (clobber (reg:CC 17))]
8401  ""
8402  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8403
8404(define_insn "*andsi_1"
8405  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8406	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8407		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8408   (clobber (reg:CC 17))]
8409  "ix86_binary_operator_ok (AND, SImode, operands)"
8410{
8411  switch (get_attr_type (insn))
8412    {
8413    case TYPE_IMOVX:
8414      {
8415	enum machine_mode mode;
8416
8417	if (GET_CODE (operands[2]) != CONST_INT)
8418	  abort ();
8419        if (INTVAL (operands[2]) == 0xff)
8420	  mode = QImode;
8421	else if (INTVAL (operands[2]) == 0xffff)
8422	  mode = HImode;
8423	else
8424	  abort ();
8425	
8426	operands[1] = gen_lowpart (mode, operands[1]);
8427	if (mode == QImode)
8428	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8429	else
8430	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8431      }
8432
8433    default:
8434      if (! rtx_equal_p (operands[0], operands[1]))
8435	abort ();
8436      return "and{l}\t{%2, %0|%0, %2}";
8437    }
8438}
8439  [(set_attr "type" "alu,alu,imovx")
8440   (set_attr "length_immediate" "*,*,0")
8441   (set_attr "mode" "SI")])
8442
8443(define_split
8444  [(set (match_operand 0 "register_operand" "")
8445	(and (match_dup 0)
8446	     (const_int -65536)))
8447   (clobber (reg:CC 17))]
8448  "optimize_size"
8449  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8450  "operands[1] = gen_lowpart (HImode, operands[0]);")
8451
8452(define_split
8453  [(set (match_operand 0 "ext_register_operand" "")
8454	(and (match_dup 0)
8455	     (const_int -256)))
8456   (clobber (reg:CC 17))]
8457  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8458  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8459  "operands[1] = gen_lowpart (QImode, operands[0]);")
8460
8461(define_split
8462  [(set (match_operand 0 "ext_register_operand" "")
8463	(and (match_dup 0)
8464	     (const_int -65281)))
8465   (clobber (reg:CC 17))]
8466  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8467  [(parallel [(set (zero_extract:SI (match_dup 0)
8468				    (const_int 8)
8469				    (const_int 8))
8470		   (xor:SI 
8471		     (zero_extract:SI (match_dup 0)
8472				      (const_int 8)
8473				      (const_int 8))
8474		     (zero_extract:SI (match_dup 0)
8475				      (const_int 8)
8476				      (const_int 8))))
8477	      (clobber (reg:CC 17))])]
8478  "operands[0] = gen_lowpart (SImode, operands[0]);")
8479
8480;; See comment for addsi_1_zext why we do use nonimmediate_operand
8481(define_insn "*andsi_1_zext"
8482  [(set (match_operand:DI 0 "register_operand" "=r")
8483	(zero_extend:DI
8484	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8485		  (match_operand:SI 2 "general_operand" "rim"))))
8486   (clobber (reg:CC 17))]
8487  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8488  "and{l}\t{%2, %k0|%k0, %2}"
8489  [(set_attr "type" "alu")
8490   (set_attr "mode" "SI")])
8491
8492(define_insn "*andsi_2"
8493  [(set (reg 17)
8494	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8495			 (match_operand:SI 2 "general_operand" "rim,ri"))
8496		 (const_int 0)))
8497   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8498	(and:SI (match_dup 1) (match_dup 2)))]
8499  "ix86_match_ccmode (insn, CCNOmode)
8500   && ix86_binary_operator_ok (AND, SImode, operands)"
8501  "and{l}\t{%2, %0|%0, %2}"
8502  [(set_attr "type" "alu")
8503   (set_attr "mode" "SI")])
8504
8505;; See comment for addsi_1_zext why we do use nonimmediate_operand
8506(define_insn "*andsi_2_zext"
8507  [(set (reg 17)
8508	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8509			 (match_operand:SI 2 "general_operand" "rim"))
8510		 (const_int 0)))
8511   (set (match_operand:DI 0 "register_operand" "=r")
8512	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8513  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8514   && ix86_binary_operator_ok (AND, SImode, operands)"
8515  "and{l}\t{%2, %k0|%k0, %2}"
8516  [(set_attr "type" "alu")
8517   (set_attr "mode" "SI")])
8518
8519(define_expand "andhi3"
8520  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8521	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8522		(match_operand:HI 2 "general_operand" "")))
8523   (clobber (reg:CC 17))]
8524  "TARGET_HIMODE_MATH"
8525  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8526
8527(define_insn "*andhi_1"
8528  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8529	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8530		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8531   (clobber (reg:CC 17))]
8532  "ix86_binary_operator_ok (AND, HImode, operands)"
8533{
8534  switch (get_attr_type (insn))
8535    {
8536    case TYPE_IMOVX:
8537      if (GET_CODE (operands[2]) != CONST_INT)
8538	abort ();
8539      if (INTVAL (operands[2]) == 0xff)
8540	return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8541      abort ();
8542
8543    default:
8544      if (! rtx_equal_p (operands[0], operands[1]))
8545	abort ();
8546
8547      return "and{w}\t{%2, %0|%0, %2}";
8548    }
8549}
8550  [(set_attr "type" "alu,alu,imovx")
8551   (set_attr "length_immediate" "*,*,0")
8552   (set_attr "mode" "HI,HI,SI")])
8553
8554(define_insn "*andhi_2"
8555  [(set (reg 17)
8556	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8557			 (match_operand:HI 2 "general_operand" "rim,ri"))
8558		 (const_int 0)))
8559   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8560	(and:HI (match_dup 1) (match_dup 2)))]
8561  "ix86_match_ccmode (insn, CCNOmode)
8562   && ix86_binary_operator_ok (AND, HImode, operands)"
8563  "and{w}\t{%2, %0|%0, %2}"
8564  [(set_attr "type" "alu")
8565   (set_attr "mode" "HI")])
8566
8567(define_expand "andqi3"
8568  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8569	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8570		(match_operand:QI 2 "general_operand" "")))
8571   (clobber (reg:CC 17))]
8572  "TARGET_QIMODE_MATH"
8573  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8574
8575;; %%% Potential partial reg stall on alternative 2.  What to do?
8576(define_insn "*andqi_1"
8577  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8578	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8579		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8580   (clobber (reg:CC 17))]
8581  "ix86_binary_operator_ok (AND, QImode, operands)"
8582  "@
8583   and{b}\t{%2, %0|%0, %2}
8584   and{b}\t{%2, %0|%0, %2}
8585   and{l}\t{%k2, %k0|%k0, %k2}"
8586  [(set_attr "type" "alu")
8587   (set_attr "mode" "QI,QI,SI")])
8588
8589(define_insn "*andqi_1_slp"
8590  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8591	(and:QI (match_dup 0)
8592		(match_operand:QI 1 "general_operand" "qi,qmi")))
8593   (clobber (reg:CC 17))]
8594  ""
8595  "and{b}\t{%1, %0|%0, %1}"
8596  [(set_attr "type" "alu1")
8597   (set_attr "mode" "QI")])
8598
8599(define_insn "*andqi_2"
8600  [(set (reg 17)
8601	(compare (and:QI
8602		   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8603		   (match_operand:QI 2 "general_operand" "qim,qi,i"))
8604		 (const_int 0)))
8605   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8606	(and:QI (match_dup 1) (match_dup 2)))]
8607  "ix86_match_ccmode (insn, CCNOmode)
8608   && ix86_binary_operator_ok (AND, QImode, operands)"
8609{
8610  if (which_alternative == 2)
8611    {
8612      if (GET_CODE (operands[2]) == CONST_INT
8613          && (INTVAL (operands[2]) & 0xffffff00))
8614        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8615      return "and{l}\t{%2, %k0|%k0, %2}";
8616    }
8617  return "and{b}\t{%2, %0|%0, %2}";
8618}
8619  [(set_attr "type" "alu")
8620   (set_attr "mode" "QI,QI,SI")])
8621
8622(define_insn "*andqi_2_slp"
8623  [(set (reg 17)
8624	(compare (and:QI
8625		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8626		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8627		 (const_int 0)))
8628   (set (strict_low_part (match_dup 0))
8629	(and:QI (match_dup 0) (match_dup 1)))]
8630  "ix86_match_ccmode (insn, CCNOmode)"
8631  "and{b}\t{%1, %0|%0, %1}"
8632  [(set_attr "type" "alu1")
8633   (set_attr "mode" "QI")])
8634
8635;; ??? A bug in recog prevents it from recognizing a const_int as an
8636;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8637;; for a QImode operand, which of course failed.
8638
8639(define_insn "andqi_ext_0"
8640  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8641			 (const_int 8)
8642			 (const_int 8))
8643	(and:SI 
8644	  (zero_extract:SI
8645	    (match_operand 1 "ext_register_operand" "0")
8646	    (const_int 8)
8647	    (const_int 8))
8648	  (match_operand 2 "const_int_operand" "n")))
8649   (clobber (reg:CC 17))]
8650  "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8651  "and{b}\t{%2, %h0|%h0, %2}"
8652  [(set_attr "type" "alu")
8653   (set_attr "length_immediate" "1")
8654   (set_attr "mode" "QI")])
8655
8656;; Generated by peephole translating test to and.  This shows up
8657;; often in fp comparisons.
8658
8659(define_insn "*andqi_ext_0_cc"
8660  [(set (reg 17)
8661	(compare
8662	  (and:SI
8663	    (zero_extract:SI
8664	      (match_operand 1 "ext_register_operand" "0")
8665	      (const_int 8)
8666	      (const_int 8))
8667	    (match_operand 2 "const_int_operand" "n"))
8668	  (const_int 0)))
8669   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8670			 (const_int 8)
8671			 (const_int 8))
8672	(and:SI 
8673	  (zero_extract:SI
8674	    (match_dup 1)
8675	    (const_int 8)
8676	    (const_int 8))
8677	  (match_dup 2)))]
8678  "ix86_match_ccmode (insn, CCNOmode)
8679   && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8680  "and{b}\t{%2, %h0|%h0, %2}"
8681  [(set_attr "type" "alu")
8682   (set_attr "length_immediate" "1")
8683   (set_attr "mode" "QI")])
8684
8685(define_insn "*andqi_ext_1"
8686  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8687			 (const_int 8)
8688			 (const_int 8))
8689	(and:SI 
8690	  (zero_extract:SI
8691	    (match_operand 1 "ext_register_operand" "0")
8692	    (const_int 8)
8693	    (const_int 8))
8694	  (zero_extend:SI
8695	    (match_operand:QI 2 "general_operand" "Qm"))))
8696   (clobber (reg:CC 17))]
8697  "!TARGET_64BIT"
8698  "and{b}\t{%2, %h0|%h0, %2}"
8699  [(set_attr "type" "alu")
8700   (set_attr "length_immediate" "0")
8701   (set_attr "mode" "QI")])
8702
8703(define_insn "*andqi_ext_1_rex64"
8704  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8705			 (const_int 8)
8706			 (const_int 8))
8707	(and:SI 
8708	  (zero_extract:SI
8709	    (match_operand 1 "ext_register_operand" "0")
8710	    (const_int 8)
8711	    (const_int 8))
8712	  (zero_extend:SI
8713	    (match_operand 2 "ext_register_operand" "Q"))))
8714   (clobber (reg:CC 17))]
8715  "TARGET_64BIT"
8716  "and{b}\t{%2, %h0|%h0, %2}"
8717  [(set_attr "type" "alu")
8718   (set_attr "length_immediate" "0")
8719   (set_attr "mode" "QI")])
8720
8721(define_insn "*andqi_ext_2"
8722  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8723			 (const_int 8)
8724			 (const_int 8))
8725	(and:SI
8726	  (zero_extract:SI
8727	    (match_operand 1 "ext_register_operand" "%0")
8728	    (const_int 8)
8729	    (const_int 8))
8730	  (zero_extract:SI
8731	    (match_operand 2 "ext_register_operand" "Q")
8732	    (const_int 8)
8733	    (const_int 8))))
8734   (clobber (reg:CC 17))]
8735  ""
8736  "and{b}\t{%h2, %h0|%h0, %h2}"
8737  [(set_attr "type" "alu")
8738   (set_attr "length_immediate" "0")
8739   (set_attr "mode" "QI")])
8740
8741;; Logical inclusive OR instructions
8742
8743;; %%% This used to optimize known byte-wide and operations to memory.
8744;; If this is considered useful, it should be done with splitters.
8745
8746(define_expand "iordi3"
8747  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8748	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8749		(match_operand:DI 2 "x86_64_general_operand" "")))
8750   (clobber (reg:CC 17))]
8751  "TARGET_64BIT"
8752  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8753
8754(define_insn "*iordi_1_rex64"
8755  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8756	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8757		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8758   (clobber (reg:CC 17))]
8759  "TARGET_64BIT
8760   && ix86_binary_operator_ok (IOR, DImode, operands)"
8761  "or{q}\t{%2, %0|%0, %2}"
8762  [(set_attr "type" "alu")
8763   (set_attr "mode" "DI")])
8764
8765(define_insn "*iordi_2_rex64"
8766  [(set (reg 17)
8767	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8768			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8769		 (const_int 0)))
8770   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8771	(ior:DI (match_dup 1) (match_dup 2)))]
8772  "TARGET_64BIT
8773   && ix86_match_ccmode (insn, CCNOmode)
8774   && ix86_binary_operator_ok (IOR, DImode, operands)"
8775  "or{q}\t{%2, %0|%0, %2}"
8776  [(set_attr "type" "alu")
8777   (set_attr "mode" "DI")])
8778
8779(define_insn "*iordi_3_rex64"
8780  [(set (reg 17)
8781	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8782			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8783		 (const_int 0)))
8784   (clobber (match_scratch:DI 0 "=r"))]
8785  "TARGET_64BIT
8786   && ix86_match_ccmode (insn, CCNOmode)
8787   && ix86_binary_operator_ok (IOR, DImode, operands)"
8788  "or{q}\t{%2, %0|%0, %2}"
8789  [(set_attr "type" "alu")
8790   (set_attr "mode" "DI")])
8791
8792
8793(define_expand "iorsi3"
8794  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8795	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8796		(match_operand:SI 2 "general_operand" "")))
8797   (clobber (reg:CC 17))]
8798  ""
8799  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8800
8801(define_insn "*iorsi_1"
8802  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8803	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8804		(match_operand:SI 2 "general_operand" "ri,rmi")))
8805   (clobber (reg:CC 17))]
8806  "ix86_binary_operator_ok (IOR, SImode, operands)"
8807  "or{l}\t{%2, %0|%0, %2}"
8808  [(set_attr "type" "alu")
8809   (set_attr "mode" "SI")])
8810
8811;; See comment for addsi_1_zext why we do use nonimmediate_operand
8812(define_insn "*iorsi_1_zext"
8813  [(set (match_operand:DI 0 "register_operand" "=rm")
8814	(zero_extend:DI
8815	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8816		  (match_operand:SI 2 "general_operand" "rim"))))
8817   (clobber (reg:CC 17))]
8818  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8819  "or{l}\t{%2, %k0|%k0, %2}"
8820  [(set_attr "type" "alu")
8821   (set_attr "mode" "SI")])
8822
8823(define_insn "*iorsi_1_zext_imm"
8824  [(set (match_operand:DI 0 "register_operand" "=rm")
8825	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8826		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8827   (clobber (reg:CC 17))]
8828  "TARGET_64BIT"
8829  "or{l}\t{%2, %k0|%k0, %2}"
8830  [(set_attr "type" "alu")
8831   (set_attr "mode" "SI")])
8832
8833(define_insn "*iorsi_2"
8834  [(set (reg 17)
8835	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8836			 (match_operand:SI 2 "general_operand" "rim,ri"))
8837		 (const_int 0)))
8838   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8839	(ior:SI (match_dup 1) (match_dup 2)))]
8840  "ix86_match_ccmode (insn, CCNOmode)
8841   && ix86_binary_operator_ok (IOR, SImode, operands)"
8842  "or{l}\t{%2, %0|%0, %2}"
8843  [(set_attr "type" "alu")
8844   (set_attr "mode" "SI")])
8845
8846;; See comment for addsi_1_zext why we do use nonimmediate_operand
8847;; ??? Special case for immediate operand is missing - it is tricky.
8848(define_insn "*iorsi_2_zext"
8849  [(set (reg 17)
8850	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8851			 (match_operand:SI 2 "general_operand" "rim"))
8852		 (const_int 0)))
8853   (set (match_operand:DI 0 "register_operand" "=r")
8854	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8855  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8856   && ix86_binary_operator_ok (IOR, SImode, operands)"
8857  "or{l}\t{%2, %k0|%k0, %2}"
8858  [(set_attr "type" "alu")
8859   (set_attr "mode" "SI")])
8860
8861(define_insn "*iorsi_2_zext_imm"
8862  [(set (reg 17)
8863	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8864			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8865		 (const_int 0)))
8866   (set (match_operand:DI 0 "register_operand" "=r")
8867	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8868  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8869   && ix86_binary_operator_ok (IOR, SImode, operands)"
8870  "or{l}\t{%2, %k0|%k0, %2}"
8871  [(set_attr "type" "alu")
8872   (set_attr "mode" "SI")])
8873
8874(define_insn "*iorsi_3"
8875  [(set (reg 17)
8876	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8877			 (match_operand:SI 2 "general_operand" "rim"))
8878		 (const_int 0)))
8879   (clobber (match_scratch:SI 0 "=r"))]
8880  "ix86_match_ccmode (insn, CCNOmode)
8881   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8882  "or{l}\t{%2, %0|%0, %2}"
8883  [(set_attr "type" "alu")
8884   (set_attr "mode" "SI")])
8885
8886(define_expand "iorhi3"
8887  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8888	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8889		(match_operand:HI 2 "general_operand" "")))
8890   (clobber (reg:CC 17))]
8891  "TARGET_HIMODE_MATH"
8892  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8893
8894(define_insn "*iorhi_1"
8895  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8896	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8897		(match_operand:HI 2 "general_operand" "rmi,ri")))
8898   (clobber (reg:CC 17))]
8899  "ix86_binary_operator_ok (IOR, HImode, operands)"
8900  "or{w}\t{%2, %0|%0, %2}"
8901  [(set_attr "type" "alu")
8902   (set_attr "mode" "HI")])
8903
8904(define_insn "*iorhi_2"
8905  [(set (reg 17)
8906	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8907			 (match_operand:HI 2 "general_operand" "rim,ri"))
8908		 (const_int 0)))
8909   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8910	(ior:HI (match_dup 1) (match_dup 2)))]
8911  "ix86_match_ccmode (insn, CCNOmode)
8912   && ix86_binary_operator_ok (IOR, HImode, operands)"
8913  "or{w}\t{%2, %0|%0, %2}"
8914  [(set_attr "type" "alu")
8915   (set_attr "mode" "HI")])
8916
8917(define_insn "*iorhi_3"
8918  [(set (reg 17)
8919	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8920			 (match_operand:HI 2 "general_operand" "rim"))
8921		 (const_int 0)))
8922   (clobber (match_scratch:HI 0 "=r"))]
8923  "ix86_match_ccmode (insn, CCNOmode)
8924   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8925  "or{w}\t{%2, %0|%0, %2}"
8926  [(set_attr "type" "alu")
8927   (set_attr "mode" "HI")])
8928
8929(define_expand "iorqi3"
8930  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8931	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8932		(match_operand:QI 2 "general_operand" "")))
8933   (clobber (reg:CC 17))]
8934  "TARGET_QIMODE_MATH"
8935  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8936
8937;; %%% Potential partial reg stall on alternative 2.  What to do?
8938(define_insn "*iorqi_1"
8939  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8940	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8941		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8942   (clobber (reg:CC 17))]
8943  "ix86_binary_operator_ok (IOR, QImode, operands)"
8944  "@
8945   or{b}\t{%2, %0|%0, %2}
8946   or{b}\t{%2, %0|%0, %2}
8947   or{l}\t{%k2, %k0|%k0, %k2}"
8948  [(set_attr "type" "alu")
8949   (set_attr "mode" "QI,QI,SI")])
8950
8951(define_insn "*iorqi_1_slp"
8952  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8953	(ior:QI (match_dup 0)
8954		(match_operand:QI 1 "general_operand" "qmi,qi")))
8955   (clobber (reg:CC 17))]
8956  ""
8957  "or{b}\t{%1, %0|%0, %1}"
8958  [(set_attr "type" "alu1")
8959   (set_attr "mode" "QI")])
8960
8961(define_insn "*iorqi_2"
8962  [(set (reg 17)
8963	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8964			 (match_operand:QI 2 "general_operand" "qim,qi"))
8965		 (const_int 0)))
8966   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8967	(ior:QI (match_dup 1) (match_dup 2)))]
8968  "ix86_match_ccmode (insn, CCNOmode)
8969   && ix86_binary_operator_ok (IOR, QImode, operands)"
8970  "or{b}\t{%2, %0|%0, %2}"
8971  [(set_attr "type" "alu")
8972   (set_attr "mode" "QI")])
8973
8974(define_insn "*iorqi_2_slp"
8975  [(set (reg 17)
8976	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8977			 (match_operand:QI 1 "general_operand" "qim,qi"))
8978		 (const_int 0)))
8979   (set (strict_low_part (match_dup 0))
8980	(ior:QI (match_dup 0) (match_dup 1)))]
8981  "ix86_match_ccmode (insn, CCNOmode)"
8982  "or{b}\t{%1, %0|%0, %1}"
8983  [(set_attr "type" "alu1")
8984   (set_attr "mode" "QI")])
8985
8986(define_insn "*iorqi_3"
8987  [(set (reg 17)
8988	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8989			 (match_operand:QI 2 "general_operand" "qim"))
8990		 (const_int 0)))
8991   (clobber (match_scratch:QI 0 "=q"))]
8992  "ix86_match_ccmode (insn, CCNOmode)
8993   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8994  "or{b}\t{%2, %0|%0, %2}"
8995  [(set_attr "type" "alu")
8996   (set_attr "mode" "QI")])
8997
8998
8999;; Logical XOR instructions
9000
9001;; %%% This used to optimize known byte-wide and operations to memory.
9002;; If this is considered useful, it should be done with splitters.
9003
9004(define_expand "xordi3"
9005  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9006	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9007		(match_operand:DI 2 "x86_64_general_operand" "")))
9008   (clobber (reg:CC 17))]
9009  "TARGET_64BIT"
9010  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9011
9012(define_insn "*xordi_1_rex64"
9013  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9014	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9015		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9016   (clobber (reg:CC 17))]
9017  "TARGET_64BIT
9018   && ix86_binary_operator_ok (XOR, DImode, operands)"
9019  "@
9020   xor{q}\t{%2, %0|%0, %2} 
9021   xor{q}\t{%2, %0|%0, %2}"
9022  [(set_attr "type" "alu")
9023   (set_attr "mode" "DI,DI")])
9024
9025(define_insn "*xordi_2_rex64"
9026  [(set (reg 17)
9027	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9028			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9029		 (const_int 0)))
9030   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9031	(xor:DI (match_dup 1) (match_dup 2)))]
9032  "TARGET_64BIT
9033   && ix86_match_ccmode (insn, CCNOmode)
9034   && ix86_binary_operator_ok (XOR, DImode, operands)"
9035  "@
9036   xor{q}\t{%2, %0|%0, %2} 
9037   xor{q}\t{%2, %0|%0, %2}"
9038  [(set_attr "type" "alu")
9039   (set_attr "mode" "DI,DI")])
9040
9041(define_insn "*xordi_3_rex64"
9042  [(set (reg 17)
9043	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9044			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9045		 (const_int 0)))
9046   (clobber (match_scratch:DI 0 "=r"))]
9047  "TARGET_64BIT
9048   && ix86_match_ccmode (insn, CCNOmode)
9049   && ix86_binary_operator_ok (XOR, DImode, operands)"
9050  "xor{q}\t{%2, %0|%0, %2}"
9051  [(set_attr "type" "alu")
9052   (set_attr "mode" "DI")])
9053
9054(define_expand "xorsi3"
9055  [(set (match_operand:SI 0 "nonimmediate_operand" "")
9056	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9057		(match_operand:SI 2 "general_operand" "")))
9058   (clobber (reg:CC 17))]
9059  ""
9060  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9061
9062(define_insn "*xorsi_1"
9063  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9064	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9065		(match_operand:SI 2 "general_operand" "ri,rm")))
9066   (clobber (reg:CC 17))]
9067  "ix86_binary_operator_ok (XOR, SImode, operands)"
9068  "xor{l}\t{%2, %0|%0, %2}"
9069  [(set_attr "type" "alu")
9070   (set_attr "mode" "SI")])
9071
9072;; See comment for addsi_1_zext why we do use nonimmediate_operand
9073;; Add speccase for immediates
9074(define_insn "*xorsi_1_zext"
9075  [(set (match_operand:DI 0 "register_operand" "=r")
9076	(zero_extend:DI
9077	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9078		  (match_operand:SI 2 "general_operand" "rim"))))
9079   (clobber (reg:CC 17))]
9080  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9081  "xor{l}\t{%2, %k0|%k0, %2}"
9082  [(set_attr "type" "alu")
9083   (set_attr "mode" "SI")])
9084
9085(define_insn "*xorsi_1_zext_imm"
9086  [(set (match_operand:DI 0 "register_operand" "=r")
9087	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9088		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9089   (clobber (reg:CC 17))]
9090  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9091  "xor{l}\t{%2, %k0|%k0, %2}"
9092  [(set_attr "type" "alu")
9093   (set_attr "mode" "SI")])
9094
9095(define_insn "*xorsi_2"
9096  [(set (reg 17)
9097	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9098			 (match_operand:SI 2 "general_operand" "rim,ri"))
9099		 (const_int 0)))
9100   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9101	(xor:SI (match_dup 1) (match_dup 2)))]
9102  "ix86_match_ccmode (insn, CCNOmode)
9103   && ix86_binary_operator_ok (XOR, SImode, operands)"
9104  "xor{l}\t{%2, %0|%0, %2}"
9105  [(set_attr "type" "alu")
9106   (set_attr "mode" "SI")])
9107
9108;; See comment for addsi_1_zext why we do use nonimmediate_operand
9109;; ??? Special case for immediate operand is missing - it is tricky.
9110(define_insn "*xorsi_2_zext"
9111  [(set (reg 17)
9112	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9113			 (match_operand:SI 2 "general_operand" "rim"))
9114		 (const_int 0)))
9115   (set (match_operand:DI 0 "register_operand" "=r")
9116	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9117  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9118   && ix86_binary_operator_ok (XOR, SImode, operands)"
9119  "xor{l}\t{%2, %k0|%k0, %2}"
9120  [(set_attr "type" "alu")
9121   (set_attr "mode" "SI")])
9122
9123(define_insn "*xorsi_2_zext_imm"
9124  [(set (reg 17)
9125	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9126			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9127		 (const_int 0)))
9128   (set (match_operand:DI 0 "register_operand" "=r")
9129	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9130  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9131   && ix86_binary_operator_ok (XOR, SImode, operands)"
9132  "xor{l}\t{%2, %k0|%k0, %2}"
9133  [(set_attr "type" "alu")
9134   (set_attr "mode" "SI")])
9135
9136(define_insn "*xorsi_3"
9137  [(set (reg 17)
9138	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9139			 (match_operand:SI 2 "general_operand" "rim"))
9140		 (const_int 0)))
9141   (clobber (match_scratch:SI 0 "=r"))]
9142  "ix86_match_ccmode (insn, CCNOmode)
9143   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9144  "xor{l}\t{%2, %0|%0, %2}"
9145  [(set_attr "type" "alu")
9146   (set_attr "mode" "SI")])
9147
9148(define_expand "xorhi3"
9149  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9150	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9151		(match_operand:HI 2 "general_operand" "")))
9152   (clobber (reg:CC 17))]
9153  "TARGET_HIMODE_MATH"
9154  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9155
9156(define_insn "*xorhi_1"
9157  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9158	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9159		(match_operand:HI 2 "general_operand" "rmi,ri")))
9160   (clobber (reg:CC 17))]
9161  "ix86_binary_operator_ok (XOR, HImode, operands)"
9162  "xor{w}\t{%2, %0|%0, %2}"
9163  [(set_attr "type" "alu")
9164   (set_attr "mode" "HI")])
9165
9166(define_insn "*xorhi_2"
9167  [(set (reg 17)
9168	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9169			 (match_operand:HI 2 "general_operand" "rim,ri"))
9170		 (const_int 0)))
9171   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9172	(xor:HI (match_dup 1) (match_dup 2)))]
9173  "ix86_match_ccmode (insn, CCNOmode)
9174   && ix86_binary_operator_ok (XOR, HImode, operands)"
9175  "xor{w}\t{%2, %0|%0, %2}"
9176  [(set_attr "type" "alu")
9177   (set_attr "mode" "HI")])
9178
9179(define_insn "*xorhi_3"
9180  [(set (reg 17)
9181	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9182			 (match_operand:HI 2 "general_operand" "rim"))
9183		 (const_int 0)))
9184   (clobber (match_scratch:HI 0 "=r"))]
9185  "ix86_match_ccmode (insn, CCNOmode)
9186   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9187  "xor{w}\t{%2, %0|%0, %2}"
9188  [(set_attr "type" "alu")
9189   (set_attr "mode" "HI")])
9190
9191(define_expand "xorqi3"
9192  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9193	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9194		(match_operand:QI 2 "general_operand" "")))
9195   (clobber (reg:CC 17))]
9196  "TARGET_QIMODE_MATH"
9197  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9198
9199;; %%% Potential partial reg stall on alternative 2.  What to do?
9200(define_insn "*xorqi_1"
9201  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9202	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9203		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9204   (clobber (reg:CC 17))]
9205  "ix86_binary_operator_ok (XOR, QImode, operands)"
9206  "@
9207   xor{b}\t{%2, %0|%0, %2}
9208   xor{b}\t{%2, %0|%0, %2}
9209   xor{l}\t{%k2, %k0|%k0, %k2}"
9210  [(set_attr "type" "alu")
9211   (set_attr "mode" "QI,QI,SI")])
9212
9213(define_insn "*xorqi_ext_1"
9214  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9215			 (const_int 8)
9216			 (const_int 8))
9217	(xor:SI 
9218	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9219	  		   (const_int 8)
9220			   (const_int 8))
9221	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9222	  		   (const_int 8)
9223			   (const_int 8))))
9224   (clobber (reg:CC 17))]
9225  ""
9226  "xor{b}\t{%h2, %h0|%h0, %h2}"
9227  [(set_attr "type" "alu")
9228   (set_attr "length_immediate" "0")
9229   (set_attr "mode" "QI")])
9230
9231(define_insn "*xorqi_cc_1"
9232  [(set (reg 17)
9233	(compare
9234	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9235		  (match_operand:QI 2 "general_operand" "qim,qi"))
9236	  (const_int 0)))
9237   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9238	(xor:QI (match_dup 1) (match_dup 2)))]
9239  "ix86_match_ccmode (insn, CCNOmode)
9240   && ix86_binary_operator_ok (XOR, QImode, operands)"
9241  "xor{b}\t{%2, %0|%0, %2}"
9242  [(set_attr "type" "alu")
9243   (set_attr "mode" "QI")])
9244
9245(define_insn "*xorqi_cc_2"
9246  [(set (reg 17)
9247	(compare
9248	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9249		  (match_operand:QI 2 "general_operand" "qim"))
9250	  (const_int 0)))
9251   (clobber (match_scratch:QI 0 "=q"))]
9252  "ix86_match_ccmode (insn, CCNOmode)
9253   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9254  "xor{b}\t{%2, %0|%0, %2}"
9255  [(set_attr "type" "alu")
9256   (set_attr "mode" "QI")])
9257
9258(define_insn "*xorqi_cc_ext_1"
9259  [(set (reg 17)
9260	(compare
9261	  (xor:SI
9262	    (zero_extract:SI
9263	      (match_operand 1 "ext_register_operand" "0")
9264	      (const_int 8)
9265	      (const_int 8))
9266	    (match_operand:QI 2 "general_operand" "qmn"))
9267	  (const_int 0)))
9268   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9269			 (const_int 8)
9270			 (const_int 8))
9271	(xor:SI 
9272	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9273	  (match_dup 2)))]
9274  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9275  "xor{b}\t{%2, %h0|%h0, %2}"
9276  [(set_attr "type" "alu")
9277   (set_attr "mode" "QI")])
9278
9279(define_insn "*xorqi_cc_ext_1_rex64"
9280  [(set (reg 17)
9281	(compare
9282	  (xor:SI
9283	    (zero_extract:SI
9284	      (match_operand 1 "ext_register_operand" "0")
9285	      (const_int 8)
9286	      (const_int 8))
9287	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9288	  (const_int 0)))
9289   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9290			 (const_int 8)
9291			 (const_int 8))
9292	(xor:SI 
9293	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9294	  (match_dup 2)))]
9295  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9296  "xor{b}\t{%2, %h0|%h0, %2}"
9297  [(set_attr "type" "alu")
9298   (set_attr "mode" "QI")])
9299
9300(define_expand "xorqi_cc_ext_1"
9301  [(parallel [
9302     (set (reg:CCNO 17)
9303	  (compare:CCNO
9304	    (xor:SI
9305	      (zero_extract:SI
9306		(match_operand 1 "ext_register_operand" "")
9307		(const_int 8)
9308		(const_int 8))
9309	      (match_operand:QI 2 "general_operand" ""))
9310	    (const_int 0)))
9311     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9312			   (const_int 8)
9313			   (const_int 8))
9314	  (xor:SI 
9315	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9316	    (match_dup 2)))])]
9317  ""
9318  "")
9319
9320;; Negation instructions
9321
9322(define_expand "negdi2"
9323  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9325	      (clobber (reg:CC 17))])]
9326  ""
9327  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9328
9329(define_insn "*negdi2_1"
9330  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9331	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9332   (clobber (reg:CC 17))]
9333  "!TARGET_64BIT
9334   && ix86_unary_operator_ok (NEG, DImode, operands)"
9335  "#")
9336
9337(define_split
9338  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9339	(neg:DI (match_operand:DI 1 "general_operand" "")))
9340   (clobber (reg:CC 17))]
9341  "!TARGET_64BIT && reload_completed"
9342  [(parallel
9343    [(set (reg:CCZ 17)
9344	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9345     (set (match_dup 0) (neg:SI (match_dup 2)))])
9346   (parallel
9347    [(set (match_dup 1)
9348	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9349			    (match_dup 3))
9350		   (const_int 0)))
9351     (clobber (reg:CC 17))])
9352   (parallel
9353    [(set (match_dup 1)
9354	  (neg:SI (match_dup 1)))
9355     (clobber (reg:CC 17))])]
9356  "split_di (operands+1, 1, operands+2, operands+3);
9357   split_di (operands+0, 1, operands+0, operands+1);")
9358
9359(define_insn "*negdi2_1_rex64"
9360  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9361	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9362   (clobber (reg:CC 17))]
9363  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9364  "neg{q}\t%0"
9365  [(set_attr "type" "negnot")
9366   (set_attr "mode" "DI")])
9367
9368;; The problem with neg is that it does not perform (compare x 0),
9369;; it really performs (compare 0 x), which leaves us with the zero
9370;; flag being the only useful item.
9371
9372(define_insn "*negdi2_cmpz_rex64"
9373  [(set (reg:CCZ 17)
9374	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9375		     (const_int 0)))
9376   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377	(neg:DI (match_dup 1)))]
9378  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9379  "neg{q}\t%0"
9380  [(set_attr "type" "negnot")
9381   (set_attr "mode" "DI")])
9382
9383
9384(define_expand "negsi2"
9385  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9387	      (clobber (reg:CC 17))])]
9388  ""
9389  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9390
9391(define_insn "*negsi2_1"
9392  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9393	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9394   (clobber (reg:CC 17))]
9395  "ix86_unary_operator_ok (NEG, SImode, operands)"
9396  "neg{l}\t%0"
9397  [(set_attr "type" "negnot")
9398   (set_attr "mode" "SI")])
9399
9400;; Combine is quite creative about this pattern.
9401(define_insn "*negsi2_1_zext"
9402  [(set (match_operand:DI 0 "register_operand" "=r")
9403	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9404					(const_int 32)))
9405		     (const_int 32)))
9406   (clobber (reg:CC 17))]
9407  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9408  "neg{l}\t%k0"
9409  [(set_attr "type" "negnot")
9410   (set_attr "mode" "SI")])
9411
9412;; The problem with neg is that it does not perform (compare x 0),
9413;; it really performs (compare 0 x), which leaves us with the zero
9414;; flag being the only useful item.
9415
9416(define_insn "*negsi2_cmpz"
9417  [(set (reg:CCZ 17)
9418	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9419		     (const_int 0)))
9420   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9421	(neg:SI (match_dup 1)))]
9422  "ix86_unary_operator_ok (NEG, SImode, operands)"
9423  "neg{l}\t%0"
9424  [(set_attr "type" "negnot")
9425   (set_attr "mode" "SI")])
9426
9427(define_insn "*negsi2_cmpz_zext"
9428  [(set (reg:CCZ 17)
9429	(compare:CCZ (lshiftrt:DI
9430		       (neg:DI (ashift:DI
9431				 (match_operand:DI 1 "register_operand" "0")
9432				 (const_int 32)))
9433		       (const_int 32))
9434		     (const_int 0)))
9435   (set (match_operand:DI 0 "register_operand" "=r")
9436	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9437					(const_int 32)))
9438		     (const_int 32)))]
9439  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9440  "neg{l}\t%k0"
9441  [(set_attr "type" "negnot")
9442   (set_attr "mode" "SI")])
9443
9444(define_expand "neghi2"
9445  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9446		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9447	      (clobber (reg:CC 17))])]
9448  "TARGET_HIMODE_MATH"
9449  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9450
9451(define_insn "*neghi2_1"
9452  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9453	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9454   (clobber (reg:CC 17))]
9455  "ix86_unary_operator_ok (NEG, HImode, operands)"
9456  "neg{w}\t%0"
9457  [(set_attr "type" "negnot")
9458   (set_attr "mode" "HI")])
9459
9460(define_insn "*neghi2_cmpz"
9461  [(set (reg:CCZ 17)
9462	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9463		     (const_int 0)))
9464   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9465	(neg:HI (match_dup 1)))]
9466  "ix86_unary_operator_ok (NEG, HImode, operands)"
9467  "neg{w}\t%0"
9468  [(set_attr "type" "negnot")
9469   (set_attr "mode" "HI")])
9470
9471(define_expand "negqi2"
9472  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9474	      (clobber (reg:CC 17))])]
9475  "TARGET_QIMODE_MATH"
9476  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9477
9478(define_insn "*negqi2_1"
9479  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9480	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9481   (clobber (reg:CC 17))]
9482  "ix86_unary_operator_ok (NEG, QImode, operands)"
9483  "neg{b}\t%0"
9484  [(set_attr "type" "negnot")
9485   (set_attr "mode" "QI")])
9486
9487(define_insn "*negqi2_cmpz"
9488  [(set (reg:CCZ 17)
9489	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9490		     (const_int 0)))
9491   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9492	(neg:QI (match_dup 1)))]
9493  "ix86_unary_operator_ok (NEG, QImode, operands)"
9494  "neg{b}\t%0"
9495  [(set_attr "type" "negnot")
9496   (set_attr "mode" "QI")])
9497
9498;; Changing of sign for FP values is doable using integer unit too.
9499
9500(define_expand "negsf2"
9501  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9503	      (clobber (reg:CC 17))])]
9504  "TARGET_80387"
9505  "if (TARGET_SSE)
9506     {
9507       /* In case operand is in memory,  we will not use SSE.  */
9508       if (memory_operand (operands[0], VOIDmode)
9509	   && rtx_equal_p (operands[0], operands[1]))
9510	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9511       else
9512	{
9513	  /* Using SSE is tricky, since we need bitwise negation of -0
9514	     in register.  */
9515	  rtx reg = gen_reg_rtx (SFmode);
9516	  rtx dest = operands[0];
9517
9518	  operands[1] = force_reg (SFmode, operands[1]);
9519	  operands[0] = force_reg (SFmode, operands[0]);
9520	  emit_move_insn (reg,
9521			  gen_lowpart (SFmode,
9522				       GEN_INT (trunc_int_for_mode (0x80000000,
9523							            SImode))));
9524	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9525	  if (dest != operands[0])
9526	    emit_move_insn (dest, operands[0]);
9527	}
9528       DONE;
9529     }
9530   ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9531
9532(define_insn "negsf2_memory"
9533  [(set (match_operand:SF 0 "memory_operand" "=m")
9534	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
9535   (clobber (reg:CC 17))]
9536  "ix86_unary_operator_ok (NEG, SFmode, operands)"
9537  "#")
9538
9539(define_insn "negsf2_ifs"
9540  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9541	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9542   (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
9543   (clobber (reg:CC 17))]
9544  "TARGET_SSE
9545   && (reload_in_progress || reload_completed
9546       || (register_operand (operands[0], VOIDmode)
9547	   && register_operand (operands[1], VOIDmode)))"
9548  "#")
9549
9550(define_split
9551  [(set (match_operand:SF 0 "memory_operand" "")
9552	(neg:SF (match_operand:SF 1 "memory_operand" "")))
9553   (use (match_operand:SF 2 "" ""))
9554   (clobber (reg:CC 17))]
9555  ""
9556  [(parallel [(set (match_dup 0)
9557		   (neg:SF (match_dup 1)))
9558	      (clobber (reg:CC 17))])])
9559
9560(define_split
9561  [(set (match_operand:SF 0 "register_operand" "")
9562	(neg:SF (match_operand:SF 1 "register_operand" "")))
9563   (use (match_operand:SF 2 "" ""))
9564   (clobber (reg:CC 17))]
9565  "reload_completed && !SSE_REG_P (operands[0])"
9566  [(parallel [(set (match_dup 0)
9567		   (neg:SF (match_dup 1)))
9568	      (clobber (reg:CC 17))])])
9569
9570(define_split
9571  [(set (match_operand:SF 0 "register_operand" "")
9572	(neg:SF (match_operand:SF 1 "register_operand" "")))
9573   (use (match_operand:SF 2 "register_operand" ""))
9574   (clobber (reg:CC 17))]
9575  "reload_completed && SSE_REG_P (operands[0])"
9576  [(set (subreg:TI (match_dup 0) 0)
9577	(xor:TI (subreg:TI (match_dup 1) 0)
9578		(subreg:TI (match_dup 2) 0)))]
9579{
9580  if (operands_match_p (operands[0], operands[2]))
9581    {
9582      rtx tmp;
9583      tmp = operands[1];
9584      operands[1] = operands[2];
9585      operands[2] = tmp;
9586    }
9587})
9588
9589
9590;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9591;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9592;; to itself.
9593(define_insn "*negsf2_if"
9594  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9595	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9596   (clobber (reg:CC 17))]
9597  "TARGET_80387 && !TARGET_SSE
9598   && ix86_unary_operator_ok (NEG, SFmode, operands)"
9599  "#")
9600
9601(define_split
9602  [(set (match_operand:SF 0 "register_operand" "")
9603	(neg:SF (match_operand:SF 1 "register_operand" "")))
9604   (clobber (reg:CC 17))]
9605  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9606  [(set (match_dup 0)
9607	(neg:SF (match_dup 1)))]
9608  "")
9609
9610(define_split
9611  [(set (match_operand:SF 0 "register_operand" "")
9612	(neg:SF (match_operand:SF 1 "register_operand" "")))
9613   (clobber (reg:CC 17))]
9614  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9615  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9616	      (clobber (reg:CC 17))])]
9617  "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9618   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9619
9620(define_split
9621  [(set (match_operand 0 "memory_operand" "")
9622	(neg (match_operand 1 "memory_operand" "")))
9623   (clobber (reg:CC 17))]
9624  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9625  [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9626	      (clobber (reg:CC 17))])]
9627{
9628  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9629
9630  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
9631  if (size >= 12)
9632    size = 10;
9633  operands[0] = adjust_address (operands[0], QImode, size - 1);
9634  operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
9635})
9636
9637(define_expand "negdf2"
9638  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9640	      (clobber (reg:CC 17))])]
9641  "TARGET_80387"
9642  "if (TARGET_SSE2)
9643     {
9644       /* In case operand is in memory,  we will not use SSE.  */
9645       if (memory_operand (operands[0], VOIDmode)
9646	   && rtx_equal_p (operands[0], operands[1]))
9647	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9648       else
9649	{
9650	  /* Using SSE is tricky, since we need bitwise negation of -0
9651	     in register.  */
9652	  rtx reg = gen_reg_rtx (DFmode);
9653#if HOST_BITS_PER_WIDE_INT >= 64
9654	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9655					        DImode));
9656#else
9657	  rtx imm = immed_double_const (0, 0x80000000, DImode);
9658#endif
9659	  rtx dest = operands[0];
9660
9661	  operands[1] = force_reg (DFmode, operands[1]);
9662	  operands[0] = force_reg (DFmode, operands[0]);
9663	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
9664	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9665	  if (dest != operands[0])
9666	    emit_move_insn (dest, operands[0]);
9667	}
9668       DONE;
9669     }
9670   ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9671
9672(define_insn "negdf2_memory"
9673  [(set (match_operand:DF 0 "memory_operand" "=m")
9674	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
9675   (clobber (reg:CC 17))]
9676  "ix86_unary_operator_ok (NEG, DFmode, operands)"
9677  "#")
9678
9679(define_insn "negdf2_ifs"
9680  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9681	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9682   (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
9683   (clobber (reg:CC 17))]
9684  "!TARGET_64BIT && TARGET_SSE2
9685   && (reload_in_progress || reload_completed
9686       || (register_operand (operands[0], VOIDmode)
9687	   && register_operand (operands[1], VOIDmode)))"
9688  "#")
9689
9690(define_insn "*negdf2_ifs_rex64"
9691  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9692	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9693   (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9694   (clobber (reg:CC 17))]
9695  "TARGET_64BIT && TARGET_SSE2
9696   && (reload_in_progress || reload_completed
9697       || (register_operand (operands[0], VOIDmode)
9698	   && register_operand (operands[1], VOIDmode)))"
9699  "#")
9700
9701(define_split
9702  [(set (match_operand:DF 0 "memory_operand" "")
9703	(neg:DF (match_operand:DF 1 "memory_operand" "")))
9704   (use (match_operand:DF 2 "" ""))
9705   (clobber (reg:CC 17))]
9706  ""
9707  [(parallel [(set (match_dup 0)
9708		   (neg:DF (match_dup 1)))
9709	      (clobber (reg:CC 17))])])
9710
9711(define_split
9712  [(set (match_operand:DF 0 "register_operand" "")
9713	(neg:DF (match_operand:DF 1 "register_operand" "")))
9714   (use (match_operand:DF 2 "" ""))
9715   (clobber (reg:CC 17))]
9716  "reload_completed && !SSE_REG_P (operands[0])
9717   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9718  [(parallel [(set (match_dup 0)
9719		   (neg:DF (match_dup 1)))
9720	      (clobber (reg:CC 17))])])
9721
9722(define_split
9723  [(set (match_operand:DF 0 "register_operand" "")
9724	(neg:DF (match_operand:DF 1 "register_operand" "")))
9725   (use (match_operand:DF 2 "" ""))
9726   (clobber (reg:CC 17))]
9727  "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9728  [(parallel [(set (match_dup 0)
9729		   (xor:DI (match_dup 1) (match_dup 2)))
9730	      (clobber (reg:CC 17))])]
9731   "operands[0] = gen_lowpart (DImode, operands[0]);
9732    operands[1] = gen_lowpart (DImode, operands[1]);
9733    operands[2] = gen_lowpart (DImode, operands[2]);")
9734
9735(define_split
9736  [(set (match_operand:DF 0 "register_operand" "")
9737	(neg:DF (match_operand:DF 1 "register_operand" "")))
9738   (use (match_operand:DF 2 "register_operand" ""))
9739   (clobber (reg:CC 17))]
9740  "reload_completed && SSE_REG_P (operands[0])"
9741  [(set (subreg:TI (match_dup 0) 0)
9742	(xor:TI (subreg:TI (match_dup 1) 0)
9743		(subreg:TI (match_dup 2) 0)))]
9744{
9745  if (operands_match_p (operands[0], operands[2]))
9746    {
9747      rtx tmp;
9748      tmp = operands[1];
9749      operands[1] = operands[2];
9750      operands[2] = tmp;
9751    }
9752})
9753
9754;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9755;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9756;; to itself.
9757(define_insn "*negdf2_if"
9758  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9759	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9760   (clobber (reg:CC 17))]
9761  "!TARGET_64BIT && TARGET_80387
9762   && ix86_unary_operator_ok (NEG, DFmode, operands)"
9763  "#")
9764
9765;; FIXME: We should to allow integer registers here.  Problem is that
9766;; we need another scratch register to get constant from.
9767;; Forcing constant to mem if no register available in peep2 should be
9768;; safe even for PIC mode, because of RIP relative addressing.
9769(define_insn "*negdf2_if_rex64"
9770  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9771	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9772   (clobber (reg:CC 17))]
9773  "TARGET_64BIT && TARGET_80387
9774   && ix86_unary_operator_ok (NEG, DFmode, operands)"
9775  "#")
9776
9777(define_split
9778  [(set (match_operand:DF 0 "register_operand" "")
9779	(neg:DF (match_operand:DF 1 "register_operand" "")))
9780   (clobber (reg:CC 17))]
9781  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9782  [(set (match_dup 0)
9783	(neg:DF (match_dup 1)))]
9784  "")
9785
9786(define_split
9787  [(set (match_operand:DF 0 "register_operand" "")
9788	(neg:DF (match_operand:DF 1 "register_operand" "")))
9789   (clobber (reg:CC 17))]
9790  "!TARGET_64BIT && TARGET_80387 && reload_completed
9791   && !FP_REGNO_P (REGNO (operands[0]))"
9792  [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9793	      (clobber (reg:CC 17))])]
9794  "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9795   split_di (operands+0, 1, operands+2, operands+3);")
9796
9797(define_expand "negxf2"
9798  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9799		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9800	      (clobber (reg:CC 17))])]
9801  "!TARGET_64BIT && TARGET_80387"
9802  "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9803
9804(define_expand "negtf2"
9805  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9806		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9807	      (clobber (reg:CC 17))])]
9808  "TARGET_80387"
9809  "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9810
9811;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9812;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9813;; to itself.
9814(define_insn "*negxf2_if"
9815  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9816	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9817   (clobber (reg:CC 17))]
9818  "!TARGET_64BIT && TARGET_80387
9819   && ix86_unary_operator_ok (NEG, XFmode, operands)"
9820  "#")
9821
9822(define_split
9823  [(set (match_operand:XF 0 "register_operand" "")
9824	(neg:XF (match_operand:XF 1 "register_operand" "")))
9825   (clobber (reg:CC 17))]
9826  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9827  [(set (match_dup 0)
9828	(neg:XF (match_dup 1)))]
9829  "")
9830
9831(define_split
9832  [(set (match_operand:XF 0 "register_operand" "")
9833	(neg:XF (match_operand:XF 1 "register_operand" "")))
9834   (clobber (reg:CC 17))]
9835  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9836  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9837	      (clobber (reg:CC 17))])]
9838  "operands[1] = GEN_INT (0x8000);
9839   operands[0] = gen_rtx_REG (SImode,
9840			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9841
9842;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9843;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9844;; to itself.
9845(define_insn "*negtf2_if"
9846  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9847	(neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9848   (clobber (reg:CC 17))]
9849  "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9850  "#")
9851
9852(define_split
9853  [(set (match_operand:TF 0 "register_operand" "")
9854	(neg:TF (match_operand:TF 1 "register_operand" "")))
9855   (clobber (reg:CC 17))]
9856  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9857  [(set (match_dup 0)
9858	(neg:TF (match_dup 1)))]
9859  "")
9860
9861(define_split
9862  [(set (match_operand:TF 0 "register_operand" "")
9863	(neg:TF (match_operand:TF 1 "register_operand" "")))
9864   (clobber (reg:CC 17))]
9865  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9866  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9867	      (clobber (reg:CC 17))])]
9868  "operands[1] = GEN_INT (0x8000);
9869   operands[0] = gen_rtx_REG (SImode,
9870			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9871
9872;; Conditionize these after reload. If they matches before reload, we 
9873;; lose the clobber and ability to use integer instructions.
9874
9875(define_insn "*negsf2_1"
9876  [(set (match_operand:SF 0 "register_operand" "=f")
9877	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
9878  "TARGET_80387 && reload_completed"
9879  "fchs"
9880  [(set_attr "type" "fsgn")
9881   (set_attr "mode" "SF")
9882   (set_attr "ppro_uops" "few")])
9883
9884(define_insn "*negdf2_1"
9885  [(set (match_operand:DF 0 "register_operand" "=f")
9886	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
9887  "TARGET_80387 && reload_completed"
9888  "fchs"
9889  [(set_attr "type" "fsgn")
9890   (set_attr "mode" "DF")
9891   (set_attr "ppro_uops" "few")])
9892
9893(define_insn "*negextendsfdf2"
9894  [(set (match_operand:DF 0 "register_operand" "=f")
9895	(neg:DF (float_extend:DF
9896		  (match_operand:SF 1 "register_operand" "0"))))]
9897  "TARGET_80387"
9898  "fchs"
9899  [(set_attr "type" "fsgn")
9900   (set_attr "mode" "DF")
9901   (set_attr "ppro_uops" "few")])
9902
9903(define_insn "*negxf2_1"
9904  [(set (match_operand:XF 0 "register_operand" "=f")
9905	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
9906  "!TARGET_64BIT && TARGET_80387 && reload_completed"
9907  "fchs"
9908  [(set_attr "type" "fsgn")
9909   (set_attr "mode" "XF")
9910   (set_attr "ppro_uops" "few")])
9911
9912(define_insn "*negextenddfxf2"
9913  [(set (match_operand:XF 0 "register_operand" "=f")
9914	(neg:XF (float_extend:XF
9915		  (match_operand:DF 1 "register_operand" "0"))))]
9916  "!TARGET_64BIT && TARGET_80387"
9917  "fchs"
9918  [(set_attr "type" "fsgn")
9919   (set_attr "mode" "XF")
9920   (set_attr "ppro_uops" "few")])
9921
9922(define_insn "*negextendsfxf2"
9923  [(set (match_operand:XF 0 "register_operand" "=f")
9924	(neg:XF (float_extend:XF
9925		  (match_operand:SF 1 "register_operand" "0"))))]
9926  "!TARGET_64BIT && TARGET_80387"
9927  "fchs"
9928  [(set_attr "type" "fsgn")
9929   (set_attr "mode" "XF")
9930   (set_attr "ppro_uops" "few")])
9931
9932(define_insn "*negtf2_1"
9933  [(set (match_operand:TF 0 "register_operand" "=f")
9934	(neg:TF (match_operand:TF 1 "register_operand" "0")))]
9935  "TARGET_80387 && reload_completed"
9936  "fchs"
9937  [(set_attr "type" "fsgn")
9938   (set_attr "mode" "XF")
9939   (set_attr "ppro_uops" "few")])
9940
9941(define_insn "*negextenddftf2"
9942  [(set (match_operand:TF 0 "register_operand" "=f")
9943	(neg:TF (float_extend:TF
9944		  (match_operand:DF 1 "register_operand" "0"))))]
9945  "TARGET_80387"
9946  "fchs"
9947  [(set_attr "type" "fsgn")
9948   (set_attr "mode" "XF")
9949   (set_attr "ppro_uops" "few")])
9950
9951(define_insn "*negextendsftf2"
9952  [(set (match_operand:TF 0 "register_operand" "=f")
9953	(neg:TF (float_extend:TF
9954		  (match_operand:SF 1 "register_operand" "0"))))]
9955  "TARGET_80387"
9956  "fchs"
9957  [(set_attr "type" "fsgn")
9958   (set_attr "mode" "XF")
9959   (set_attr "ppro_uops" "few")])
9960
9961;; Absolute value instructions
9962
9963(define_expand "abssf2"
9964  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9965		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9966	      (clobber (reg:CC 17))])]
9967  "TARGET_80387"
9968  "if (TARGET_SSE)
9969     {
9970       /* In case operand is in memory,  we will not use SSE.  */
9971       if (memory_operand (operands[0], VOIDmode)
9972	   && rtx_equal_p (operands[0], operands[1]))
9973	 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9974       else
9975	{
9976	  /* Using SSE is tricky, since we need bitwise negation of -0
9977	     in register.  */
9978	  rtx reg = gen_reg_rtx (SFmode);
9979	  rtx dest = operands[0];
9980
9981	  operands[1] = force_reg (SFmode, operands[1]);
9982	  operands[0] = force_reg (SFmode, operands[0]);
9983	  emit_move_insn (reg,
9984			  gen_lowpart (SFmode,
9985				       GEN_INT (trunc_int_for_mode (0x80000000,
9986							            SImode))));
9987	  emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9988	  if (dest != operands[0])
9989	    emit_move_insn (dest, operands[0]);
9990	}
9991       DONE;
9992     }
9993   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9994
9995(define_insn "abssf2_memory"
9996  [(set (match_operand:SF 0 "memory_operand" "=m")
9997	(abs:SF (match_operand:SF 1 "memory_operand" "0")))
9998   (clobber (reg:CC 17))]
9999  "ix86_unary_operator_ok (ABS, SFmode, operands)"
10000  "#")
10001
10002(define_insn "abssf2_ifs"
10003  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
10004	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
10005   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
10006   (clobber (reg:CC 17))]
10007  "TARGET_SSE
10008   && (reload_in_progress || reload_completed
10009       || (register_operand (operands[0], VOIDmode)
10010	   && register_operand (operands[1], VOIDmode)))"
10011  "#")
10012
10013(define_split
10014  [(set (match_operand:SF 0 "memory_operand" "")
10015	(abs:SF (match_operand:SF 1 "memory_operand" "")))
10016   (use (match_operand:SF 2 "" ""))
10017   (clobber (reg:CC 17))]
10018  ""
10019  [(parallel [(set (match_dup 0)
10020		   (abs:SF (match_dup 1)))
10021	      (clobber (reg:CC 17))])])
10022
10023(define_split
10024  [(set (match_operand:SF 0 "register_operand" "")
10025	(abs:SF (match_operand:SF 1 "register_operand" "")))
10026   (use (match_operand:SF 2 "" ""))
10027   (clobber (reg:CC 17))]
10028  "reload_completed && !SSE_REG_P (operands[0])"
10029  [(parallel [(set (match_dup 0)
10030		   (abs:SF (match_dup 1)))
10031	      (clobber (reg:CC 17))])])
10032
10033(define_split
10034  [(set (match_operand:SF 0 "register_operand" "")
10035	(abs:SF (match_operand:SF 1 "register_operand" "")))
10036   (use (match_operand:SF 2 "register_operand" ""))
10037   (clobber (reg:CC 17))]
10038  "reload_completed && SSE_REG_P (operands[0])"
10039  [(set (subreg:TI (match_dup 0) 0)
10040	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
10041		(subreg:TI (match_dup 1) 0)))])
10042
10043;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10044;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10045;; to itself.
10046(define_insn "*abssf2_if"
10047  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10048	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10049   (clobber (reg:CC 17))]
10050  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10051  "#")
10052
10053(define_split
10054  [(set (match_operand:SF 0 "register_operand" "")
10055	(abs:SF (match_operand:SF 1 "register_operand" "")))
10056   (clobber (reg:CC 17))]
10057  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
10058  [(set (match_dup 0)
10059	(abs:SF (match_dup 1)))]
10060  "")
10061
10062(define_split
10063  [(set (match_operand:SF 0 "register_operand" "")
10064	(abs:SF (match_operand:SF 1 "register_operand" "")))
10065   (clobber (reg:CC 17))]
10066  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10067  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10068	      (clobber (reg:CC 17))])]
10069  "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
10070   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
10071
10072(define_split
10073  [(set (match_operand 0 "memory_operand" "")
10074	(abs (match_operand 1 "memory_operand" "")))
10075   (clobber (reg:CC 17))]
10076  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10077  [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10078	      (clobber (reg:CC 17))])]
10079{
10080  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10081
10082  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
10083  if (size >= 12)
10084    size = 10;
10085  operands[0] = adjust_address (operands[0], QImode, size - 1);
10086  operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
10087})
10088
10089(define_expand "absdf2"
10090  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10091		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10092	      (clobber (reg:CC 17))])]
10093  "TARGET_80387"
10094  "if (TARGET_SSE2)
10095     {
10096       /* In case operand is in memory,  we will not use SSE.  */
10097       if (memory_operand (operands[0], VOIDmode)
10098	   && rtx_equal_p (operands[0], operands[1]))
10099	 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10100       else
10101	{
10102	  /* Using SSE is tricky, since we need bitwise negation of -0
10103	     in register.  */
10104	  rtx reg = gen_reg_rtx (DFmode);
10105#if HOST_BITS_PER_WIDE_INT >= 64
10106	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
10107					        DImode));
10108#else
10109	  rtx imm = immed_double_const (0, 0x80000000, DImode);
10110#endif
10111	  rtx dest = operands[0];
10112
10113	  operands[1] = force_reg (DFmode, operands[1]);
10114	  operands[0] = force_reg (DFmode, operands[0]);
10115	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
10116	  emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10117	  if (dest != operands[0])
10118	    emit_move_insn (dest, operands[0]);
10119	}
10120       DONE;
10121     }
10122   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10123
10124(define_insn "absdf2_memory"
10125  [(set (match_operand:DF 0 "memory_operand" "=m")
10126	(abs:DF (match_operand:DF 1 "memory_operand" "0")))
10127   (clobber (reg:CC 17))]
10128  "ix86_unary_operator_ok (ABS, DFmode, operands)"
10129  "#")
10130
10131(define_insn "absdf2_ifs"
10132  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
10133	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
10134   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
10135   (clobber (reg:CC 17))]
10136  "!TARGET_64BIT && TARGET_SSE2
10137   && (reload_in_progress || reload_completed
10138       || (register_operand (operands[0], VOIDmode)
10139	   && register_operand (operands[1], VOIDmode)))"
10140  "#")
10141
10142(define_insn "*absdf2_ifs_rex64"
10143  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
10144	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
10145   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
10146   (clobber (reg:CC 17))]
10147  "TARGET_64BIT && TARGET_SSE2
10148   && (reload_in_progress || reload_completed
10149       || (register_operand (operands[0], VOIDmode)
10150	   && register_operand (operands[1], VOIDmode)))"
10151  "#")
10152
10153(define_split
10154  [(set (match_operand:DF 0 "memory_operand" "")
10155	(abs:DF (match_operand:DF 1 "memory_operand" "")))
10156   (use (match_operand:DF 2 "" ""))
10157   (clobber (reg:CC 17))]
10158  ""
10159  [(parallel [(set (match_dup 0)
10160		   (abs:DF (match_dup 1)))
10161	      (clobber (reg:CC 17))])])
10162
10163(define_split
10164  [(set (match_operand:DF 0 "register_operand" "")
10165	(abs:DF (match_operand:DF 1 "register_operand" "")))
10166   (use (match_operand:DF 2 "" ""))
10167   (clobber (reg:CC 17))]
10168  "reload_completed && !SSE_REG_P (operands[0])"
10169  [(parallel [(set (match_dup 0)
10170		   (abs:DF (match_dup 1)))
10171	      (clobber (reg:CC 17))])])
10172
10173(define_split
10174  [(set (match_operand:DF 0 "register_operand" "")
10175	(abs:DF (match_operand:DF 1 "register_operand" "")))
10176   (use (match_operand:DF 2 "register_operand" ""))
10177   (clobber (reg:CC 17))]
10178  "reload_completed && SSE_REG_P (operands[0])"
10179  [(set (subreg:TI (match_dup 0) 0)
10180	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
10181		(subreg:TI (match_dup 1) 0)))])
10182
10183
10184;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10185;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10186;; to itself.
10187(define_insn "*absdf2_if"
10188  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10189	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10190   (clobber (reg:CC 17))]
10191  "!TARGET_64BIT && TARGET_80387
10192   && ix86_unary_operator_ok (ABS, DFmode, operands)"
10193  "#")
10194
10195;; FIXME: We should to allow integer registers here.  Problem is that
10196;; we need another scratch register to get constant from.
10197;; Forcing constant to mem if no register available in peep2 should be
10198;; safe even for PIC mode, because of RIP relative addressing.
10199(define_insn "*absdf2_if_rex64"
10200  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10201	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10202   (clobber (reg:CC 17))]
10203  "TARGET_64BIT && TARGET_80387
10204   && ix86_unary_operator_ok (ABS, DFmode, operands)"
10205  "#")
10206
10207(define_split
10208  [(set (match_operand:DF 0 "register_operand" "")
10209	(abs:DF (match_operand:DF 1 "register_operand" "")))
10210   (clobber (reg:CC 17))]
10211  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10212  [(set (match_dup 0)
10213	(abs:DF (match_dup 1)))]
10214  "")
10215
10216(define_split
10217  [(set (match_operand:DF 0 "register_operand" "")
10218	(abs:DF (match_operand:DF 1 "register_operand" "")))
10219   (clobber (reg:CC 17))]
10220  "!TARGET_64BIT && TARGET_80387 && reload_completed &&
10221   !FP_REGNO_P (REGNO (operands[0]))"
10222  [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10223	      (clobber (reg:CC 17))])]
10224  "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
10225   split_di (operands+0, 1, operands+2, operands+3);")
10226
10227(define_expand "absxf2"
10228  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10229		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10230	      (clobber (reg:CC 17))])]
10231  "!TARGET_64BIT && TARGET_80387"
10232  "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10233
10234(define_expand "abstf2"
10235  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10236		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10237	      (clobber (reg:CC 17))])]
10238  "TARGET_80387"
10239  "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10240
10241;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10242;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10243;; to itself.
10244(define_insn "*absxf2_if"
10245  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10246	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10247   (clobber (reg:CC 17))]
10248  "!TARGET_64BIT && TARGET_80387
10249   && ix86_unary_operator_ok (ABS, XFmode, operands)"
10250  "#")
10251
10252(define_split
10253  [(set (match_operand:XF 0 "register_operand" "")
10254	(abs:XF (match_operand:XF 1 "register_operand" "")))
10255   (clobber (reg:CC 17))]
10256  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10257  [(set (match_dup 0)
10258	(abs:XF (match_dup 1)))]
10259  "")
10260
10261(define_split
10262  [(set (match_operand:XF 0 "register_operand" "")
10263	(abs:XF (match_operand:XF 1 "register_operand" "")))
10264   (clobber (reg:CC 17))]
10265  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10266  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10267	      (clobber (reg:CC 17))])]
10268  "operands[1] = GEN_INT (~0x8000);
10269   operands[0] = gen_rtx_REG (SImode,
10270			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10271
10272(define_insn "*abstf2_if"
10273  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10274	(abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10275   (clobber (reg:CC 17))]
10276  "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10277  "#")
10278
10279(define_split
10280  [(set (match_operand:TF 0 "register_operand" "")
10281	(abs:TF (match_operand:TF 1 "register_operand" "")))
10282   (clobber (reg:CC 17))]
10283  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10284  [(set (match_dup 0)
10285	(abs:TF (match_dup 1)))]
10286  "")
10287
10288(define_split
10289  [(set (match_operand:TF 0 "register_operand" "")
10290	(abs:TF (match_operand:TF 1 "register_operand" "")))
10291   (clobber (reg:CC 17))]
10292  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10293  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10294	      (clobber (reg:CC 17))])]
10295  "operands[1] = GEN_INT (~0x8000);
10296   operands[0] = gen_rtx_REG (SImode,
10297			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10298
10299(define_insn "*abssf2_1"
10300  [(set (match_operand:SF 0 "register_operand" "=f")
10301	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
10302  "TARGET_80387 && reload_completed"
10303  "fabs"
10304  [(set_attr "type" "fsgn")
10305   (set_attr "mode" "SF")])
10306
10307(define_insn "*absdf2_1"
10308  [(set (match_operand:DF 0 "register_operand" "=f")
10309	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
10310  "TARGET_80387 && reload_completed"
10311  "fabs"
10312  [(set_attr "type" "fsgn")
10313   (set_attr "mode" "DF")])
10314
10315(define_insn "*absextendsfdf2"
10316  [(set (match_operand:DF 0 "register_operand" "=f")
10317	(abs:DF (float_extend:DF
10318		  (match_operand:SF 1 "register_operand" "0"))))]
10319  "TARGET_80387"
10320  "fabs"
10321  [(set_attr "type" "fsgn")
10322   (set_attr "mode" "DF")])
10323
10324(define_insn "*absxf2_1"
10325  [(set (match_operand:XF 0 "register_operand" "=f")
10326	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
10327  "!TARGET_64BIT && TARGET_80387 && reload_completed"
10328  "fabs"
10329  [(set_attr "type" "fsgn")
10330   (set_attr "mode" "DF")])
10331
10332(define_insn "*absextenddfxf2"
10333  [(set (match_operand:XF 0 "register_operand" "=f")
10334	(abs:XF (float_extend:XF
10335	  (match_operand:DF 1 "register_operand" "0"))))]
10336  "!TARGET_64BIT && TARGET_80387"
10337  "fabs"
10338  [(set_attr "type" "fsgn")
10339   (set_attr "mode" "XF")])
10340
10341(define_insn "*absextendsfxf2"
10342  [(set (match_operand:XF 0 "register_operand" "=f")
10343	(abs:XF (float_extend:XF
10344	  (match_operand:SF 1 "register_operand" "0"))))]
10345  "!TARGET_64BIT && TARGET_80387"
10346  "fabs"
10347  [(set_attr "type" "fsgn")
10348   (set_attr "mode" "XF")])
10349
10350(define_insn "*abstf2_1"
10351  [(set (match_operand:TF 0 "register_operand" "=f")
10352	(abs:TF (match_operand:TF 1 "register_operand" "0")))]
10353  "TARGET_80387 && reload_completed"
10354  "fabs"
10355  [(set_attr "type" "fsgn")
10356   (set_attr "mode" "DF")])
10357
10358(define_insn "*absextenddftf2"
10359  [(set (match_operand:TF 0 "register_operand" "=f")
10360	(abs:TF (float_extend:TF
10361	  (match_operand:DF 1 "register_operand" "0"))))]
10362  "TARGET_80387"
10363  "fabs"
10364  [(set_attr "type" "fsgn")
10365   (set_attr "mode" "XF")])
10366
10367(define_insn "*absextendsftf2"
10368  [(set (match_operand:TF 0 "register_operand" "=f")
10369	(abs:TF (float_extend:TF
10370	  (match_operand:SF 1 "register_operand" "0"))))]
10371  "TARGET_80387"
10372  "fabs"
10373  [(set_attr "type" "fsgn")
10374   (set_attr "mode" "XF")])
10375
10376;; One complement instructions
10377
10378(define_expand "one_cmpldi2"
10379  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10380	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10381  "TARGET_64BIT"
10382  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10383
10384(define_insn "*one_cmpldi2_1_rex64"
10385  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10386	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10387  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10388  "not{q}\t%0"
10389  [(set_attr "type" "negnot")
10390   (set_attr "mode" "DI")])
10391
10392(define_insn "*one_cmpldi2_2_rex64"
10393  [(set (reg 17)
10394	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10395		 (const_int 0)))
10396   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397	(not:DI (match_dup 1)))]
10398  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10399   && ix86_unary_operator_ok (NOT, DImode, operands)"
10400  "#"
10401  [(set_attr "type" "alu1")
10402   (set_attr "mode" "DI")])
10403
10404(define_split
10405  [(set (reg 17)
10406	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10407		 (const_int 0)))
10408   (set (match_operand:DI 0 "nonimmediate_operand" "")
10409	(not:DI (match_dup 1)))]
10410  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10411  [(parallel [(set (reg:CCNO 17)
10412		   (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10413				 (const_int 0)))
10414	      (set (match_dup 0)
10415		   (xor:DI (match_dup 1) (const_int -1)))])]
10416  "")
10417
10418(define_expand "one_cmplsi2"
10419  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10420	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10421  ""
10422  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10423
10424(define_insn "*one_cmplsi2_1"
10425  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10426	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10427  "ix86_unary_operator_ok (NOT, SImode, operands)"
10428  "not{l}\t%0"
10429  [(set_attr "type" "negnot")
10430   (set_attr "mode" "SI")])
10431
10432;; ??? Currently never generated - xor is used instead.
10433(define_insn "*one_cmplsi2_1_zext"
10434  [(set (match_operand:DI 0 "register_operand" "=r")
10435	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10436  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10437  "not{l}\t%k0"
10438  [(set_attr "type" "negnot")
10439   (set_attr "mode" "SI")])
10440
10441(define_insn "*one_cmplsi2_2"
10442  [(set (reg 17)
10443	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10444		 (const_int 0)))
10445   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10446	(not:SI (match_dup 1)))]
10447  "ix86_match_ccmode (insn, CCNOmode)
10448   && ix86_unary_operator_ok (NOT, SImode, operands)"
10449  "#"
10450  [(set_attr "type" "alu1")
10451   (set_attr "mode" "SI")])
10452
10453(define_split
10454  [(set (reg 17)
10455	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10456		 (const_int 0)))
10457   (set (match_operand:SI 0 "nonimmediate_operand" "")
10458	(not:SI (match_dup 1)))]
10459  "ix86_match_ccmode (insn, CCNOmode)"
10460  [(parallel [(set (reg:CCNO 17)
10461		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10462				 (const_int 0)))
10463	      (set (match_dup 0)
10464		   (xor:SI (match_dup 1) (const_int -1)))])]
10465  "")
10466
10467;; ??? Currently never generated - xor is used instead.
10468(define_insn "*one_cmplsi2_2_zext"
10469  [(set (reg 17)
10470	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10471		 (const_int 0)))
10472   (set (match_operand:DI 0 "register_operand" "=r")
10473	(zero_extend:DI (not:SI (match_dup 1))))]
10474  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10475   && ix86_unary_operator_ok (NOT, SImode, operands)"
10476  "#"
10477  [(set_attr "type" "alu1")
10478   (set_attr "mode" "SI")])
10479
10480(define_split
10481  [(set (reg 17)
10482	(compare (not:SI (match_operand:SI 1 "register_operand" ""))
10483		 (const_int 0)))
10484   (set (match_operand:DI 0 "register_operand" "")
10485	(zero_extend:DI (not:SI (match_dup 1))))]
10486  "ix86_match_ccmode (insn, CCNOmode)"
10487  [(parallel [(set (reg:CCNO 17)
10488		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10489				 (const_int 0)))
10490	      (set (match_dup 0)
10491		   (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10492  "")
10493
10494(define_expand "one_cmplhi2"
10495  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10496	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10497  "TARGET_HIMODE_MATH"
10498  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10499
10500(define_insn "*one_cmplhi2_1"
10501  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10502	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10503  "ix86_unary_operator_ok (NOT, HImode, operands)"
10504  "not{w}\t%0"
10505  [(set_attr "type" "negnot")
10506   (set_attr "mode" "HI")])
10507
10508(define_insn "*one_cmplhi2_2"
10509  [(set (reg 17)
10510	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10511		 (const_int 0)))
10512   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10513	(not:HI (match_dup 1)))]
10514  "ix86_match_ccmode (insn, CCNOmode)
10515   && ix86_unary_operator_ok (NEG, HImode, operands)"
10516  "#"
10517  [(set_attr "type" "alu1")
10518   (set_attr "mode" "HI")])
10519
10520(define_split
10521  [(set (reg 17)
10522	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10523		 (const_int 0)))
10524   (set (match_operand:HI 0 "nonimmediate_operand" "")
10525	(not:HI (match_dup 1)))]
10526  "ix86_match_ccmode (insn, CCNOmode)"
10527  [(parallel [(set (reg:CCNO 17)
10528		   (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10529		      		 (const_int 0)))
10530	      (set (match_dup 0)
10531		   (xor:HI (match_dup 1) (const_int -1)))])]
10532  "")
10533
10534;; %%% Potential partial reg stall on alternative 1.  What to do?
10535(define_expand "one_cmplqi2"
10536  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10537	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10538  "TARGET_QIMODE_MATH"
10539  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10540
10541(define_insn "*one_cmplqi2_1"
10542  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10543	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10544  "ix86_unary_operator_ok (NOT, QImode, operands)"
10545  "@
10546   not{b}\t%0
10547   not{l}\t%k0"
10548  [(set_attr "type" "negnot")
10549   (set_attr "mode" "QI,SI")])
10550
10551(define_insn "*one_cmplqi2_2"
10552  [(set (reg 17)
10553	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10554		 (const_int 0)))
10555   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10556	(not:QI (match_dup 1)))]
10557  "ix86_match_ccmode (insn, CCNOmode)
10558   && ix86_unary_operator_ok (NOT, QImode, operands)"
10559  "#"
10560  [(set_attr "type" "alu1")
10561   (set_attr "mode" "QI")])
10562
10563(define_split
10564  [(set (reg 17)
10565	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10566		 (const_int 0)))
10567   (set (match_operand:QI 0 "nonimmediate_operand" "")
10568	(not:QI (match_dup 1)))]
10569  "ix86_match_ccmode (insn, CCNOmode)"
10570  [(parallel [(set (reg:CCNO 17)
10571		   (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10572		      		 (const_int 0)))
10573	      (set (match_dup 0)
10574		   (xor:QI (match_dup 1) (const_int -1)))])]
10575  "")
10576
10577;; Arithmetic shift instructions
10578
10579;; DImode shifts are implemented using the i386 "shift double" opcode,
10580;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10581;; is variable, then the count is in %cl and the "imm" operand is dropped
10582;; from the assembler input.
10583;;
10584;; This instruction shifts the target reg/mem as usual, but instead of
10585;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10586;; is a left shift double, bits are taken from the high order bits of
10587;; reg, else if the insn is a shift right double, bits are taken from the
10588;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10589;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10590;;
10591;; Since sh[lr]d does not change the `reg' operand, that is done
10592;; separately, making all shifts emit pairs of shift double and normal
10593;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10594;; support a 63 bit shift, each shift where the count is in a reg expands
10595;; to a pair of shifts, a branch, a shift by 32 and a label.
10596;;
10597;; If the shift count is a constant, we need never emit more than one
10598;; shift pair, instead using moves and sign extension for counts greater
10599;; than 31.
10600
10601(define_expand "ashldi3"
10602  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10603		   (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10604			      (match_operand:QI 2 "nonmemory_operand" "")))
10605	      (clobber (reg:CC 17))])]
10606  ""
10607{
10608  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10609    {
10610      emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10611      DONE;
10612    }
10613  ix86_expand_binary_operator (ASHIFT, DImode, operands);
10614  DONE;
10615})
10616
10617(define_insn "*ashldi3_1_rex64"
10618  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10619	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10620		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10621   (clobber (reg:CC 17))]
10622  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10623{
10624  switch (get_attr_type (insn))
10625    {
10626    case TYPE_ALU:
10627      if (operands[2] != const1_rtx)
10628	abort ();
10629      if (!rtx_equal_p (operands[0], operands[1]))
10630	abort ();
10631      return "add{q}\t{%0, %0|%0, %0}";
10632
10633    case TYPE_LEA:
10634      if (GET_CODE (operands[2]) != CONST_INT
10635	  || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10636	abort ();
10637      operands[1] = gen_rtx_MULT (DImode, operands[1],
10638				  GEN_INT (1 << INTVAL (operands[2])));
10639      return "lea{q}\t{%a1, %0|%0, %a1}";
10640
10641    default:
10642      if (REG_P (operands[2]))
10643	return "sal{q}\t{%b2, %0|%0, %b2}";
10644      else if (GET_CODE (operands[2]) == CONST_INT
10645	       && INTVAL (operands[2]) == 1
10646	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10647	return "sal{q}\t%0";
10648      else
10649	return "sal{q}\t{%2, %0|%0, %2}";
10650    }
10651}
10652  [(set (attr "type")
10653     (cond [(eq_attr "alternative" "1")
10654	      (const_string "lea")
10655            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10656		          (const_int 0))
10657		      (match_operand 0 "register_operand" ""))
10658		 (match_operand 2 "const1_operand" ""))
10659	      (const_string "alu")
10660	   ]
10661	   (const_string "ishift")))
10662   (set_attr "mode" "DI")])
10663
10664;; Convert lea to the lea pattern to avoid flags dependency.
10665(define_split
10666  [(set (match_operand:DI 0 "register_operand" "")
10667	(ashift:DI (match_operand:DI 1 "register_operand" "")
10668		   (match_operand:QI 2 "immediate_operand" "")))
10669   (clobber (reg:CC 17))]
10670  "TARGET_64BIT && reload_completed
10671   && true_regnum (operands[0]) != true_regnum (operands[1])"
10672  [(set (match_dup 0)
10673	(mult:DI (match_dup 1)
10674		 (match_dup 2)))]
10675  "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10676					      DImode));")
10677
10678;; This pattern can't accept a variable shift count, since shifts by
10679;; zero don't affect the flags.  We assume that shifts by constant
10680;; zero are optimized away.
10681(define_insn "*ashldi3_cmp_rex64"
10682  [(set (reg 17)
10683	(compare
10684	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10685		     (match_operand:QI 2 "immediate_operand" "e"))
10686	  (const_int 0)))
10687   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10688	(ashift:DI (match_dup 1) (match_dup 2)))]
10689  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10690   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10691{
10692  switch (get_attr_type (insn))
10693    {
10694    case TYPE_ALU:
10695      if (operands[2] != const1_rtx)
10696	abort ();
10697      return "add{q}\t{%0, %0|%0, %0}";
10698
10699    default:
10700      if (REG_P (operands[2]))
10701	return "sal{q}\t{%b2, %0|%0, %b2}";
10702      else if (GET_CODE (operands[2]) == CONST_INT
10703	       && INTVAL (operands[2]) == 1
10704	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10705	return "sal{q}\t%0";
10706      else
10707	return "sal{q}\t{%2, %0|%0, %2}";
10708    }
10709}
10710  [(set (attr "type")
10711     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10712		          (const_int 0))
10713		      (match_operand 0 "register_operand" ""))
10714		 (match_operand 2 "const1_operand" ""))
10715	      (const_string "alu")
10716	   ]
10717	   (const_string "ishift")))
10718   (set_attr "mode" "DI")])
10719
10720(define_insn "ashldi3_1"
10721  [(set (match_operand:DI 0 "register_operand" "=r")
10722	(ashift:DI (match_operand:DI 1 "register_operand" "0")
10723		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
10724   (clobber (match_scratch:SI 3 "=&r"))
10725   (clobber (reg:CC 17))]
10726  "!TARGET_64BIT && TARGET_CMOVE"
10727  "#"
10728  [(set_attr "type" "multi")])
10729
10730(define_insn "*ashldi3_2"
10731  [(set (match_operand:DI 0 "register_operand" "=r")
10732	(ashift:DI (match_operand:DI 1 "register_operand" "0")
10733		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
10734   (clobber (reg:CC 17))]
10735  "!TARGET_64BIT"
10736  "#"
10737  [(set_attr "type" "multi")])
10738
10739(define_split
10740  [(set (match_operand:DI 0 "register_operand" "")
10741	(ashift:DI (match_operand:DI 1 "register_operand" "")
10742		   (match_operand:QI 2 "nonmemory_operand" "")))
10743   (clobber (match_scratch:SI 3 ""))
10744   (clobber (reg:CC 17))]
10745  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10746  [(const_int 0)]
10747  "ix86_split_ashldi (operands, operands[3]); DONE;")
10748
10749(define_split
10750  [(set (match_operand:DI 0 "register_operand" "")
10751	(ashift:DI (match_operand:DI 1 "register_operand" "")
10752		   (match_operand:QI 2 "nonmemory_operand" "")))
10753   (clobber (reg:CC 17))]
10754  "!TARGET_64BIT && reload_completed"
10755  [(const_int 0)]
10756  "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10757
10758(define_insn "x86_shld_1"
10759  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10760        (ior:SI (ashift:SI (match_dup 0)
10761		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10762		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10763		  (minus:QI (const_int 32) (match_dup 2)))))
10764   (clobber (reg:CC 17))]
10765  ""
10766  "@
10767   shld{l}\t{%2, %1, %0|%0, %1, %2}
10768   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10769  [(set_attr "type" "ishift")
10770   (set_attr "prefix_0f" "1")
10771   (set_attr "mode" "SI")
10772   (set_attr "pent_pair" "np")
10773   (set_attr "athlon_decode" "vector")
10774   (set_attr "ppro_uops" "few")])
10775
10776(define_expand "x86_shift_adj_1"
10777  [(set (reg:CCZ 17)
10778	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10779			     (const_int 32))
10780		     (const_int 0)))
10781   (set (match_operand:SI 0 "register_operand" "")
10782        (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10783			 (match_operand:SI 1 "register_operand" "")
10784			 (match_dup 0)))
10785   (set (match_dup 1)
10786	(if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10787			 (match_operand:SI 3 "register_operand" "r")
10788			 (match_dup 1)))]
10789  "TARGET_CMOVE"
10790  "")
10791
10792(define_expand "x86_shift_adj_2"
10793  [(use (match_operand:SI 0 "register_operand" ""))
10794   (use (match_operand:SI 1 "register_operand" ""))
10795   (use (match_operand:QI 2 "register_operand" ""))]
10796  ""
10797{
10798  rtx label = gen_label_rtx ();
10799  rtx tmp;
10800
10801  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10802
10803  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10804  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10805  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10806			      gen_rtx_LABEL_REF (VOIDmode, label),
10807			      pc_rtx);
10808  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10809  JUMP_LABEL (tmp) = label;
10810
10811  emit_move_insn (operands[0], operands[1]);
10812  emit_move_insn (operands[1], const0_rtx);
10813
10814  emit_label (label);
10815  LABEL_NUSES (label) = 1;
10816
10817  DONE;
10818})
10819
10820(define_expand "ashlsi3"
10821  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10822	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10823		   (match_operand:QI 2 "nonmemory_operand" "")))
10824   (clobber (reg:CC 17))]
10825  ""
10826  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10827
10828(define_insn "*ashlsi3_1"
10829  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10830	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10831		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10832   (clobber (reg:CC 17))]
10833  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10834{
10835  switch (get_attr_type (insn))
10836    {
10837    case TYPE_ALU:
10838      if (operands[2] != const1_rtx)
10839	abort ();
10840      if (!rtx_equal_p (operands[0], operands[1]))
10841	abort ();
10842      return "add{l}\t{%0, %0|%0, %0}";
10843
10844    case TYPE_LEA:
10845      return "#";
10846
10847    default:
10848      if (REG_P (operands[2]))
10849	return "sal{l}\t{%b2, %0|%0, %b2}";
10850      else if (GET_CODE (operands[2]) == CONST_INT
10851	       && INTVAL (operands[2]) == 1
10852	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10853	return "sal{l}\t%0";
10854      else
10855	return "sal{l}\t{%2, %0|%0, %2}";
10856    }
10857}
10858  [(set (attr "type")
10859     (cond [(eq_attr "alternative" "1")
10860	      (const_string "lea")
10861            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10862		          (const_int 0))
10863		      (match_operand 0 "register_operand" ""))
10864		 (match_operand 2 "const1_operand" ""))
10865	      (const_string "alu")
10866	   ]
10867	   (const_string "ishift")))
10868   (set_attr "mode" "SI")])
10869
10870;; Convert lea to the lea pattern to avoid flags dependency.
10871(define_split
10872  [(set (match_operand 0 "register_operand" "")
10873	(ashift (match_operand 1 "register_operand" "")
10874                (match_operand:QI 2 "const_int_operand" "")))
10875   (clobber (reg:CC 17))]
10876  "reload_completed
10877   && true_regnum (operands[0]) != true_regnum (operands[1])"
10878  [(const_int 0)]
10879{
10880  rtx pat;
10881  operands[0] = gen_lowpart (SImode, operands[0]);
10882  operands[1] = gen_lowpart (Pmode, operands[1]);
10883  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10884					     Pmode));
10885  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10886  if (Pmode != SImode)
10887    pat = gen_rtx_SUBREG (SImode, pat, 0);
10888  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10889  DONE;
10890})
10891
10892(define_insn "*ashlsi3_1_zext"
10893  [(set (match_operand:DI 0 "register_operand" "=r,r")
10894	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10895			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10896   (clobber (reg:CC 17))]
10897  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10898{
10899  switch (get_attr_type (insn))
10900    {
10901    case TYPE_ALU:
10902      if (operands[2] != const1_rtx)
10903	abort ();
10904      return "add{l}\t{%k0, %k0|%k0, %k0}";
10905
10906    case TYPE_LEA:
10907      return "#";
10908
10909    default:
10910      if (REG_P (operands[2]))
10911	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10912      else if (GET_CODE (operands[2]) == CONST_INT
10913	       && INTVAL (operands[2]) == 1
10914	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10915	return "sal{l}\t%k0";
10916      else
10917	return "sal{l}\t{%2, %k0|%k0, %2}";
10918    }
10919}
10920  [(set (attr "type")
10921     (cond [(eq_attr "alternative" "1")
10922	      (const_string "lea")
10923            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10924		     (const_int 0))
10925		 (match_operand 2 "const1_operand" ""))
10926	      (const_string "alu")
10927	   ]
10928	   (const_string "ishift")))
10929   (set_attr "mode" "SI")])
10930
10931;; Convert lea to the lea pattern to avoid flags dependency.
10932(define_split
10933  [(set (match_operand:DI 0 "register_operand" "")
10934	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10935				(match_operand:QI 2 "const_int_operand" ""))))
10936   (clobber (reg:CC 17))]
10937  "reload_completed
10938   && true_regnum (operands[0]) != true_regnum (operands[1])"
10939  [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10940{
10941  operands[1] = gen_lowpart (Pmode, operands[1]);
10942  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10943					     Pmode));
10944})
10945
10946;; This pattern can't accept a variable shift count, since shifts by
10947;; zero don't affect the flags.  We assume that shifts by constant
10948;; zero are optimized away.
10949(define_insn "*ashlsi3_cmp"
10950  [(set (reg 17)
10951	(compare
10952	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10953		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
10954	  (const_int 0)))
10955   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10956	(ashift:SI (match_dup 1) (match_dup 2)))]
10957  "ix86_match_ccmode (insn, CCGOCmode)
10958   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10959{
10960  switch (get_attr_type (insn))
10961    {
10962    case TYPE_ALU:
10963      if (operands[2] != const1_rtx)
10964	abort ();
10965      return "add{l}\t{%0, %0|%0, %0}";
10966
10967    default:
10968      if (REG_P (operands[2]))
10969	return "sal{l}\t{%b2, %0|%0, %b2}";
10970      else if (GET_CODE (operands[2]) == CONST_INT
10971	       && INTVAL (operands[2]) == 1
10972	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10973	return "sal{l}\t%0";
10974      else
10975	return "sal{l}\t{%2, %0|%0, %2}";
10976    }
10977}
10978  [(set (attr "type")
10979     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980		          (const_int 0))
10981		      (match_operand 0 "register_operand" ""))
10982		 (match_operand 2 "const1_operand" ""))
10983	      (const_string "alu")
10984	   ]
10985	   (const_string "ishift")))
10986   (set_attr "mode" "SI")])
10987
10988(define_insn "*ashlsi3_cmp_zext"
10989  [(set (reg 17)
10990	(compare
10991	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10992		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
10993	  (const_int 0)))
10994   (set (match_operand:DI 0 "register_operand" "=r")
10995	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10996  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10997   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10998{
10999  switch (get_attr_type (insn))
11000    {
11001    case TYPE_ALU:
11002      if (operands[2] != const1_rtx)
11003	abort ();
11004      return "add{l}\t{%k0, %k0|%k0, %k0}";
11005
11006    default:
11007      if (REG_P (operands[2]))
11008	return "sal{l}\t{%b2, %k0|%k0, %b2}";
11009      else if (GET_CODE (operands[2]) == CONST_INT
11010	       && INTVAL (operands[2]) == 1
11011	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11012	return "sal{l}\t%k0";
11013      else
11014	return "sal{l}\t{%2, %k0|%k0, %2}";
11015    }
11016}
11017  [(set (attr "type")
11018     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11019		     (const_int 0))
11020		 (match_operand 2 "const1_operand" ""))
11021	      (const_string "alu")
11022	   ]
11023	   (const_string "ishift")))
11024   (set_attr "mode" "SI")])
11025
11026(define_expand "ashlhi3"
11027  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11028	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11029		   (match_operand:QI 2 "nonmemory_operand" "")))
11030   (clobber (reg:CC 17))]
11031  "TARGET_HIMODE_MATH"
11032  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11033
11034(define_insn "*ashlhi3_1_lea"
11035  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11036	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11037		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11038   (clobber (reg:CC 17))]
11039  "!TARGET_PARTIAL_REG_STALL
11040   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11041{
11042  switch (get_attr_type (insn))
11043    {
11044    case TYPE_LEA:
11045      return "#";
11046    case TYPE_ALU:
11047      if (operands[2] != const1_rtx)
11048	abort ();
11049      return "add{w}\t{%0, %0|%0, %0}";
11050
11051    default:
11052      if (REG_P (operands[2]))
11053	return "sal{w}\t{%b2, %0|%0, %b2}";
11054      else if (GET_CODE (operands[2]) == CONST_INT
11055	       && INTVAL (operands[2]) == 1
11056	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11057	return "sal{w}\t%0";
11058      else
11059	return "sal{w}\t{%2, %0|%0, %2}";
11060    }
11061}
11062  [(set (attr "type")
11063     (cond [(eq_attr "alternative" "1")
11064	      (const_string "lea")
11065            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11066		          (const_int 0))
11067		      (match_operand 0 "register_operand" ""))
11068		 (match_operand 2 "const1_operand" ""))
11069	      (const_string "alu")
11070	   ]
11071	   (const_string "ishift")))
11072   (set_attr "mode" "HI,SI")])
11073
11074(define_insn "*ashlhi3_1"
11075  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11076	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11077		   (match_operand:QI 2 "nonmemory_operand" "cI")))
11078   (clobber (reg:CC 17))]
11079  "TARGET_PARTIAL_REG_STALL
11080   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11081{
11082  switch (get_attr_type (insn))
11083    {
11084    case TYPE_ALU:
11085      if (operands[2] != const1_rtx)
11086	abort ();
11087      return "add{w}\t{%0, %0|%0, %0}";
11088
11089    default:
11090      if (REG_P (operands[2]))
11091	return "sal{w}\t{%b2, %0|%0, %b2}";
11092      else if (GET_CODE (operands[2]) == CONST_INT
11093	       && INTVAL (operands[2]) == 1
11094	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11095	return "sal{w}\t%0";
11096      else
11097	return "sal{w}\t{%2, %0|%0, %2}";
11098    }
11099}
11100  [(set (attr "type")
11101     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102		          (const_int 0))
11103		      (match_operand 0 "register_operand" ""))
11104		 (match_operand 2 "const1_operand" ""))
11105	      (const_string "alu")
11106	   ]
11107	   (const_string "ishift")))
11108   (set_attr "mode" "HI")])
11109
11110;; This pattern can't accept a variable shift count, since shifts by
11111;; zero don't affect the flags.  We assume that shifts by constant
11112;; zero are optimized away.
11113(define_insn "*ashlhi3_cmp"
11114  [(set (reg 17)
11115	(compare
11116	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11117		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
11118	  (const_int 0)))
11119   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11120	(ashift:HI (match_dup 1) (match_dup 2)))]
11121  "ix86_match_ccmode (insn, CCGOCmode)
11122   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11123{
11124  switch (get_attr_type (insn))
11125    {
11126    case TYPE_ALU:
11127      if (operands[2] != const1_rtx)
11128	abort ();
11129      return "add{w}\t{%0, %0|%0, %0}";
11130
11131    default:
11132      if (REG_P (operands[2]))
11133	return "sal{w}\t{%b2, %0|%0, %b2}";
11134      else if (GET_CODE (operands[2]) == CONST_INT
11135	       && INTVAL (operands[2]) == 1
11136	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11137	return "sal{w}\t%0";
11138      else
11139	return "sal{w}\t{%2, %0|%0, %2}";
11140    }
11141}
11142  [(set (attr "type")
11143     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11144		          (const_int 0))
11145		      (match_operand 0 "register_operand" ""))
11146		 (match_operand 2 "const1_operand" ""))
11147	      (const_string "alu")
11148	   ]
11149	   (const_string "ishift")))
11150   (set_attr "mode" "HI")])
11151
11152(define_expand "ashlqi3"
11153  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11154	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11155		   (match_operand:QI 2 "nonmemory_operand" "")))
11156   (clobber (reg:CC 17))]
11157  "TARGET_QIMODE_MATH"
11158  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11159
11160;; %%% Potential partial reg stall on alternative 2.  What to do?
11161
11162(define_insn "*ashlqi3_1_lea"
11163  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11164	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11165		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11166   (clobber (reg:CC 17))]
11167  "!TARGET_PARTIAL_REG_STALL
11168   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11169{
11170  switch (get_attr_type (insn))
11171    {
11172    case TYPE_LEA:
11173      return "#";
11174    case TYPE_ALU:
11175      if (operands[2] != const1_rtx)
11176	abort ();
11177      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11178        return "add{l}\t{%k0, %k0|%k0, %k0}";
11179      else
11180        return "add{b}\t{%0, %0|%0, %0}";
11181
11182    default:
11183      if (REG_P (operands[2]))
11184	{
11185	  if (get_attr_mode (insn) == MODE_SI)
11186	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11187	  else
11188	    return "sal{b}\t{%b2, %0|%0, %b2}";
11189	}
11190      else if (GET_CODE (operands[2]) == CONST_INT
11191	       && INTVAL (operands[2]) == 1
11192	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11193	{
11194	  if (get_attr_mode (insn) == MODE_SI)
11195	    return "sal{l}\t%0";
11196	  else
11197	    return "sal{b}\t%0";
11198	}
11199      else
11200	{
11201	  if (get_attr_mode (insn) == MODE_SI)
11202	    return "sal{l}\t{%2, %k0|%k0, %2}";
11203	  else
11204	    return "sal{b}\t{%2, %0|%0, %2}";
11205	}
11206    }
11207}
11208  [(set (attr "type")
11209     (cond [(eq_attr "alternative" "2")
11210	      (const_string "lea")
11211            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11212		          (const_int 0))
11213		      (match_operand 0 "register_operand" ""))
11214		 (match_operand 2 "const1_operand" ""))
11215	      (const_string "alu")
11216	   ]
11217	   (const_string "ishift")))
11218   (set_attr "mode" "QI,SI,SI")])
11219
11220(define_insn "*ashlqi3_1"
11221  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11222	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11223		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11224   (clobber (reg:CC 17))]
11225  "TARGET_PARTIAL_REG_STALL
11226   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11227{
11228  switch (get_attr_type (insn))
11229    {
11230    case TYPE_ALU:
11231      if (operands[2] != const1_rtx)
11232	abort ();
11233      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11234        return "add{l}\t{%k0, %k0|%k0, %k0}";
11235      else
11236        return "add{b}\t{%0, %0|%0, %0}";
11237
11238    default:
11239      if (REG_P (operands[2]))
11240	{
11241	  if (get_attr_mode (insn) == MODE_SI)
11242	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11243	  else
11244	    return "sal{b}\t{%b2, %0|%0, %b2}";
11245	}
11246      else if (GET_CODE (operands[2]) == CONST_INT
11247	       && INTVAL (operands[2]) == 1
11248	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11249	{
11250	  if (get_attr_mode (insn) == MODE_SI)
11251	    return "sal{l}\t%0";
11252	  else
11253	    return "sal{b}\t%0";
11254	}
11255      else
11256	{
11257	  if (get_attr_mode (insn) == MODE_SI)
11258	    return "sal{l}\t{%2, %k0|%k0, %2}";
11259	  else
11260	    return "sal{b}\t{%2, %0|%0, %2}";
11261	}
11262    }
11263}
11264  [(set (attr "type")
11265     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11266		          (const_int 0))
11267		      (match_operand 0 "register_operand" ""))
11268		 (match_operand 2 "const1_operand" ""))
11269	      (const_string "alu")
11270	   ]
11271	   (const_string "ishift")))
11272   (set_attr "mode" "QI,SI")])
11273
11274;; This pattern can't accept a variable shift count, since shifts by
11275;; zero don't affect the flags.  We assume that shifts by constant
11276;; zero are optimized away.
11277(define_insn "*ashlqi3_cmp"
11278  [(set (reg 17)
11279	(compare
11280	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11281		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
11282	  (const_int 0)))
11283   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11284	(ashift:QI (match_dup 1) (match_dup 2)))]
11285  "ix86_match_ccmode (insn, CCGOCmode)
11286   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11287{
11288  switch (get_attr_type (insn))
11289    {
11290    case TYPE_ALU:
11291      if (operands[2] != const1_rtx)
11292	abort ();
11293      return "add{b}\t{%0, %0|%0, %0}";
11294
11295    default:
11296      if (REG_P (operands[2]))
11297	return "sal{b}\t{%b2, %0|%0, %b2}";
11298      else if (GET_CODE (operands[2]) == CONST_INT
11299	       && INTVAL (operands[2]) == 1
11300	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11301	return "sal{b}\t%0";
11302      else
11303	return "sal{b}\t{%2, %0|%0, %2}";
11304    }
11305}
11306  [(set (attr "type")
11307     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11308		          (const_int 0))
11309		      (match_operand 0 "register_operand" ""))
11310		 (match_operand 2 "const1_operand" ""))
11311	      (const_string "alu")
11312	   ]
11313	   (const_string "ishift")))
11314   (set_attr "mode" "QI")])
11315
11316;; See comment above `ashldi3' about how this works.
11317
11318(define_expand "ashrdi3"
11319  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11320		   (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11321				(match_operand:QI 2 "nonmemory_operand" "")))
11322	      (clobber (reg:CC 17))])]
11323  ""
11324{
11325  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11326    {
11327      emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11328      DONE;
11329    }
11330  ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11331  DONE;
11332})
11333
11334(define_insn "ashrdi3_63_rex64"
11335  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11336	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11337		     (match_operand:DI 2 "const_int_operand" "i,i")))
11338   (clobber (reg:CC 17))]
11339  "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11340   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11341  "@
11342   {cqto|cqo}
11343   sar{q}\t{%2, %0|%0, %2}"
11344  [(set_attr "type" "imovx,ishift")
11345   (set_attr "prefix_0f" "0,*")
11346   (set_attr "length_immediate" "0,*")
11347   (set_attr "modrm" "0,1")
11348   (set_attr "mode" "DI")])
11349
11350(define_insn "*ashrdi3_1_one_bit_rex64"
11351  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11352	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11353		     (match_operand:QI 2 "const_int_1_operand" "")))
11354   (clobber (reg:CC 17))]
11355  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11356   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11357  "sar{q}\t%0"
11358  [(set_attr "type" "ishift")
11359   (set (attr "length") 
11360     (if_then_else (match_operand:DI 0 "register_operand" "") 
11361	(const_string "2")
11362	(const_string "*")))])
11363
11364(define_insn "*ashrdi3_1_rex64"
11365  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11366	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11367		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11368   (clobber (reg:CC 17))]
11369  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370  "@
11371   sar{q}\t{%2, %0|%0, %2}
11372   sar{q}\t{%b2, %0|%0, %b2}"
11373  [(set_attr "type" "ishift")
11374   (set_attr "mode" "DI")])
11375
11376;; This pattern can't accept a variable shift count, since shifts by
11377;; zero don't affect the flags.  We assume that shifts by constant
11378;; zero are optimized away.
11379(define_insn "*ashrdi3_one_bit_cmp_rex64"
11380  [(set (reg 17)
11381	(compare
11382	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11383		       (match_operand:QI 2 "const_int_1_operand" ""))
11384	  (const_int 0)))
11385   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11386	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11387  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11388   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11389   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11390  "sar{q}\t%0"
11391  [(set_attr "type" "ishift")
11392   (set (attr "length") 
11393     (if_then_else (match_operand:DI 0 "register_operand" "") 
11394	(const_string "2")
11395	(const_string "*")))])
11396
11397;; This pattern can't accept a variable shift count, since shifts by
11398;; zero don't affect the flags.  We assume that shifts by constant
11399;; zero are optimized away.
11400(define_insn "*ashrdi3_cmp_rex64"
11401  [(set (reg 17)
11402	(compare
11403	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404		       (match_operand:QI 2 "const_int_operand" "n"))
11405	  (const_int 0)))
11406   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11407	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11408  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11409   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11410  "sar{q}\t{%2, %0|%0, %2}"
11411  [(set_attr "type" "ishift")
11412   (set_attr "mode" "DI")])
11413
11414
11415(define_insn "ashrdi3_1"
11416  [(set (match_operand:DI 0 "register_operand" "=r")
11417	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11418		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11419   (clobber (match_scratch:SI 3 "=&r"))
11420   (clobber (reg:CC 17))]
11421  "!TARGET_64BIT && TARGET_CMOVE"
11422  "#"
11423  [(set_attr "type" "multi")])
11424
11425(define_insn "*ashrdi3_2"
11426  [(set (match_operand:DI 0 "register_operand" "=r")
11427	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11428		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11429   (clobber (reg:CC 17))]
11430  "!TARGET_64BIT"
11431  "#"
11432  [(set_attr "type" "multi")])
11433
11434(define_split
11435  [(set (match_operand:DI 0 "register_operand" "")
11436	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11437		     (match_operand:QI 2 "nonmemory_operand" "")))
11438   (clobber (match_scratch:SI 3 ""))
11439   (clobber (reg:CC 17))]
11440  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11441  [(const_int 0)]
11442  "ix86_split_ashrdi (operands, operands[3]); DONE;")
11443
11444(define_split
11445  [(set (match_operand:DI 0 "register_operand" "")
11446	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11447		     (match_operand:QI 2 "nonmemory_operand" "")))
11448   (clobber (reg:CC 17))]
11449  "!TARGET_64BIT && reload_completed"
11450  [(const_int 0)]
11451  "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11452
11453(define_insn "x86_shrd_1"
11454  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11455        (ior:SI (ashiftrt:SI (match_dup 0)
11456		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11457		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11458		  (minus:QI (const_int 32) (match_dup 2)))))
11459   (clobber (reg:CC 17))]
11460  ""
11461  "@
11462   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11463   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11464  [(set_attr "type" "ishift")
11465   (set_attr "prefix_0f" "1")
11466   (set_attr "pent_pair" "np")
11467   (set_attr "ppro_uops" "few")
11468   (set_attr "mode" "SI")])
11469
11470(define_expand "x86_shift_adj_3"
11471  [(use (match_operand:SI 0 "register_operand" ""))
11472   (use (match_operand:SI 1 "register_operand" ""))
11473   (use (match_operand:QI 2 "register_operand" ""))]
11474  ""
11475{
11476  rtx label = gen_label_rtx ();
11477  rtx tmp;
11478
11479  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11480
11481  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11482  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11483  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11484			      gen_rtx_LABEL_REF (VOIDmode, label),
11485			      pc_rtx);
11486  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11487  JUMP_LABEL (tmp) = label;
11488
11489  emit_move_insn (operands[0], operands[1]);
11490  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11491
11492  emit_label (label);
11493  LABEL_NUSES (label) = 1;
11494
11495  DONE;
11496})
11497
11498(define_insn "ashrsi3_31"
11499  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11500	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11501		     (match_operand:SI 2 "const_int_operand" "i,i")))
11502   (clobber (reg:CC 17))]
11503  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11504   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11505  "@
11506   {cltd|cdq}
11507   sar{l}\t{%2, %0|%0, %2}"
11508  [(set_attr "type" "imovx,ishift")
11509   (set_attr "prefix_0f" "0,*")
11510   (set_attr "length_immediate" "0,*")
11511   (set_attr "modrm" "0,1")
11512   (set_attr "mode" "SI")])
11513
11514(define_insn "*ashrsi3_31_zext"
11515  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11516	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11517				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11518   (clobber (reg:CC 17))]
11519  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11520   && INTVAL (operands[2]) == 31
11521   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11522  "@
11523   {cltd|cdq}
11524   sar{l}\t{%2, %k0|%k0, %2}"
11525  [(set_attr "type" "imovx,ishift")
11526   (set_attr "prefix_0f" "0,*")
11527   (set_attr "length_immediate" "0,*")
11528   (set_attr "modrm" "0,1")
11529   (set_attr "mode" "SI")])
11530
11531(define_expand "ashrsi3"
11532  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11533	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11534		     (match_operand:QI 2 "nonmemory_operand" "")))
11535   (clobber (reg:CC 17))]
11536  ""
11537  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11538
11539(define_insn "*ashrsi3_1_one_bit"
11540  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11541	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11542		     (match_operand:QI 2 "const_int_1_operand" "")))
11543   (clobber (reg:CC 17))]
11544  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11545   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11546  "sar{l}\t%0"
11547  [(set_attr "type" "ishift")
11548   (set (attr "length") 
11549     (if_then_else (match_operand:SI 0 "register_operand" "") 
11550	(const_string "2")
11551	(const_string "*")))])
11552
11553(define_insn "*ashrsi3_1_one_bit_zext"
11554  [(set (match_operand:DI 0 "register_operand" "=r")
11555	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11556				     (match_operand:QI 2 "const_int_1_operand" ""))))
11557   (clobber (reg:CC 17))]
11558  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11559   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11560  "sar{l}\t%k0"
11561  [(set_attr "type" "ishift")
11562   (set_attr "length" "2")])
11563
11564(define_insn "*ashrsi3_1"
11565  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11566	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11567		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11568   (clobber (reg:CC 17))]
11569  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570  "@
11571   sar{l}\t{%2, %0|%0, %2}
11572   sar{l}\t{%b2, %0|%0, %b2}"
11573  [(set_attr "type" "ishift")
11574   (set_attr "mode" "SI")])
11575
11576(define_insn "*ashrsi3_1_zext"
11577  [(set (match_operand:DI 0 "register_operand" "=r,r")
11578	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11579				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11580   (clobber (reg:CC 17))]
11581  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11582  "@
11583   sar{l}\t{%2, %k0|%k0, %2}
11584   sar{l}\t{%b2, %k0|%k0, %b2}"
11585  [(set_attr "type" "ishift")
11586   (set_attr "mode" "SI")])
11587
11588;; This pattern can't accept a variable shift count, since shifts by
11589;; zero don't affect the flags.  We assume that shifts by constant
11590;; zero are optimized away.
11591(define_insn "*ashrsi3_one_bit_cmp"
11592  [(set (reg 17)
11593	(compare
11594	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11595		       (match_operand:QI 2 "const_int_1_operand" ""))
11596	  (const_int 0)))
11597   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11598	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11599  "ix86_match_ccmode (insn, CCGOCmode)
11600   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11601   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11602  "sar{l}\t%0"
11603  [(set_attr "type" "ishift")
11604   (set (attr "length") 
11605     (if_then_else (match_operand:SI 0 "register_operand" "") 
11606	(const_string "2")
11607	(const_string "*")))])
11608
11609(define_insn "*ashrsi3_one_bit_cmp_zext"
11610  [(set (reg 17)
11611	(compare
11612	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11613		       (match_operand:QI 2 "const_int_1_operand" ""))
11614	  (const_int 0)))
11615   (set (match_operand:DI 0 "register_operand" "=r")
11616	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11617  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11618   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11619   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620  "sar{l}\t%k0"
11621  [(set_attr "type" "ishift")
11622   (set_attr "length" "2")])
11623
11624;; This pattern can't accept a variable shift count, since shifts by
11625;; zero don't affect the flags.  We assume that shifts by constant
11626;; zero are optimized away.
11627(define_insn "*ashrsi3_cmp"
11628  [(set (reg 17)
11629	(compare
11630	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11632	  (const_int 0)))
11633   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635  "ix86_match_ccmode (insn, CCGOCmode)
11636   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637  "sar{l}\t{%2, %0|%0, %2}"
11638  [(set_attr "type" "ishift")
11639   (set_attr "mode" "SI")])
11640
11641(define_insn "*ashrsi3_cmp_zext"
11642  [(set (reg 17)
11643	(compare
11644	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11645		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11646	  (const_int 0)))
11647   (set (match_operand:DI 0 "register_operand" "=r")
11648	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11649  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11651  "sar{l}\t{%2, %k0|%k0, %2}"
11652  [(set_attr "type" "ishift")
11653   (set_attr "mode" "SI")])
11654
11655(define_expand "ashrhi3"
11656  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11657	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11658		     (match_operand:QI 2 "nonmemory_operand" "")))
11659   (clobber (reg:CC 17))]
11660  "TARGET_HIMODE_MATH"
11661  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11662
11663(define_insn "*ashrhi3_1_one_bit"
11664  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11665	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666		     (match_operand:QI 2 "const_int_1_operand" "")))
11667   (clobber (reg:CC 17))]
11668  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11669   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11670  "sar{w}\t%0"
11671  [(set_attr "type" "ishift")
11672   (set (attr "length") 
11673     (if_then_else (match_operand 0 "register_operand" "") 
11674	(const_string "2")
11675	(const_string "*")))])
11676
11677(define_insn "*ashrhi3_1"
11678  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11679	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11680		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11681   (clobber (reg:CC 17))]
11682  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11683  "@
11684   sar{w}\t{%2, %0|%0, %2}
11685   sar{w}\t{%b2, %0|%0, %b2}"
11686  [(set_attr "type" "ishift")
11687   (set_attr "mode" "HI")])
11688
11689;; This pattern can't accept a variable shift count, since shifts by
11690;; zero don't affect the flags.  We assume that shifts by constant
11691;; zero are optimized away.
11692(define_insn "*ashrhi3_one_bit_cmp"
11693  [(set (reg 17)
11694	(compare
11695	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11696		       (match_operand:QI 2 "const_int_1_operand" ""))
11697	  (const_int 0)))
11698   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11699	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11700  "ix86_match_ccmode (insn, CCGOCmode)
11701   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11702   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703  "sar{w}\t%0"
11704  [(set_attr "type" "ishift")
11705   (set (attr "length") 
11706     (if_then_else (match_operand 0 "register_operand" "") 
11707	(const_string "2")
11708	(const_string "*")))])
11709
11710;; This pattern can't accept a variable shift count, since shifts by
11711;; zero don't affect the flags.  We assume that shifts by constant
11712;; zero are optimized away.
11713(define_insn "*ashrhi3_cmp"
11714  [(set (reg 17)
11715	(compare
11716	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11718	  (const_int 0)))
11719   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11720	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11721  "ix86_match_ccmode (insn, CCGOCmode)
11722   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11723  "sar{w}\t{%2, %0|%0, %2}"
11724  [(set_attr "type" "ishift")
11725   (set_attr "mode" "HI")])
11726
11727(define_expand "ashrqi3"
11728  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11729	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11730		     (match_operand:QI 2 "nonmemory_operand" "")))
11731   (clobber (reg:CC 17))]
11732  "TARGET_QIMODE_MATH"
11733  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11734
11735(define_insn "*ashrqi3_1_one_bit"
11736  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11737	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11738		     (match_operand:QI 2 "const_int_1_operand" "")))
11739   (clobber (reg:CC 17))]
11740  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11741   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11742  "sar{b}\t%0"
11743  [(set_attr "type" "ishift")
11744   (set (attr "length") 
11745     (if_then_else (match_operand 0 "register_operand" "") 
11746	(const_string "2")
11747	(const_string "*")))])
11748
11749(define_insn "*ashrqi3_1"
11750  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11751	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11752		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11753   (clobber (reg:CC 17))]
11754  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11755  "@
11756   sar{b}\t{%2, %0|%0, %2}
11757   sar{b}\t{%b2, %0|%0, %b2}"
11758  [(set_attr "type" "ishift")
11759   (set_attr "mode" "QI")])
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 "*ashrqi3_one_bit_cmp"
11765  [(set (reg 17)
11766	(compare
11767	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11768		       (match_operand:QI 2 "const_int_1_operand" "I"))
11769	  (const_int 0)))
11770   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11771	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11772  "ix86_match_ccmode (insn, CCGOCmode)
11773   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11774   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11775  "sar{b}\t%0"
11776  [(set_attr "type" "ishift")
11777   (set (attr "length") 
11778     (if_then_else (match_operand 0 "register_operand" "") 
11779	(const_string "2")
11780	(const_string "*")))])
11781
11782;; This pattern can't accept a variable shift count, since shifts by
11783;; zero don't affect the flags.  We assume that shifts by constant
11784;; zero are optimized away.
11785(define_insn "*ashrqi3_cmp"
11786  [(set (reg 17)
11787	(compare
11788	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
11790	  (const_int 0)))
11791   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11792	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11793  "ix86_match_ccmode (insn, CCGOCmode)
11794   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11795  "sar{b}\t{%2, %0|%0, %2}"
11796  [(set_attr "type" "ishift")
11797   (set_attr "mode" "QI")])
11798
11799;; Logical shift instructions
11800
11801;; See comment above `ashldi3' about how this works.
11802
11803(define_expand "lshrdi3"
11804  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11805		   (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11806			        (match_operand:QI 2 "nonmemory_operand" "")))
11807	      (clobber (reg:CC 17))])]
11808  ""
11809{
11810  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11811    {
11812      emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11813      DONE;
11814    }
11815  ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11816  DONE;
11817})
11818
11819(define_insn "*lshrdi3_1_one_bit_rex64"
11820  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11821	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11822		     (match_operand:QI 2 "const_int_1_operand" "")))
11823   (clobber (reg:CC 17))]
11824  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11825   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11826  "shr{q}\t%0"
11827  [(set_attr "type" "ishift")
11828   (set (attr "length") 
11829     (if_then_else (match_operand:DI 0 "register_operand" "") 
11830	(const_string "2")
11831	(const_string "*")))])
11832
11833(define_insn "*lshrdi3_1_rex64"
11834  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11835	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11836		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11837   (clobber (reg:CC 17))]
11838  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11839  "@
11840   shr{q}\t{%2, %0|%0, %2}
11841   shr{q}\t{%b2, %0|%0, %b2}"
11842  [(set_attr "type" "ishift")
11843   (set_attr "mode" "DI")])
11844
11845;; This pattern can't accept a variable shift count, since shifts by
11846;; zero don't affect the flags.  We assume that shifts by constant
11847;; zero are optimized away.
11848(define_insn "*lshrdi3_cmp_one_bit_rex64"
11849  [(set (reg 17)
11850	(compare
11851	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11852		       (match_operand:QI 2 "const_int_1_operand" ""))
11853	  (const_int 0)))
11854   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11855	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
11856  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11857   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11858   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11859  "shr{q}\t%0"
11860  [(set_attr "type" "ishift")
11861   (set (attr "length") 
11862     (if_then_else (match_operand:DI 0 "register_operand" "") 
11863	(const_string "2")
11864	(const_string "*")))])
11865
11866;; This pattern can't accept a variable shift count, since shifts by
11867;; zero don't affect the flags.  We assume that shifts by constant
11868;; zero are optimized away.
11869(define_insn "*lshrdi3_cmp_rex64"
11870  [(set (reg 17)
11871	(compare
11872	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11873		       (match_operand:QI 2 "const_int_operand" "e"))
11874	  (const_int 0)))
11875   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11876	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
11877  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11878   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11879  "shr{q}\t{%2, %0|%0, %2}"
11880  [(set_attr "type" "ishift")
11881   (set_attr "mode" "DI")])
11882
11883(define_insn "lshrdi3_1"
11884  [(set (match_operand:DI 0 "register_operand" "=r")
11885	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11886		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11887   (clobber (match_scratch:SI 3 "=&r"))
11888   (clobber (reg:CC 17))]
11889  "!TARGET_64BIT && TARGET_CMOVE"
11890  "#"
11891  [(set_attr "type" "multi")])
11892
11893(define_insn "*lshrdi3_2"
11894  [(set (match_operand:DI 0 "register_operand" "=r")
11895	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11896		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11897   (clobber (reg:CC 17))]
11898  "!TARGET_64BIT"
11899  "#"
11900  [(set_attr "type" "multi")])
11901
11902(define_split 
11903  [(set (match_operand:DI 0 "register_operand" "")
11904	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11905		     (match_operand:QI 2 "nonmemory_operand" "")))
11906   (clobber (match_scratch:SI 3 ""))
11907   (clobber (reg:CC 17))]
11908  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11909  [(const_int 0)]
11910  "ix86_split_lshrdi (operands, operands[3]); DONE;")
11911
11912(define_split 
11913  [(set (match_operand:DI 0 "register_operand" "")
11914	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11915		     (match_operand:QI 2 "nonmemory_operand" "")))
11916   (clobber (reg:CC 17))]
11917  "!TARGET_64BIT && reload_completed"
11918  [(const_int 0)]
11919  "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11920
11921(define_expand "lshrsi3"
11922  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11923	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11924		     (match_operand:QI 2 "nonmemory_operand" "")))
11925   (clobber (reg:CC 17))]
11926  ""
11927  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11928
11929(define_insn "*lshrsi3_1_one_bit"
11930  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11931	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11932		     (match_operand:QI 2 "const_int_1_operand" "")))
11933   (clobber (reg:CC 17))]
11934  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11935   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11936  "shr{l}\t%0"
11937  [(set_attr "type" "ishift")
11938   (set (attr "length") 
11939     (if_then_else (match_operand:SI 0 "register_operand" "") 
11940	(const_string "2")
11941	(const_string "*")))])
11942
11943(define_insn "*lshrsi3_1_one_bit_zext"
11944  [(set (match_operand:DI 0 "register_operand" "=r")
11945	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11946		     (match_operand:QI 2 "const_int_1_operand" "")))
11947   (clobber (reg:CC 17))]
11948  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11949   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11950  "shr{l}\t%k0"
11951  [(set_attr "type" "ishift")
11952   (set_attr "length" "2")])
11953
11954(define_insn "*lshrsi3_1"
11955  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11956	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11957		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11958   (clobber (reg:CC 17))]
11959  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11960  "@
11961   shr{l}\t{%2, %0|%0, %2}
11962   shr{l}\t{%b2, %0|%0, %b2}"
11963  [(set_attr "type" "ishift")
11964   (set_attr "mode" "SI")])
11965
11966(define_insn "*lshrsi3_1_zext"
11967  [(set (match_operand:DI 0 "register_operand" "=r,r")
11968	(zero_extend:DI
11969	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11970		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11971   (clobber (reg:CC 17))]
11972  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11973  "@
11974   shr{l}\t{%2, %k0|%k0, %2}
11975   shr{l}\t{%b2, %k0|%k0, %b2}"
11976  [(set_attr "type" "ishift")
11977   (set_attr "mode" "SI")])
11978
11979;; This pattern can't accept a variable shift count, since shifts by
11980;; zero don't affect the flags.  We assume that shifts by constant
11981;; zero are optimized away.
11982(define_insn "*lshrsi3_one_bit_cmp"
11983  [(set (reg 17)
11984	(compare
11985	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11986		       (match_operand:QI 2 "const_int_1_operand" ""))
11987	  (const_int 0)))
11988   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11989	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
11990  "ix86_match_ccmode (insn, CCGOCmode)
11991   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11992   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11993  "shr{l}\t%0"
11994  [(set_attr "type" "ishift")
11995   (set (attr "length") 
11996     (if_then_else (match_operand:SI 0 "register_operand" "") 
11997	(const_string "2")
11998	(const_string "*")))])
11999
12000(define_insn "*lshrsi3_cmp_one_bit_zext"
12001  [(set (reg 17)
12002	(compare
12003	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12004		       (match_operand:QI 2 "const_int_1_operand" ""))
12005	  (const_int 0)))
12006   (set (match_operand:DI 0 "register_operand" "=r")
12007	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12008  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12009   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12010   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12011  "shr{l}\t%k0"
12012  [(set_attr "type" "ishift")
12013   (set_attr "length" "2")])
12014
12015;; This pattern can't accept a variable shift count, since shifts by
12016;; zero don't affect the flags.  We assume that shifts by constant
12017;; zero are optimized away.
12018(define_insn "*lshrsi3_cmp"
12019  [(set (reg 17)
12020	(compare
12021	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12022		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12023	  (const_int 0)))
12024   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12025	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12026  "ix86_match_ccmode (insn, CCGOCmode)
12027   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12028  "shr{l}\t{%2, %0|%0, %2}"
12029  [(set_attr "type" "ishift")
12030   (set_attr "mode" "SI")])
12031
12032(define_insn "*lshrsi3_cmp_zext"
12033  [(set (reg 17)
12034	(compare
12035	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12036		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12037	  (const_int 0)))
12038   (set (match_operand:DI 0 "register_operand" "=r")
12039	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12040  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12041   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12042  "shr{l}\t{%2, %k0|%k0, %2}"
12043  [(set_attr "type" "ishift")
12044   (set_attr "mode" "SI")])
12045
12046(define_expand "lshrhi3"
12047  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12048	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12049		     (match_operand:QI 2 "nonmemory_operand" "")))
12050   (clobber (reg:CC 17))]
12051  "TARGET_HIMODE_MATH"
12052  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12053
12054(define_insn "*lshrhi3_1_one_bit"
12055  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12056	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12057		     (match_operand:QI 2 "const_int_1_operand" "")))
12058   (clobber (reg:CC 17))]
12059  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12060   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12061  "shr{w}\t%0"
12062  [(set_attr "type" "ishift")
12063   (set (attr "length") 
12064     (if_then_else (match_operand 0 "register_operand" "") 
12065	(const_string "2")
12066	(const_string "*")))])
12067
12068(define_insn "*lshrhi3_1"
12069  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12070	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12071		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12072   (clobber (reg:CC 17))]
12073  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12074  "@
12075   shr{w}\t{%2, %0|%0, %2}
12076   shr{w}\t{%b2, %0|%0, %b2}"
12077  [(set_attr "type" "ishift")
12078   (set_attr "mode" "HI")])
12079
12080;; This pattern can't accept a variable shift count, since shifts by
12081;; zero don't affect the flags.  We assume that shifts by constant
12082;; zero are optimized away.
12083(define_insn "*lshrhi3_one_bit_cmp"
12084  [(set (reg 17)
12085	(compare
12086	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12087		       (match_operand:QI 2 "const_int_1_operand" ""))
12088	  (const_int 0)))
12089   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12090	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12091  "ix86_match_ccmode (insn, CCGOCmode)
12092   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12093   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12094  "shr{w}\t%0"
12095  [(set_attr "type" "ishift")
12096   (set (attr "length") 
12097     (if_then_else (match_operand:SI 0 "register_operand" "") 
12098	(const_string "2")
12099	(const_string "*")))])
12100
12101;; This pattern can't accept a variable shift count, since shifts by
12102;; zero don't affect the flags.  We assume that shifts by constant
12103;; zero are optimized away.
12104(define_insn "*lshrhi3_cmp"
12105  [(set (reg 17)
12106	(compare
12107	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12108		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12109	  (const_int 0)))
12110   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12111	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12112  "ix86_match_ccmode (insn, CCGOCmode)
12113   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12114  "shr{w}\t{%2, %0|%0, %2}"
12115  [(set_attr "type" "ishift")
12116   (set_attr "mode" "HI")])
12117
12118(define_expand "lshrqi3"
12119  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12120	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12121		     (match_operand:QI 2 "nonmemory_operand" "")))
12122   (clobber (reg:CC 17))]
12123  "TARGET_QIMODE_MATH"
12124  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12125
12126(define_insn "*lshrqi3_1_one_bit"
12127  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12128	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12129		     (match_operand:QI 2 "const_int_1_operand" "")))
12130   (clobber (reg:CC 17))]
12131  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12132   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12133  "shr{b}\t%0"
12134  [(set_attr "type" "ishift")
12135   (set (attr "length") 
12136     (if_then_else (match_operand 0 "register_operand" "") 
12137	(const_string "2")
12138	(const_string "*")))])
12139
12140(define_insn "*lshrqi3_1"
12141  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12142	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12143		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12144   (clobber (reg:CC 17))]
12145  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12146  "@
12147   shr{b}\t{%2, %0|%0, %2}
12148   shr{b}\t{%b2, %0|%0, %b2}"
12149  [(set_attr "type" "ishift")
12150   (set_attr "mode" "QI")])
12151
12152;; This pattern can't accept a variable shift count, since shifts by
12153;; zero don't affect the flags.  We assume that shifts by constant
12154;; zero are optimized away.
12155(define_insn "*lshrqi2_one_bit_cmp"
12156  [(set (reg 17)
12157	(compare
12158	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12159		       (match_operand:QI 2 "const_int_1_operand" ""))
12160	  (const_int 0)))
12161   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12162	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12163  "ix86_match_ccmode (insn, CCGOCmode)
12164   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12165   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12166  "shr{b}\t%0"
12167  [(set_attr "type" "ishift")
12168   (set (attr "length") 
12169     (if_then_else (match_operand:SI 0 "register_operand" "") 
12170	(const_string "2")
12171	(const_string "*")))])
12172
12173;; This pattern can't accept a variable shift count, since shifts by
12174;; zero don't affect the flags.  We assume that shifts by constant
12175;; zero are optimized away.
12176(define_insn "*lshrqi2_cmp"
12177  [(set (reg 17)
12178	(compare
12179	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12180		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
12181	  (const_int 0)))
12182   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12183	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12184  "ix86_match_ccmode (insn, CCGOCmode)
12185   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12186  "shr{b}\t{%2, %0|%0, %2}"
12187  [(set_attr "type" "ishift")
12188   (set_attr "mode" "QI")])
12189
12190;; Rotate instructions
12191
12192(define_expand "rotldi3"
12193  [(set (match_operand:DI 0 "nonimmediate_operand" "")
12194	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12195		   (match_operand:QI 2 "nonmemory_operand" "")))
12196   (clobber (reg:CC 17))]
12197  "TARGET_64BIT"
12198  "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12199
12200(define_insn "*rotlsi3_1_one_bit_rex64"
12201  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12202	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12203		   (match_operand:QI 2 "const_int_1_operand" "")))
12204   (clobber (reg:CC 17))]
12205  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12206   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12207  "rol{q}\t%0"
12208  [(set_attr "type" "ishift")
12209   (set (attr "length") 
12210     (if_then_else (match_operand:DI 0 "register_operand" "") 
12211	(const_string "2")
12212	(const_string "*")))])
12213
12214(define_insn "*rotldi3_1_rex64"
12215  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12216	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12217		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12218   (clobber (reg:CC 17))]
12219  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12220  "@
12221   rol{q}\t{%2, %0|%0, %2}
12222   rol{q}\t{%b2, %0|%0, %b2}"
12223  [(set_attr "type" "ishift")
12224   (set_attr "mode" "DI")])
12225
12226(define_expand "rotlsi3"
12227  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12228	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12229		   (match_operand:QI 2 "nonmemory_operand" "")))
12230   (clobber (reg:CC 17))]
12231  ""
12232  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12233
12234(define_insn "*rotlsi3_1_one_bit"
12235  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12236	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12237		   (match_operand:QI 2 "const_int_1_operand" "")))
12238   (clobber (reg:CC 17))]
12239  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12240   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12241  "rol{l}\t%0"
12242  [(set_attr "type" "ishift")
12243   (set (attr "length") 
12244     (if_then_else (match_operand:SI 0 "register_operand" "") 
12245	(const_string "2")
12246	(const_string "*")))])
12247
12248(define_insn "*rotlsi3_1_one_bit_zext"
12249  [(set (match_operand:DI 0 "register_operand" "=r")
12250	(zero_extend:DI
12251	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12252		     (match_operand:QI 2 "const_int_1_operand" ""))))
12253   (clobber (reg:CC 17))]
12254  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12255   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12256  "rol{l}\t%k0"
12257  [(set_attr "type" "ishift")
12258   (set_attr "length" "2")])
12259
12260(define_insn "*rotlsi3_1"
12261  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12262	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12263		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12264   (clobber (reg:CC 17))]
12265  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12266  "@
12267   rol{l}\t{%2, %0|%0, %2}
12268   rol{l}\t{%b2, %0|%0, %b2}"
12269  [(set_attr "type" "ishift")
12270   (set_attr "mode" "SI")])
12271
12272(define_insn "*rotlsi3_1_zext"
12273  [(set (match_operand:DI 0 "register_operand" "=r,r")
12274	(zero_extend:DI
12275	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12276		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12277   (clobber (reg:CC 17))]
12278  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12279  "@
12280   rol{l}\t{%2, %k0|%k0, %2}
12281   rol{l}\t{%b2, %k0|%k0, %b2}"
12282  [(set_attr "type" "ishift")
12283   (set_attr "mode" "SI")])
12284
12285(define_expand "rotlhi3"
12286  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12287	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12288		   (match_operand:QI 2 "nonmemory_operand" "")))
12289   (clobber (reg:CC 17))]
12290  "TARGET_HIMODE_MATH"
12291  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12292
12293(define_insn "*rotlhi3_1_one_bit"
12294  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12295	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12296		   (match_operand:QI 2 "const_int_1_operand" "")))
12297   (clobber (reg:CC 17))]
12298  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12299   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12300  "rol{w}\t%0"
12301  [(set_attr "type" "ishift")
12302   (set (attr "length") 
12303     (if_then_else (match_operand 0 "register_operand" "") 
12304	(const_string "2")
12305	(const_string "*")))])
12306
12307(define_insn "*rotlhi3_1"
12308  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12309	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12310		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12311   (clobber (reg:CC 17))]
12312  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12313  "@
12314   rol{w}\t{%2, %0|%0, %2}
12315   rol{w}\t{%b2, %0|%0, %b2}"
12316  [(set_attr "type" "ishift")
12317   (set_attr "mode" "HI")])
12318
12319(define_expand "rotlqi3"
12320  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12321	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12322		   (match_operand:QI 2 "nonmemory_operand" "")))
12323   (clobber (reg:CC 17))]
12324  "TARGET_QIMODE_MATH"
12325  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12326
12327(define_insn "*rotlqi3_1_one_bit"
12328  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12329	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12330		   (match_operand:QI 2 "const_int_1_operand" "")))
12331   (clobber (reg:CC 17))]
12332  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12333   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12334  "rol{b}\t%0"
12335  [(set_attr "type" "ishift")
12336   (set (attr "length") 
12337     (if_then_else (match_operand 0 "register_operand" "") 
12338	(const_string "2")
12339	(const_string "*")))])
12340
12341(define_insn "*rotlqi3_1"
12342  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12343	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12344		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12345   (clobber (reg:CC 17))]
12346  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12347  "@
12348   rol{b}\t{%2, %0|%0, %2}
12349   rol{b}\t{%b2, %0|%0, %b2}"
12350  [(set_attr "type" "ishift")
12351   (set_attr "mode" "QI")])
12352
12353(define_expand "rotrdi3"
12354  [(set (match_operand:DI 0 "nonimmediate_operand" "")
12355	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12356		     (match_operand:QI 2 "nonmemory_operand" "")))
12357   (clobber (reg:CC 17))]
12358  "TARGET_64BIT"
12359  "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12360
12361(define_insn "*rotrdi3_1_one_bit_rex64"
12362  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12363	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12364		     (match_operand:QI 2 "const_int_1_operand" "")))
12365   (clobber (reg:CC 17))]
12366  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12367   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12368  "ror{q}\t%0"
12369  [(set_attr "type" "ishift")
12370   (set (attr "length") 
12371     (if_then_else (match_operand:DI 0 "register_operand" "") 
12372	(const_string "2")
12373	(const_string "*")))])
12374
12375(define_insn "*rotrdi3_1_rex64"
12376  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12377	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12378		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12379   (clobber (reg:CC 17))]
12380  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12381  "@
12382   ror{q}\t{%2, %0|%0, %2}
12383   ror{q}\t{%b2, %0|%0, %b2}"
12384  [(set_attr "type" "ishift")
12385   (set_attr "mode" "DI")])
12386
12387(define_expand "rotrsi3"
12388  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12389	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12390		     (match_operand:QI 2 "nonmemory_operand" "")))
12391   (clobber (reg:CC 17))]
12392  ""
12393  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12394
12395(define_insn "*rotrsi3_1_one_bit"
12396  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12397	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12398		     (match_operand:QI 2 "const_int_1_operand" "")))
12399   (clobber (reg:CC 17))]
12400  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12401   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12402  "ror{l}\t%0"
12403  [(set_attr "type" "ishift")
12404   (set (attr "length") 
12405     (if_then_else (match_operand:SI 0 "register_operand" "") 
12406	(const_string "2")
12407	(const_string "*")))])
12408
12409(define_insn "*rotrsi3_1_one_bit_zext"
12410  [(set (match_operand:DI 0 "register_operand" "=r")
12411	(zero_extend:DI
12412	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12413		       (match_operand:QI 2 "const_int_1_operand" ""))))
12414   (clobber (reg:CC 17))]
12415  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12416   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12417  "ror{l}\t%k0"
12418  [(set_attr "type" "ishift")
12419   (set (attr "length") 
12420     (if_then_else (match_operand:SI 0 "register_operand" "") 
12421	(const_string "2")
12422	(const_string "*")))])
12423
12424(define_insn "*rotrsi3_1"
12425  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12426	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12427		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12428   (clobber (reg:CC 17))]
12429  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12430  "@
12431   ror{l}\t{%2, %0|%0, %2}
12432   ror{l}\t{%b2, %0|%0, %b2}"
12433  [(set_attr "type" "ishift")
12434   (set_attr "mode" "SI")])
12435
12436(define_insn "*rotrsi3_1_zext"
12437  [(set (match_operand:DI 0 "register_operand" "=r,r")
12438	(zero_extend:DI
12439	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12440		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12441   (clobber (reg:CC 17))]
12442  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12443  "@
12444   ror{l}\t{%2, %k0|%k0, %2}
12445   ror{l}\t{%b2, %k0|%k0, %b2}"
12446  [(set_attr "type" "ishift")
12447   (set_attr "mode" "SI")])
12448
12449(define_expand "rotrhi3"
12450  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12451	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12452		     (match_operand:QI 2 "nonmemory_operand" "")))
12453   (clobber (reg:CC 17))]
12454  "TARGET_HIMODE_MATH"
12455  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12456
12457(define_insn "*rotrhi3_one_bit"
12458  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12459	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12460		     (match_operand:QI 2 "const_int_1_operand" "")))
12461   (clobber (reg:CC 17))]
12462  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12463   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12464  "ror{w}\t%0"
12465  [(set_attr "type" "ishift")
12466   (set (attr "length") 
12467     (if_then_else (match_operand 0 "register_operand" "") 
12468	(const_string "2")
12469	(const_string "*")))])
12470
12471(define_insn "*rotrhi3"
12472  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12473	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12474		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12475   (clobber (reg:CC 17))]
12476  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12477  "@
12478   ror{w}\t{%2, %0|%0, %2}
12479   ror{w}\t{%b2, %0|%0, %b2}"
12480  [(set_attr "type" "ishift")
12481   (set_attr "mode" "HI")])
12482
12483(define_expand "rotrqi3"
12484  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12485	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12486		     (match_operand:QI 2 "nonmemory_operand" "")))
12487   (clobber (reg:CC 17))]
12488  "TARGET_QIMODE_MATH"
12489  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12490
12491(define_insn "*rotrqi3_1_one_bit"
12492  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12493	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12494		     (match_operand:QI 2 "const_int_1_operand" "")))
12495   (clobber (reg:CC 17))]
12496  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12497   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12498  "ror{b}\t%0"
12499  [(set_attr "type" "ishift")
12500   (set (attr "length") 
12501     (if_then_else (match_operand 0 "register_operand" "") 
12502	(const_string "2")
12503	(const_string "*")))])
12504
12505(define_insn "*rotrqi3_1"
12506  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12507	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12508		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12509   (clobber (reg:CC 17))]
12510  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12511  "@
12512   ror{b}\t{%2, %0|%0, %2}
12513   ror{b}\t{%b2, %0|%0, %b2}"
12514  [(set_attr "type" "ishift")
12515   (set_attr "mode" "QI")])
12516
12517;; Bit set / bit test instructions
12518
12519(define_expand "extv"
12520  [(set (match_operand:SI 0 "register_operand" "")
12521	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
12522			 (match_operand:SI 2 "immediate_operand" "")
12523			 (match_operand:SI 3 "immediate_operand" "")))]
12524  ""
12525{
12526  /* Handle extractions from %ah et al.  */
12527  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12528    FAIL;
12529
12530  /* From mips.md: extract_bit_field doesn't verify that our source
12531     matches the predicate, so check it again here.  */
12532  if (! register_operand (operands[1], VOIDmode))
12533    FAIL;
12534})
12535
12536(define_expand "extzv"
12537  [(set (match_operand:SI 0 "register_operand" "")
12538	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
12539			 (match_operand:SI 2 "immediate_operand" "")
12540			 (match_operand:SI 3 "immediate_operand" "")))]
12541  ""
12542{
12543  /* Handle extractions from %ah et al.  */
12544  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12545    FAIL;
12546
12547  /* From mips.md: extract_bit_field doesn't verify that our source
12548     matches the predicate, so check it again here.  */
12549  if (! register_operand (operands[1], VOIDmode))
12550    FAIL;
12551})
12552
12553(define_expand "insv"
12554  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12555			 (match_operand:SI 1 "immediate_operand" "")
12556			 (match_operand:SI 2 "immediate_operand" ""))
12557        (match_operand:SI 3 "register_operand" ""))]
12558  ""
12559{
12560  /* Handle extractions from %ah et al.  */
12561  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12562    FAIL;
12563
12564  /* From mips.md: insert_bit_field doesn't verify that our source
12565     matches the predicate, so check it again here.  */
12566  if (! register_operand (operands[0], VOIDmode))
12567    FAIL;
12568})
12569
12570;; %%% bts, btr, btc, bt.
12571
12572;; Store-flag instructions.
12573
12574;; For all sCOND expanders, also expand the compare or test insn that
12575;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12576
12577;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12578;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12579;; way, which can later delete the movzx if only QImode is needed.
12580
12581(define_expand "seq"
12582  [(set (match_operand:QI 0 "register_operand" "")
12583        (eq:QI (reg:CC 17) (const_int 0)))]
12584  ""
12585  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12586
12587(define_expand "sne"
12588  [(set (match_operand:QI 0 "register_operand" "")
12589        (ne:QI (reg:CC 17) (const_int 0)))]
12590  ""
12591  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12592
12593(define_expand "sgt"
12594  [(set (match_operand:QI 0 "register_operand" "")
12595        (gt:QI (reg:CC 17) (const_int 0)))]
12596  ""
12597  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12598
12599(define_expand "sgtu"
12600  [(set (match_operand:QI 0 "register_operand" "")
12601        (gtu:QI (reg:CC 17) (const_int 0)))]
12602  ""
12603  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12604
12605(define_expand "slt"
12606  [(set (match_operand:QI 0 "register_operand" "")
12607        (lt:QI (reg:CC 17) (const_int 0)))]
12608  ""
12609  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12610
12611(define_expand "sltu"
12612  [(set (match_operand:QI 0 "register_operand" "")
12613        (ltu:QI (reg:CC 17) (const_int 0)))]
12614  ""
12615  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12616
12617(define_expand "sge"
12618  [(set (match_operand:QI 0 "register_operand" "")
12619        (ge:QI (reg:CC 17) (const_int 0)))]
12620  ""
12621  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12622
12623(define_expand "sgeu"
12624  [(set (match_operand:QI 0 "register_operand" "")
12625        (geu:QI (reg:CC 17) (const_int 0)))]
12626  ""
12627  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12628
12629(define_expand "sle"
12630  [(set (match_operand:QI 0 "register_operand" "")
12631        (le:QI (reg:CC 17) (const_int 0)))]
12632  ""
12633  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12634
12635(define_expand "sleu"
12636  [(set (match_operand:QI 0 "register_operand" "")
12637        (leu:QI (reg:CC 17) (const_int 0)))]
12638  ""
12639  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12640
12641(define_expand "sunordered"
12642  [(set (match_operand:QI 0 "register_operand" "")
12643        (unordered:QI (reg:CC 17) (const_int 0)))]
12644  "TARGET_80387 || TARGET_SSE"
12645  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12646
12647(define_expand "sordered"
12648  [(set (match_operand:QI 0 "register_operand" "")
12649        (ordered:QI (reg:CC 17) (const_int 0)))]
12650  "TARGET_80387"
12651  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12652
12653(define_expand "suneq"
12654  [(set (match_operand:QI 0 "register_operand" "")
12655        (uneq:QI (reg:CC 17) (const_int 0)))]
12656  "TARGET_80387 || TARGET_SSE"
12657  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12658
12659(define_expand "sunge"
12660  [(set (match_operand:QI 0 "register_operand" "")
12661        (unge:QI (reg:CC 17) (const_int 0)))]
12662  "TARGET_80387 || TARGET_SSE"
12663  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12664
12665(define_expand "sungt"
12666  [(set (match_operand:QI 0 "register_operand" "")
12667        (ungt:QI (reg:CC 17) (const_int 0)))]
12668  "TARGET_80387 || TARGET_SSE"
12669  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12670
12671(define_expand "sunle"
12672  [(set (match_operand:QI 0 "register_operand" "")
12673        (unle:QI (reg:CC 17) (const_int 0)))]
12674  "TARGET_80387 || TARGET_SSE"
12675  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12676
12677(define_expand "sunlt"
12678  [(set (match_operand:QI 0 "register_operand" "")
12679        (unlt:QI (reg:CC 17) (const_int 0)))]
12680  "TARGET_80387 || TARGET_SSE"
12681  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12682
12683(define_expand "sltgt"
12684  [(set (match_operand:QI 0 "register_operand" "")
12685        (ltgt:QI (reg:CC 17) (const_int 0)))]
12686  "TARGET_80387 || TARGET_SSE"
12687  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12688
12689(define_insn "*setcc_1"
12690  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12691	(match_operator:QI 1 "ix86_comparison_operator"
12692	  [(reg 17) (const_int 0)]))]
12693  ""
12694  "set%C1\t%0"
12695  [(set_attr "type" "setcc")
12696   (set_attr "mode" "QI")])
12697
12698(define_insn "setcc_2"
12699  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12700	(match_operator:QI 1 "ix86_comparison_operator"
12701	  [(reg 17) (const_int 0)]))]
12702  ""
12703  "set%C1\t%0"
12704  [(set_attr "type" "setcc")
12705   (set_attr "mode" "QI")])
12706
12707;; In general it is not safe to assume too much about CCmode registers,
12708;; so simplify-rtx stops when it sees a second one.  Under certain 
12709;; conditions this is safe on x86, so help combine not create
12710;;
12711;;	seta	%al
12712;;	testb	%al, %al
12713;;	sete	%al
12714
12715(define_split 
12716  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12717	(ne:QI (match_operator 1 "ix86_comparison_operator"
12718	         [(reg 17) (const_int 0)])
12719	    (const_int 0)))]
12720  ""
12721  [(set (match_dup 0) (match_dup 1))]
12722{
12723  PUT_MODE (operands[1], QImode);
12724})
12725
12726(define_split 
12727  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12728	(ne:QI (match_operator 1 "ix86_comparison_operator"
12729	         [(reg 17) (const_int 0)])
12730	    (const_int 0)))]
12731  ""
12732  [(set (match_dup 0) (match_dup 1))]
12733{
12734  PUT_MODE (operands[1], QImode);
12735})
12736
12737(define_split 
12738  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12739	(eq:QI (match_operator 1 "ix86_comparison_operator"
12740	         [(reg 17) (const_int 0)])
12741	    (const_int 0)))]
12742  ""
12743  [(set (match_dup 0) (match_dup 1))]
12744{
12745  rtx new_op1 = copy_rtx (operands[1]);
12746  operands[1] = new_op1;
12747  PUT_MODE (new_op1, QImode);
12748  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12749					GET_MODE (XEXP (new_op1, 0))));
12750
12751  /* Make sure that (a) the CCmode we have for the flags is strong
12752     enough for the reversed compare or (b) we have a valid FP compare.  */
12753  if (! ix86_comparison_operator (new_op1, VOIDmode))
12754    FAIL;
12755})
12756
12757(define_split 
12758  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12759	(eq:QI (match_operator 1 "ix86_comparison_operator"
12760	         [(reg 17) (const_int 0)])
12761	    (const_int 0)))]
12762  ""
12763  [(set (match_dup 0) (match_dup 1))]
12764{
12765  rtx new_op1 = copy_rtx (operands[1]);
12766  operands[1] = new_op1;
12767  PUT_MODE (new_op1, QImode);
12768  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12769					GET_MODE (XEXP (new_op1, 0))));
12770
12771  /* Make sure that (a) the CCmode we have for the flags is strong
12772     enough for the reversed compare or (b) we have a valid FP compare.  */
12773  if (! ix86_comparison_operator (new_op1, VOIDmode))
12774    FAIL;
12775})
12776
12777;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12778;; subsequent logical operations are used to imitate conditional moves.
12779;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12780;; it directly.  Futher holding this value in pseudo register might bring
12781;; problem in implicit normalization in spill code.
12782;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12783;; instructions after reload by splitting the conditional move patterns.
12784
12785(define_insn "*sse_setccsf"
12786  [(set (match_operand:SF 0 "register_operand" "=x")
12787	(match_operator:SF 1 "sse_comparison_operator"
12788	  [(match_operand:SF 2 "register_operand" "0")
12789	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12790  "TARGET_SSE && reload_completed"
12791  "cmp%D1ss\t{%3, %0|%0, %3}"
12792  [(set_attr "type" "sse")
12793   (set_attr "mode" "SF")])
12794
12795(define_insn "*sse_setccdf"
12796  [(set (match_operand:DF 0 "register_operand" "=Y")
12797	(match_operator:DF 1 "sse_comparison_operator"
12798	  [(match_operand:DF 2 "register_operand" "0")
12799	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12800  "TARGET_SSE2 && reload_completed"
12801  "cmp%D1sd\t{%3, %0|%0, %3}"
12802  [(set_attr "type" "sse")
12803   (set_attr "mode" "DF")])
12804
12805;; Basic conditional jump instructions.
12806;; We ignore the overflow flag for signed branch instructions.
12807
12808;; For all bCOND expanders, also expand the compare or test insn that
12809;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
12810
12811(define_expand "beq"
12812  [(set (pc)
12813	(if_then_else (match_dup 1)
12814		      (label_ref (match_operand 0 "" ""))
12815		      (pc)))]
12816  ""
12817  "ix86_expand_branch (EQ, operands[0]); DONE;")
12818
12819(define_expand "bne"
12820  [(set (pc)
12821	(if_then_else (match_dup 1)
12822		      (label_ref (match_operand 0 "" ""))
12823		      (pc)))]
12824  ""
12825  "ix86_expand_branch (NE, operands[0]); DONE;")
12826
12827(define_expand "bgt"
12828  [(set (pc)
12829	(if_then_else (match_dup 1)
12830		      (label_ref (match_operand 0 "" ""))
12831		      (pc)))]
12832  ""
12833  "ix86_expand_branch (GT, operands[0]); DONE;")
12834
12835(define_expand "bgtu"
12836  [(set (pc)
12837	(if_then_else (match_dup 1)
12838		      (label_ref (match_operand 0 "" ""))
12839		      (pc)))]
12840  ""
12841  "ix86_expand_branch (GTU, operands[0]); DONE;")
12842
12843(define_expand "blt"
12844  [(set (pc)
12845	(if_then_else (match_dup 1)
12846		      (label_ref (match_operand 0 "" ""))
12847		      (pc)))]
12848  ""
12849  "ix86_expand_branch (LT, operands[0]); DONE;")
12850
12851(define_expand "bltu"
12852  [(set (pc)
12853	(if_then_else (match_dup 1)
12854		      (label_ref (match_operand 0 "" ""))
12855		      (pc)))]
12856  ""
12857  "ix86_expand_branch (LTU, operands[0]); DONE;")
12858
12859(define_expand "bge"
12860  [(set (pc)
12861	(if_then_else (match_dup 1)
12862		      (label_ref (match_operand 0 "" ""))
12863		      (pc)))]
12864  ""
12865  "ix86_expand_branch (GE, operands[0]); DONE;")
12866
12867(define_expand "bgeu"
12868  [(set (pc)
12869	(if_then_else (match_dup 1)
12870		      (label_ref (match_operand 0 "" ""))
12871		      (pc)))]
12872  ""
12873  "ix86_expand_branch (GEU, operands[0]); DONE;")
12874
12875(define_expand "ble"
12876  [(set (pc)
12877	(if_then_else (match_dup 1)
12878		      (label_ref (match_operand 0 "" ""))
12879		      (pc)))]
12880  ""
12881  "ix86_expand_branch (LE, operands[0]); DONE;")
12882
12883(define_expand "bleu"
12884  [(set (pc)
12885	(if_then_else (match_dup 1)
12886		      (label_ref (match_operand 0 "" ""))
12887		      (pc)))]
12888  ""
12889  "ix86_expand_branch (LEU, operands[0]); DONE;")
12890
12891(define_expand "bunordered"
12892  [(set (pc)
12893	(if_then_else (match_dup 1)
12894		      (label_ref (match_operand 0 "" ""))
12895		      (pc)))]
12896  "TARGET_80387 || TARGET_SSE"
12897  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12898
12899(define_expand "bordered"
12900  [(set (pc)
12901	(if_then_else (match_dup 1)
12902		      (label_ref (match_operand 0 "" ""))
12903		      (pc)))]
12904  "TARGET_80387 || TARGET_SSE"
12905  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12906
12907(define_expand "buneq"
12908  [(set (pc)
12909	(if_then_else (match_dup 1)
12910		      (label_ref (match_operand 0 "" ""))
12911		      (pc)))]
12912  "TARGET_80387 || TARGET_SSE"
12913  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12914
12915(define_expand "bunge"
12916  [(set (pc)
12917	(if_then_else (match_dup 1)
12918		      (label_ref (match_operand 0 "" ""))
12919		      (pc)))]
12920  "TARGET_80387 || TARGET_SSE"
12921  "ix86_expand_branch (UNGE, operands[0]); DONE;")
12922
12923(define_expand "bungt"
12924  [(set (pc)
12925	(if_then_else (match_dup 1)
12926		      (label_ref (match_operand 0 "" ""))
12927		      (pc)))]
12928  "TARGET_80387 || TARGET_SSE"
12929  "ix86_expand_branch (UNGT, operands[0]); DONE;")
12930
12931(define_expand "bunle"
12932  [(set (pc)
12933	(if_then_else (match_dup 1)
12934		      (label_ref (match_operand 0 "" ""))
12935		      (pc)))]
12936  "TARGET_80387 || TARGET_SSE"
12937  "ix86_expand_branch (UNLE, operands[0]); DONE;")
12938
12939(define_expand "bunlt"
12940  [(set (pc)
12941	(if_then_else (match_dup 1)
12942		      (label_ref (match_operand 0 "" ""))
12943		      (pc)))]
12944  "TARGET_80387 || TARGET_SSE"
12945  "ix86_expand_branch (UNLT, operands[0]); DONE;")
12946
12947(define_expand "bltgt"
12948  [(set (pc)
12949	(if_then_else (match_dup 1)
12950		      (label_ref (match_operand 0 "" ""))
12951		      (pc)))]
12952  "TARGET_80387 || TARGET_SSE"
12953  "ix86_expand_branch (LTGT, operands[0]); DONE;")
12954
12955(define_insn "*jcc_1"
12956  [(set (pc)
12957	(if_then_else (match_operator 1 "ix86_comparison_operator"
12958				      [(reg 17) (const_int 0)])
12959		      (label_ref (match_operand 0 "" ""))
12960		      (pc)))]
12961  ""
12962  "%+j%C1\t%l0"
12963  [(set_attr "type" "ibr")
12964   (set (attr "prefix_0f")
12965	   (if_then_else (and (ge (minus (match_dup 0) (pc))
12966				  (const_int -128))
12967			      (lt (minus (match_dup 0) (pc))
12968				  (const_int 124)))
12969	     (const_int 0)
12970	     (const_int 1)))])
12971
12972(define_insn "*jcc_2"
12973  [(set (pc)
12974	(if_then_else (match_operator 1 "ix86_comparison_operator"
12975				      [(reg 17) (const_int 0)])
12976		      (pc)
12977		      (label_ref (match_operand 0 "" ""))))]
12978  ""
12979  "%+j%c1\t%l0"
12980  [(set_attr "type" "ibr")
12981   (set (attr "prefix_0f")
12982	   (if_then_else (and (ge (minus (match_dup 0) (pc))
12983				  (const_int -128))
12984			      (lt (minus (match_dup 0) (pc))
12985				  (const_int 124)))
12986	     (const_int 0)
12987	     (const_int 1)))])
12988
12989;; In general it is not safe to assume too much about CCmode registers,
12990;; so simplify-rtx stops when it sees a second one.  Under certain 
12991;; conditions this is safe on x86, so help combine not create
12992;;
12993;;	seta	%al
12994;;	testb	%al, %al
12995;;	je	Lfoo
12996
12997(define_split 
12998  [(set (pc)
12999	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13000				      [(reg 17) (const_int 0)])
13001			  (const_int 0))
13002		      (label_ref (match_operand 1 "" ""))
13003		      (pc)))]
13004  ""
13005  [(set (pc)
13006	(if_then_else (match_dup 0)
13007		      (label_ref (match_dup 1))
13008		      (pc)))]
13009{
13010  PUT_MODE (operands[0], VOIDmode);
13011})
13012  
13013(define_split 
13014  [(set (pc)
13015	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13016				      [(reg 17) (const_int 0)])
13017			  (const_int 0))
13018		      (label_ref (match_operand 1 "" ""))
13019		      (pc)))]
13020  ""
13021  [(set (pc)
13022	(if_then_else (match_dup 0)
13023		      (label_ref (match_dup 1))
13024		      (pc)))]
13025{
13026  rtx new_op0 = copy_rtx (operands[0]);
13027  operands[0] = new_op0;
13028  PUT_MODE (new_op0, VOIDmode);
13029  PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13030					GET_MODE (XEXP (new_op0, 0))));
13031
13032  /* Make sure that (a) the CCmode we have for the flags is strong
13033     enough for the reversed compare or (b) we have a valid FP compare.  */
13034  if (! ix86_comparison_operator (new_op0, VOIDmode))
13035    FAIL;
13036})
13037
13038;; Define combination compare-and-branch fp compare instructions to use
13039;; during early optimization.  Splitting the operation apart early makes
13040;; for bad code when we want to reverse the operation.
13041
13042(define_insn "*fp_jcc_1"
13043  [(set (pc)
13044	(if_then_else (match_operator 0 "comparison_operator"
13045			[(match_operand 1 "register_operand" "f")
13046			 (match_operand 2 "register_operand" "f")])
13047	  (label_ref (match_operand 3 "" ""))
13048	  (pc)))
13049   (clobber (reg:CCFP 18))
13050   (clobber (reg:CCFP 17))]
13051  "TARGET_CMOVE && TARGET_80387
13052   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13053   && FLOAT_MODE_P (GET_MODE (operands[1]))
13054   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13055   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13056  "#")
13057
13058(define_insn "*fp_jcc_1_sse"
13059  [(set (pc)
13060	(if_then_else (match_operator 0 "comparison_operator"
13061			[(match_operand 1 "register_operand" "f#x,x#f")
13062			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13063	  (label_ref (match_operand 3 "" ""))
13064	  (pc)))
13065   (clobber (reg:CCFP 18))
13066   (clobber (reg:CCFP 17))]
13067  "TARGET_80387
13068   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13069   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13070   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13071  "#")
13072
13073(define_insn "*fp_jcc_1_sse_only"
13074  [(set (pc)
13075	(if_then_else (match_operator 0 "comparison_operator"
13076			[(match_operand 1 "register_operand" "x")
13077			 (match_operand 2 "nonimmediate_operand" "xm")])
13078	  (label_ref (match_operand 3 "" ""))
13079	  (pc)))
13080   (clobber (reg:CCFP 18))
13081   (clobber (reg:CCFP 17))]
13082  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13083   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13084   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13085  "#")
13086
13087(define_insn "*fp_jcc_2"
13088  [(set (pc)
13089	(if_then_else (match_operator 0 "comparison_operator"
13090			[(match_operand 1 "register_operand" "f")
13091			 (match_operand 2 "register_operand" "f")])
13092	  (pc)
13093	  (label_ref (match_operand 3 "" ""))))
13094   (clobber (reg:CCFP 18))
13095   (clobber (reg:CCFP 17))]
13096  "TARGET_CMOVE && TARGET_80387
13097   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13098   && FLOAT_MODE_P (GET_MODE (operands[1]))
13099   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13100   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13101  "#")
13102
13103(define_insn "*fp_jcc_2_sse"
13104  [(set (pc)
13105	(if_then_else (match_operator 0 "comparison_operator"
13106			[(match_operand 1 "register_operand" "f#x,x#f")
13107			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13108	  (pc)
13109	  (label_ref (match_operand 3 "" ""))))
13110   (clobber (reg:CCFP 18))
13111   (clobber (reg:CCFP 17))]
13112  "TARGET_80387
13113   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13114   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13115   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13116  "#")
13117
13118(define_insn "*fp_jcc_2_sse_only"
13119  [(set (pc)
13120	(if_then_else (match_operator 0 "comparison_operator"
13121			[(match_operand 1 "register_operand" "x")
13122			 (match_operand 2 "nonimmediate_operand" "xm")])
13123	  (pc)
13124	  (label_ref (match_operand 3 "" ""))))
13125   (clobber (reg:CCFP 18))
13126   (clobber (reg:CCFP 17))]
13127  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13128   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13129   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13130  "#")
13131
13132(define_insn "*fp_jcc_3"
13133  [(set (pc)
13134	(if_then_else (match_operator 0 "comparison_operator"
13135			[(match_operand 1 "register_operand" "f")
13136			 (match_operand 2 "nonimmediate_operand" "fm")])
13137	  (label_ref (match_operand 3 "" ""))
13138	  (pc)))
13139   (clobber (reg:CCFP 18))
13140   (clobber (reg:CCFP 17))
13141   (clobber (match_scratch:HI 4 "=a"))]
13142  "TARGET_80387
13143   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13144   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13145   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13146   && SELECT_CC_MODE (GET_CODE (operands[0]),
13147		      operands[1], operands[2]) == CCFPmode
13148   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13149  "#")
13150
13151(define_insn "*fp_jcc_4"
13152  [(set (pc)
13153	(if_then_else (match_operator 0 "comparison_operator"
13154			[(match_operand 1 "register_operand" "f")
13155			 (match_operand 2 "nonimmediate_operand" "fm")])
13156	  (pc)
13157	  (label_ref (match_operand 3 "" ""))))
13158   (clobber (reg:CCFP 18))
13159   (clobber (reg:CCFP 17))
13160   (clobber (match_scratch:HI 4 "=a"))]
13161  "TARGET_80387
13162   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13163   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13164   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13165   && SELECT_CC_MODE (GET_CODE (operands[0]),
13166		      operands[1], operands[2]) == CCFPmode
13167   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13168  "#")
13169
13170(define_insn "*fp_jcc_5"
13171  [(set (pc)
13172	(if_then_else (match_operator 0 "comparison_operator"
13173			[(match_operand 1 "register_operand" "f")
13174			 (match_operand 2 "register_operand" "f")])
13175	  (label_ref (match_operand 3 "" ""))
13176	  (pc)))
13177   (clobber (reg:CCFP 18))
13178   (clobber (reg:CCFP 17))
13179   (clobber (match_scratch:HI 4 "=a"))]
13180  "TARGET_80387
13181   && FLOAT_MODE_P (GET_MODE (operands[1]))
13182   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13183   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13184  "#")
13185
13186(define_insn "*fp_jcc_6"
13187  [(set (pc)
13188	(if_then_else (match_operator 0 "comparison_operator"
13189			[(match_operand 1 "register_operand" "f")
13190			 (match_operand 2 "register_operand" "f")])
13191	  (pc)
13192	  (label_ref (match_operand 3 "" ""))))
13193   (clobber (reg:CCFP 18))
13194   (clobber (reg:CCFP 17))
13195   (clobber (match_scratch:HI 4 "=a"))]
13196  "TARGET_80387
13197   && FLOAT_MODE_P (GET_MODE (operands[1]))
13198   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13199   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13200  "#")
13201
13202(define_split
13203  [(set (pc)
13204	(if_then_else (match_operator 0 "comparison_operator"
13205			[(match_operand 1 "register_operand" "")
13206			 (match_operand 2 "nonimmediate_operand" "")])
13207	  (match_operand 3 "" "")
13208	  (match_operand 4 "" "")))
13209   (clobber (reg:CCFP 18))
13210   (clobber (reg:CCFP 17))]
13211  "reload_completed"
13212  [(const_int 0)]
13213{
13214  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13215			operands[3], operands[4], NULL_RTX);
13216  DONE;
13217})
13218
13219(define_split
13220  [(set (pc)
13221	(if_then_else (match_operator 0 "comparison_operator"
13222			[(match_operand 1 "register_operand" "")
13223			 (match_operand 2 "nonimmediate_operand" "")])
13224	  (match_operand 3 "" "")
13225	  (match_operand 4 "" "")))
13226   (clobber (reg:CCFP 18))
13227   (clobber (reg:CCFP 17))
13228   (clobber (match_scratch:HI 5 "=a"))]
13229  "reload_completed"
13230  [(set (pc)
13231	(if_then_else (match_dup 6)
13232	  (match_dup 3)
13233	  (match_dup 4)))]
13234{
13235  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13236			operands[3], operands[4], operands[5]);
13237  DONE;
13238})
13239
13240;; Unconditional and other jump instructions
13241
13242(define_insn "jump"
13243  [(set (pc)
13244	(label_ref (match_operand 0 "" "")))]
13245  ""
13246  "jmp\t%l0"
13247  [(set_attr "type" "ibr")])
13248
13249(define_expand "indirect_jump"
13250  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13251  ""
13252  "")
13253
13254(define_insn "*indirect_jump"
13255  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13256  "!TARGET_64BIT"
13257  "jmp\t%A0"
13258  [(set_attr "type" "ibr")
13259   (set_attr "length_immediate" "0")])
13260
13261(define_insn "*indirect_jump_rtx64"
13262  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13263  "TARGET_64BIT"
13264  "jmp\t%A0"
13265  [(set_attr "type" "ibr")
13266   (set_attr "length_immediate" "0")])
13267
13268(define_expand "tablejump"
13269  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13270	      (use (label_ref (match_operand 1 "" "")))])]
13271  ""
13272{
13273  /* In PIC mode, the table entries are stored GOT-relative.  Convert
13274     the relative address to an absolute address.  */
13275  if (flag_pic)
13276    {
13277      if (TARGET_64BIT)
13278	operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13279					   gen_rtx_LABEL_REF (Pmode, operands[1]),
13280					   NULL_RTX, 0,
13281					   OPTAB_DIRECT);
13282      else if (HAVE_AS_GOTOFF_IN_DATA)
13283	{
13284	  operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13285					     pic_offset_table_rtx, NULL_RTX,
13286					     1, OPTAB_DIRECT);
13287	  current_function_uses_pic_offset_table = 1;
13288	}
13289      else
13290	{
13291	  operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
13292					     operands[0], NULL_RTX, 1,
13293					     OPTAB_DIRECT);
13294	  current_function_uses_pic_offset_table = 1;
13295	}
13296    }
13297})
13298
13299(define_insn "*tablejump_1"
13300  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13301   (use (label_ref (match_operand 1 "" "")))]
13302  "!TARGET_64BIT"
13303  "jmp\t%A0"
13304  [(set_attr "type" "ibr")
13305   (set_attr "length_immediate" "0")])
13306
13307(define_insn "*tablejump_1_rtx64"
13308  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13309   (use (label_ref (match_operand 1 "" "")))]
13310  "TARGET_64BIT"
13311  "jmp\t%A0"
13312  [(set_attr "type" "ibr")
13313   (set_attr "length_immediate" "0")])
13314
13315;; Loop instruction
13316;;
13317;; This is all complicated by the fact that since this is a jump insn
13318;; we must handle our own reloads.
13319
13320(define_expand "doloop_end"
13321  [(use (match_operand 0 "" ""))        ; loop pseudo
13322   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13323   (use (match_operand 2 "" ""))        ; max iterations
13324   (use (match_operand 3 "" ""))        ; loop level 
13325   (use (match_operand 4 "" ""))]       ; label
13326  "!TARGET_64BIT && TARGET_USE_LOOP"
13327  "                                 
13328{
13329  /* Only use cloop on innermost loops.  */
13330  if (INTVAL (operands[3]) > 1)
13331    FAIL;
13332  if (GET_MODE (operands[0]) != SImode)
13333    FAIL;
13334  emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13335					   operands[0]));
13336  DONE;
13337}")
13338
13339(define_insn "doloop_end_internal"
13340  [(set (pc)
13341	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13342			  (const_int 1))
13343		      (label_ref (match_operand 0 "" ""))
13344		      (pc)))
13345   (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13346	(plus:SI (match_dup 1)
13347		 (const_int -1)))
13348   (clobber (match_scratch:SI 3 "=X,X,r"))
13349   (clobber (reg:CC 17))]
13350  "!TARGET_64BIT && TARGET_USE_LOOP"
13351{
13352  if (which_alternative != 0)
13353    return "#";
13354  if (get_attr_length (insn) == 2)
13355    return "%+loop\t%l0";
13356  else
13357    return "dec{l}\t%1\;%+jne\t%l0";
13358}
13359  [(set_attr "ppro_uops" "many")
13360   (set (attr "type")
13361	(if_then_else (and (eq_attr "alternative" "0")
13362			   (and (ge (minus (match_dup 0) (pc))
13363			            (const_int -128))
13364			        (lt (minus (match_dup 0) (pc))
13365			            (const_int 124))))
13366		      (const_string "ibr")
13367		      (const_string "multi")))])
13368
13369(define_split
13370  [(set (pc)
13371	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
13372			  (const_int 1))
13373		      (match_operand 0 "" "")
13374		      (pc)))
13375   (set (match_dup 1)
13376	(plus:SI (match_dup 1)
13377		 (const_int -1)))
13378   (clobber (match_scratch:SI 2 ""))
13379   (clobber (reg:CC 17))]
13380  "!TARGET_64BIT && TARGET_USE_LOOP
13381   && reload_completed
13382   && REGNO (operands[1]) != 2"
13383  [(parallel [(set (reg:CCZ 17)
13384		   (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13385				 (const_int 0)))
13386	      (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13387   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13388			   (match_dup 0)
13389			   (pc)))]
13390  "")
13391  
13392(define_split
13393  [(set (pc)
13394	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
13395			  (const_int 1))
13396		      (match_operand 0 "" "")
13397		      (pc)))
13398   (set (match_operand:SI 2 "nonimmediate_operand" "")
13399	(plus:SI (match_dup 1)
13400		 (const_int -1)))
13401   (clobber (match_scratch:SI 3 ""))
13402   (clobber (reg:CC 17))]
13403  "!TARGET_64BIT && TARGET_USE_LOOP
13404   && reload_completed
13405   && (! REG_P (operands[2])
13406       || ! rtx_equal_p (operands[1], operands[2]))"
13407  [(set (match_dup 3) (match_dup 1))
13408   (parallel [(set (reg:CCZ 17)
13409		   (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13410				(const_int 0)))
13411	      (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13412   (set (match_dup 2) (match_dup 3))
13413   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13414			   (match_dup 0)
13415			   (pc)))]
13416  "")
13417
13418;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13419
13420(define_peephole2
13421  [(set (reg 17) (match_operand 0 "" ""))
13422   (set (match_operand:QI 1 "register_operand" "")
13423	(match_operator:QI 2 "ix86_comparison_operator"
13424	  [(reg 17) (const_int 0)]))
13425   (set (match_operand 3 "q_regs_operand" "")
13426	(zero_extend (match_dup 1)))]
13427  "(peep2_reg_dead_p (3, operands[1])
13428    || operands_match_p (operands[1], operands[3]))
13429   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13430  [(set (match_dup 4) (match_dup 0))
13431   (set (strict_low_part (match_dup 5))
13432	(match_dup 2))]
13433{
13434  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13435  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13436  ix86_expand_clear (operands[3]);
13437})
13438
13439;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13440
13441(define_peephole2
13442  [(set (reg 17) (match_operand 0 "" ""))
13443   (set (match_operand:QI 1 "register_operand" "")
13444	(match_operator:QI 2 "ix86_comparison_operator"
13445	  [(reg 17) (const_int 0)]))
13446   (parallel [(set (match_operand 3 "q_regs_operand" "")
13447		   (zero_extend (match_dup 1)))
13448	      (clobber (reg:CC 17))])]
13449  "(peep2_reg_dead_p (3, operands[1])
13450    || operands_match_p (operands[1], operands[3]))
13451   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13452  [(set (match_dup 4) (match_dup 0))
13453   (set (strict_low_part (match_dup 5))
13454	(match_dup 2))]
13455{
13456  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13457  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13458  ix86_expand_clear (operands[3]);
13459})
13460
13461;; Call instructions.
13462
13463;; The predicates normally associated with named expanders are not properly
13464;; checked for calls.  This is a bug in the generic code, but it isn't that
13465;; easy to fix.  Ignore it for now and be prepared to fix things up.
13466
13467;; Call subroutine returning no value.
13468
13469(define_expand "call_pop"
13470  [(parallel [(call (match_operand:QI 0 "" "")
13471		    (match_operand:SI 1 "" ""))
13472	      (set (reg:SI 7)
13473		   (plus:SI (reg:SI 7)
13474			    (match_operand:SI 3 "" "")))])]
13475  "!TARGET_64BIT"
13476{
13477  if (operands[3] == const0_rtx)
13478    {
13479      emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
13480      DONE;
13481    }
13482  /* Static functions and indirect calls don't need
13483     current_function_uses_pic_offset_table.  */
13484  if (flag_pic
13485      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13486      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13487    current_function_uses_pic_offset_table = 1;
13488  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13489    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13490  if (TARGET_64BIT)
13491    abort();
13492})
13493
13494(define_insn "*call_pop_0"
13495  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13496	 (match_operand:SI 1 "" ""))
13497   (set (reg:SI 7) (plus:SI (reg:SI 7)
13498			    (match_operand:SI 2 "immediate_operand" "")))]
13499  "!TARGET_64BIT"
13500{
13501  if (SIBLING_CALL_P (insn))
13502    return "jmp\t%P0";
13503  else
13504    return "call\t%P0";
13505}
13506  [(set_attr "type" "call")])
13507  
13508(define_insn "*call_pop_1"
13509  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13510	 (match_operand:SI 1 "" ""))
13511   (set (reg:SI 7) (plus:SI (reg:SI 7)
13512			    (match_operand:SI 2 "immediate_operand" "i")))]
13513  "!TARGET_64BIT"
13514{
13515  if (constant_call_address_operand (operands[0], Pmode))
13516    {
13517      if (SIBLING_CALL_P (insn))
13518	return "jmp\t%P0";
13519      else
13520	return "call\t%P0";
13521    }
13522  if (SIBLING_CALL_P (insn))
13523    return "jmp\t%A0";
13524  else
13525    return "call\t%A0";
13526}
13527  [(set_attr "type" "call")])
13528
13529(define_expand "call"
13530  [(call (match_operand:QI 0 "" "")
13531	 (match_operand 1 "" ""))
13532   (use (match_operand 2 "" ""))]
13533  ;; Operand 1 not used on the i386.
13534  ""
13535{
13536  rtx insn;
13537  /* Static functions and indirect calls don't need
13538     current_function_uses_pic_offset_table.  */
13539  if (flag_pic
13540      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13541      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13542    current_function_uses_pic_offset_table = 1;
13543
13544  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13545    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13546  if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
13547    {
13548      rtx reg = gen_rtx_REG (QImode, 0);
13549      emit_move_insn (reg, operands[2]);
13550      insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13551      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13552      DONE;
13553    }
13554   insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13555   DONE;
13556})
13557
13558(define_expand "call_exp"
13559  [(call (match_operand:QI 0 "" "")
13560	 (match_operand 1 "" ""))]
13561  ""
13562  "")
13563
13564(define_insn "*call_0"
13565  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13566	 (match_operand 1 "" ""))]
13567  ""
13568{
13569  if (SIBLING_CALL_P (insn))
13570    return "jmp\t%P0";
13571  else
13572    return "call\t%P0";
13573}
13574  [(set_attr "type" "call")])
13575
13576(define_insn "*call_1"
13577  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13578	 (match_operand 1 "" ""))]
13579  "!TARGET_64BIT"
13580{
13581  if (constant_call_address_operand (operands[0], QImode))
13582    {
13583      if (SIBLING_CALL_P (insn))
13584	return "jmp\t%P0";
13585      else
13586	return "call\t%P0";
13587    }
13588  if (SIBLING_CALL_P (insn))
13589    return "jmp\t%A0";
13590  else
13591    return "call\t%A0";
13592}
13593  [(set_attr "type" "call")])
13594
13595(define_insn "*call_1_rex64"
13596  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13597	 (match_operand 1 "" ""))]
13598  "TARGET_64BIT"
13599{
13600  if (constant_call_address_operand (operands[0], QImode))
13601    {
13602      if (SIBLING_CALL_P (insn))
13603	return "jmp\t%P0";
13604      else
13605	return "call\t%P0";
13606    }
13607  if (SIBLING_CALL_P (insn))
13608    return "jmp\t%A0";
13609  else
13610    return "call\t%A0";
13611}
13612  [(set_attr "type" "call")])
13613
13614;; Call subroutine, returning value in operand 0
13615;; (which must be a hard register).
13616
13617(define_expand "call_value_pop"
13618  [(parallel [(set (match_operand 0 "" "")
13619		   (call (match_operand:QI 1 "" "")
13620			 (match_operand:SI 2 "" "")))
13621	      (set (reg:SI 7)
13622		   (plus:SI (reg:SI 7)
13623			    (match_operand:SI 4 "" "")))])]
13624  "!TARGET_64BIT"
13625{
13626  if (operands[4] == const0_rtx)
13627    {
13628      emit_insn (gen_call_value (operands[0], operands[1], operands[2],
13629				 constm1_rtx));
13630      DONE;
13631    }
13632  /* Static functions and indirect calls don't need
13633     current_function_uses_pic_offset_table.  */
13634  if (flag_pic
13635      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13636      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13637    current_function_uses_pic_offset_table = 1;
13638  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13639    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13640})
13641
13642(define_expand "call_value"
13643  [(set (match_operand 0 "" "")
13644	(call (match_operand:QI 1 "" "")
13645	      (match_operand:SI 2 "" "")))
13646   (use (match_operand:SI 3 "" ""))]
13647  ;; Operand 2 not used on the i386.
13648  ""
13649{
13650  rtx insn;
13651  /* Static functions and indirect calls don't need
13652     current_function_uses_pic_offset_table.  */
13653  if (flag_pic
13654      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13655      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13656    current_function_uses_pic_offset_table = 1;
13657  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13658    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13659  if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
13660    {
13661      rtx reg = gen_rtx_REG (QImode, 0);
13662      emit_move_insn (reg, operands[3]);
13663      insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13664						 operands[2]));
13665      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13666      DONE;
13667    }
13668  insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13669					     operands[2]));
13670  DONE;
13671})
13672
13673(define_expand "call_value_exp"
13674  [(set (match_operand 0 "" "")
13675	(call (match_operand:QI 1 "" "")
13676	      (match_operand:SI 2 "" "")))]
13677  ""
13678  "")
13679
13680;; Call subroutine returning any type.
13681
13682(define_expand "untyped_call"
13683  [(parallel [(call (match_operand 0 "" "")
13684		    (const_int 0))
13685	      (match_operand 1 "" "")
13686	      (match_operand 2 "" "")])]
13687  ""
13688{
13689  int i;
13690
13691  /* In order to give reg-stack an easier job in validating two
13692     coprocessor registers as containing a possible return value,
13693     simply pretend the untyped call returns a complex long double
13694     value.  */
13695
13696  emit_call_insn (TARGET_FLOAT_RETURNS_IN_80387
13697                  ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
13698				    operands[0], const0_rtx,
13699				    GEN_INT (SSE_REGPARM_MAX - 1))
13700                  : gen_call (operands[0], const0_rtx,
13701			      GEN_INT (SSE_REGPARM_MAX - 1)));
13702
13703  for (i = 0; i < XVECLEN (operands[2], 0); i++)
13704    {
13705      rtx set = XVECEXP (operands[2], 0, i);
13706      emit_move_insn (SET_DEST (set), SET_SRC (set));
13707    }
13708
13709  /* The optimizer does not know that the call sets the function value
13710     registers we stored in the result block.  We avoid problems by
13711     claiming that all hard registers are used and clobbered at this
13712     point.  */
13713  emit_insn (gen_blockage ());
13714
13715  DONE;
13716})
13717
13718;; Prologue and epilogue instructions
13719
13720;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13721;; all of memory.  This blocks insns from being moved across this point.
13722
13723(define_insn "blockage"
13724  [(unspec_volatile [(const_int 0)] 0)]
13725  ""
13726  ""
13727  [(set_attr "length" "0")])
13728
13729;; Insn emitted into the body of a function to return from a function.
13730;; This is only done if the function's epilogue is known to be simple.
13731;; See comments for ix86_can_use_return_insn_p in i386.c.
13732
13733(define_expand "return"
13734  [(return)]
13735  "ix86_can_use_return_insn_p ()"
13736{
13737  if (current_function_pops_args)
13738    {
13739      rtx popc = GEN_INT (current_function_pops_args);
13740      emit_jump_insn (gen_return_pop_internal (popc));
13741      DONE;
13742    }
13743})
13744
13745(define_insn "return_internal"
13746  [(return)]
13747  "reload_completed"
13748  "ret"
13749  [(set_attr "length" "1")
13750   (set_attr "length_immediate" "0")
13751   (set_attr "modrm" "0")])
13752
13753(define_insn "return_pop_internal"
13754  [(return)
13755   (use (match_operand:SI 0 "const_int_operand" ""))]
13756  "reload_completed"
13757  "ret\t%0"
13758  [(set_attr "length" "3")
13759   (set_attr "length_immediate" "2")
13760   (set_attr "modrm" "0")])
13761
13762(define_insn "return_indirect_internal"
13763  [(return)
13764   (use (match_operand:SI 0 "register_operand" "r"))]
13765  "reload_completed"
13766  "jmp\t%A0"
13767  [(set_attr "type" "ibr")
13768   (set_attr "length_immediate" "0")])
13769
13770(define_insn "nop"
13771  [(const_int 0)]
13772  ""
13773  "nop"
13774  [(set_attr "length" "1")
13775   (set_attr "length_immediate" "0")
13776   (set_attr "modrm" "0")
13777   (set_attr "ppro_uops" "one")])
13778
13779(define_expand "prologue"
13780  [(const_int 1)]
13781  ""
13782  "ix86_expand_prologue (); DONE;")
13783
13784(define_insn "prologue_set_got"
13785  [(set (match_operand:SI 0 "register_operand" "=r")
13786	(unspec_volatile:SI
13787	 [(plus:SI (match_dup 0)
13788		   (plus:SI (match_operand:SI 1 "symbolic_operand" "")
13789			    (minus:SI (pc) (match_operand 2 "" ""))))] 1))
13790   (clobber (reg:CC 17))]
13791  "!TARGET_64BIT"
13792{
13793  if (GET_CODE (operands[2]) == LABEL_REF)
13794     operands[2] = XEXP (operands[2], 0);
13795  if (TARGET_DEEP_BRANCH_PREDICTION) 
13796    return "add{l}\t{%1, %0|%0, %1}";
13797  else  
13798    return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
13799}
13800  [(set_attr "type" "alu")
13801   ; Since this insn may have two constant operands, we must set the
13802   ; length manually.
13803   (set_attr "length_immediate" "4")
13804   (set_attr "mode" "SI")])
13805
13806(define_insn "prologue_get_pc"
13807  [(set (match_operand:SI 0 "register_operand" "=r")
13808    (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
13809  "!TARGET_64BIT"
13810{
13811  if (GET_CODE (operands[1]) == LABEL_REF)
13812    operands[1] = XEXP (operands[1], 0);
13813  output_asm_insn ("call\t%X1", operands);
13814  if (! TARGET_DEEP_BRANCH_PREDICTION)
13815    {
13816      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
13817				 CODE_LABEL_NUMBER (operands[1]));
13818      return "pop{l}\t%0";
13819    }
13820  RET;
13821}
13822  [(set_attr "type" "multi")])
13823
13824(define_expand "epilogue"
13825  [(const_int 1)]
13826  ""
13827  "ix86_expand_epilogue (1); DONE;")
13828
13829(define_expand "sibcall_epilogue"
13830  [(const_int 1)]
13831  ""
13832  "ix86_expand_epilogue (0); DONE;")
13833
13834(define_expand "eh_return"
13835  [(use (match_operand 0 "register_operand" ""))
13836   (use (match_operand 1 "register_operand" ""))]
13837  ""
13838{
13839  rtx tmp, sa = operands[0], ra = operands[1];
13840
13841  /* Tricky bit: we write the address of the handler to which we will
13842     be returning into someone else's stack frame, one word below the
13843     stack address we wish to restore.  */
13844  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13845  tmp = plus_constant (tmp, -UNITS_PER_WORD);
13846  tmp = gen_rtx_MEM (Pmode, tmp);
13847  emit_move_insn (tmp, ra);
13848
13849  if (Pmode == SImode)
13850    emit_insn (gen_eh_return_si (sa));
13851  else
13852    emit_insn (gen_eh_return_di (sa));
13853  emit_barrier ();
13854  DONE;
13855})
13856
13857(define_insn_and_split "eh_return_si"
13858  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
13859  "!TARGET_64BIT"
13860  "#"
13861  "reload_completed"
13862  [(const_int 1)]
13863  "ix86_expand_epilogue (2); DONE;")
13864
13865(define_insn_and_split "eh_return_di"
13866  [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
13867  "TARGET_64BIT"
13868  "#"
13869  "reload_completed"
13870  [(const_int 1)]
13871  "ix86_expand_epilogue (2); DONE;")
13872
13873(define_insn "leave"
13874  [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13875   (set (reg:SI 6) (mem:SI (reg:SI 6)))
13876   (clobber (mem:BLK (scratch)))]
13877  "!TARGET_64BIT"
13878  "leave"
13879  [(set_attr "length_immediate" "0")
13880   (set_attr "length" "1")
13881   (set_attr "modrm" "0")
13882   (set_attr "modrm" "0")
13883   (set_attr "athlon_decode" "vector")
13884   (set_attr "ppro_uops" "few")])
13885
13886(define_insn "leave_rex64"
13887  [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13888   (set (reg:DI 6) (mem:DI (reg:DI 6)))
13889   (clobber (mem:BLK (scratch)))]
13890  "TARGET_64BIT"
13891  "leave"
13892  [(set_attr "length_immediate" "0")
13893   (set_attr "length" "1")
13894   (set_attr "modrm" "0")
13895   (set_attr "modrm" "0")
13896   (set_attr "athlon_decode" "vector")
13897   (set_attr "ppro_uops" "few")])
13898
13899(define_expand "ffssi2"
13900  [(set (match_operand:SI 0 "nonimmediate_operand" "") 
13901	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
13902  ""
13903{
13904  rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13905  rtx in = operands[1];
13906
13907  if (TARGET_CMOVE)
13908    {
13909      emit_move_insn (tmp, constm1_rtx);
13910      emit_insn (gen_ffssi_1 (out, in));
13911      emit_insn (gen_rtx_SET (VOIDmode, out,
13912		  gen_rtx_IF_THEN_ELSE (SImode, 
13913		    gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13914				const0_rtx),
13915		    tmp,
13916		    out)));
13917      emit_insn (gen_addsi3 (out, out, const1_rtx));
13918      emit_move_insn (operands[0], out);
13919    }
13920
13921  /* Pentium bsf instruction is extremly slow.  The following code is
13922     recommended by the Intel Optimizing Manual as a reasonable replacement:
13923           TEST    EAX,EAX
13924	   JZ      SHORT BS2
13925	   XOR     ECX,ECX
13926	   MOV     DWORD PTR [TEMP+4],ECX
13927	   SUB     ECX,EAX
13928	   AND     EAX,ECX
13929	   MOV     DWORD PTR [TEMP],EAX
13930	   FILD    QWORD PTR [TEMP]
13931	   FSTP    QWORD PTR [TEMP]
13932	   WAIT    ; WAIT only needed for compatibility with
13933	           ; earlier processors
13934	   MOV     ECX, DWORD PTR [TEMP+4]
13935	   SHR     ECX,20
13936	   SUB     ECX,3FFH
13937	   TEST    EAX,EAX       ; clear zero flag
13938       BS2:
13939     Following piece of code expand ffs to similar beast.
13940       */
13941
13942  else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13943    {
13944      rtx label = gen_label_rtx ();
13945      rtx lo, hi;
13946      rtx mem = assign_386_stack_local (DImode, 0);
13947      rtx fptmp = gen_reg_rtx (DFmode);
13948      split_di (&mem, 1, &lo, &hi);
13949
13950      emit_move_insn (out, const0_rtx);
13951
13952      emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
13953
13954      emit_move_insn (hi, out);
13955      emit_insn (gen_subsi3 (out, out, in));
13956      emit_insn (gen_andsi3 (out, out, in));
13957      emit_move_insn (lo, out);
13958      emit_insn (gen_floatdidf2 (fptmp,mem));
13959      emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13960      emit_move_insn (out, hi);
13961      emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13962      emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13963
13964      emit_label (label);
13965      LABEL_NUSES (label) = 1;
13966
13967      emit_move_insn (operands[0], out);
13968    }
13969  else
13970    {
13971      emit_move_insn (tmp, const0_rtx);
13972      emit_insn (gen_ffssi_1 (out, in));
13973      emit_insn (gen_rtx_SET (VOIDmode, 
13974		  gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13975		  gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13976			      const0_rtx)));
13977      emit_insn (gen_negsi2 (tmp, tmp));
13978      emit_insn (gen_iorsi3 (out, out, tmp));
13979      emit_insn (gen_addsi3 (out, out, const1_rtx));
13980      emit_move_insn (operands[0], out);
13981    }
13982  DONE;  
13983})
13984
13985(define_insn "ffssi_1"
13986  [(set (reg:CCZ 17)
13987        (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13988		     (const_int 0)))
13989   (set (match_operand:SI 0 "register_operand" "=r")
13990	(unspec:SI [(match_dup 1)] 5))]
13991  ""
13992  "bsf{l}\t{%1, %0|%0, %1}"
13993  [(set_attr "prefix_0f" "1")
13994   (set_attr "ppro_uops" "few")])
13995
13996;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13997;; and slower than the two-byte movzx insn needed to do the work in SImode.
13998
13999;; These patterns match the binary 387 instructions for addM3, subM3,
14000;; mulM3 and divM3.  There are three patterns for each of DFmode and
14001;; SFmode.  The first is the normal insn, the second the same insn but
14002;; with one operand a conversion, and the third the same insn but with
14003;; the other operand a conversion.  The conversion may be SFmode or
14004;; SImode if the target mode DFmode, but only SImode if the target mode
14005;; is SFmode.
14006
14007;; Gcc is slightly more smart about handling normal two address instructions
14008;; so use special patterns for add and mull.
14009(define_insn "*fop_sf_comm_nosse"
14010  [(set (match_operand:SF 0 "register_operand" "=f")
14011	(match_operator:SF 3 "binary_fp_operator"
14012			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14013			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14014  "TARGET_80387 && !TARGET_SSE_MATH
14015   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14016   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14017  "* return output_387_binary_op (insn, operands);"
14018  [(set (attr "type") 
14019	(if_then_else (match_operand:SF 3 "mult_operator" "") 
14020	   (const_string "fmul")
14021	   (const_string "fop")))
14022   (set_attr "mode" "SF")])
14023
14024(define_insn "*fop_sf_comm"
14025  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14026	(match_operator:SF 3 "binary_fp_operator"
14027			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14028			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14029  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14030   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14031   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14032  "* return output_387_binary_op (insn, operands);"
14033  [(set (attr "type") 
14034	(if_then_else (eq_attr "alternative" "1")
14035           (const_string "sse")
14036	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14037	      (const_string "fmul")
14038	      (const_string "fop"))))
14039   (set_attr "mode" "SF")])
14040
14041(define_insn "*fop_sf_comm_sse"
14042  [(set (match_operand:SF 0 "register_operand" "=x")
14043	(match_operator:SF 3 "binary_fp_operator"
14044			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14045			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14046  "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14047   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14048  "* return output_387_binary_op (insn, operands);"
14049  [(set_attr "type" "sse")
14050   (set_attr "mode" "SF")])
14051
14052(define_insn "*fop_df_comm_nosse"
14053  [(set (match_operand:DF 0 "register_operand" "=f")
14054	(match_operator:DF 3 "binary_fp_operator"
14055			[(match_operand:DF 1 "nonimmediate_operand" "%0")
14056			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14057  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14058   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14059   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14060  "* return output_387_binary_op (insn, operands);"
14061  [(set (attr "type") 
14062	(if_then_else (match_operand:SF 3 "mult_operator" "") 
14063	   (const_string "fmul")
14064	   (const_string "fop")))
14065   (set_attr "mode" "DF")])
14066
14067(define_insn "*fop_df_comm"
14068  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14069	(match_operator:DF 3 "binary_fp_operator"
14070			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14071			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14072  "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14073   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14074   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14075  "* return output_387_binary_op (insn, operands);"
14076  [(set (attr "type") 
14077	(if_then_else (eq_attr "alternative" "1")
14078           (const_string "sse")
14079	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14080	      (const_string "fmul")
14081	      (const_string "fop"))))
14082   (set_attr "mode" "DF")])
14083
14084(define_insn "*fop_df_comm_sse"
14085  [(set (match_operand:DF 0 "register_operand" "=Y")
14086	(match_operator:DF 3 "binary_fp_operator"
14087			[(match_operand:DF 1 "nonimmediate_operand" "%0")
14088			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14089  "TARGET_SSE2 && TARGET_SSE_MATH
14090   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14091   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14092  "* return output_387_binary_op (insn, operands);"
14093  [(set_attr "type" "sse")
14094   (set_attr "mode" "DF")])
14095
14096(define_insn "*fop_xf_comm"
14097  [(set (match_operand:XF 0 "register_operand" "=f")
14098	(match_operator:XF 3 "binary_fp_operator"
14099			[(match_operand:XF 1 "register_operand" "%0")
14100			 (match_operand:XF 2 "register_operand" "f")]))]
14101  "!TARGET_64BIT && TARGET_80387
14102   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14103  "* return output_387_binary_op (insn, operands);"
14104  [(set (attr "type") 
14105        (if_then_else (match_operand:XF 3 "mult_operator" "") 
14106           (const_string "fmul")
14107           (const_string "fop")))
14108   (set_attr "mode" "XF")])
14109
14110(define_insn "*fop_tf_comm"
14111  [(set (match_operand:TF 0 "register_operand" "=f")
14112	(match_operator:TF 3 "binary_fp_operator"
14113			[(match_operand:TF 1 "register_operand" "%0")
14114			 (match_operand:TF 2 "register_operand" "f")]))]
14115  "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14116  "* return output_387_binary_op (insn, operands);"
14117  [(set (attr "type") 
14118        (if_then_else (match_operand:TF 3 "mult_operator" "") 
14119           (const_string "fmul")
14120           (const_string "fop")))
14121   (set_attr "mode" "XF")])
14122
14123(define_insn "*fop_sf_1_nosse"
14124  [(set (match_operand:SF 0 "register_operand" "=f,f")
14125	(match_operator:SF 3 "binary_fp_operator"
14126			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14127			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14128  "TARGET_80387 && !TARGET_SSE_MATH
14129   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14130   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14131  "* return output_387_binary_op (insn, operands);"
14132  [(set (attr "type") 
14133        (cond [(match_operand:SF 3 "mult_operator" "") 
14134                 (const_string "fmul")
14135               (match_operand:SF 3 "div_operator" "") 
14136                 (const_string "fdiv")
14137              ]
14138              (const_string "fop")))
14139   (set_attr "mode" "SF")])
14140
14141(define_insn "*fop_sf_1"
14142  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14143	(match_operator:SF 3 "binary_fp_operator"
14144			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14145			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14146  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14147   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14148   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14149  "* return output_387_binary_op (insn, operands);"
14150  [(set (attr "type") 
14151        (cond [(eq_attr "alternative" "2")
14152                 (const_string "sse")
14153	       (match_operand:SF 3 "mult_operator" "") 
14154                 (const_string "fmul")
14155               (match_operand:SF 3 "div_operator" "") 
14156                 (const_string "fdiv")
14157              ]
14158              (const_string "fop")))
14159   (set_attr "mode" "SF")])
14160
14161(define_insn "*fop_sf_1_sse"
14162  [(set (match_operand:SF 0 "register_operand" "=x")
14163	(match_operator:SF 3 "binary_fp_operator"
14164			[(match_operand:SF 1 "register_operand" "0")
14165			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14166  "TARGET_SSE_MATH
14167   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14168  "* return output_387_binary_op (insn, operands);"
14169  [(set_attr "type" "sse")
14170   (set_attr "mode" "SF")])
14171
14172;; ??? Add SSE splitters for these!
14173(define_insn "*fop_sf_2"
14174  [(set (match_operand:SF 0 "register_operand" "=f,f")
14175	(match_operator:SF 3 "binary_fp_operator"
14176	  [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14177	   (match_operand:SF 2 "register_operand" "0,0")]))]
14178  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14179  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14180  [(set (attr "type") 
14181        (cond [(match_operand:SF 3 "mult_operator" "") 
14182                 (const_string "fmul")
14183               (match_operand:SF 3 "div_operator" "") 
14184                 (const_string "fdiv")
14185              ]
14186              (const_string "fop")))
14187   (set_attr "fp_int_src" "true")
14188   (set_attr "ppro_uops" "many")
14189   (set_attr "mode" "SI")])
14190
14191(define_insn "*fop_sf_3"
14192  [(set (match_operand:SF 0 "register_operand" "=f,f")
14193	(match_operator:SF 3 "binary_fp_operator"
14194	  [(match_operand:SF 1 "register_operand" "0,0")
14195	   (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14196  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14197  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14198  [(set (attr "type") 
14199        (cond [(match_operand:SF 3 "mult_operator" "") 
14200                 (const_string "fmul")
14201               (match_operand:SF 3 "div_operator" "") 
14202                 (const_string "fdiv")
14203              ]
14204              (const_string "fop")))
14205   (set_attr "fp_int_src" "true")
14206   (set_attr "ppro_uops" "many")
14207   (set_attr "mode" "SI")])
14208
14209(define_insn "*fop_df_1_nosse"
14210  [(set (match_operand:DF 0 "register_operand" "=f,f")
14211	(match_operator:DF 3 "binary_fp_operator"
14212			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14213			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14214  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14215   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14216   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14217  "* return output_387_binary_op (insn, operands);"
14218  [(set (attr "type") 
14219        (cond [(match_operand:DF 3 "mult_operator" "") 
14220                 (const_string "fmul")
14221               (match_operand:DF 3 "div_operator" "") 
14222                 (const_string "fdiv")
14223              ]
14224              (const_string "fop")))
14225   (set_attr "mode" "DF")])
14226
14227
14228(define_insn "*fop_df_1"
14229  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14230	(match_operator:DF 3 "binary_fp_operator"
14231			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14232			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14233  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14234   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14235   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14236  "* return output_387_binary_op (insn, operands);"
14237  [(set (attr "type") 
14238        (cond [(eq_attr "alternative" "2")
14239                 (const_string "sse")
14240	       (match_operand:DF 3 "mult_operator" "") 
14241                 (const_string "fmul")
14242               (match_operand:DF 3 "div_operator" "") 
14243                 (const_string "fdiv")
14244              ]
14245              (const_string "fop")))
14246   (set_attr "mode" "DF")])
14247
14248(define_insn "*fop_df_1_sse"
14249  [(set (match_operand:DF 0 "register_operand" "=Y")
14250	(match_operator:DF 3 "binary_fp_operator"
14251			[(match_operand:DF 1 "register_operand" "0")
14252			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14253  "TARGET_SSE2 && TARGET_SSE_MATH
14254   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14255  "* return output_387_binary_op (insn, operands);"
14256  [(set_attr "type" "sse")])
14257
14258;; ??? Add SSE splitters for these!
14259(define_insn "*fop_df_2"
14260  [(set (match_operand:DF 0 "register_operand" "=f,f")
14261	(match_operator:DF 3 "binary_fp_operator"
14262	   [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14263	    (match_operand:DF 2 "register_operand" "0,0")]))]
14264  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14265  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14266  [(set (attr "type") 
14267        (cond [(match_operand:DF 3 "mult_operator" "") 
14268                 (const_string "fmul")
14269               (match_operand:DF 3 "div_operator" "") 
14270                 (const_string "fdiv")
14271              ]
14272              (const_string "fop")))
14273   (set_attr "fp_int_src" "true")
14274   (set_attr "ppro_uops" "many")
14275   (set_attr "mode" "SI")])
14276
14277(define_insn "*fop_df_3"
14278  [(set (match_operand:DF 0 "register_operand" "=f,f")
14279	(match_operator:DF 3 "binary_fp_operator"
14280	   [(match_operand:DF 1 "register_operand" "0,0")
14281	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14282  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14283  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14284  [(set (attr "type") 
14285        (cond [(match_operand:DF 3 "mult_operator" "") 
14286                 (const_string "fmul")
14287               (match_operand:DF 3 "div_operator" "") 
14288                 (const_string "fdiv")
14289              ]
14290              (const_string "fop")))
14291   (set_attr "fp_int_src" "true")
14292   (set_attr "ppro_uops" "many")
14293   (set_attr "mode" "SI")])
14294
14295(define_insn "*fop_df_4"
14296  [(set (match_operand:DF 0 "register_operand" "=f,f")
14297	(match_operator:DF 3 "binary_fp_operator"
14298	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14299	    (match_operand:DF 2 "register_operand" "0,f")]))]
14300  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14301   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14302  "* return output_387_binary_op (insn, operands);"
14303  [(set (attr "type") 
14304        (cond [(match_operand:DF 3 "mult_operator" "") 
14305                 (const_string "fmul")
14306               (match_operand:DF 3 "div_operator" "") 
14307                 (const_string "fdiv")
14308              ]
14309              (const_string "fop")))
14310   (set_attr "mode" "SF")])
14311
14312(define_insn "*fop_df_5"
14313  [(set (match_operand:DF 0 "register_operand" "=f,f")
14314	(match_operator:DF 3 "binary_fp_operator"
14315	  [(match_operand:DF 1 "register_operand" "0,f")
14316	   (float_extend:DF
14317	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14318  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14319  "* return output_387_binary_op (insn, operands);"
14320  [(set (attr "type") 
14321        (cond [(match_operand:DF 3 "mult_operator" "") 
14322                 (const_string "fmul")
14323               (match_operand:DF 3 "div_operator" "") 
14324                 (const_string "fdiv")
14325              ]
14326              (const_string "fop")))
14327   (set_attr "mode" "SF")])
14328
14329(define_insn "*fop_xf_1"
14330  [(set (match_operand:XF 0 "register_operand" "=f,f")
14331	(match_operator:XF 3 "binary_fp_operator"
14332			[(match_operand:XF 1 "register_operand" "0,f")
14333			 (match_operand:XF 2 "register_operand" "f,0")]))]
14334  "!TARGET_64BIT && TARGET_80387
14335   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14336  "* return output_387_binary_op (insn, operands);"
14337  [(set (attr "type") 
14338        (cond [(match_operand:XF 3 "mult_operator" "") 
14339                 (const_string "fmul")
14340               (match_operand:XF 3 "div_operator" "") 
14341                 (const_string "fdiv")
14342              ]
14343              (const_string "fop")))
14344   (set_attr "mode" "XF")])
14345
14346(define_insn "*fop_tf_1"
14347  [(set (match_operand:TF 0 "register_operand" "=f,f")
14348	(match_operator:TF 3 "binary_fp_operator"
14349			[(match_operand:TF 1 "register_operand" "0,f")
14350			 (match_operand:TF 2 "register_operand" "f,0")]))]
14351  "TARGET_80387
14352   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14353  "* return output_387_binary_op (insn, operands);"
14354  [(set (attr "type") 
14355        (cond [(match_operand:TF 3 "mult_operator" "") 
14356                 (const_string "fmul")
14357               (match_operand:TF 3 "div_operator" "") 
14358                 (const_string "fdiv")
14359              ]
14360              (const_string "fop")))
14361   (set_attr "mode" "XF")])
14362
14363(define_insn "*fop_xf_2"
14364  [(set (match_operand:XF 0 "register_operand" "=f,f")
14365	(match_operator:XF 3 "binary_fp_operator"
14366	   [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14367	    (match_operand:XF 2 "register_operand" "0,0")]))]
14368  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14369  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14370  [(set (attr "type") 
14371        (cond [(match_operand:XF 3 "mult_operator" "") 
14372                 (const_string "fmul")
14373               (match_operand:XF 3 "div_operator" "") 
14374                 (const_string "fdiv")
14375              ]
14376              (const_string "fop")))
14377   (set_attr "fp_int_src" "true")
14378   (set_attr "mode" "SI")
14379   (set_attr "ppro_uops" "many")])
14380
14381(define_insn "*fop_tf_2"
14382  [(set (match_operand:TF 0 "register_operand" "=f,f")
14383	(match_operator:TF 3 "binary_fp_operator"
14384	   [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14385	    (match_operand:TF 2 "register_operand" "0,0")]))]
14386  "TARGET_80387 && TARGET_USE_FIOP"
14387  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14388  [(set (attr "type") 
14389        (cond [(match_operand:TF 3 "mult_operator" "") 
14390                 (const_string "fmul")
14391               (match_operand:TF 3 "div_operator" "") 
14392                 (const_string "fdiv")
14393              ]
14394              (const_string "fop")))
14395   (set_attr "fp_int_src" "true")
14396   (set_attr "mode" "SI")
14397   (set_attr "ppro_uops" "many")])
14398
14399(define_insn "*fop_xf_3"
14400  [(set (match_operand:XF 0 "register_operand" "=f,f")
14401	(match_operator:XF 3 "binary_fp_operator"
14402	  [(match_operand:XF 1 "register_operand" "0,0")
14403	   (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14404  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14405  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14406  [(set (attr "type") 
14407        (cond [(match_operand:XF 3 "mult_operator" "") 
14408                 (const_string "fmul")
14409               (match_operand:XF 3 "div_operator" "") 
14410                 (const_string "fdiv")
14411              ]
14412              (const_string "fop")))
14413   (set_attr "fp_int_src" "true")
14414   (set_attr "mode" "SI")
14415   (set_attr "ppro_uops" "many")])
14416
14417(define_insn "*fop_tf_3"
14418  [(set (match_operand:TF 0 "register_operand" "=f,f")
14419	(match_operator:TF 3 "binary_fp_operator"
14420	  [(match_operand:TF 1 "register_operand" "0,0")
14421	   (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14422  "TARGET_80387 && TARGET_USE_FIOP"
14423  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14424  [(set (attr "type") 
14425        (cond [(match_operand:TF 3 "mult_operator" "") 
14426                 (const_string "fmul")
14427               (match_operand:TF 3 "div_operator" "") 
14428                 (const_string "fdiv")
14429              ]
14430              (const_string "fop")))
14431   (set_attr "fp_int_src" "true")
14432   (set_attr "mode" "SI")
14433   (set_attr "ppro_uops" "many")])
14434
14435(define_insn "*fop_xf_4"
14436  [(set (match_operand:XF 0 "register_operand" "=f,f")
14437	(match_operator:XF 3 "binary_fp_operator"
14438	   [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14439	    (match_operand:XF 2 "register_operand" "0,f")]))]
14440  "!TARGET_64BIT && TARGET_80387"
14441  "* return output_387_binary_op (insn, operands);"
14442  [(set (attr "type") 
14443        (cond [(match_operand:XF 3 "mult_operator" "") 
14444                 (const_string "fmul")
14445               (match_operand:XF 3 "div_operator" "") 
14446                 (const_string "fdiv")
14447              ]
14448              (const_string "fop")))
14449   (set_attr "mode" "SF")])
14450
14451(define_insn "*fop_tf_4"
14452  [(set (match_operand:TF 0 "register_operand" "=f,f")
14453	(match_operator:TF 3 "binary_fp_operator"
14454	   [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14455	    (match_operand:TF 2 "register_operand" "0,f")]))]
14456  "TARGET_80387"
14457  "* return output_387_binary_op (insn, operands);"
14458  [(set (attr "type") 
14459        (cond [(match_operand:TF 3 "mult_operator" "") 
14460                 (const_string "fmul")
14461               (match_operand:TF 3 "div_operator" "") 
14462                 (const_string "fdiv")
14463              ]
14464              (const_string "fop")))
14465   (set_attr "mode" "SF")])
14466
14467(define_insn "*fop_xf_5"
14468  [(set (match_operand:XF 0 "register_operand" "=f,f")
14469	(match_operator:XF 3 "binary_fp_operator"
14470	  [(match_operand:XF 1 "register_operand" "0,f")
14471	   (float_extend:XF
14472	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14473  "!TARGET_64BIT && TARGET_80387"
14474  "* return output_387_binary_op (insn, operands);"
14475  [(set (attr "type") 
14476        (cond [(match_operand:XF 3 "mult_operator" "") 
14477                 (const_string "fmul")
14478               (match_operand:XF 3 "div_operator" "") 
14479                 (const_string "fdiv")
14480              ]
14481              (const_string "fop")))
14482   (set_attr "mode" "SF")])
14483
14484(define_insn "*fop_tf_5"
14485  [(set (match_operand:TF 0 "register_operand" "=f,f")
14486	(match_operator:TF 3 "binary_fp_operator"
14487	  [(match_operand:TF 1 "register_operand" "0,f")
14488	   (float_extend:TF
14489	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14490  "TARGET_80387"
14491  "* return output_387_binary_op (insn, operands);"
14492  [(set (attr "type") 
14493        (cond [(match_operand:TF 3 "mult_operator" "") 
14494                 (const_string "fmul")
14495               (match_operand:TF 3 "div_operator" "") 
14496                 (const_string "fdiv")
14497              ]
14498              (const_string "fop")))
14499   (set_attr "mode" "SF")])
14500
14501(define_insn "*fop_xf_6"
14502  [(set (match_operand:XF 0 "register_operand" "=f,f")
14503	(match_operator:XF 3 "binary_fp_operator"
14504	   [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14505	    (match_operand:XF 2 "register_operand" "0,f")]))]
14506  "!TARGET_64BIT && TARGET_80387"
14507  "* return output_387_binary_op (insn, operands);"
14508  [(set (attr "type") 
14509        (cond [(match_operand:XF 3 "mult_operator" "") 
14510                 (const_string "fmul")
14511               (match_operand:XF 3 "div_operator" "") 
14512                 (const_string "fdiv")
14513              ]
14514              (const_string "fop")))
14515   (set_attr "mode" "DF")])
14516
14517(define_insn "*fop_tf_6"
14518  [(set (match_operand:TF 0 "register_operand" "=f,f")
14519	(match_operator:TF 3 "binary_fp_operator"
14520	   [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14521	    (match_operand:TF 2 "register_operand" "0,f")]))]
14522  "TARGET_80387"
14523  "* return output_387_binary_op (insn, operands);"
14524  [(set (attr "type") 
14525        (cond [(match_operand:TF 3 "mult_operator" "") 
14526                 (const_string "fmul")
14527               (match_operand:TF 3 "div_operator" "") 
14528                 (const_string "fdiv")
14529              ]
14530              (const_string "fop")))
14531   (set_attr "mode" "DF")])
14532
14533(define_insn "*fop_xf_7"
14534  [(set (match_operand:XF 0 "register_operand" "=f,f")
14535	(match_operator:XF 3 "binary_fp_operator"
14536	  [(match_operand:XF 1 "register_operand" "0,f")
14537	   (float_extend:XF
14538	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14539  "!TARGET_64BIT && TARGET_80387"
14540  "* return output_387_binary_op (insn, operands);"
14541  [(set (attr "type") 
14542        (cond [(match_operand:XF 3 "mult_operator" "") 
14543                 (const_string "fmul")
14544               (match_operand:XF 3 "div_operator" "") 
14545                 (const_string "fdiv")
14546              ]
14547              (const_string "fop")))
14548   (set_attr "mode" "DF")])
14549
14550(define_insn "*fop_tf_7"
14551  [(set (match_operand:TF 0 "register_operand" "=f,f")
14552	(match_operator:TF 3 "binary_fp_operator"
14553	  [(match_operand:TF 1 "register_operand" "0,f")
14554	   (float_extend:TF
14555	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14556  "TARGET_80387"
14557  "* return output_387_binary_op (insn, operands);"
14558  [(set (attr "type") 
14559        (cond [(match_operand:TF 3 "mult_operator" "") 
14560                 (const_string "fmul")
14561               (match_operand:TF 3 "div_operator" "") 
14562                 (const_string "fdiv")
14563              ]
14564              (const_string "fop")))
14565   (set_attr "mode" "DF")])
14566
14567(define_split
14568  [(set (match_operand 0 "register_operand" "")
14569	(match_operator 3 "binary_fp_operator"
14570	   [(float (match_operand:SI 1 "register_operand" ""))
14571	    (match_operand 2 "register_operand" "")]))]
14572  "TARGET_80387 && reload_completed
14573   && FLOAT_MODE_P (GET_MODE (operands[0]))"
14574  [(const_int 0)]
14575{ 
14576  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14577  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14578  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14579			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
14580					  GET_MODE (operands[3]),
14581					  operands[4],
14582					  operands[2])));
14583  ix86_free_from_memory (GET_MODE (operands[1]));
14584  DONE;
14585})
14586
14587(define_split
14588  [(set (match_operand 0 "register_operand" "")
14589	(match_operator 3 "binary_fp_operator"
14590	   [(match_operand 1 "register_operand" "")
14591	    (float (match_operand:SI 2 "register_operand" ""))]))]
14592  "TARGET_80387 && reload_completed
14593   && FLOAT_MODE_P (GET_MODE (operands[0]))"
14594  [(const_int 0)]
14595{
14596  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14597  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14598  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14599			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
14600					  GET_MODE (operands[3]),
14601					  operands[1],
14602					  operands[4])));
14603  ix86_free_from_memory (GET_MODE (operands[2]));
14604  DONE;
14605})
14606
14607;; FPU special functions.
14608
14609(define_expand "sqrtsf2"
14610  [(set (match_operand:SF 0 "register_operand" "")
14611	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14612  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14613{
14614  if (!TARGET_SSE_MATH)
14615    operands[1] = force_reg (SFmode, operands[1]);
14616})
14617
14618(define_insn "sqrtsf2_1"
14619  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14620	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14621  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14622   && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14623  "@
14624   fsqrt
14625   sqrtss\t{%1, %0|%0, %1}"
14626  [(set_attr "type" "fpspc,sse")
14627   (set_attr "mode" "SF,SF")
14628   (set_attr "athlon_decode" "direct,*")])
14629
14630(define_insn "sqrtsf2_1_sse_only"
14631  [(set (match_operand:SF 0 "register_operand" "=x")
14632	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14633  "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14634  "sqrtss\t{%1, %0|%0, %1}"
14635  [(set_attr "type" "sse")
14636   (set_attr "mode" "SF")
14637   (set_attr "athlon_decode" "*")])
14638
14639(define_insn "sqrtsf2_i387"
14640  [(set (match_operand:SF 0 "register_operand" "=f")
14641	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14642  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14643   && !TARGET_SSE_MATH"
14644  "fsqrt"
14645  [(set_attr "type" "fpspc")
14646   (set_attr "mode" "SF")
14647   (set_attr "athlon_decode" "direct")])
14648
14649(define_expand "sqrtdf2"
14650  [(set (match_operand:DF 0 "register_operand" "")
14651	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14652  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14653   || (TARGET_SSE2 && TARGET_SSE_MATH)"
14654{
14655  if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14656    operands[1] = force_reg (DFmode, operands[1]);
14657})
14658
14659(define_insn "sqrtdf2_1"
14660  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14661	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14662  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14663   && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14664  "@
14665   fsqrt
14666   sqrtsd\t{%1, %0|%0, %1}"
14667  [(set_attr "type" "fpspc,sse")
14668   (set_attr "mode" "DF,DF")
14669   (set_attr "athlon_decode" "direct,*")])
14670
14671(define_insn "sqrtdf2_1_sse_only"
14672  [(set (match_operand:DF 0 "register_operand" "=Y")
14673	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14674  "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14675  "sqrtsd\t{%1, %0|%0, %1}"
14676  [(set_attr "type" "sse")
14677   (set_attr "mode" "DF")
14678   (set_attr "athlon_decode" "*")])
14679
14680(define_insn "sqrtdf2_i387"
14681  [(set (match_operand:DF 0 "register_operand" "=f")
14682	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14683  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14684   && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14685  "fsqrt"
14686  [(set_attr "type" "fpspc")
14687   (set_attr "mode" "DF")
14688   (set_attr "athlon_decode" "direct")])
14689
14690(define_insn "*sqrtextendsfdf2"
14691  [(set (match_operand:DF 0 "register_operand" "=f")
14692	(sqrt:DF (float_extend:DF
14693		  (match_operand:SF 1 "register_operand" "0"))))]
14694  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14695   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14696  "fsqrt"
14697  [(set_attr "type" "fpspc")
14698   (set_attr "mode" "DF")
14699   (set_attr "athlon_decode" "direct")])
14700
14701(define_insn "sqrtxf2"
14702  [(set (match_operand:XF 0 "register_operand" "=f")
14703	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14704  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
14705   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14706  "fsqrt"
14707  [(set_attr "type" "fpspc")
14708   (set_attr "mode" "XF")
14709   (set_attr "athlon_decode" "direct")])
14710
14711(define_insn "sqrttf2"
14712  [(set (match_operand:TF 0 "register_operand" "=f")
14713	(sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14714  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14715   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14716  "fsqrt"
14717  [(set_attr "type" "fpspc")
14718   (set_attr "mode" "XF")
14719   (set_attr "athlon_decode" "direct")])
14720
14721(define_insn "*sqrtextenddfxf2"
14722  [(set (match_operand:XF 0 "register_operand" "=f")
14723	(sqrt:XF (float_extend:XF
14724		  (match_operand:DF 1 "register_operand" "0"))))]
14725  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14726  "fsqrt"
14727  [(set_attr "type" "fpspc")
14728   (set_attr "mode" "XF")
14729   (set_attr "athlon_decode" "direct")])
14730
14731(define_insn "*sqrtextenddftf2"
14732  [(set (match_operand:TF 0 "register_operand" "=f")
14733	(sqrt:TF (float_extend:TF
14734		  (match_operand:DF 1 "register_operand" "0"))))]
14735  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14736  "fsqrt"
14737  [(set_attr "type" "fpspc")
14738   (set_attr "mode" "XF")
14739   (set_attr "athlon_decode" "direct")])
14740
14741(define_insn "*sqrtextendsfxf2"
14742  [(set (match_operand:XF 0 "register_operand" "=f")
14743	(sqrt:XF (float_extend:XF
14744		  (match_operand:SF 1 "register_operand" "0"))))]
14745  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14746  "fsqrt"
14747  [(set_attr "type" "fpspc")
14748   (set_attr "mode" "XF")
14749   (set_attr "athlon_decode" "direct")])
14750
14751(define_insn "*sqrtextendsftf2"
14752  [(set (match_operand:TF 0 "register_operand" "=f")
14753	(sqrt:TF (float_extend:TF
14754		  (match_operand:SF 1 "register_operand" "0"))))]
14755  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14756  "fsqrt"
14757  [(set_attr "type" "fpspc")
14758   (set_attr "mode" "XF")
14759   (set_attr "athlon_decode" "direct")])
14760
14761(define_insn "sindf2"
14762  [(set (match_operand:DF 0 "register_operand" "=f")
14763	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
14764  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14765   && flag_unsafe_math_optimizations"
14766  "fsin"
14767  [(set_attr "type" "fpspc")
14768   (set_attr "mode" "DF")])
14769
14770(define_insn "sinsf2"
14771  [(set (match_operand:SF 0 "register_operand" "=f")
14772	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
14773  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14774   && flag_unsafe_math_optimizations"
14775  "fsin"
14776  [(set_attr "type" "fpspc")
14777   (set_attr "mode" "SF")])
14778
14779(define_insn "*sinextendsfdf2"
14780  [(set (match_operand:DF 0 "register_operand" "=f")
14781	(unspec:DF [(float_extend:DF
14782		     (match_operand:SF 1 "register_operand" "0"))] 1))]
14783  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14784   && flag_unsafe_math_optimizations"
14785  "fsin"
14786  [(set_attr "type" "fpspc")
14787   (set_attr "mode" "DF")])
14788
14789(define_insn "sinxf2"
14790  [(set (match_operand:XF 0 "register_operand" "=f")
14791	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
14792  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14793   && flag_unsafe_math_optimizations"
14794  "fsin"
14795  [(set_attr "type" "fpspc")
14796   (set_attr "mode" "XF")])
14797
14798(define_insn "sintf2"
14799  [(set (match_operand:TF 0 "register_operand" "=f")
14800	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
14801  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14802   && flag_unsafe_math_optimizations"
14803  "fsin"
14804  [(set_attr "type" "fpspc")
14805   (set_attr "mode" "XF")])
14806
14807(define_insn "cosdf2"
14808  [(set (match_operand:DF 0 "register_operand" "=f")
14809	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
14810  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14811   && flag_unsafe_math_optimizations"
14812  "fcos"
14813  [(set_attr "type" "fpspc")
14814   (set_attr "mode" "DF")])
14815
14816(define_insn "cossf2"
14817  [(set (match_operand:SF 0 "register_operand" "=f")
14818	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
14819  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14820   && flag_unsafe_math_optimizations"
14821  "fcos"
14822  [(set_attr "type" "fpspc")
14823   (set_attr "mode" "SF")])
14824
14825(define_insn "*cosextendsfdf2"
14826  [(set (match_operand:DF 0 "register_operand" "=f")
14827	(unspec:DF [(float_extend:DF
14828		     (match_operand:SF 1 "register_operand" "0"))] 2))]
14829  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14830   && flag_unsafe_math_optimizations"
14831  "fcos"
14832  [(set_attr "type" "fpspc")
14833   (set_attr "mode" "DF")])
14834
14835(define_insn "cosxf2"
14836  [(set (match_operand:XF 0 "register_operand" "=f")
14837	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
14838  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14839   && flag_unsafe_math_optimizations"
14840  "fcos"
14841  [(set_attr "type" "fpspc")
14842   (set_attr "mode" "XF")])
14843
14844(define_insn "costf2"
14845  [(set (match_operand:TF 0 "register_operand" "=f")
14846	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
14847  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
14848   && flag_unsafe_math_optimizations"
14849  "fcos"
14850  [(set_attr "type" "fpspc")
14851   (set_attr "mode" "XF")])
14852
14853;; Block operation instructions
14854
14855(define_insn "cld"
14856 [(set (reg:SI 19) (const_int 0))]
14857 ""
14858 "cld"
14859  [(set_attr "type" "cld")])
14860
14861(define_expand "movstrsi"
14862  [(use (match_operand:BLK 0 "memory_operand" ""))
14863   (use (match_operand:BLK 1 "memory_operand" ""))
14864   (use (match_operand:SI 2 "nonmemory_operand" ""))
14865   (use (match_operand:SI 3 "const_int_operand" ""))]
14866  ""
14867{
14868 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14869   DONE;
14870 else
14871   FAIL;
14872})
14873
14874(define_expand "movstrdi"
14875  [(use (match_operand:BLK 0 "memory_operand" ""))
14876   (use (match_operand:BLK 1 "memory_operand" ""))
14877   (use (match_operand:DI 2 "nonmemory_operand" ""))
14878   (use (match_operand:DI 3 "const_int_operand" ""))]
14879  "TARGET_64BIT"
14880{
14881 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14882   DONE;
14883 else
14884   FAIL;
14885})
14886
14887;; Most CPUs don't like single string operations
14888;; Handle this case here to simplify previous expander.
14889
14890(define_expand "strmovdi_rex64"
14891  [(set (match_dup 2)
14892  	(mem:DI (match_operand:DI 1 "register_operand" "")))
14893   (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14894        (match_dup 2))
14895   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14896	      (clobber (reg:CC 17))])
14897   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14898	      (clobber (reg:CC 17))])]
14899  "TARGET_64BIT"
14900{
14901  if (TARGET_SINGLE_STRINGOP || optimize_size)
14902    {
14903      emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14904				     operands[1]));
14905      DONE;
14906    }
14907  else 
14908    operands[2] = gen_reg_rtx (DImode);
14909})
14910
14911
14912(define_expand "strmovsi"
14913  [(set (match_dup 2)
14914  	(mem:SI (match_operand:SI 1 "register_operand" "")))
14915   (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14916        (match_dup 2))
14917   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14918	      (clobber (reg:CC 17))])
14919   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14920	      (clobber (reg:CC 17))])]
14921  ""
14922{
14923  if (TARGET_64BIT)
14924    {
14925      emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14926      DONE;
14927    }
14928  if (TARGET_SINGLE_STRINGOP || optimize_size)
14929    {
14930      emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14931				operands[1]));
14932      DONE;
14933    }
14934  else 
14935    operands[2] = gen_reg_rtx (SImode);
14936})
14937
14938(define_expand "strmovsi_rex64"
14939  [(set (match_dup 2)
14940  	(mem:SI (match_operand:DI 1 "register_operand" "")))
14941   (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14942        (match_dup 2))
14943   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14944	      (clobber (reg:CC 17))])
14945   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14946	      (clobber (reg:CC 17))])]
14947  "TARGET_64BIT"
14948{
14949  if (TARGET_SINGLE_STRINGOP || optimize_size)
14950    {
14951      emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14952				     operands[1]));
14953      DONE;
14954    }
14955  else 
14956    operands[2] = gen_reg_rtx (SImode);
14957})
14958
14959(define_expand "strmovhi"
14960  [(set (match_dup 2)
14961  	(mem:HI (match_operand:SI 1 "register_operand" "")))
14962   (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14963        (match_dup 2))
14964   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14965	      (clobber (reg:CC 17))])
14966   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14967	      (clobber (reg:CC 17))])]
14968  ""
14969{
14970  if (TARGET_64BIT)
14971    {
14972      emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14973      DONE;
14974    }
14975  if (TARGET_SINGLE_STRINGOP || optimize_size)
14976    {
14977      emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14978				operands[1]));
14979      DONE;
14980    }
14981  else 
14982    operands[2] = gen_reg_rtx (HImode);
14983})
14984
14985(define_expand "strmovhi_rex64"
14986  [(set (match_dup 2)
14987  	(mem:HI (match_operand:DI 1 "register_operand" "")))
14988   (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14989        (match_dup 2))
14990   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14991	      (clobber (reg:CC 17))])
14992   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14993	      (clobber (reg:CC 17))])]
14994  "TARGET_64BIT"
14995{
14996  if (TARGET_SINGLE_STRINGOP || optimize_size)
14997    {
14998      emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14999				     operands[1]));
15000      DONE;
15001    }
15002  else 
15003    operands[2] = gen_reg_rtx (HImode);
15004})
15005
15006(define_expand "strmovqi"
15007  [(set (match_dup 2)
15008  	(mem:QI (match_operand:SI 1 "register_operand" "")))
15009   (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15010        (match_dup 2))
15011   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15012	      (clobber (reg:CC 17))])
15013   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15014	      (clobber (reg:CC 17))])]
15015  ""
15016{
15017  if (TARGET_64BIT)
15018    {
15019      emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15020      DONE;
15021    }
15022  if (TARGET_SINGLE_STRINGOP || optimize_size)
15023    {
15024      emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15025				operands[1]));
15026      DONE;
15027    }
15028  else 
15029    operands[2] = gen_reg_rtx (QImode);
15030})
15031
15032(define_expand "strmovqi_rex64"
15033  [(set (match_dup 2)
15034  	(mem:QI (match_operand:DI 1 "register_operand" "")))
15035   (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15036        (match_dup 2))
15037   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15038	      (clobber (reg:CC 17))])
15039   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15040	      (clobber (reg:CC 17))])]
15041  "TARGET_64BIT"
15042{
15043  if (TARGET_SINGLE_STRINGOP || optimize_size)
15044    {
15045      emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15046				     operands[1]));
15047      DONE;
15048    }
15049  else 
15050    operands[2] = gen_reg_rtx (QImode);
15051})
15052
15053(define_insn "strmovdi_rex_1"
15054  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15055	(mem:DI (match_operand:DI 3 "register_operand" "1")))
15056   (set (match_operand:DI 0 "register_operand" "=D")
15057	(plus:DI (match_dup 2)
15058		 (const_int 8)))
15059   (set (match_operand:DI 1 "register_operand" "=S")
15060	(plus:DI (match_dup 3)
15061		 (const_int 8)))
15062   (use (reg:SI 19))]
15063  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15064  "movsq"
15065  [(set_attr "type" "str")
15066   (set_attr "mode" "DI")
15067   (set_attr "memory" "both")])
15068
15069(define_insn "strmovsi_1"
15070  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15071	(mem:SI (match_operand:SI 3 "register_operand" "1")))
15072   (set (match_operand:SI 0 "register_operand" "=D")
15073	(plus:SI (match_dup 2)
15074		 (const_int 4)))
15075   (set (match_operand:SI 1 "register_operand" "=S")
15076	(plus:SI (match_dup 3)
15077		 (const_int 4)))
15078   (use (reg:SI 19))]
15079  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15080  "{movsl|movsd}"
15081  [(set_attr "type" "str")
15082   (set_attr "mode" "SI")
15083   (set_attr "memory" "both")])
15084
15085(define_insn "strmovsi_rex_1"
15086  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15087	(mem:SI (match_operand:DI 3 "register_operand" "1")))
15088   (set (match_operand:DI 0 "register_operand" "=D")
15089	(plus:DI (match_dup 2)
15090		 (const_int 4)))
15091   (set (match_operand:DI 1 "register_operand" "=S")
15092	(plus:DI (match_dup 3)
15093		 (const_int 4)))
15094   (use (reg:SI 19))]
15095  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15096  "{movsl|movsd}"
15097  [(set_attr "type" "str")
15098   (set_attr "mode" "SI")
15099   (set_attr "memory" "both")])
15100
15101(define_insn "strmovhi_1"
15102  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15103	(mem:HI (match_operand:SI 3 "register_operand" "1")))
15104   (set (match_operand:SI 0 "register_operand" "=D")
15105	(plus:SI (match_dup 2)
15106		 (const_int 2)))
15107   (set (match_operand:SI 1 "register_operand" "=S")
15108	(plus:SI (match_dup 3)
15109		 (const_int 2)))
15110   (use (reg:SI 19))]
15111  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15112  "movsw"
15113  [(set_attr "type" "str")
15114   (set_attr "memory" "both")
15115   (set_attr "mode" "HI")])
15116
15117(define_insn "strmovhi_rex_1"
15118  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15119	(mem:HI (match_operand:DI 3 "register_operand" "1")))
15120   (set (match_operand:DI 0 "register_operand" "=D")
15121	(plus:DI (match_dup 2)
15122		 (const_int 2)))
15123   (set (match_operand:DI 1 "register_operand" "=S")
15124	(plus:DI (match_dup 3)
15125		 (const_int 2)))
15126   (use (reg:SI 19))]
15127  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15128  "movsw"
15129  [(set_attr "type" "str")
15130   (set_attr "memory" "both")
15131   (set_attr "mode" "HI")])
15132
15133(define_insn "strmovqi_1"
15134  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15135	(mem:QI (match_operand:SI 3 "register_operand" "1")))
15136   (set (match_operand:SI 0 "register_operand" "=D")
15137	(plus:SI (match_dup 2)
15138		 (const_int 1)))
15139   (set (match_operand:SI 1 "register_operand" "=S")
15140	(plus:SI (match_dup 3)
15141		 (const_int 1)))
15142   (use (reg:SI 19))]
15143  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15144  "movsb"
15145  [(set_attr "type" "str")
15146   (set_attr "memory" "both")
15147   (set_attr "mode" "QI")])
15148
15149(define_insn "strmovqi_rex_1"
15150  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15151	(mem:QI (match_operand:DI 3 "register_operand" "1")))
15152   (set (match_operand:DI 0 "register_operand" "=D")
15153	(plus:DI (match_dup 2)
15154		 (const_int 1)))
15155   (set (match_operand:DI 1 "register_operand" "=S")
15156	(plus:DI (match_dup 3)
15157		 (const_int 1)))
15158   (use (reg:SI 19))]
15159  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15160  "movsb"
15161  [(set_attr "type" "str")
15162   (set_attr "memory" "both")
15163   (set_attr "mode" "QI")])
15164
15165(define_insn "rep_movdi_rex64"
15166  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15167   (set (match_operand:DI 0 "register_operand" "=D") 
15168        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15169			    (const_int 3))
15170		 (match_operand:DI 3 "register_operand" "0")))
15171   (set (match_operand:DI 1 "register_operand" "=S") 
15172        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15173		 (match_operand:DI 4 "register_operand" "1")))
15174   (set (mem:BLK (match_dup 3))
15175	(mem:BLK (match_dup 4)))
15176   (use (match_dup 5))
15177   (use (reg:SI 19))]
15178  "TARGET_64BIT"
15179  "{rep\;movsq|rep movsq}"
15180  [(set_attr "type" "str")
15181   (set_attr "prefix_rep" "1")
15182   (set_attr "memory" "both")
15183   (set_attr "mode" "DI")])
15184
15185(define_insn "rep_movsi"
15186  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15187   (set (match_operand:SI 0 "register_operand" "=D") 
15188        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15189			    (const_int 2))
15190		 (match_operand:SI 3 "register_operand" "0")))
15191   (set (match_operand:SI 1 "register_operand" "=S") 
15192        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15193		 (match_operand:SI 4 "register_operand" "1")))
15194   (set (mem:BLK (match_dup 3))
15195	(mem:BLK (match_dup 4)))
15196   (use (match_dup 5))
15197   (use (reg:SI 19))]
15198  "!TARGET_64BIT"
15199  "{rep\;movsl|rep movsd}"
15200  [(set_attr "type" "str")
15201   (set_attr "prefix_rep" "1")
15202   (set_attr "memory" "both")
15203   (set_attr "mode" "SI")])
15204
15205(define_insn "rep_movsi_rex64"
15206  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15207   (set (match_operand:DI 0 "register_operand" "=D") 
15208        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15209			    (const_int 2))
15210		 (match_operand:DI 3 "register_operand" "0")))
15211   (set (match_operand:DI 1 "register_operand" "=S") 
15212        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15213		 (match_operand:DI 4 "register_operand" "1")))
15214   (set (mem:BLK (match_dup 3))
15215	(mem:BLK (match_dup 4)))
15216   (use (match_dup 5))
15217   (use (reg:SI 19))]
15218  "TARGET_64BIT"
15219  "{rep\;movsl|rep movsd}"
15220  [(set_attr "type" "str")
15221   (set_attr "prefix_rep" "1")
15222   (set_attr "memory" "both")
15223   (set_attr "mode" "SI")])
15224
15225(define_insn "rep_movqi"
15226  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15227   (set (match_operand:SI 0 "register_operand" "=D") 
15228        (plus:SI (match_operand:SI 3 "register_operand" "0")
15229		 (match_operand:SI 5 "register_operand" "2")))
15230   (set (match_operand:SI 1 "register_operand" "=S") 
15231        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15232   (set (mem:BLK (match_dup 3))
15233	(mem:BLK (match_dup 4)))
15234   (use (match_dup 5))
15235   (use (reg:SI 19))]
15236  "!TARGET_64BIT"
15237  "{rep\;movsb|rep movsb}"
15238  [(set_attr "type" "str")
15239   (set_attr "prefix_rep" "1")
15240   (set_attr "memory" "both")
15241   (set_attr "mode" "SI")])
15242
15243(define_insn "rep_movqi_rex64"
15244  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15245   (set (match_operand:DI 0 "register_operand" "=D") 
15246        (plus:DI (match_operand:DI 3 "register_operand" "0")
15247		 (match_operand:DI 5 "register_operand" "2")))
15248   (set (match_operand:DI 1 "register_operand" "=S") 
15249        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15250   (set (mem:BLK (match_dup 3))
15251	(mem:BLK (match_dup 4)))
15252   (use (match_dup 5))
15253   (use (reg:SI 19))]
15254  "TARGET_64BIT"
15255  "{rep\;movsb|rep movsb}"
15256  [(set_attr "type" "str")
15257   (set_attr "prefix_rep" "1")
15258   (set_attr "memory" "both")
15259   (set_attr "mode" "SI")])
15260
15261(define_expand "clrstrsi"
15262   [(use (match_operand:BLK 0 "memory_operand" ""))
15263    (use (match_operand:SI 1 "nonmemory_operand" ""))
15264    (use (match_operand 2 "const_int_operand" ""))]
15265  ""
15266{
15267 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15268   DONE;
15269 else
15270   FAIL;
15271})
15272
15273(define_expand "clrstrdi"
15274   [(use (match_operand:BLK 0 "memory_operand" ""))
15275    (use (match_operand:DI 1 "nonmemory_operand" ""))
15276    (use (match_operand 2 "const_int_operand" ""))]
15277  "TARGET_64BIT"
15278{
15279 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15280   DONE;
15281 else
15282   FAIL;
15283})
15284
15285;; Most CPUs don't like single string operations
15286;; Handle this case here to simplify previous expander.
15287
15288(define_expand "strsetdi_rex64"
15289  [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15290	(match_operand:DI 1 "register_operand" ""))
15291   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15292	      (clobber (reg:CC 17))])]
15293  "TARGET_64BIT"
15294{
15295  if (TARGET_SINGLE_STRINGOP || optimize_size)
15296    {
15297      emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15298      DONE;
15299    }
15300})
15301
15302(define_expand "strsetsi"
15303  [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15304	(match_operand:SI 1 "register_operand" ""))
15305   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15306	      (clobber (reg:CC 17))])]
15307  ""
15308{
15309  if (TARGET_64BIT)
15310    {
15311      emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15312      DONE;
15313    }
15314  else if (TARGET_SINGLE_STRINGOP || optimize_size)
15315    {
15316      emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15317      DONE;
15318    }
15319})
15320
15321(define_expand "strsetsi_rex64"
15322  [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15323	(match_operand:SI 1 "register_operand" ""))
15324   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15325	      (clobber (reg:CC 17))])]
15326  "TARGET_64BIT"
15327{
15328  if (TARGET_SINGLE_STRINGOP || optimize_size)
15329    {
15330      emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15331      DONE;
15332    }
15333})
15334
15335(define_expand "strsethi"
15336  [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15337	(match_operand:HI 1 "register_operand" ""))
15338   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15339	      (clobber (reg:CC 17))])]
15340  ""
15341{
15342  if (TARGET_64BIT)
15343    {
15344      emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15345      DONE;
15346    }
15347  else if (TARGET_SINGLE_STRINGOP || optimize_size)
15348    {
15349      emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15350      DONE;
15351    }
15352})
15353
15354(define_expand "strsethi_rex64"
15355  [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15356	(match_operand:HI 1 "register_operand" ""))
15357   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15358	      (clobber (reg:CC 17))])]
15359  "TARGET_64BIT"
15360{
15361  if (TARGET_SINGLE_STRINGOP || optimize_size)
15362    {
15363      emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15364      DONE;
15365    }
15366})
15367
15368(define_expand "strsetqi"
15369  [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15370	(match_operand:QI 1 "register_operand" ""))
15371   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15372	      (clobber (reg:CC 17))])]
15373  ""
15374{
15375  if (TARGET_64BIT)
15376    {
15377      emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15378      DONE;
15379    }
15380  else if (TARGET_SINGLE_STRINGOP || optimize_size)
15381    {
15382      emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15383      DONE;
15384    }
15385})
15386
15387(define_expand "strsetqi_rex64"
15388  [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15389	(match_operand:QI 1 "register_operand" ""))
15390   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15391	      (clobber (reg:CC 17))])]
15392  "TARGET_64BIT"
15393{
15394  if (TARGET_SINGLE_STRINGOP || optimize_size)
15395    {
15396      emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15397      DONE;
15398    }
15399})
15400
15401(define_insn "strsetdi_rex_1"
15402  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15403	(match_operand:SI 2 "register_operand" "a"))
15404   (set (match_operand:DI 0 "register_operand" "=D")
15405	(plus:DI (match_dup 1)
15406		 (const_int 8)))
15407   (use (reg:SI 19))]
15408  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15409  "stosq"
15410  [(set_attr "type" "str")
15411   (set_attr "memory" "store")
15412   (set_attr "mode" "DI")])
15413
15414(define_insn "strsetsi_1"
15415  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15416	(match_operand:SI 2 "register_operand" "a"))
15417   (set (match_operand:SI 0 "register_operand" "=D")
15418	(plus:SI (match_dup 1)
15419		 (const_int 4)))
15420   (use (reg:SI 19))]
15421  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15422  "{stosl|stosd}"
15423  [(set_attr "type" "str")
15424   (set_attr "memory" "store")
15425   (set_attr "mode" "SI")])
15426
15427(define_insn "strsetsi_rex_1"
15428  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15429	(match_operand:SI 2 "register_operand" "a"))
15430   (set (match_operand:DI 0 "register_operand" "=D")
15431	(plus:DI (match_dup 1)
15432		 (const_int 4)))
15433   (use (reg:SI 19))]
15434  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15435  "{stosl|stosd}"
15436  [(set_attr "type" "str")
15437   (set_attr "memory" "store")
15438   (set_attr "mode" "SI")])
15439
15440(define_insn "strsethi_1"
15441  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15442	(match_operand:HI 2 "register_operand" "a"))
15443   (set (match_operand:SI 0 "register_operand" "=D")
15444	(plus:SI (match_dup 1)
15445		 (const_int 2)))
15446   (use (reg:SI 19))]
15447  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15448  "stosw"
15449  [(set_attr "type" "str")
15450   (set_attr "memory" "store")
15451   (set_attr "mode" "HI")])
15452
15453(define_insn "strsethi_rex_1"
15454  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15455	(match_operand:HI 2 "register_operand" "a"))
15456   (set (match_operand:DI 0 "register_operand" "=D")
15457	(plus:DI (match_dup 1)
15458		 (const_int 2)))
15459   (use (reg:SI 19))]
15460  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15461  "stosw"
15462  [(set_attr "type" "str")
15463   (set_attr "memory" "store")
15464   (set_attr "mode" "HI")])
15465
15466(define_insn "strsetqi_1"
15467  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15468	(match_operand:QI 2 "register_operand" "a"))
15469   (set (match_operand:SI 0 "register_operand" "=D")
15470	(plus:SI (match_dup 1)
15471		 (const_int 1)))
15472   (use (reg:SI 19))]
15473  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15474  "stosb"
15475  [(set_attr "type" "str")
15476   (set_attr "memory" "store")
15477   (set_attr "mode" "QI")])
15478
15479(define_insn "strsetqi_rex_1"
15480  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15481	(match_operand:QI 2 "register_operand" "a"))
15482   (set (match_operand:DI 0 "register_operand" "=D")
15483	(plus:DI (match_dup 1)
15484		 (const_int 1)))
15485   (use (reg:SI 19))]
15486  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15487  "stosb"
15488  [(set_attr "type" "str")
15489   (set_attr "memory" "store")
15490   (set_attr "mode" "QI")])
15491
15492(define_insn "rep_stosdi_rex64"
15493  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15494   (set (match_operand:DI 0 "register_operand" "=D") 
15495        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15496			    (const_int 3))
15497		 (match_operand:DI 3 "register_operand" "0")))
15498   (set (mem:BLK (match_dup 3))
15499	(const_int 0))
15500   (use (match_operand:DI 2 "register_operand" "a"))
15501   (use (match_dup 4))
15502   (use (reg:SI 19))]
15503  "TARGET_64BIT"
15504  "{rep\;stosq|rep stosq}"
15505  [(set_attr "type" "str")
15506   (set_attr "prefix_rep" "1")
15507   (set_attr "memory" "store")
15508   (set_attr "mode" "DI")])
15509
15510(define_insn "rep_stossi"
15511  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15512   (set (match_operand:SI 0 "register_operand" "=D") 
15513        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15514			    (const_int 2))
15515		 (match_operand:SI 3 "register_operand" "0")))
15516   (set (mem:BLK (match_dup 3))
15517	(const_int 0))
15518   (use (match_operand:SI 2 "register_operand" "a"))
15519   (use (match_dup 4))
15520   (use (reg:SI 19))]
15521  "!TARGET_64BIT"
15522  "{rep\;stosl|rep stosd}"
15523  [(set_attr "type" "str")
15524   (set_attr "prefix_rep" "1")
15525   (set_attr "memory" "store")
15526   (set_attr "mode" "SI")])
15527
15528(define_insn "rep_stossi_rex64"
15529  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15530   (set (match_operand:DI 0 "register_operand" "=D") 
15531        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15532			    (const_int 2))
15533		 (match_operand:DI 3 "register_operand" "0")))
15534   (set (mem:BLK (match_dup 3))
15535	(const_int 0))
15536   (use (match_operand:SI 2 "register_operand" "a"))
15537   (use (match_dup 4))
15538   (use (reg:SI 19))]
15539  "TARGET_64BIT"
15540  "{rep\;stosl|rep stosd}"
15541  [(set_attr "type" "str")
15542   (set_attr "prefix_rep" "1")
15543   (set_attr "memory" "store")
15544   (set_attr "mode" "SI")])
15545
15546(define_insn "rep_stosqi"
15547  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15548   (set (match_operand:SI 0 "register_operand" "=D") 
15549        (plus:SI (match_operand:SI 3 "register_operand" "0")
15550		 (match_operand:SI 4 "register_operand" "1")))
15551   (set (mem:BLK (match_dup 3))
15552	(const_int 0))
15553   (use (match_operand:QI 2 "register_operand" "a"))
15554   (use (match_dup 4))
15555   (use (reg:SI 19))]
15556  "!TARGET_64BIT"
15557  "{rep\;stosb|rep stosb}"
15558  [(set_attr "type" "str")
15559   (set_attr "prefix_rep" "1")
15560   (set_attr "memory" "store")
15561   (set_attr "mode" "QI")])
15562
15563(define_insn "rep_stosqi_rex64"
15564  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15565   (set (match_operand:DI 0 "register_operand" "=D") 
15566        (plus:DI (match_operand:DI 3 "register_operand" "0")
15567		 (match_operand:DI 4 "register_operand" "1")))
15568   (set (mem:BLK (match_dup 3))
15569	(const_int 0))
15570   (use (match_operand:QI 2 "register_operand" "a"))
15571   (use (match_dup 4))
15572   (use (reg:DI 19))]
15573  "TARGET_64BIT"
15574  "{rep\;stosb|rep stosb}"
15575  [(set_attr "type" "str")
15576   (set_attr "prefix_rep" "1")
15577   (set_attr "memory" "store")
15578   (set_attr "mode" "QI")])
15579
15580(define_expand "cmpstrsi"
15581  [(set (match_operand:SI 0 "register_operand" "")
15582	(compare:SI (match_operand:BLK 1 "general_operand" "")
15583		    (match_operand:BLK 2 "general_operand" "")))
15584   (use (match_operand 3 "general_operand" ""))
15585   (use (match_operand 4 "immediate_operand" ""))]
15586  ""
15587{
15588  rtx addr1, addr2, out, outlow, count, countreg, align;
15589
15590  out = operands[0];
15591  if (GET_CODE (out) != REG)
15592    out = gen_reg_rtx (SImode);
15593
15594  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15595  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15596  
15597  count = operands[3];
15598  countreg = ix86_zero_extend_to_Pmode (count);
15599
15600  /* %%% Iff we are testing strict equality, we can use known alignment
15601     to good advantage.  This may be possible with combine, particularly
15602     once cc0 is dead.  */
15603  align = operands[4];
15604
15605  emit_insn (gen_cld ());
15606  if (GET_CODE (count) == CONST_INT)
15607    {
15608      if (INTVAL (count) == 0)
15609	{
15610	  emit_move_insn (operands[0], const0_rtx);
15611	  DONE;
15612	}
15613      if (TARGET_64BIT)
15614	emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15615					  addr1, addr2, countreg));
15616      else
15617	emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15618				      addr1, addr2, countreg));
15619    }
15620  else
15621    {
15622      if (TARGET_64BIT)
15623	{
15624	  emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15625	  emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15626					 addr1, addr2, countreg));
15627	}
15628      else
15629	{
15630	  emit_insn (gen_cmpsi_1 (countreg, countreg));
15631	  emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15632				     addr1, addr2, countreg));
15633	}
15634    }
15635
15636  outlow = gen_lowpart (QImode, out);
15637  emit_insn (gen_cmpintqi (outlow));
15638  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15639
15640  if (operands[0] != out)
15641    emit_move_insn (operands[0], out);
15642
15643  DONE;
15644})
15645
15646;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15647
15648(define_expand "cmpintqi"
15649  [(set (match_dup 1)
15650	(gtu:QI (reg:CC 17) (const_int 0)))
15651   (set (match_dup 2)
15652	(ltu:QI (reg:CC 17) (const_int 0)))
15653   (parallel [(set (match_operand:QI 0 "register_operand" "")
15654		   (minus:QI (match_dup 1)
15655			     (match_dup 2)))
15656	      (clobber (reg:CC 17))])]
15657  ""
15658  "operands[1] = gen_reg_rtx (QImode);
15659   operands[2] = gen_reg_rtx (QImode);")
15660
15661;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15662;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15663
15664(define_insn "cmpstrqi_nz_1"
15665  [(set (reg:CC 17)
15666	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15667		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15668   (use (match_operand:SI 6 "register_operand" "2"))
15669   (use (match_operand:SI 3 "immediate_operand" "i"))
15670   (use (reg:SI 19))
15671   (clobber (match_operand:SI 0 "register_operand" "=S"))
15672   (clobber (match_operand:SI 1 "register_operand" "=D"))
15673   (clobber (match_operand:SI 2 "register_operand" "=c"))]
15674  "!TARGET_64BIT"
15675  "repz{\;| }cmpsb"
15676  [(set_attr "type" "str")
15677   (set_attr "mode" "QI")
15678   (set_attr "prefix_rep" "1")])
15679
15680(define_insn "cmpstrqi_nz_rex_1"
15681  [(set (reg:CC 17)
15682	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15683		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15684   (use (match_operand:DI 6 "register_operand" "2"))
15685   (use (match_operand:SI 3 "immediate_operand" "i"))
15686   (use (reg:SI 19))
15687   (clobber (match_operand:DI 0 "register_operand" "=S"))
15688   (clobber (match_operand:DI 1 "register_operand" "=D"))
15689   (clobber (match_operand:DI 2 "register_operand" "=c"))]
15690  "TARGET_64BIT"
15691  "repz{\;| }cmpsb"
15692  [(set_attr "type" "str")
15693   (set_attr "mode" "QI")
15694   (set_attr "prefix_rep" "1")])
15695
15696;; The same, but the count is not known to not be zero.
15697
15698(define_insn "cmpstrqi_1"
15699  [(set (reg:CC 17)
15700	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15701			     (const_int 0))
15702	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15703		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15704	  (const_int 0)))
15705   (use (match_operand:SI 3 "immediate_operand" "i"))
15706   (use (reg:CC 17))
15707   (use (reg:SI 19))
15708   (clobber (match_operand:SI 0 "register_operand" "=S"))
15709   (clobber (match_operand:SI 1 "register_operand" "=D"))
15710   (clobber (match_operand:SI 2 "register_operand" "=c"))]
15711  "!TARGET_64BIT"
15712  "repz{\;| }cmpsb"
15713  [(set_attr "type" "str")
15714   (set_attr "mode" "QI")
15715   (set_attr "prefix_rep" "1")])
15716
15717(define_insn "cmpstrqi_rex_1"
15718  [(set (reg:CC 17)
15719	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15720			     (const_int 0))
15721	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15722		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15723	  (const_int 0)))
15724   (use (match_operand:SI 3 "immediate_operand" "i"))
15725   (use (reg:CC 17))
15726   (use (reg:SI 19))
15727   (clobber (match_operand:DI 0 "register_operand" "=S"))
15728   (clobber (match_operand:DI 1 "register_operand" "=D"))
15729   (clobber (match_operand:DI 2 "register_operand" "=c"))]
15730  "TARGET_64BIT"
15731  "repz{\;| }cmpsb"
15732  [(set_attr "type" "str")
15733   (set_attr "mode" "QI")
15734   (set_attr "prefix_rep" "1")])
15735
15736(define_expand "strlensi"
15737  [(set (match_operand:SI 0 "register_operand" "")
15738	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
15739		    (match_operand:QI 2 "immediate_operand" "")
15740		    (match_operand 3 "immediate_operand" "")] 0))]
15741  ""
15742{
15743 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15744   DONE;
15745 else
15746   FAIL;
15747})
15748
15749(define_expand "strlendi"
15750  [(set (match_operand:DI 0 "register_operand" "")
15751	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
15752		    (match_operand:QI 2 "immediate_operand" "")
15753		    (match_operand 3 "immediate_operand" "")] 0))]
15754  ""
15755{
15756 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15757   DONE;
15758 else
15759   FAIL;
15760})
15761
15762(define_insn "strlenqi_1"
15763  [(set (match_operand:SI 0 "register_operand" "=&c")
15764	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15765		    (match_operand:QI 2 "register_operand" "a")
15766		    (match_operand:SI 3 "immediate_operand" "i")
15767		    (match_operand:SI 4 "register_operand" "0")] 0))
15768   (use (reg:SI 19))
15769   (clobber (match_operand:SI 1 "register_operand" "=D"))
15770   (clobber (reg:CC 17))]
15771  "!TARGET_64BIT"
15772  "repnz{\;| }scasb"
15773  [(set_attr "type" "str")
15774   (set_attr "mode" "QI")
15775   (set_attr "prefix_rep" "1")])
15776
15777(define_insn "strlenqi_rex_1"
15778  [(set (match_operand:DI 0 "register_operand" "=&c")
15779	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15780		    (match_operand:QI 2 "register_operand" "a")
15781		    (match_operand:DI 3 "immediate_operand" "i")
15782		    (match_operand:DI 4 "register_operand" "0")] 0))
15783   (use (reg:SI 19))
15784   (clobber (match_operand:DI 1 "register_operand" "=D"))
15785   (clobber (reg:CC 17))]
15786  "TARGET_64BIT"
15787  "repnz{\;| }scasb"
15788  [(set_attr "type" "str")
15789   (set_attr "mode" "QI")
15790   (set_attr "prefix_rep" "1")])
15791
15792;; Peephole optimizations to clean up after cmpstr*.  This should be
15793;; handled in combine, but it is not currently up to the task.
15794;; When used for their truth value, the cmpstr* expanders generate
15795;; code like this:
15796;;
15797;;   repz cmpsb
15798;;   seta 	%al
15799;;   setb 	%dl
15800;;   cmpb 	%al, %dl
15801;;   jcc	label
15802;;
15803;; The intermediate three instructions are unnecessary.
15804
15805;; This one handles cmpstr*_nz_1...
15806(define_peephole2
15807  [(parallel[
15808     (set (reg:CC 17)
15809	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15810		      (mem:BLK (match_operand 5 "register_operand" ""))))
15811     (use (match_operand 6 "register_operand" ""))
15812     (use (match_operand:SI 3 "immediate_operand" ""))
15813     (use (reg:SI 19))
15814     (clobber (match_operand 0 "register_operand" ""))
15815     (clobber (match_operand 1 "register_operand" ""))
15816     (clobber (match_operand 2 "register_operand" ""))])
15817   (set (match_operand:QI 7 "register_operand" "")
15818	(gtu:QI (reg:CC 17) (const_int 0)))
15819   (set (match_operand:QI 8 "register_operand" "")
15820	(ltu:QI (reg:CC 17) (const_int 0)))
15821   (set (reg 17)
15822	(compare (match_dup 7) (match_dup 8)))
15823  ]
15824  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15825  [(parallel[
15826     (set (reg:CC 17)
15827	  (compare:CC (mem:BLK (match_dup 4))
15828		      (mem:BLK (match_dup 5))))
15829     (use (match_dup 6))
15830     (use (match_dup 3))
15831     (use (reg:SI 19))
15832     (clobber (match_dup 0))
15833     (clobber (match_dup 1))
15834     (clobber (match_dup 2))])]
15835  "")
15836
15837;; ...and this one handles cmpstr*_1.
15838(define_peephole2
15839  [(parallel[
15840     (set (reg:CC 17)
15841	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15842			       (const_int 0))
15843	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15844		        (mem:BLK (match_operand 5 "register_operand" "")))
15845	    (const_int 0)))
15846     (use (match_operand:SI 3 "immediate_operand" ""))
15847     (use (reg:CC 17))
15848     (use (reg:SI 19))
15849     (clobber (match_operand 0 "register_operand" ""))
15850     (clobber (match_operand 1 "register_operand" ""))
15851     (clobber (match_operand 2 "register_operand" ""))])
15852   (set (match_operand:QI 7 "register_operand" "")
15853	(gtu:QI (reg:CC 17) (const_int 0)))
15854   (set (match_operand:QI 8 "register_operand" "")
15855	(ltu:QI (reg:CC 17) (const_int 0)))
15856   (set (reg 17)
15857	(compare (match_dup 7) (match_dup 8)))
15858  ]
15859  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15860  [(parallel[
15861     (set (reg:CC 17)
15862	  (if_then_else:CC (ne (match_dup 6)
15863			       (const_int 0))
15864	    (compare:CC (mem:BLK (match_dup 4))
15865			(mem:BLK (match_dup 5)))
15866	    (const_int 0)))
15867     (use (match_dup 3))
15868     (use (reg:CC 17))
15869     (use (reg:SI 19))
15870     (clobber (match_dup 0))
15871     (clobber (match_dup 1))
15872     (clobber (match_dup 2))])]
15873  "")
15874
15875
15876
15877;; Conditional move instructions.
15878
15879(define_expand "movdicc"
15880  [(set (match_operand:DI 0 "register_operand" "")
15881	(if_then_else:DI (match_operand 1 "comparison_operator" "")
15882			 (match_operand:DI 2 "general_operand" "")
15883			 (match_operand:DI 3 "general_operand" "")))]
15884  "TARGET_64BIT"
15885  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15886
15887(define_insn "x86_movdicc_0_m1_rex64"
15888  [(set (match_operand:DI 0 "register_operand" "=r")
15889	(if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15890	  (const_int -1)
15891	  (const_int 0)))
15892   (clobber (reg:CC 17))]
15893  "TARGET_64BIT"
15894  "sbb{q}\t%0, %0"
15895  ; Since we don't have the proper number of operands for an alu insn,
15896  ; fill in all the blanks.
15897  [(set_attr "type" "alu")
15898   (set_attr "memory" "none")
15899   (set_attr "imm_disp" "false")
15900   (set_attr "mode" "DI")
15901   (set_attr "length_immediate" "0")])
15902
15903(define_insn "*movdicc_c_rex64"
15904  [(set (match_operand:DI 0 "register_operand" "=r,r")
15905	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
15906				[(reg 17) (const_int 0)])
15907		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15908		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15909  "TARGET_64BIT && TARGET_CMOVE
15910   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15911  "@
15912   cmov%O2%C1\t{%2, %0|%0, %2}
15913   cmov%O2%c1\t{%3, %0|%0, %3}"
15914  [(set_attr "type" "icmov")
15915   (set_attr "mode" "DI")])
15916
15917(define_expand "movsicc"
15918  [(set (match_operand:SI 0 "register_operand" "")
15919	(if_then_else:SI (match_operand 1 "comparison_operator" "")
15920			 (match_operand:SI 2 "general_operand" "")
15921			 (match_operand:SI 3 "general_operand" "")))]
15922  ""
15923  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15924
15925;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15926;; the register first winds up with `sbbl $0,reg', which is also weird.
15927;; So just document what we're doing explicitly.
15928
15929(define_insn "x86_movsicc_0_m1"
15930  [(set (match_operand:SI 0 "register_operand" "=r")
15931	(if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15932	  (const_int -1)
15933	  (const_int 0)))
15934   (clobber (reg:CC 17))]
15935  ""
15936  "sbb{l}\t%0, %0"
15937  ; Since we don't have the proper number of operands for an alu insn,
15938  ; fill in all the blanks.
15939  [(set_attr "type" "alu")
15940   (set_attr "memory" "none")
15941   (set_attr "imm_disp" "false")
15942   (set_attr "mode" "SI")
15943   (set_attr "length_immediate" "0")])
15944
15945(define_insn "*movsicc_noc"
15946  [(set (match_operand:SI 0 "register_operand" "=r,r")
15947	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
15948				[(reg 17) (const_int 0)])
15949		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15950		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15951  "TARGET_CMOVE
15952   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15953  "@
15954   cmov%O2%C1\t{%2, %0|%0, %2}
15955   cmov%O2%c1\t{%3, %0|%0, %3}"
15956  [(set_attr "type" "icmov")
15957   (set_attr "mode" "SI")])
15958
15959(define_expand "movhicc"
15960  [(set (match_operand:HI 0 "register_operand" "")
15961	(if_then_else:HI (match_operand 1 "comparison_operator" "")
15962			 (match_operand:HI 2 "nonimmediate_operand" "")
15963			 (match_operand:HI 3 "nonimmediate_operand" "")))]
15964  "TARGET_CMOVE && TARGET_HIMODE_MATH"
15965  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15966
15967(define_insn "*movhicc_noc"
15968  [(set (match_operand:HI 0 "register_operand" "=r,r")
15969	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
15970				[(reg 17) (const_int 0)])
15971		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15972		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15973  "TARGET_CMOVE
15974   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15975  "@
15976   cmov%O2%C1\t{%2, %0|%0, %2}
15977   cmov%O2%c1\t{%3, %0|%0, %3}"
15978  [(set_attr "type" "icmov")
15979   (set_attr "mode" "HI")])
15980
15981(define_expand "movsfcc"
15982  [(set (match_operand:SF 0 "register_operand" "")
15983	(if_then_else:SF (match_operand 1 "comparison_operator" "")
15984			 (match_operand:SF 2 "register_operand" "")
15985			 (match_operand:SF 3 "register_operand" "")))]
15986  "TARGET_CMOVE"
15987  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15988
15989(define_insn "*movsfcc_1"
15990  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15991	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
15992				[(reg 17) (const_int 0)])
15993		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15994		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15995  "TARGET_CMOVE
15996   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15997  "@
15998   fcmov%F1\t{%2, %0|%0, %2}
15999   fcmov%f1\t{%3, %0|%0, %3}
16000   cmov%O2%C1\t{%2, %0|%0, %2}
16001   cmov%O2%c1\t{%3, %0|%0, %3}"
16002  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16003   (set_attr "mode" "SF,SF,SI,SI")])
16004
16005(define_expand "movdfcc"
16006  [(set (match_operand:DF 0 "register_operand" "")
16007	(if_then_else:DF (match_operand 1 "comparison_operator" "")
16008			 (match_operand:DF 2 "register_operand" "")
16009			 (match_operand:DF 3 "register_operand" "")))]
16010  "TARGET_CMOVE"
16011  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16012
16013(define_insn "*movdfcc_1"
16014  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16015	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16016				[(reg 17) (const_int 0)])
16017		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16018		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16019  "!TARGET_64BIT && TARGET_CMOVE
16020   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16021  "@
16022   fcmov%F1\t{%2, %0|%0, %2}
16023   fcmov%f1\t{%3, %0|%0, %3}
16024   #
16025   #"
16026  [(set_attr "type" "fcmov,fcmov,multi,multi")
16027   (set_attr "mode" "DF")])
16028
16029(define_insn "*movdfcc_1_rex64"
16030  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16031	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16032				[(reg 17) (const_int 0)])
16033		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16034		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16035  "TARGET_64BIT && TARGET_CMOVE
16036   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16037  "@
16038   fcmov%F1\t{%2, %0|%0, %2}
16039   fcmov%f1\t{%3, %0|%0, %3}
16040   cmov%O2%C1\t{%2, %0|%0, %2}
16041   cmov%O2%c1\t{%3, %0|%0, %3}"
16042  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16043   (set_attr "mode" "DF")])
16044
16045(define_split
16046  [(set (match_operand:DF 0 "register_operand" "")
16047	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16048				[(match_operand 4 "" "") (const_int 0)])
16049		      (match_operand:DF 2 "nonimmediate_operand" "")
16050		      (match_operand:DF 3 "nonimmediate_operand" "")))]
16051  "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
16052  [(set (match_dup 2)
16053	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16054		      (match_dup 5)
16055		      (match_dup 7)))
16056   (set (match_dup 3)
16057	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16058		      (match_dup 6)
16059		      (match_dup 8)))]
16060  "split_di (operands+2, 1, operands+5, operands+6);
16061   split_di (operands+3, 1, operands+7, operands+8);
16062   split_di (operands, 1, operands+2, operands+3);")
16063
16064(define_expand "movxfcc"
16065  [(set (match_operand:XF 0 "register_operand" "")
16066	(if_then_else:XF (match_operand 1 "comparison_operator" "")
16067			 (match_operand:XF 2 "register_operand" "")
16068			 (match_operand:XF 3 "register_operand" "")))]
16069  "!TARGET_64BIT && TARGET_CMOVE"
16070  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16071
16072(define_expand "movtfcc"
16073  [(set (match_operand:TF 0 "register_operand" "")
16074	(if_then_else:TF (match_operand 1 "comparison_operator" "")
16075			 (match_operand:TF 2 "register_operand" "")
16076			 (match_operand:TF 3 "register_operand" "")))]
16077  "TARGET_CMOVE"
16078  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16079
16080(define_insn "*movxfcc_1"
16081  [(set (match_operand:XF 0 "register_operand" "=f,f")
16082	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
16083				[(reg 17) (const_int 0)])
16084		      (match_operand:XF 2 "register_operand" "f,0")
16085		      (match_operand:XF 3 "register_operand" "0,f")))]
16086  "!TARGET_64BIT && TARGET_CMOVE"
16087  "@
16088   fcmov%F1\t{%2, %0|%0, %2}
16089   fcmov%f1\t{%3, %0|%0, %3}"
16090  [(set_attr "type" "fcmov")
16091   (set_attr "mode" "XF")])
16092
16093(define_insn "*movtfcc_1"
16094  [(set (match_operand:TF 0 "register_operand" "=f,f")
16095	(if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
16096				[(reg 17) (const_int 0)])
16097		      (match_operand:TF 2 "register_operand" "f,0")
16098		      (match_operand:TF 3 "register_operand" "0,f")))]
16099  "TARGET_CMOVE"
16100  "@
16101   fcmov%F1\t{%2, %0|%0, %2}
16102   fcmov%f1\t{%3, %0|%0, %3}"
16103  [(set_attr "type" "fcmov")
16104   (set_attr "mode" "XF")])
16105
16106(define_expand "minsf3"
16107  [(parallel [
16108     (set (match_operand:SF 0 "register_operand" "")
16109	  (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16110			       (match_operand:SF 2 "nonimmediate_operand" ""))
16111			   (match_dup 1)
16112			   (match_dup 2)))
16113     (clobber (reg:CC 17))])]
16114  "TARGET_SSE"
16115  "")
16116
16117(define_insn "*minsf"
16118  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16119	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16120			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16121			 (match_dup 1)
16122			 (match_dup 2)))
16123   (clobber (reg:CC 17))]
16124  "TARGET_SSE && TARGET_IEEE_FP"
16125  "#")
16126
16127(define_insn "*minsf_nonieee"
16128  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16129	(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16130			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16131			 (match_dup 1)
16132			 (match_dup 2)))
16133   (clobber (reg:CC 17))]
16134  "TARGET_SSE && !TARGET_IEEE_FP
16135   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16136  "#")
16137
16138(define_split
16139  [(set (match_operand:SF 0 "register_operand" "")
16140	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16141			     (match_operand:SF 2 "nonimmediate_operand" ""))
16142			 (match_operand:SF 3 "register_operand" "")
16143			 (match_operand:SF 4 "nonimmediate_operand" "")))
16144   (clobber (reg:CC 17))]
16145  "SSE_REG_P (operands[0]) && reload_completed
16146   && ((operands_match_p (operands[1], operands[3])
16147	&& operands_match_p (operands[2], operands[4]))
16148       || (operands_match_p (operands[1], operands[4])
16149	   && operands_match_p (operands[2], operands[3])))"
16150  [(set (match_dup 0)
16151	(if_then_else:SF (lt (match_dup 1)
16152			     (match_dup 2))
16153			 (match_dup 1)
16154			 (match_dup 2)))])
16155
16156;; We can't represent the LT test directly.  Do this by swapping the operands.
16157
16158(define_split
16159  [(set (match_operand:SF 0 "register_operand" "")
16160	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16161			     (match_operand:SF 2 "register_operand" ""))
16162			 (match_operand:SF 3 "register_operand" "")
16163			 (match_operand:SF 4 "register_operand" "")))
16164   (clobber (reg:CC 17))]
16165  "FP_REG_P (operands[0]) && reload_completed
16166   && ((operands_match_p (operands[1], operands[3])
16167	&& operands_match_p (operands[2], operands[4]))
16168       || (operands_match_p (operands[1], operands[4])
16169	   && operands_match_p (operands[2], operands[3])))"
16170  [(set (reg:CCFP 17)
16171	(compare:CCFP (match_dup 2)
16172		      (match_dup 1)))
16173   (set (match_dup 0)
16174	(if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16175			 (match_dup 1)
16176			 (match_dup 2)))])
16177
16178(define_insn "*minsf_sse"
16179  [(set (match_operand:SF 0 "register_operand" "=x")
16180	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16181			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
16182			 (match_dup 1)
16183			 (match_dup 2)))]
16184  "TARGET_SSE && reload_completed"
16185  "minss\t{%2, %0|%0, %2}"
16186  [(set_attr "type" "sse")
16187   (set_attr "mode" "SF")])
16188
16189(define_expand "mindf3"
16190  [(parallel [
16191     (set (match_operand:DF 0 "register_operand" "")
16192	  (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16193			       (match_operand:DF 2 "nonimmediate_operand" ""))
16194			   (match_dup 1)
16195			   (match_dup 2)))
16196     (clobber (reg:CC 17))])]
16197  "TARGET_SSE2 && TARGET_SSE_MATH"
16198  "#")
16199
16200(define_insn "*mindf"
16201  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16202	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16203			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16204			 (match_dup 1)
16205			 (match_dup 2)))
16206   (clobber (reg:CC 17))]
16207  "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16208  "#")
16209
16210(define_insn "*mindf_nonieee"
16211  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16212	(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16213			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16214			 (match_dup 1)
16215			 (match_dup 2)))
16216   (clobber (reg:CC 17))]
16217  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16218   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16219  "#")
16220
16221(define_split
16222  [(set (match_operand:DF 0 "register_operand" "")
16223	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16224			     (match_operand:DF 2 "nonimmediate_operand" ""))
16225			 (match_operand:DF 3 "register_operand" "")
16226			 (match_operand:DF 4 "nonimmediate_operand" "")))
16227   (clobber (reg:CC 17))]
16228  "SSE_REG_P (operands[0]) && reload_completed
16229   && ((operands_match_p (operands[1], operands[3])
16230	&& operands_match_p (operands[2], operands[4]))
16231       || (operands_match_p (operands[1], operands[4])
16232	   && operands_match_p (operands[2], operands[3])))"
16233  [(set (match_dup 0)
16234	(if_then_else:DF (lt (match_dup 1)
16235			     (match_dup 2))
16236			 (match_dup 1)
16237			 (match_dup 2)))])
16238
16239;; We can't represent the LT test directly.  Do this by swapping the operands.
16240(define_split
16241  [(set (match_operand:DF 0 "register_operand" "")
16242	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16243			     (match_operand:DF 2 "register_operand" ""))
16244			 (match_operand:DF 3 "register_operand" "")
16245			 (match_operand:DF 4 "register_operand" "")))
16246   (clobber (reg:CC 17))]
16247  "FP_REG_P (operands[0]) && reload_completed
16248   && ((operands_match_p (operands[1], operands[3])
16249	&& operands_match_p (operands[2], operands[4]))
16250       || (operands_match_p (operands[1], operands[4])
16251	   && operands_match_p (operands[2], operands[3])))"
16252  [(set (reg:CCFP 17)
16253	(compare:CCFP (match_dup 2)
16254		      (match_dup 2)))
16255   (set (match_dup 0)
16256	(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16257			 (match_dup 1)
16258			 (match_dup 2)))])
16259
16260(define_insn "*mindf_sse"
16261  [(set (match_operand:DF 0 "register_operand" "=Y")
16262	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16263			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16264			 (match_dup 1)
16265			 (match_dup 2)))]
16266  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16267  "minsd\t{%2, %0|%0, %2}"
16268  [(set_attr "type" "sse")
16269   (set_attr "mode" "DF")])
16270
16271(define_expand "maxsf3"
16272  [(parallel [
16273     (set (match_operand:SF 0 "register_operand" "")
16274	  (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16275			       (match_operand:SF 2 "nonimmediate_operand" ""))
16276			   (match_dup 1)
16277			   (match_dup 2)))
16278     (clobber (reg:CC 17))])]
16279  "TARGET_SSE"
16280  "#")
16281
16282(define_insn "*maxsf"
16283  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16284	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16285			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16286			 (match_dup 1)
16287			 (match_dup 2)))
16288   (clobber (reg:CC 17))]
16289  "TARGET_SSE && TARGET_IEEE_FP"
16290  "#")
16291
16292(define_insn "*maxsf_nonieee"
16293  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16294	(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16295			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16296			 (match_dup 1)
16297			 (match_dup 2)))
16298   (clobber (reg:CC 17))]
16299  "TARGET_SSE && !TARGET_IEEE_FP
16300   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16301  "#")
16302
16303(define_split
16304  [(set (match_operand:SF 0 "register_operand" "")
16305	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16306			     (match_operand:SF 2 "nonimmediate_operand" ""))
16307			 (match_operand:SF 3 "register_operand" "")
16308			 (match_operand:SF 4 "nonimmediate_operand" "")))
16309   (clobber (reg:CC 17))]
16310  "SSE_REG_P (operands[0]) && reload_completed
16311   && ((operands_match_p (operands[1], operands[3])
16312	&& operands_match_p (operands[2], operands[4]))
16313       || (operands_match_p (operands[1], operands[4])
16314	   && operands_match_p (operands[2], operands[3])))"
16315  [(set (match_dup 0)
16316	(if_then_else:SF (gt (match_dup 1)
16317			     (match_dup 2))
16318			 (match_dup 1)
16319			 (match_dup 2)))])
16320
16321(define_split
16322  [(set (match_operand:SF 0 "register_operand" "")
16323	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16324			     (match_operand:SF 2 "register_operand" ""))
16325			 (match_operand:SF 3 "register_operand" "")
16326			 (match_operand:SF 4 "register_operand" "")))
16327   (clobber (reg:CC 17))]
16328  "FP_REG_P (operands[0]) && reload_completed
16329   && ((operands_match_p (operands[1], operands[3])
16330	&& operands_match_p (operands[2], operands[4]))
16331       || (operands_match_p (operands[1], operands[4])
16332	   && operands_match_p (operands[2], operands[3])))"
16333  [(set (reg:CCFP 17)
16334	(compare:CCFP (match_dup 1)
16335		      (match_dup 2)))
16336   (set (match_dup 0)
16337	(if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16338			 (match_dup 1)
16339			 (match_dup 2)))])
16340
16341(define_insn "*maxsf_sse"
16342  [(set (match_operand:SF 0 "register_operand" "=x")
16343	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16344			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
16345			 (match_dup 1)
16346			 (match_dup 2)))]
16347  "TARGET_SSE && reload_completed"
16348  "maxss\t{%2, %0|%0, %2}"
16349  [(set_attr "type" "sse")
16350   (set_attr "mode" "SF")])
16351
16352(define_expand "maxdf3"
16353  [(parallel [
16354     (set (match_operand:DF 0 "register_operand" "")
16355	  (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16356			       (match_operand:DF 2 "nonimmediate_operand" ""))
16357			   (match_dup 1)
16358			   (match_dup 2)))
16359     (clobber (reg:CC 17))])]
16360  "TARGET_SSE2 && TARGET_SSE_MATH"
16361  "#")
16362
16363(define_insn "*maxdf"
16364  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16365	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16366			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16367			 (match_dup 1)
16368			 (match_dup 2)))
16369   (clobber (reg:CC 17))]
16370  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16371  "#")
16372
16373(define_insn "*maxdf_nonieee"
16374  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16375	(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16376			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16377			 (match_dup 1)
16378			 (match_dup 2)))
16379   (clobber (reg:CC 17))]
16380  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16381   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16382  "#")
16383
16384(define_split
16385  [(set (match_operand:DF 0 "register_operand" "")
16386	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16387			     (match_operand:DF 2 "nonimmediate_operand" ""))
16388			 (match_operand:DF 3 "register_operand" "")
16389			 (match_operand:DF 4 "nonimmediate_operand" "")))
16390   (clobber (reg:CC 17))]
16391  "SSE_REG_P (operands[0]) && reload_completed
16392   && ((operands_match_p (operands[1], operands[3])
16393	&& operands_match_p (operands[2], operands[4]))
16394       || (operands_match_p (operands[1], operands[4])
16395	   && operands_match_p (operands[2], operands[3])))"
16396  [(set (match_dup 0)
16397	(if_then_else:DF (gt (match_dup 1)
16398			     (match_dup 2))
16399			 (match_dup 1)
16400			 (match_dup 2)))])
16401
16402(define_split
16403  [(set (match_operand:DF 0 "register_operand" "")
16404	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16405			     (match_operand:DF 2 "register_operand" ""))
16406			 (match_operand:DF 3 "register_operand" "")
16407			 (match_operand:DF 4 "register_operand" "")))
16408   (clobber (reg:CC 17))]
16409  "FP_REG_P (operands[0]) && reload_completed
16410   && ((operands_match_p (operands[1], operands[3])
16411	&& operands_match_p (operands[2], operands[4]))
16412       || (operands_match_p (operands[1], operands[4])
16413	   && operands_match_p (operands[2], operands[3])))"
16414  [(set (reg:CCFP 17)
16415	(compare:CCFP (match_dup 1)
16416		      (match_dup 2)))
16417   (set (match_dup 0)
16418	(if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16419			 (match_dup 1)
16420			 (match_dup 2)))])
16421
16422(define_insn "*maxdf_sse"
16423  [(set (match_operand:DF 0 "register_operand" "=Y")
16424	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16425			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16426			 (match_dup 1)
16427			 (match_dup 2)))]
16428  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16429  "maxsd\t{%2, %0|%0, %2}"
16430  [(set_attr "type" "sse")
16431   (set_attr "mode" "DF")])
16432
16433;; Misc patterns (?)
16434
16435;; This pattern exists to put a dependency on all ebp-based memory accesses.
16436;; Otherwise there will be nothing to keep
16437;; 
16438;; [(set (reg ebp) (reg esp))]
16439;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16440;;  (clobber (eflags)]
16441;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16442;;
16443;; in proper program order.
16444(define_expand "pro_epilogue_adjust_stack"
16445  [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
16446		   (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16447			    (match_operand:SI 2 "immediate_operand" "i,i")))
16448	      (clobber (reg:CC 17))
16449	      (clobber (mem:BLK (scratch)))])]
16450 ""
16451{
16452  if (TARGET_64BIT)
16453    {
16454      emit_insn (gen_pro_epilogue_adjust_stack_rex64
16455		 (operands[0], operands[1], operands[2]));
16456      DONE;
16457    }
16458})
16459
16460(define_insn "*pro_epilogue_adjust_stack_1"
16461  [(set (match_operand:SI 0 "register_operand" "=r,r")
16462	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
16463	         (match_operand:SI 2 "immediate_operand" "i,i")))
16464   (clobber (reg:CC 17))
16465   (clobber (mem:BLK (scratch)))]
16466  "!TARGET_64BIT"
16467{
16468  switch (get_attr_type (insn))
16469    {
16470    case TYPE_IMOV:
16471      return "mov{l}\t{%1, %0|%0, %1}";
16472
16473    case TYPE_ALU:
16474      if (GET_CODE (operands[2]) == CONST_INT
16475          && (INTVAL (operands[2]) == 128
16476	      || (INTVAL (operands[2]) < 0
16477	          && INTVAL (operands[2]) != -128)))
16478	{
16479	  operands[2] = GEN_INT (-INTVAL (operands[2]));
16480	  return "sub{l}\t{%2, %0|%0, %2}";
16481	}
16482      return "add{l}\t{%2, %0|%0, %2}";
16483
16484    case TYPE_LEA:
16485      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16486      return "lea{l}\t{%a2, %0|%0, %a2}";
16487
16488    default:
16489      abort ();
16490    }
16491}
16492  [(set (attr "type")
16493	(cond [(eq_attr "alternative" "0")
16494		 (const_string "alu")
16495	       (match_operand:SI 2 "const0_operand" "")
16496		 (const_string "imov")
16497	      ]
16498	      (const_string "lea")))
16499   (set_attr "mode" "SI")])
16500
16501(define_insn "pro_epilogue_adjust_stack_rex64"
16502  [(set (match_operand:DI 0 "register_operand" "=r,r")
16503	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
16504		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16505   (clobber (reg:CC 17))
16506   (clobber (mem:BLK (scratch)))]
16507  "TARGET_64BIT"
16508{
16509  switch (get_attr_type (insn))
16510    {
16511    case TYPE_IMOV:
16512      return "mov{q}\t{%1, %0|%0, %1}";
16513
16514    case TYPE_ALU:
16515      if (GET_CODE (operands[2]) == CONST_INT
16516          && (INTVAL (operands[2]) == 128
16517	      || (INTVAL (operands[2]) < 0
16518	          && INTVAL (operands[2]) != -128)))
16519	{
16520	  operands[2] = GEN_INT (-INTVAL (operands[2]));
16521	  return "sub{q}\t{%2, %0|%0, %2}";
16522	}
16523      return "add{q}\t{%2, %0|%0, %2}";
16524
16525    case TYPE_LEA:
16526      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16527      return "lea{q}\t{%a2, %0|%0, %a2}";
16528
16529    default:
16530      abort ();
16531    }
16532}
16533  [(set (attr "type")
16534	(cond [(eq_attr "alternative" "0")
16535		 (const_string "alu")
16536	       (match_operand:DI 2 "const0_operand" "")
16537		 (const_string "imov")
16538	      ]
16539	      (const_string "lea")))
16540   (set_attr "mode" "DI")])
16541
16542
16543;; Placeholder for the conditional moves.  This one is split either to SSE
16544;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
16545;; fact is that compares supported by the cmp??ss instructions are exactly
16546;; swapped of those supported by cmove sequence.
16547;; The EQ/NE comparisons also needs bit care, since they are not directly
16548;; supported by i387 comparisons and we do need to emit two conditional moves
16549;; in tandem.
16550
16551(define_insn "sse_movsfcc"
16552  [(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")
16553	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
16554			[(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")
16555			 (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")])
16556		      (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")
16557		      (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")))
16558   (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16559   (clobber (reg:CC 17))]
16560  "TARGET_SSE
16561   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16562   && (!TARGET_IEEE_FP
16563       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16564  "#")
16565
16566(define_insn "sse_movsfcc_eq"
16567  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16568	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16569			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16570		      (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16571		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16572   (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16573   (clobber (reg:CC 17))]
16574  "TARGET_SSE
16575   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16576  "#")
16577
16578(define_insn "sse_movdfcc"
16579  [(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")
16580	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16581			[(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")
16582			 (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")])
16583		      (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")
16584		      (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")))
16585   (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16586   (clobber (reg:CC 17))]
16587  "TARGET_SSE2
16588   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16589   && (!TARGET_IEEE_FP
16590       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16591  "#")
16592
16593(define_insn "sse_movdfcc_eq"
16594  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16595	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16596			     (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16597		      (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16598		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16599   (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16600   (clobber (reg:CC 17))]
16601  "TARGET_SSE
16602   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16603  "#")
16604
16605;; For non-sse moves just expand the usual cmove sequence.
16606(define_split
16607  [(set (match_operand 0 "register_operand" "")
16608	(if_then_else (match_operator 1 "comparison_operator"
16609			[(match_operand 4 "nonimmediate_operand" "")
16610			 (match_operand 5 "register_operand" "")])
16611		      (match_operand 2 "nonimmediate_operand" "")
16612		      (match_operand 3 "nonimmediate_operand" "")))
16613   (clobber (match_operand 6 "" ""))
16614   (clobber (reg:CC 17))]
16615  "!SSE_REG_P (operands[0]) && reload_completed
16616   && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16617  [(const_int 0)]
16618{
16619   ix86_compare_op0 = operands[5];
16620   ix86_compare_op1 = operands[4];
16621   operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16622				 VOIDmode, operands[5], operands[4]);
16623   ix86_expand_fp_movcc (operands);
16624   DONE;
16625})
16626
16627;; Split SSE based conditional move into seqence:
16628;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
16629;; and   op2, op0   -  zero op2 if comparison was false
16630;; nand  op0, op3   -  load op3 to op0 if comparison was false
16631;; or	 op2, op0   -  get the non-zero one into the result.
16632(define_split
16633  [(set (match_operand 0 "register_operand" "")
16634	(if_then_else (match_operator 1 "sse_comparison_operator"
16635			[(match_operand 4 "register_operand" "")
16636			 (match_operand 5 "nonimmediate_operand" "")])
16637		      (match_operand 2 "register_operand" "")
16638		      (match_operand 3 "register_operand" "")))
16639   (clobber (match_operand 6 "" ""))
16640   (clobber (reg:CC 17))]
16641  "SSE_REG_P (operands[0]) && reload_completed"
16642  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16643   (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16644					    (subreg:TI (match_dup 4) 0)))
16645   (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16646					    (subreg:TI (match_dup 3) 0)))
16647   (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16648					    (subreg:TI (match_dup 7) 0)))]
16649{
16650  /* If op2 == op3, op3 will be clobbered before it is used.
16651     This should be optimized out though.  */
16652  if (operands_match_p (operands[2], operands[3]))
16653    abort ();
16654  PUT_MODE (operands[1], GET_MODE (operands[0]));
16655  if (operands_match_p (operands[0], operands[4]))
16656    operands[6] = operands[4], operands[7] = operands[2];
16657  else
16658    operands[6] = operands[2], operands[7] = operands[4];
16659})
16660
16661;; Special case of conditional move we can handle effectivly.
16662;; Do not brother with the integer/floating point case, since these are
16663;; bot considerably slower, unlike in the generic case.
16664(define_insn "*sse_movsfcc_const0_1"
16665  [(set (match_operand:SF 0 "register_operand" "=&x")
16666	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
16667			[(match_operand:SF 4 "register_operand" "0")
16668			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16669		      (match_operand:SF 2 "register_operand" "x")
16670		      (match_operand:SF 3 "const0_operand" "X")))]
16671  "TARGET_SSE"
16672  "#")
16673
16674(define_insn "*sse_movsfcc_const0_2"
16675  [(set (match_operand:SF 0 "register_operand" "=&x")
16676	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
16677			[(match_operand:SF 4 "register_operand" "0")
16678			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16679		      (match_operand:SF 2 "const0_operand" "X")
16680		      (match_operand:SF 3 "register_operand" "x")))]
16681  "TARGET_SSE"
16682  "#")
16683
16684(define_insn "*sse_movsfcc_const0_3"
16685  [(set (match_operand:SF 0 "register_operand" "=&x")
16686	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16687			[(match_operand:SF 4 "nonimmediate_operand" "xm")
16688			 (match_operand:SF 5 "register_operand" "0")])
16689		      (match_operand:SF 2 "register_operand" "x")
16690		      (match_operand:SF 3 "const0_operand" "X")))]
16691  "TARGET_SSE"
16692  "#")
16693
16694(define_insn "*sse_movsfcc_const0_4"
16695  [(set (match_operand:SF 0 "register_operand" "=&x")
16696	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16697			[(match_operand:SF 4 "nonimmediate_operand" "xm")
16698			 (match_operand:SF 5 "register_operand" "0")])
16699		      (match_operand:SF 2 "const0_operand" "X")
16700		      (match_operand:SF 3 "register_operand" "x")))]
16701  "TARGET_SSE"
16702  "#")
16703
16704(define_insn "*sse_movdfcc_const0_1"
16705  [(set (match_operand:DF 0 "register_operand" "=&Y")
16706	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16707			[(match_operand:DF 4 "register_operand" "0")
16708			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16709		      (match_operand:DF 2 "register_operand" "Y")
16710		      (match_operand:DF 3 "const0_operand" "X")))]
16711  "TARGET_SSE2"
16712  "#")
16713
16714(define_insn "*sse_movdfcc_const0_2"
16715  [(set (match_operand:DF 0 "register_operand" "=&Y")
16716	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16717			[(match_operand:DF 4 "register_operand" "0")
16718			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16719		      (match_operand:DF 2 "const0_operand" "X")
16720		      (match_operand:DF 3 "register_operand" "Y")))]
16721  "TARGET_SSE2"
16722  "#")
16723
16724(define_insn "*sse_movdfcc_const0_3"
16725  [(set (match_operand:DF 0 "register_operand" "=&Y")
16726	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16727			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16728			 (match_operand:DF 5 "register_operand" "0")])
16729		      (match_operand:DF 2 "register_operand" "Y")
16730		      (match_operand:DF 3 "const0_operand" "X")))]
16731  "TARGET_SSE2"
16732  "#")
16733
16734(define_insn "*sse_movdfcc_const0_4"
16735  [(set (match_operand:DF 0 "register_operand" "=&Y")
16736	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16737			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16738			 (match_operand:DF 5 "register_operand" "0")])
16739		      (match_operand:DF 2 "const0_operand" "X")
16740		      (match_operand:DF 3 "register_operand" "Y")))]
16741  "TARGET_SSE2"
16742  "#")
16743
16744(define_split
16745  [(set (match_operand 0 "register_operand" "")
16746	(if_then_else (match_operator 1 "comparison_operator"
16747			[(match_operand 4 "register_operand" "")
16748			 (match_operand 5 "nonimmediate_operand" "")])
16749		      (match_operand 2 "nonmemory_operand" "")
16750		      (match_operand 3 "nonmemory_operand" "")))]
16751  "SSE_REG_P (operands[0]) && reload_completed
16752   && (const0_operand (operands[2], GET_MODE (operands[0]))
16753       || const0_operand (operands[3], GET_MODE (operands[0])))"
16754  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16755   (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16756					    (subreg:TI (match_dup 7) 0)))]
16757{
16758  PUT_MODE (operands[1], GET_MODE (operands[0]));
16759  if (!sse_comparison_operator (operands[1], VOIDmode))
16760    {
16761      rtx tmp = operands[5];
16762      operands[5] = operands[4];
16763      operands[4] = tmp;
16764      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16765    }
16766  if (const0_operand (operands[2], GET_MODE (operands[0])))
16767    {
16768      operands[7] = operands[3];
16769      operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16770							 0));
16771    }
16772  else
16773    {
16774      operands[7] = operands[2];
16775      operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16776    }
16777})
16778
16779(define_expand "allocate_stack_worker"
16780  [(match_operand:SI 0 "register_operand" "")]
16781  "TARGET_STACK_PROBE"
16782{
16783  if (TARGET_64BIT)
16784    emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16785  else
16786    emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16787  DONE;
16788})
16789
16790(define_insn "allocate_stack_worker_1"
16791  [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
16792   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16793   (clobber (match_dup 0))
16794   (clobber (reg:CC 17))]
16795  "!TARGET_64BIT && TARGET_STACK_PROBE"
16796  "call\t__alloca"
16797  [(set_attr "type" "multi")
16798   (set_attr "length" "5")])
16799
16800(define_insn "allocate_stack_worker_rex64"
16801  [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
16802   (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16803   (clobber (match_dup 0))
16804   (clobber (reg:CC 17))]
16805  "TARGET_64BIT && TARGET_STACK_PROBE"
16806  "call\t__alloca"
16807  [(set_attr "type" "multi")
16808   (set_attr "length" "5")])
16809
16810(define_expand "allocate_stack"
16811  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16812		   (minus:SI (reg:SI 7)
16813			     (match_operand:SI 1 "general_operand" "")))
16814	      (clobber (reg:CC 17))])
16815   (parallel [(set (reg:SI 7)
16816		   (minus:SI (reg:SI 7) (match_dup 1)))
16817	      (clobber (reg:CC 17))])]
16818  "TARGET_STACK_PROBE"
16819{
16820#ifdef CHECK_STACK_LIMIT
16821  if (GET_CODE (operands[1]) == CONST_INT
16822      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16823    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16824			   operands[1]));
16825  else 
16826#endif
16827    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16828							    operands[1])));
16829
16830  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16831  DONE;
16832})
16833
16834(define_expand "builtin_setjmp_receiver"
16835  [(label_ref (match_operand 0 "" ""))]
16836  "!TARGET_64BIT && flag_pic"
16837{
16838  load_pic_register ();
16839  DONE;
16840})
16841
16842;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16843
16844(define_split
16845  [(set (match_operand 0 "register_operand" "")
16846	(match_operator 3 "promotable_binary_operator"
16847	   [(match_operand 1 "register_operand" "")
16848	    (match_operand 2 "aligned_operand" "")]))
16849   (clobber (reg:CC 17))]
16850  "! TARGET_PARTIAL_REG_STALL && reload_completed
16851   && ((GET_MODE (operands[0]) == HImode 
16852	&& (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16853	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16854       || (GET_MODE (operands[0]) == QImode 
16855	   && (TARGET_PROMOTE_QImode || optimize_size)))"
16856  [(parallel [(set (match_dup 0)
16857		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16858	      (clobber (reg:CC 17))])]
16859  "operands[0] = gen_lowpart (SImode, operands[0]);
16860   operands[1] = gen_lowpart (SImode, operands[1]);
16861   if (GET_CODE (operands[3]) != ASHIFT)
16862     operands[2] = gen_lowpart (SImode, operands[2]);
16863   PUT_MODE (operands[3], SImode);")
16864
16865(define_split
16866  [(set (reg 17)
16867	(compare (and (match_operand 1 "aligned_operand" "")
16868		      (match_operand 2 "const_int_operand" ""))
16869		 (const_int 0)))
16870   (set (match_operand 0 "register_operand" "")
16871	(and (match_dup 1) (match_dup 2)))]
16872  "! TARGET_PARTIAL_REG_STALL && reload_completed
16873   && ix86_match_ccmode (insn, CCNOmode)
16874   && (GET_MODE (operands[0]) == HImode
16875       || (GET_MODE (operands[0]) == QImode 
16876	   && (TARGET_PROMOTE_QImode || optimize_size)))"
16877  [(parallel [(set (reg:CCNO 17)
16878		   (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16879			         (const_int 0)))
16880	      (set (match_dup 0)
16881		   (and:SI (match_dup 1) (match_dup 2)))])]
16882  "operands[2]
16883     = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
16884				    & GET_MODE_MASK (GET_MODE (operands[0])),
16885				    SImode));
16886   operands[0] = gen_lowpart (SImode, operands[0]);
16887   operands[1] = gen_lowpart (SImode, operands[1]);")
16888
16889(define_split
16890  [(set (reg 17)
16891	(compare (and (match_operand 0 "aligned_operand" "")
16892		      (match_operand 1 "const_int_operand" ""))
16893		 (const_int 0)))]
16894  "! TARGET_PARTIAL_REG_STALL && reload_completed
16895   && ix86_match_ccmode (insn, CCNOmode)
16896   && (GET_MODE (operands[0]) == HImode
16897       || (GET_MODE (operands[0]) == QImode 
16898	   && (TARGET_PROMOTE_QImode || optimize_size)))"
16899  [(set (reg:CCNO 17)
16900	(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16901		      (const_int 0)))]
16902  "operands[1]
16903     = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
16904				    & GET_MODE_MASK (GET_MODE (operands[0])),
16905				    SImode));
16906   operands[0] = gen_lowpart (SImode, operands[0]);")
16907
16908(define_split
16909  [(set (match_operand 0 "register_operand" "")
16910	(neg (match_operand 1 "register_operand" "")))
16911   (clobber (reg:CC 17))]
16912  "! TARGET_PARTIAL_REG_STALL && reload_completed
16913   && (GET_MODE (operands[0]) == HImode
16914       || (GET_MODE (operands[0]) == QImode 
16915	   && (TARGET_PROMOTE_QImode || optimize_size)))"
16916  [(parallel [(set (match_dup 0)
16917		   (neg:SI (match_dup 1)))
16918	      (clobber (reg:CC 17))])]
16919  "operands[0] = gen_lowpart (SImode, operands[0]);
16920   operands[1] = gen_lowpart (SImode, operands[1]);")
16921
16922(define_split
16923  [(set (match_operand 0 "register_operand" "")
16924	(not (match_operand 1 "register_operand" "")))]
16925  "! TARGET_PARTIAL_REG_STALL && reload_completed
16926   && (GET_MODE (operands[0]) == HImode
16927       || (GET_MODE (operands[0]) == QImode 
16928	   && (TARGET_PROMOTE_QImode || optimize_size)))"
16929  [(set (match_dup 0)
16930	(not:SI (match_dup 1)))]
16931  "operands[0] = gen_lowpart (SImode, operands[0]);
16932   operands[1] = gen_lowpart (SImode, operands[1]);")
16933
16934(define_split 
16935  [(set (match_operand 0 "register_operand" "")
16936	(if_then_else (match_operator 1 "comparison_operator" 
16937				[(reg 17) (const_int 0)])
16938		      (match_operand 2 "register_operand" "")
16939		      (match_operand 3 "register_operand" "")))]
16940  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16941   && (GET_MODE (operands[0]) == HImode
16942       || (GET_MODE (operands[0]) == QImode 
16943	   && (TARGET_PROMOTE_QImode || optimize_size)))"
16944  [(set (match_dup 0)
16945	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16946  "operands[0] = gen_lowpart (SImode, operands[0]);
16947   operands[2] = gen_lowpart (SImode, operands[2]);
16948   operands[3] = gen_lowpart (SImode, operands[3]);")
16949			
16950
16951;; RTL Peephole optimizations, run before sched2.  These primarily look to
16952;; transform a complex memory operation into two memory to register operations.
16953
16954;; Don't push memory operands
16955(define_peephole2
16956  [(set (match_operand:SI 0 "push_operand" "")
16957	(match_operand:SI 1 "memory_operand" ""))
16958   (match_scratch:SI 2 "r")]
16959  "! optimize_size && ! TARGET_PUSH_MEMORY"
16960  [(set (match_dup 2) (match_dup 1))
16961   (set (match_dup 0) (match_dup 2))]
16962  "")
16963
16964(define_peephole2
16965  [(set (match_operand:DI 0 "push_operand" "")
16966	(match_operand:DI 1 "memory_operand" ""))
16967   (match_scratch:DI 2 "r")]
16968  "! optimize_size && ! TARGET_PUSH_MEMORY"
16969  [(set (match_dup 2) (match_dup 1))
16970   (set (match_dup 0) (match_dup 2))]
16971  "")
16972
16973;; We need to handle SFmode only, because DFmode and XFmode is split to
16974;; SImode pushes.
16975(define_peephole2
16976  [(set (match_operand:SF 0 "push_operand" "")
16977	(match_operand:SF 1 "memory_operand" ""))
16978   (match_scratch:SF 2 "r")]
16979  "! optimize_size && ! TARGET_PUSH_MEMORY"
16980  [(set (match_dup 2) (match_dup 1))
16981   (set (match_dup 0) (match_dup 2))]
16982  "")
16983
16984(define_peephole2
16985  [(set (match_operand:HI 0 "push_operand" "")
16986	(match_operand:HI 1 "memory_operand" ""))
16987   (match_scratch:HI 2 "r")]
16988  "! optimize_size && ! TARGET_PUSH_MEMORY"
16989  [(set (match_dup 2) (match_dup 1))
16990   (set (match_dup 0) (match_dup 2))]
16991  "")
16992
16993(define_peephole2
16994  [(set (match_operand:QI 0 "push_operand" "")
16995	(match_operand:QI 1 "memory_operand" ""))
16996   (match_scratch:QI 2 "q")]
16997  "! optimize_size && ! TARGET_PUSH_MEMORY"
16998  [(set (match_dup 2) (match_dup 1))
16999   (set (match_dup 0) (match_dup 2))]
17000  "")
17001
17002;; Don't move an immediate directly to memory when the instruction
17003;; gets too big.
17004(define_peephole2
17005  [(match_scratch:SI 1 "r")
17006   (set (match_operand:SI 0 "memory_operand" "")
17007        (const_int 0))]
17008  "! optimize_size
17009   && ! TARGET_USE_MOV0
17010   && TARGET_SPLIT_LONG_MOVES
17011   && get_attr_length (insn) >= ix86_cost->large_insn
17012   && peep2_regno_dead_p (0, FLAGS_REG)"
17013  [(parallel [(set (match_dup 1) (const_int 0))
17014	      (clobber (reg:CC 17))])
17015   (set (match_dup 0) (match_dup 1))]
17016  "")
17017
17018(define_peephole2
17019  [(match_scratch:HI 1 "r")
17020   (set (match_operand:HI 0 "memory_operand" "")
17021        (const_int 0))]
17022  "! optimize_size
17023   && ! TARGET_USE_MOV0
17024   && TARGET_SPLIT_LONG_MOVES
17025   && get_attr_length (insn) >= ix86_cost->large_insn
17026   && peep2_regno_dead_p (0, FLAGS_REG)"
17027  [(parallel [(set (match_dup 2) (const_int 0))
17028	      (clobber (reg:CC 17))])
17029   (set (match_dup 0) (match_dup 1))]
17030  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
17031
17032(define_peephole2
17033  [(match_scratch:QI 1 "q")
17034   (set (match_operand:QI 0 "memory_operand" "")
17035        (const_int 0))]
17036  "! optimize_size
17037   && ! TARGET_USE_MOV0
17038   && TARGET_SPLIT_LONG_MOVES
17039   && get_attr_length (insn) >= ix86_cost->large_insn
17040   && peep2_regno_dead_p (0, FLAGS_REG)"
17041  [(parallel [(set (match_dup 2) (const_int 0))
17042	      (clobber (reg:CC 17))])
17043   (set (match_dup 0) (match_dup 1))]
17044  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
17045
17046(define_peephole2
17047  [(match_scratch:SI 2 "r")
17048   (set (match_operand:SI 0 "memory_operand" "")
17049        (match_operand:SI 1 "immediate_operand" ""))]
17050  "! optimize_size
17051   && get_attr_length (insn) >= ix86_cost->large_insn
17052   && TARGET_SPLIT_LONG_MOVES"
17053  [(set (match_dup 2) (match_dup 1))
17054   (set (match_dup 0) (match_dup 2))]
17055  "")
17056
17057(define_peephole2
17058  [(match_scratch:HI 2 "r")
17059   (set (match_operand:HI 0 "memory_operand" "")
17060        (match_operand:HI 1 "immediate_operand" ""))]
17061  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17062  && TARGET_SPLIT_LONG_MOVES"
17063  [(set (match_dup 2) (match_dup 1))
17064   (set (match_dup 0) (match_dup 2))]
17065  "")
17066
17067(define_peephole2
17068  [(match_scratch:QI 2 "q")
17069   (set (match_operand:QI 0 "memory_operand" "")
17070        (match_operand:QI 1 "immediate_operand" ""))]
17071  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17072  && TARGET_SPLIT_LONG_MOVES"
17073  [(set (match_dup 2) (match_dup 1))
17074   (set (match_dup 0) (match_dup 2))]
17075  "")
17076
17077;; Don't compare memory with zero, load and use a test instead.
17078(define_peephole2
17079  [(set (reg 17)
17080	(compare (match_operand:SI 0 "memory_operand" "")
17081	         (const_int 0)))
17082   (match_scratch:SI 3 "r")]
17083  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17084  [(set (match_dup 3) (match_dup 0))
17085   (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17086  "")
17087
17088;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
17089;; Don't split NOTs with a displacement operand, because resulting XOR
17090;; will not be pariable anyway.
17091;;
17092;; On AMD K6, NOT is vector decoded with memory operand that can not be
17093;; represented using a modRM byte.  The XOR replacement is long decoded,
17094;; so this split helps here as well.
17095;;
17096;; Note: Can't do this as a regular split because we can't get proper
17097;; lifetime information then.
17098
17099(define_peephole2
17100  [(set (match_operand:SI 0 "nonimmediate_operand" "")
17101	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17102  "!optimize_size
17103   && peep2_regno_dead_p (0, FLAGS_REG)
17104   && ((TARGET_PENTIUM 
17105        && (GET_CODE (operands[0]) != MEM
17106            || !memory_displacement_operand (operands[0], SImode)))
17107       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17108  [(parallel [(set (match_dup 0)
17109		   (xor:SI (match_dup 1) (const_int -1)))
17110	      (clobber (reg:CC 17))])]
17111  "")
17112
17113(define_peephole2
17114  [(set (match_operand:HI 0 "nonimmediate_operand" "")
17115	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17116  "!optimize_size
17117   && peep2_regno_dead_p (0, FLAGS_REG)
17118   && ((TARGET_PENTIUM 
17119        && (GET_CODE (operands[0]) != MEM
17120            || !memory_displacement_operand (operands[0], HImode)))
17121       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17122  [(parallel [(set (match_dup 0)
17123		   (xor:HI (match_dup 1) (const_int -1)))
17124	      (clobber (reg:CC 17))])]
17125  "")
17126
17127(define_peephole2
17128  [(set (match_operand:QI 0 "nonimmediate_operand" "")
17129	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17130  "!optimize_size
17131   && peep2_regno_dead_p (0, FLAGS_REG)
17132   && ((TARGET_PENTIUM 
17133        && (GET_CODE (operands[0]) != MEM
17134            || !memory_displacement_operand (operands[0], QImode)))
17135       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17136  [(parallel [(set (match_dup 0)
17137		   (xor:QI (match_dup 1) (const_int -1)))
17138	      (clobber (reg:CC 17))])]
17139  "")
17140
17141;; Non pairable "test imm, reg" instructions can be translated to
17142;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17143;; byte opcode instead of two, have a short form for byte operands),
17144;; so do it for other CPUs as well.  Given that the value was dead,
17145;; this should not create any new dependencies.  Pass on the sub-word
17146;; versions if we're concerned about partial register stalls.
17147
17148(define_peephole2
17149  [(set (reg 17)
17150	(compare (and:SI (match_operand:SI 0 "register_operand" "")
17151			 (match_operand:SI 1 "immediate_operand" ""))
17152		 (const_int 0)))]
17153  "ix86_match_ccmode (insn, CCNOmode)
17154   && (true_regnum (operands[0]) != 0
17155       || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
17156   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17157  [(parallel
17158     [(set (reg:CCNO 17)
17159	   (compare:CCNO (and:SI (match_dup 0)
17160			         (match_dup 1))
17161		         (const_int 0)))
17162      (set (match_dup 0)
17163	   (and:SI (match_dup 0) (match_dup 1)))])]
17164  "")
17165
17166;; We don't need to handle HImode case, because it will be promoted to SImode
17167;; on ! TARGET_PARTIAL_REG_STALL
17168
17169(define_peephole2
17170  [(set (reg 17)
17171	(compare (and:QI (match_operand:QI 0 "register_operand" "")
17172			 (match_operand:QI 1 "immediate_operand" ""))
17173		 (const_int 0)))]
17174  "! TARGET_PARTIAL_REG_STALL
17175   && ix86_match_ccmode (insn, CCNOmode)
17176   && true_regnum (operands[0]) != 0
17177   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17178  [(parallel
17179     [(set (reg:CCNO 17)
17180	   (compare:CCNO (and:QI (match_dup 0)
17181 			         (match_dup 1))
17182		         (const_int 0)))
17183      (set (match_dup 0)
17184	   (and:QI (match_dup 0) (match_dup 1)))])]
17185  "")
17186
17187(define_peephole2
17188  [(set (reg 17)
17189	(compare
17190	  (and:SI
17191	    (zero_extract:SI
17192	      (match_operand 0 "ext_register_operand" "")
17193	      (const_int 8)
17194	      (const_int 8))
17195	    (match_operand 1 "const_int_operand" ""))
17196	  (const_int 0)))]
17197  "! TARGET_PARTIAL_REG_STALL
17198   && ix86_match_ccmode (insn, CCNOmode)
17199   && true_regnum (operands[0]) != 0
17200   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17201  [(parallel [(set (reg:CCNO 17)
17202		   (compare:CCNO
17203		       (and:SI
17204			 (zero_extract:SI
17205			 (match_dup 0)
17206			 (const_int 8)
17207			 (const_int 8))
17208			(match_dup 1))
17209		   (const_int 0)))
17210	      (set (zero_extract:SI (match_dup 0)
17211				    (const_int 8)
17212				    (const_int 8))
17213		   (and:SI 
17214		     (zero_extract:SI
17215		       (match_dup 0)
17216		       (const_int 8)
17217		       (const_int 8))
17218		     (match_dup 1)))])]
17219  "")
17220
17221;; Don't do logical operations with memory inputs.
17222(define_peephole2
17223  [(match_scratch:SI 2 "r")
17224   (parallel [(set (match_operand:SI 0 "register_operand" "")
17225                   (match_operator:SI 3 "arith_or_logical_operator"
17226                     [(match_dup 0)
17227                      (match_operand:SI 1 "memory_operand" "")]))
17228              (clobber (reg:CC 17))])]
17229  "! optimize_size && ! TARGET_READ_MODIFY"
17230  [(set (match_dup 2) (match_dup 1))
17231   (parallel [(set (match_dup 0)
17232                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17233              (clobber (reg:CC 17))])]
17234  "")
17235
17236(define_peephole2
17237  [(match_scratch:SI 2 "r")
17238   (parallel [(set (match_operand:SI 0 "register_operand" "")
17239                   (match_operator:SI 3 "arith_or_logical_operator"
17240                     [(match_operand:SI 1 "memory_operand" "")
17241                      (match_dup 0)]))
17242              (clobber (reg:CC 17))])]
17243  "! optimize_size && ! TARGET_READ_MODIFY"
17244  [(set (match_dup 2) (match_dup 1))
17245   (parallel [(set (match_dup 0)
17246                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17247              (clobber (reg:CC 17))])]
17248  "")
17249
17250; Don't do logical operations with memory outputs
17251;
17252; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17253; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17254; the same decoder scheduling characteristics as the original.
17255
17256(define_peephole2
17257  [(match_scratch:SI 2 "r")
17258   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17259                   (match_operator:SI 3 "arith_or_logical_operator"
17260                     [(match_dup 0)
17261                      (match_operand:SI 1 "nonmemory_operand" "")]))
17262              (clobber (reg:CC 17))])]
17263  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17264  [(set (match_dup 2) (match_dup 0))
17265   (parallel [(set (match_dup 2)
17266                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17267              (clobber (reg:CC 17))])
17268   (set (match_dup 0) (match_dup 2))]
17269  "")
17270
17271(define_peephole2
17272  [(match_scratch:SI 2 "r")
17273   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17274                   (match_operator:SI 3 "arith_or_logical_operator"
17275                     [(match_operand:SI 1 "nonmemory_operand" "")
17276                      (match_dup 0)]))
17277              (clobber (reg:CC 17))])]
17278  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17279  [(set (match_dup 2) (match_dup 0))
17280   (parallel [(set (match_dup 2)
17281                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17282              (clobber (reg:CC 17))])
17283   (set (match_dup 0) (match_dup 2))]
17284  "")
17285
17286;; Attempt to always use XOR for zeroing registers.
17287(define_peephole2
17288  [(set (match_operand 0 "register_operand" "")
17289	(const_int 0))]
17290  "(GET_MODE (operands[0]) == QImode
17291    || GET_MODE (operands[0]) == HImode
17292    || GET_MODE (operands[0]) == SImode
17293    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17294   && (! TARGET_USE_MOV0 || optimize_size)
17295   && peep2_regno_dead_p (0, FLAGS_REG)"
17296  [(parallel [(set (match_dup 0) (const_int 0))
17297	      (clobber (reg:CC 17))])]
17298  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17299			      true_regnum (operands[0]));")
17300
17301(define_peephole2
17302  [(set (strict_low_part (match_operand 0 "register_operand" ""))
17303	(const_int 0))]
17304  "(GET_MODE (operands[0]) == QImode
17305    || GET_MODE (operands[0]) == HImode)
17306   && (! TARGET_USE_MOV0 || optimize_size)
17307   && peep2_regno_dead_p (0, FLAGS_REG)"
17308  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17309	      (clobber (reg:CC 17))])])
17310
17311;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17312(define_peephole2
17313  [(set (match_operand 0 "register_operand" "")
17314	(const_int -1))]
17315  "(GET_MODE (operands[0]) == HImode
17316    || GET_MODE (operands[0]) == SImode 
17317    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17318   && (optimize_size || TARGET_PENTIUM)
17319   && peep2_regno_dead_p (0, FLAGS_REG)"
17320  [(parallel [(set (match_dup 0) (const_int -1))
17321	      (clobber (reg:CC 17))])]
17322  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17323			      true_regnum (operands[0]));")
17324
17325;; Attempt to convert simple leas to adds. These can be created by
17326;; move expanders.
17327(define_peephole2
17328  [(set (match_operand:SI 0 "register_operand" "")
17329  	(plus:SI (match_dup 0)
17330		 (match_operand:SI 1 "nonmemory_operand" "")))]
17331  "peep2_regno_dead_p (0, FLAGS_REG)"
17332  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17333	      (clobber (reg:CC 17))])]
17334  "")
17335
17336(define_peephole2
17337  [(set (match_operand:SI 0 "register_operand" "")
17338  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17339			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17340  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17341  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17342	      (clobber (reg:CC 17))])]
17343  "operands[2] = gen_lowpart (SImode, operands[2]);")
17344
17345(define_peephole2
17346  [(set (match_operand:DI 0 "register_operand" "")
17347  	(plus:DI (match_dup 0)
17348		 (match_operand:DI 1 "x86_64_general_operand" "")))]
17349  "peep2_regno_dead_p (0, FLAGS_REG)"
17350  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17351	      (clobber (reg:CC 17))])]
17352  "")
17353
17354(define_peephole2
17355  [(set (match_operand:SI 0 "register_operand" "")
17356  	(mult:SI (match_dup 0)
17357		 (match_operand:SI 1 "const_int_operand" "")))]
17358  "exact_log2 (INTVAL (operands[1])) >= 0
17359   && peep2_regno_dead_p (0, FLAGS_REG)"
17360  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17361	      (clobber (reg:CC 17))])]
17362  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17363
17364(define_peephole2
17365  [(set (match_operand:DI 0 "register_operand" "")
17366  	(mult:DI (match_dup 0)
17367		 (match_operand:DI 1 "const_int_operand" "")))]
17368  "exact_log2 (INTVAL (operands[1])) >= 0
17369   && peep2_regno_dead_p (0, FLAGS_REG)"
17370  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17371	      (clobber (reg:CC 17))])]
17372  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17373
17374(define_peephole2
17375  [(set (match_operand:SI 0 "register_operand" "")
17376  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17377		   (match_operand:DI 2 "const_int_operand" "")) 0))]
17378  "exact_log2 (INTVAL (operands[1])) >= 0
17379   && REGNO (operands[0]) == REGNO (operands[1])
17380   && peep2_regno_dead_p (0, FLAGS_REG)"
17381  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17382	      (clobber (reg:CC 17))])]
17383  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17384
17385;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17386;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17387;; many CPUs it is also faster, since special hardware to avoid esp
17388;; dependencies is present.
17389
17390;; While some of these conversions may be done using splitters, we use peepholes
17391;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17392
17393;; Convert prologue esp subtractions to push.
17394;; We need register to push.  In order to keep verify_flow_info happy we have
17395;; two choices
17396;; - use scratch and clobber it in order to avoid dependencies
17397;; - use already live register
17398;; We can't use the second way right now, since there is no reliable way how to
17399;; verify that given register is live.  First choice will also most likely in
17400;; fewer dependencies.  On the place of esp adjustments it is very likely that
17401;; call clobbered registers are dead.  We may want to use base pointer as an
17402;; alternative when no register is available later.
17403
17404(define_peephole2
17405  [(match_scratch:SI 0 "r")
17406   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17407	      (clobber (reg:CC 17))
17408	      (clobber (mem:BLK (scratch)))])]
17409  "optimize_size || !TARGET_SUB_ESP_4"
17410  [(clobber (match_dup 0))
17411   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17412	      (clobber (mem:BLK (scratch)))])])
17413
17414(define_peephole2
17415  [(match_scratch:SI 0 "r")
17416   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17417	      (clobber (reg:CC 17))
17418	      (clobber (mem:BLK (scratch)))])]
17419  "optimize_size || !TARGET_SUB_ESP_8"
17420  [(clobber (match_dup 0))
17421   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17422   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17423	      (clobber (mem:BLK (scratch)))])])
17424
17425;; Convert esp subtractions to push.
17426(define_peephole2
17427  [(match_scratch:SI 0 "r")
17428   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17429	      (clobber (reg:CC 17))])]
17430  "optimize_size || !TARGET_SUB_ESP_4"
17431  [(clobber (match_dup 0))
17432   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17433
17434(define_peephole2
17435  [(match_scratch:SI 0 "r")
17436   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17437	      (clobber (reg:CC 17))])]
17438  "optimize_size || !TARGET_SUB_ESP_8"
17439  [(clobber (match_dup 0))
17440   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17441   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17442
17443;; Convert epilogue deallocator to pop.
17444(define_peephole2
17445  [(match_scratch:SI 0 "r")
17446   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17447	      (clobber (reg:CC 17))
17448	      (clobber (mem:BLK (scratch)))])]
17449  "optimize_size || !TARGET_ADD_ESP_4"
17450  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17451	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17452	      (clobber (mem:BLK (scratch)))])]
17453  "")
17454
17455;; Two pops case is tricky, since pop causes dependency on destination register.
17456;; We use two registers if available.
17457(define_peephole2
17458  [(match_scratch:SI 0 "r")
17459   (match_scratch:SI 1 "r")
17460   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17461	      (clobber (reg:CC 17))
17462	      (clobber (mem:BLK (scratch)))])]
17463  "optimize_size || !TARGET_ADD_ESP_8"
17464  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17465	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17466	      (clobber (mem:BLK (scratch)))])
17467   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17468	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17469  "")
17470
17471(define_peephole2
17472  [(match_scratch:SI 0 "r")
17473   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17474	      (clobber (reg:CC 17))
17475	      (clobber (mem:BLK (scratch)))])]
17476  "optimize_size"
17477  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17478	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17479	      (clobber (mem:BLK (scratch)))])
17480   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17481	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17482  "")
17483
17484;; Convert esp additions to pop.
17485(define_peephole2
17486  [(match_scratch:SI 0 "r")
17487   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17488	      (clobber (reg:CC 17))])]
17489  ""
17490  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17491	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17492  "")
17493
17494;; Two pops case is tricky, since pop causes dependency on destination register.
17495;; We use two registers if available.
17496(define_peephole2
17497  [(match_scratch:SI 0 "r")
17498   (match_scratch:SI 1 "r")
17499   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17500	      (clobber (reg:CC 17))])]
17501  ""
17502  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17503	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17504   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17505	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17506  "")
17507
17508(define_peephole2
17509  [(match_scratch:SI 0 "r")
17510   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17511	      (clobber (reg:CC 17))])]
17512  "optimize_size"
17513  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17514	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17515   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17516	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17517  "")
17518
17519;; Convert compares with 1 to shorter inc/dec operations when CF is not
17520;; required and register dies.
17521(define_peephole2
17522  [(set (reg 17)
17523	(compare (match_operand:SI 0 "register_operand" "")
17524		 (match_operand:SI 1 "incdec_operand" "")))]
17525  "ix86_match_ccmode (insn, CCGCmode)
17526   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17527  [(parallel [(set (reg:CCGC 17)
17528		   (compare:CCGC (match_dup 0)
17529				 (match_dup 1)))
17530	      (clobber (match_dup 0))])]
17531  "")
17532
17533(define_peephole2
17534  [(set (reg 17)
17535	(compare (match_operand:HI 0 "register_operand" "")
17536		 (match_operand:HI 1 "incdec_operand" "")))]
17537  "ix86_match_ccmode (insn, CCGCmode)
17538   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17539  [(parallel [(set (reg:CCGC 17)
17540		   (compare:CCGC (match_dup 0)
17541				 (match_dup 1)))
17542	      (clobber (match_dup 0))])]
17543  "")
17544
17545(define_peephole2
17546  [(set (reg 17)
17547	(compare (match_operand:QI 0 "register_operand" "")
17548		 (match_operand:QI 1 "incdec_operand" "")))]
17549  "ix86_match_ccmode (insn, CCGCmode)
17550   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17551  [(parallel [(set (reg:CCGC 17)
17552		   (compare:CCGC (match_dup 0)
17553				 (match_dup 1)))
17554	      (clobber (match_dup 0))])]
17555  "")
17556
17557;; Convert compares with 128 to shorter add -128
17558(define_peephole2
17559  [(set (reg 17)
17560	(compare (match_operand:SI 0 "register_operand" "")
17561		 (const_int 128)))]
17562  "ix86_match_ccmode (insn, CCGCmode)
17563   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17564  [(parallel [(set (reg:CCGC 17)
17565		   (compare:CCGC (match_dup 0)
17566			         (const_int 128)))
17567	      (clobber (match_dup 0))])]
17568  "")
17569
17570(define_peephole2
17571  [(set (reg 17)
17572	(compare (match_operand:HI 0 "register_operand" "")
17573		 (const_int 128)))]
17574  "ix86_match_ccmode (insn, CCGCmode)
17575   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17576  [(parallel [(set (reg:CCGC 17)
17577		   (compare:CCGC (match_dup 0)
17578			         (const_int 128)))
17579	      (clobber (match_dup 0))])]
17580  "")
17581
17582(define_peephole2
17583  [(match_scratch:DI 0 "r")
17584   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17585	      (clobber (reg:CC 17))
17586	      (clobber (mem:BLK (scratch)))])]
17587  "optimize_size || !TARGET_SUB_ESP_4"
17588  [(clobber (match_dup 0))
17589   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17590	      (clobber (mem:BLK (scratch)))])])
17591
17592(define_peephole2
17593  [(match_scratch:DI 0 "r")
17594   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17595	      (clobber (reg:CC 17))
17596	      (clobber (mem:BLK (scratch)))])]
17597  "optimize_size || !TARGET_SUB_ESP_8"
17598  [(clobber (match_dup 0))
17599   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17600   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17601	      (clobber (mem:BLK (scratch)))])])
17602
17603;; Convert esp subtractions to push.
17604(define_peephole2
17605  [(match_scratch:DI 0 "r")
17606   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17607	      (clobber (reg:CC 17))])]
17608  "optimize_size || !TARGET_SUB_ESP_4"
17609  [(clobber (match_dup 0))
17610   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17611
17612(define_peephole2
17613  [(match_scratch:DI 0 "r")
17614   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17615	      (clobber (reg:CC 17))])]
17616  "optimize_size || !TARGET_SUB_ESP_8"
17617  [(clobber (match_dup 0))
17618   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17619   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17620
17621;; Convert epilogue deallocator to pop.
17622(define_peephole2
17623  [(match_scratch:DI 0 "r")
17624   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17625	      (clobber (reg:CC 17))
17626	      (clobber (mem:BLK (scratch)))])]
17627  "optimize_size || !TARGET_ADD_ESP_4"
17628  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17629	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17630	      (clobber (mem:BLK (scratch)))])]
17631  "")
17632
17633;; Two pops case is tricky, since pop causes dependency on destination register.
17634;; We use two registers if available.
17635(define_peephole2
17636  [(match_scratch:DI 0 "r")
17637   (match_scratch:DI 1 "r")
17638   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17639	      (clobber (reg:CC 17))
17640	      (clobber (mem:BLK (scratch)))])]
17641  "optimize_size || !TARGET_ADD_ESP_8"
17642  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17643	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17644	      (clobber (mem:BLK (scratch)))])
17645   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17646	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17647  "")
17648
17649(define_peephole2
17650  [(match_scratch:DI 0 "r")
17651   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17652	      (clobber (reg:CC 17))
17653	      (clobber (mem:BLK (scratch)))])]
17654  "optimize_size"
17655  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17656	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17657	      (clobber (mem:BLK (scratch)))])
17658   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17659	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17660  "")
17661
17662;; Convert esp additions to pop.
17663(define_peephole2
17664  [(match_scratch:DI 0 "r")
17665   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17666	      (clobber (reg:CC 17))])]
17667  ""
17668  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17669	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17670  "")
17671
17672;; Two pops case is tricky, since pop causes dependency on destination register.
17673;; We use two registers if available.
17674(define_peephole2
17675  [(match_scratch:DI 0 "r")
17676   (match_scratch:DI 1 "r")
17677   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17678	      (clobber (reg:CC 17))])]
17679  ""
17680  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17681	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17682   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17683	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17684  "")
17685
17686(define_peephole2
17687  [(match_scratch:DI 0 "r")
17688   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17689	      (clobber (reg:CC 17))])]
17690  "optimize_size"
17691  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17692	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17693   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17694	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17695  "")
17696
17697;; Call-value patterns last so that the wildcard operand does not
17698;; disrupt insn-recog's switch tables.
17699
17700(define_insn "*call_value_pop_0"
17701  [(set (match_operand 0 "" "")
17702	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17703	      (match_operand:SI 2 "" "")))
17704   (set (reg:SI 7) (plus:SI (reg:SI 7)
17705			    (match_operand:SI 3 "immediate_operand" "")))]
17706  "!TARGET_64BIT"
17707{
17708  if (SIBLING_CALL_P (insn))
17709    return "jmp\t%P1";
17710  else
17711    return "call\t%P1";
17712}
17713  [(set_attr "type" "callv")])
17714
17715(define_insn "*call_value_pop_1"
17716  [(set (match_operand 0 "" "")
17717	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17718	      (match_operand:SI 2 "" "")))
17719   (set (reg:SI 7) (plus:SI (reg:SI 7)
17720			    (match_operand:SI 3 "immediate_operand" "i")))]
17721  "!TARGET_64BIT"
17722{
17723  if (constant_call_address_operand (operands[1], QImode))
17724    {
17725      if (SIBLING_CALL_P (insn))
17726	return "jmp\t%P1";
17727      else
17728	return "call\t%P1";
17729    }
17730  if (SIBLING_CALL_P (insn))
17731    return "jmp\t%A1";
17732  else
17733    return "call\t%A1";
17734}
17735  [(set_attr "type" "callv")])
17736
17737(define_insn "*call_value_0"
17738  [(set (match_operand 0 "" "")
17739	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17740	      (match_operand:SI 2 "" "")))]
17741  "!TARGET_64BIT"
17742{
17743  if (SIBLING_CALL_P (insn))
17744    return "jmp\t%P1";
17745  else
17746    return "call\t%P1";
17747}
17748  [(set_attr "type" "callv")])
17749
17750(define_insn "*call_value_0_rex64"
17751  [(set (match_operand 0 "" "")
17752	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17753	      (match_operand:DI 2 "const_int_operand" "")))]
17754  "TARGET_64BIT"
17755{
17756  if (SIBLING_CALL_P (insn))
17757    return "jmp\t%P1";
17758  else
17759    return "call\t%P1";
17760}
17761  [(set_attr "type" "callv")])
17762
17763(define_insn "*call_value_1"
17764  [(set (match_operand 0 "" "")
17765	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17766	      (match_operand:SI 2 "" "")))]
17767  "!TARGET_64BIT"
17768{
17769  if (constant_call_address_operand (operands[1], QImode))
17770    {
17771      if (SIBLING_CALL_P (insn))
17772	return "jmp\t%P1";
17773      else
17774	return "call\t%P1";
17775    }
17776  if (SIBLING_CALL_P (insn))
17777    return "jmp\t%*%1";
17778  else
17779    return "call\t%*%1";
17780}
17781  [(set_attr "type" "callv")])
17782
17783(define_insn "*call_value_1_rex64"
17784  [(set (match_operand 0 "" "")
17785	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17786	      (match_operand:DI 2 "" "")))]
17787  "TARGET_64BIT"
17788{
17789  if (constant_call_address_operand (operands[1], QImode))
17790    {
17791      if (SIBLING_CALL_P (insn))
17792	return "jmp\t%P1";
17793      else
17794	return "call\t%P1";
17795    }
17796  if (SIBLING_CALL_P (insn))
17797    return "jmp\t%A1";
17798  else
17799    return "call\t%A1";
17800}
17801  [(set_attr "type" "callv")])
17802
17803(define_insn "trap"
17804  [(trap_if (const_int 1) (const_int 5))]
17805  ""
17806  "int\t$5")
17807
17808;;; ix86 doesn't have conditional trap instructions, but we fake them
17809;;; for the sake of bounds checking.  By emitting bounds checks as
17810;;; conditional traps rather than as conditional jumps around
17811;;; unconditional traps we avoid introducing spurious basic-block
17812;;; boundaries and facilitate elimination of redundant checks.  In
17813;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17814;;; interrupt 5.
17815;;; 
17816;;; FIXME: Static branch prediction rules for ix86 are such that
17817;;; forward conditional branches predict as untaken.  As implemented
17818;;; below, pseudo conditional traps violate that rule.  We should use
17819;;; .pushsection/.popsection to place all of the `int 5's in a special
17820;;; section loaded at the end of the text segment and branch forward
17821;;; there on bounds-failure, and then jump back immediately (in case
17822;;; the system chooses to ignore bounds violations, or to report
17823;;; violations and continue execution).
17824
17825(define_expand "conditional_trap"
17826  [(trap_if (match_operator 0 "comparison_operator"
17827	     [(match_dup 2) (const_int 0)])
17828	    (match_operand 1 "const_int_operand" ""))]
17829  ""
17830{
17831  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17832			      ix86_expand_compare (GET_CODE (operands[0]),
17833						   NULL, NULL),
17834			      operands[1]));
17835  DONE;
17836})
17837
17838(define_insn "*conditional_trap_1"
17839  [(trap_if (match_operator 0 "comparison_operator"
17840	     [(reg 17) (const_int 0)])
17841	    (match_operand 1 "const_int_operand" ""))]
17842  ""
17843{
17844  operands[2] = gen_label_rtx ();
17845  output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17846  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
17847			     CODE_LABEL_NUMBER (operands[2]));
17848  RET;
17849})
17850
17851	;; Pentium III SIMD instructions.
17852
17853;; Moves for SSE/MMX regs.
17854
17855(define_insn "movv4sf_internal"
17856  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17857	(match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
17858  "TARGET_SSE"
17859  ;; @@@ let's try to use movaps here.
17860  "movaps\t{%1, %0|%0, %1}"
17861  [(set_attr "type" "sse")])
17862
17863(define_insn "movv4si_internal"
17864  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17865	(match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
17866  "TARGET_SSE"
17867  ;; @@@ let's try to use movaps here.
17868  "movaps\t{%1, %0|%0, %1}"
17869  [(set_attr "type" "sse")])
17870
17871(define_insn "movv8qi_internal"
17872  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17873	(match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
17874  "TARGET_MMX"
17875  "movq\t{%1, %0|%0, %1}"
17876  [(set_attr "type" "mmx")])
17877
17878(define_insn "movv4hi_internal"
17879  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17880	(match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
17881  "TARGET_MMX"
17882  "movq\t{%1, %0|%0, %1}"
17883  [(set_attr "type" "mmx")])
17884
17885(define_insn "movv2si_internal"
17886  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17887	(match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
17888  "TARGET_MMX"
17889  "movq\t{%1, %0|%0, %1}"
17890  [(set_attr "type" "mmx")])
17891
17892(define_insn "movv2sf_internal"
17893  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17894        (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
17895  "TARGET_3DNOW"
17896  "movq\\t{%1, %0|%0, %1}"
17897  [(set_attr "type" "mmx")])
17898
17899(define_expand "movti"
17900  [(set (match_operand:TI 0 "general_operand" "")
17901	(match_operand:TI 1 "general_operand" ""))]
17902  "TARGET_SSE || TARGET_64BIT"
17903{
17904  if (TARGET_64BIT)
17905    ix86_expand_move (TImode, operands);
17906  else
17907    ix86_expand_vector_move (TImode, operands);
17908  DONE;
17909})
17910
17911(define_expand "movv4sf"
17912  [(set (match_operand:V4SF 0 "general_operand" "")
17913	(match_operand:V4SF 1 "general_operand" ""))]
17914  "TARGET_SSE"
17915{
17916  ix86_expand_vector_move (V4SFmode, operands);
17917  DONE;
17918})
17919
17920(define_expand "movv4si"
17921  [(set (match_operand:V4SI 0 "general_operand" "")
17922	(match_operand:V4SI 1 "general_operand" ""))]
17923  "TARGET_MMX"
17924{
17925  ix86_expand_vector_move (V4SImode, operands);
17926  DONE;
17927})
17928
17929(define_expand "movv2si"
17930  [(set (match_operand:V2SI 0 "general_operand" "")
17931	(match_operand:V2SI 1 "general_operand" ""))]
17932  "TARGET_MMX"
17933{
17934  ix86_expand_vector_move (V2SImode, operands);
17935  DONE;
17936})
17937
17938(define_expand "movv4hi"
17939  [(set (match_operand:V4HI 0 "general_operand" "")
17940	(match_operand:V4HI 1 "general_operand" ""))]
17941  "TARGET_MMX"
17942{
17943  ix86_expand_vector_move (V4HImode, operands);
17944  DONE;
17945})
17946
17947(define_expand "movv8qi"
17948  [(set (match_operand:V8QI 0 "general_operand" "")
17949	(match_operand:V8QI 1 "general_operand" ""))]
17950  "TARGET_MMX"
17951{
17952  ix86_expand_vector_move (V8QImode, operands);
17953  DONE;
17954})
17955
17956(define_expand "movv2sf"
17957  [(set (match_operand:V2SF 0 "general_operand" "")
17958	(match_operand:V2SF 1 "general_operand" ""))]
17959   "TARGET_3DNOW"
17960{
17961  ix86_expand_vector_move (V2SFmode, operands);
17962  DONE;
17963})
17964
17965(define_insn_and_split "*pushti"
17966  [(set (match_operand:TI 0 "push_operand" "=<")
17967	(match_operand:TI 1 "nonmemory_operand" "x"))]
17968  "TARGET_SSE"
17969  "#"
17970  ""
17971  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17972   (set (mem:TI (reg:SI 7)) (match_dup 1))]
17973  ""
17974  [(set_attr "type" "sse")])
17975
17976(define_insn_and_split "*pushv4sf"
17977  [(set (match_operand:V4SF 0 "push_operand" "=<")
17978	(match_operand:V4SF 1 "nonmemory_operand" "x"))]
17979  "TARGET_SSE"
17980  "#"
17981  ""
17982  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17983   (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17984  ""
17985  [(set_attr "type" "sse")])
17986
17987(define_insn_and_split "*pushv4si"
17988  [(set (match_operand:V4SI 0 "push_operand" "=<")
17989	(match_operand:V4SI 1 "nonmemory_operand" "x"))]
17990  "TARGET_SSE"
17991  "#"
17992  ""
17993  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17994   (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17995  ""
17996  [(set_attr "type" "sse")])
17997
17998(define_insn_and_split "*pushv2si"
17999  [(set (match_operand:V2SI 0 "push_operand" "=<")
18000	(match_operand:V2SI 1 "nonmemory_operand" "y"))]
18001  "TARGET_MMX"
18002  "#"
18003  ""
18004  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18005   (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
18006  ""
18007  [(set_attr "type" "mmx")])
18008
18009(define_insn_and_split "*pushv4hi"
18010  [(set (match_operand:V4HI 0 "push_operand" "=<")
18011	(match_operand:V4HI 1 "nonmemory_operand" "y"))]
18012  "TARGET_MMX"
18013  "#"
18014  ""
18015  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18016   (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
18017  ""
18018  [(set_attr "type" "mmx")])
18019
18020(define_insn_and_split "*pushv8qi"
18021  [(set (match_operand:V8QI 0 "push_operand" "=<")
18022	(match_operand:V8QI 1 "nonmemory_operand" "y"))]
18023  "TARGET_MMX"
18024  "#"
18025  ""
18026  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18027   (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
18028  ""
18029  [(set_attr "type" "mmx")])
18030
18031(define_insn_and_split "*pushv2sf"
18032  [(set (match_operand:V2SF 0 "push_operand" "=<")
18033	(match_operand:V2SF 1 "nonmemory_operand" "y"))]
18034  "TARGET_3DNOW"
18035  "#"
18036  ""
18037  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18038   (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
18039  ""
18040  [(set_attr "type" "mmx")])
18041
18042(define_insn "movti_internal"
18043  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18044	(match_operand:TI 1 "general_operand" "O,xm,x"))]
18045  "TARGET_SSE && !TARGET_64BIT"
18046  "@
18047   xorps\t%0, %0
18048   movaps\t{%1, %0|%0, %1}
18049   movaps\t{%1, %0|%0, %1}"
18050  [(set_attr "type" "sse")])
18051
18052(define_insn "*movti_rex64"
18053  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
18054	(match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
18055  "TARGET_64BIT
18056   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18057  "@
18058   #
18059   #
18060   xorps\t%0, %0
18061   movaps\\t{%1, %0|%0, %1}
18062   movaps\\t{%1, %0|%0, %1}"
18063  [(set_attr "type" "*,*,sse,sse,sse")
18064   (set_attr "mode" "TI")])
18065
18066(define_split
18067  [(set (match_operand:TI 0 "nonimmediate_operand" "")
18068        (match_operand:TI 1 "general_operand" ""))]
18069  "reload_completed && !SSE_REG_P (operands[0])
18070   && !SSE_REG_P (operands[1])"
18071  [(const_int 0)]
18072  "ix86_split_long_move (operands); DONE;")
18073
18074;; These two patterns are useful for specifying exactly whether to use
18075;; movaps or movups
18076(define_insn "sse_movaps"
18077  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18078	(unspec:V4SF
18079	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 38))]
18080  "TARGET_SSE"
18081  "@
18082   movaps\t{%1, %0|%0, %1}
18083   movaps\t{%1, %0|%0, %1}"
18084  [(set_attr "type" "sse")])
18085
18086(define_insn "sse_movups"
18087  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18088	(unspec:V4SF
18089	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 39))]
18090  "TARGET_SSE"
18091  "@
18092   movups\t{%1, %0|%0, %1}
18093   movups\t{%1, %0|%0, %1}"
18094  [(set_attr "type" "sse")])
18095
18096
18097;; SSE Strange Moves.
18098
18099(define_insn "sse_movmskps"
18100  [(set (match_operand:SI 0 "register_operand" "=r")
18101	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
18102  "TARGET_SSE"
18103  "movmskps\t{%1, %0|%0, %1}"
18104  [(set_attr "type" "sse")])
18105
18106(define_insn "mmx_pmovmskb"
18107  [(set (match_operand:SI 0 "register_operand" "=r")
18108	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
18109  "TARGET_SSE || TARGET_3DNOW_A"
18110  "pmovmskb\t{%1, %0|%0, %1}"
18111  [(set_attr "type" "sse")])
18112
18113(define_insn "mmx_maskmovq"
18114  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
18115	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18116		      (match_operand:V8QI 2 "register_operand" "y")] 32))]
18117  "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
18118  ;; @@@ check ordering of operands in intel/nonintel syntax
18119  "maskmovq\t{%2, %1|%1, %2}"
18120  [(set_attr "type" "sse")])
18121
18122(define_insn "mmx_maskmovq_rex"
18123  [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
18124	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18125		      (match_operand:V8QI 2 "register_operand" "y")] 32))]
18126  "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
18127  ;; @@@ check ordering of operands in intel/nonintel syntax
18128  "maskmovq\t{%2, %1|%1, %2}"
18129  [(set_attr "type" "sse")])
18130
18131(define_insn "sse_movntv4sf"
18132  [(set (match_operand:V4SF 0 "memory_operand" "=m")
18133	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
18134  "TARGET_SSE"
18135  "movntps\t{%1, %0|%0, %1}"
18136  [(set_attr "type" "sse")])
18137
18138(define_insn "sse_movntdi"
18139  [(set (match_operand:DI 0 "memory_operand" "=m")
18140	(unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
18141  "TARGET_SSE || TARGET_3DNOW_A"
18142  "movntq\t{%1, %0|%0, %1}"
18143  [(set_attr "type" "sse")])
18144
18145(define_insn "sse_movhlps"
18146  [(set (match_operand:V4SF 0 "register_operand" "=x")
18147	(vec_merge:V4SF
18148	 (match_operand:V4SF 1 "register_operand" "0")
18149	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18150			  (parallel [(const_int 2)
18151				     (const_int 3)
18152				     (const_int 0)
18153				     (const_int 1)]))
18154	 (const_int 3)))]
18155  "TARGET_SSE"
18156  "movhlps\t{%2, %0|%0, %2}"
18157  [(set_attr "type" "sse")])
18158
18159(define_insn "sse_movlhps"
18160  [(set (match_operand:V4SF 0 "register_operand" "=x")
18161	(vec_merge:V4SF
18162	 (match_operand:V4SF 1 "register_operand" "0")
18163	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18164			  (parallel [(const_int 2)
18165				     (const_int 3)
18166				     (const_int 0)
18167				     (const_int 1)]))
18168	 (const_int 12)))]
18169  "TARGET_SSE"
18170  "movlhps\t{%2, %0|%0, %2}"
18171  [(set_attr "type" "sse")])
18172
18173(define_insn "sse_movhps"
18174  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18175	(vec_merge:V4SF
18176	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18177	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18178	 (const_int 12)))]
18179  "TARGET_SSE
18180   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18181  "movhps\t{%2, %0|%0, %2}"
18182  [(set_attr "type" "sse")])
18183
18184(define_insn "sse_movlps"
18185  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18186	(vec_merge:V4SF
18187	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18188	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18189	 (const_int 3)))]
18190  "TARGET_SSE
18191   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18192  "movlps\t{%2, %0|%0, %2}"
18193  [(set_attr "type" "sse")])
18194
18195(define_insn "sse_loadss"
18196  [(set (match_operand:V4SF 0 "register_operand" "=x")
18197	(vec_merge:V4SF
18198	 (match_operand:V4SF 1 "memory_operand" "m")
18199	 (vec_duplicate:V4SF (float:SF (const_int 0)))
18200	 (const_int 1)))]
18201  "TARGET_SSE"
18202  "movss\t{%1, %0|%0, %1}"
18203  [(set_attr "type" "sse")])
18204
18205(define_insn "sse_movss"
18206  [(set (match_operand:V4SF 0 "register_operand" "=x")
18207	(vec_merge:V4SF
18208	 (match_operand:V4SF 1 "register_operand" "0")
18209	 (match_operand:V4SF 2 "register_operand" "x")
18210	 (const_int 1)))]
18211  "TARGET_SSE"
18212  "movss\t{%2, %0|%0, %2}"
18213  [(set_attr "type" "sse")])
18214
18215(define_insn "sse_storess"
18216  [(set (match_operand:SF 0 "memory_operand" "=m")
18217	(vec_select:SF
18218	 (match_operand:V4SF 1 "register_operand" "x")
18219	 (parallel [(const_int 0)])))]
18220  "TARGET_SSE"
18221  "movss\t{%1, %0|%0, %1}"
18222  [(set_attr "type" "sse")])
18223
18224(define_insn "sse_shufps"
18225  [(set (match_operand:V4SF 0 "register_operand" "=x")
18226        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
18227		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")
18228		      (match_operand:SI 3 "immediate_operand" "i")] 41))]
18229  "TARGET_SSE"
18230  ;; @@@ check operand order for intel/nonintel syntax
18231  "shufps\t{%3, %2, %0|%0, %2, %3}"
18232  [(set_attr "type" "sse")])
18233
18234
18235;; SSE arithmetic
18236
18237(define_insn "addv4sf3"
18238  [(set (match_operand:V4SF 0 "register_operand" "=x")
18239        (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18240	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18241  "TARGET_SSE"
18242  "addps\t{%2, %0|%0, %2}"
18243  [(set_attr "type" "sse")])
18244
18245(define_insn "vmaddv4sf3"
18246  [(set (match_operand:V4SF 0 "register_operand" "=x")
18247	(vec_merge:V4SF
18248	 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18249		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18250	 (match_dup 1)
18251	 (const_int 1)))]
18252  "TARGET_SSE"
18253  "addss\t{%2, %0|%0, %2}"
18254  [(set_attr "type" "sse")])
18255
18256(define_insn "subv4sf3"
18257  [(set (match_operand:V4SF 0 "register_operand" "=x")
18258        (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18259		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18260  "TARGET_SSE"
18261  "subps\t{%2, %0|%0, %2}"
18262  [(set_attr "type" "sse")])
18263
18264(define_insn "vmsubv4sf3"
18265  [(set (match_operand:V4SF 0 "register_operand" "=x")
18266	(vec_merge:V4SF
18267	 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18268		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18269	 (match_dup 1)
18270	 (const_int 1)))]
18271  "TARGET_SSE"
18272  "subss\t{%2, %0|%0, %2}"
18273  [(set_attr "type" "sse")])
18274
18275(define_insn "mulv4sf3"
18276  [(set (match_operand:V4SF 0 "register_operand" "=x")
18277        (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18278	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18279  "TARGET_SSE"
18280  "mulps\t{%2, %0|%0, %2}"
18281  [(set_attr "type" "sse")])
18282
18283(define_insn "vmmulv4sf3"
18284  [(set (match_operand:V4SF 0 "register_operand" "=x")
18285	(vec_merge:V4SF
18286	 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18287		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18288	 (match_dup 1)
18289	 (const_int 1)))]
18290  "TARGET_SSE"
18291  "mulss\t{%2, %0|%0, %2}"
18292  [(set_attr "type" "sse")])
18293
18294(define_insn "divv4sf3"
18295  [(set (match_operand:V4SF 0 "register_operand" "=x")
18296        (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18297	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18298  "TARGET_SSE"
18299  "divps\t{%2, %0|%0, %2}"
18300  [(set_attr "type" "sse")])
18301
18302(define_insn "vmdivv4sf3"
18303  [(set (match_operand:V4SF 0 "register_operand" "=x")
18304	(vec_merge:V4SF
18305	 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18306		   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18307	 (match_dup 1)
18308	 (const_int 1)))]
18309  "TARGET_SSE"
18310  "divss\t{%2, %0|%0, %2}"
18311  [(set_attr "type" "sse")])
18312
18313
18314;; SSE square root/reciprocal
18315
18316(define_insn "rcpv4sf2"
18317  [(set (match_operand:V4SF 0 "register_operand" "=x")
18318        (unspec:V4SF
18319	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42))]
18320  "TARGET_SSE"
18321  "rcpps\t{%1, %0|%0, %1}"
18322  [(set_attr "type" "sse")])
18323
18324(define_insn "vmrcpv4sf2"
18325  [(set (match_operand:V4SF 0 "register_operand" "=x")
18326	(vec_merge:V4SF
18327	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42)
18328	 (match_operand:V4SF 2 "register_operand" "0")
18329	 (const_int 1)))]
18330  "TARGET_SSE"
18331  "rcpss\t{%1, %0|%0, %1}"
18332  [(set_attr "type" "sse")])
18333
18334(define_insn "rsqrtv4sf2"
18335  [(set (match_operand:V4SF 0 "register_operand" "=x")
18336        (unspec:V4SF
18337	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43))]
18338  "TARGET_SSE"
18339  "rsqrtps\t{%1, %0|%0, %1}"
18340  [(set_attr "type" "sse")])
18341
18342(define_insn "vmrsqrtv4sf2"
18343  [(set (match_operand:V4SF 0 "register_operand" "=x")
18344	(vec_merge:V4SF
18345	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43)
18346	 (match_operand:V4SF 2 "register_operand" "0")
18347	 (const_int 1)))]
18348  "TARGET_SSE"
18349  "rsqrtss\t{%1, %0|%0, %1}"
18350  [(set_attr "type" "sse")])
18351
18352(define_insn "sqrtv4sf2"
18353  [(set (match_operand:V4SF 0 "register_operand" "=x")
18354        (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
18355  "TARGET_SSE"
18356  "sqrtps\t{%1, %0|%0, %1}"
18357  [(set_attr "type" "sse")])
18358
18359(define_insn "vmsqrtv4sf2"
18360  [(set (match_operand:V4SF 0 "register_operand" "=x")
18361	(vec_merge:V4SF
18362	 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18363	 (match_operand:V4SF 2 "register_operand" "0")
18364	 (const_int 1)))]
18365  "TARGET_SSE"
18366  "sqrtss\t{%1, %0|%0, %1}"
18367  [(set_attr "type" "sse")])
18368
18369;; SSE logical operations.
18370
18371;; These are not called andti3 etc. because we really really don't want
18372;; the compiler to widen DImode ands to TImode ands and then try to move
18373;; into DImode subregs of SSE registers, and them together, and move out
18374;; of DImode subregs again!
18375
18376(define_insn "*sse_andti3_df_1"
18377  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18378        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18379		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18380  "TARGET_SSE2"
18381  "andpd\t{%2, %0|%0, %2}"
18382  [(set_attr "type" "sse")])
18383
18384(define_insn "*sse_andti3_df_2"
18385  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18386        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18387		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18388  "TARGET_SSE2"
18389  "andpd\t{%2, %0|%0, %2}"
18390  [(set_attr "type" "sse")])
18391
18392(define_insn "*sse_andti3_sf_1"
18393  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18394        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18395		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18396  "TARGET_SSE"
18397  "andps\t{%2, %0|%0, %2}"
18398  [(set_attr "type" "sse")])
18399
18400(define_insn "*sse_andti3_sf_2"
18401  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18402        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18403		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18404  "TARGET_SSE"
18405  "andps\t{%2, %0|%0, %2}"
18406  [(set_attr "type" "sse")])
18407
18408(define_insn "sse_andti3"
18409  [(set (match_operand:TI 0 "register_operand" "=x")
18410        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18411		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18412  "TARGET_SSE && !TARGET_SSE2
18413   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18414  "andps\t{%2, %0|%0, %2}"
18415  [(set_attr "type" "sse")])
18416
18417(define_insn "*sse_andti3_sse2"
18418  [(set (match_operand:TI 0 "register_operand" "=x")
18419        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18420		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18421  "TARGET_SSE2
18422   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18423  "pand\t{%2, %0|%0, %2}"
18424  [(set_attr "type" "sse")])
18425
18426(define_insn "*sse_nandti3_df"
18427  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18428        (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18429		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18430  "TARGET_SSE2"
18431  "andnpd\t{%2, %0|%0, %2}"
18432  [(set_attr "type" "sse")])
18433
18434(define_insn "*sse_nandti3_sf"
18435  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18436        (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18437		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18438  "TARGET_SSE"
18439  "andnps\t{%2, %0|%0, %2}"
18440  [(set_attr "type" "sse")])
18441
18442(define_insn "sse_nandti3"
18443  [(set (match_operand:TI 0 "register_operand" "=x")
18444        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18445		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18446  "TARGET_SSE && !TARGET_SSE2"
18447  "andnps\t{%2, %0|%0, %2}"
18448  [(set_attr "type" "sse")])
18449
18450(define_insn "*sse_nandti3_sse2"
18451  [(set (match_operand:TI 0 "register_operand" "=x")
18452        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18453		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18454  "TARGET_SSE2"
18455  "pnand\t{%2, %0|%0, %2}"
18456  [(set_attr "type" "sse")])
18457
18458(define_insn "*sse_iorti3_df_1"
18459  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18460        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18461		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18462  "TARGET_SSE2"
18463  "orpd\t{%2, %0|%0, %2}"
18464  [(set_attr "type" "sse")])
18465
18466(define_insn "*sse_iorti3_df_2"
18467  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18468        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18469		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18470  "TARGET_SSE2"
18471  "orpd\t{%2, %0|%0, %2}"
18472  [(set_attr "type" "sse")])
18473
18474(define_insn "*sse_iorti3_sf_1"
18475  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18476        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18477		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18478  "TARGET_SSE"
18479  "orps\t{%2, %0|%0, %2}"
18480  [(set_attr "type" "sse")])
18481
18482(define_insn "*sse_iorti3_sf_2"
18483  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18484        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18485		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18486  "TARGET_SSE"
18487  "orps\t{%2, %0|%0, %2}"
18488  [(set_attr "type" "sse")])
18489
18490(define_insn "sse_iorti3"
18491  [(set (match_operand:TI 0 "register_operand" "=x")
18492        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18493		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18494  "TARGET_SSE && !TARGET_SSE2
18495   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18496  "orps\t{%2, %0|%0, %2}"
18497  [(set_attr "type" "sse")])
18498
18499(define_insn "*sse_iorti3_sse2"
18500  [(set (match_operand:TI 0 "register_operand" "=x")
18501        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18502		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18503  "TARGET_SSE2
18504   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18505  "por\t{%2, %0|%0, %2}"
18506  [(set_attr "type" "sse")])
18507
18508(define_insn "*sse_xorti3_df_1"
18509  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18510        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18511		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18512  "TARGET_SSE2"
18513  "xorpd\t{%2, %0|%0, %2}"
18514  [(set_attr "type" "sse")])
18515
18516(define_insn "*sse_xorti3_df_2"
18517  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18518        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18519		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18520  "TARGET_SSE2"
18521  "xorpd\t{%2, %0|%0, %2}"
18522  [(set_attr "type" "sse")])
18523
18524(define_insn "*sse_xorti3_sf_1"
18525  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18526        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18527		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18528  "TARGET_SSE"
18529  "xorps\t{%2, %0|%0, %2}"
18530  [(set_attr "type" "sse")])
18531
18532(define_insn "*sse_xorti3_sf_2"
18533  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18534        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18535		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18536  "TARGET_SSE"
18537  "xorps\t{%2, %0|%0, %2}"
18538  [(set_attr "type" "sse")])
18539
18540(define_insn "sse_xorti3"
18541  [(set (match_operand:TI 0 "register_operand" "=x")
18542        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18543		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18544  "TARGET_SSE && !TARGET_SSE2
18545   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18546  "xorps\t{%2, %0|%0, %2}"
18547  [(set_attr "type" "sse")])
18548
18549(define_insn "*sse_xorti3_sse2"
18550  [(set (match_operand:TI 0 "register_operand" "=x")
18551        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18552		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
18553  "TARGET_SSE2
18554   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18555  "pxor\t{%2, %0|%0, %2}"
18556  [(set_attr "type" "sse")])
18557
18558;; Use xor, but don't show input operands so they aren't live before
18559;; this insn.
18560(define_insn "sse_clrv4sf"
18561  [(set (match_operand:V4SF 0 "register_operand" "=x")
18562        (unspec:V4SF [(const_int 0)] 45))]
18563  "TARGET_SSE"
18564  "xorps\t{%0, %0|%0, %0}"
18565  [(set_attr "type" "sse")
18566   (set_attr "memory" "none")])
18567
18568;; SSE mask-generating compares
18569
18570(define_insn "maskcmpv4sf3"
18571  [(set (match_operand:V4SI 0 "register_operand" "=x")
18572        (match_operator:V4SI 3 "sse_comparison_operator"
18573		[(match_operand:V4SF 1 "register_operand" "0")
18574		 (match_operand:V4SF 2 "register_operand" "x")]))]
18575  "TARGET_SSE"
18576  "cmp%D3ps\t{%2, %0|%0, %2}"
18577  [(set_attr "type" "sse")])
18578
18579(define_insn "maskncmpv4sf3"
18580  [(set (match_operand:V4SI 0 "register_operand" "=x")
18581        (not:V4SI
18582	 (match_operator:V4SI 3 "sse_comparison_operator"
18583		[(match_operand:V4SF 1 "register_operand" "0")
18584		 (match_operand:V4SF 2 "register_operand" "x")])))]
18585  "TARGET_SSE"
18586{
18587  if (GET_CODE (operands[3]) == UNORDERED)
18588    return "cmpordps\t{%2, %0|%0, %2}";
18589  else
18590    return "cmpn%D3ps\t{%2, %0|%0, %2}";
18591}
18592  [(set_attr "type" "sse")])
18593
18594(define_insn "vmmaskcmpv4sf3"
18595  [(set (match_operand:V4SI 0 "register_operand" "=x")
18596	(vec_merge:V4SI
18597	 (match_operator:V4SI 3 "sse_comparison_operator"
18598		[(match_operand:V4SF 1 "register_operand" "0")
18599		 (match_operand:V4SF 2 "register_operand" "x")])
18600	 (match_dup 1)
18601	 (const_int 1)))]
18602  "TARGET_SSE"
18603  "cmp%D3ss\t{%2, %0|%0, %2}"
18604  [(set_attr "type" "sse")])
18605
18606(define_insn "vmmaskncmpv4sf3"
18607  [(set (match_operand:V4SI 0 "register_operand" "=x")
18608	(vec_merge:V4SI
18609	 (not:V4SI
18610	  (match_operator:V4SI 3 "sse_comparison_operator"
18611		[(match_operand:V4SF 1 "register_operand" "0")
18612		 (match_operand:V4SF 2 "register_operand" "x")]))
18613	 (subreg:V4SI (match_dup 1) 0)
18614	 (const_int 1)))]
18615  "TARGET_SSE"
18616{
18617  if (GET_CODE (operands[3]) == UNORDERED)
18618    return "cmpordss\t{%2, %0|%0, %2}";
18619  else
18620    return "cmpn%D3ss\t{%2, %0|%0, %2}";
18621}
18622  [(set_attr "type" "sse")])
18623
18624(define_insn "sse_comi"
18625  [(set (reg:CCFP 17)
18626        (match_operator:CCFP 2 "sse_comparison_operator"
18627			[(vec_select:SF
18628			  (match_operand:V4SF 0 "register_operand" "x")
18629			  (parallel [(const_int 0)]))
18630			 (vec_select:SF
18631			  (match_operand:V4SF 1 "register_operand" "x")
18632			  (parallel [(const_int 0)]))]))]
18633  "TARGET_SSE"
18634  "comiss\t{%1, %0|%0, %1}"
18635  [(set_attr "type" "sse")])
18636
18637(define_insn "sse_ucomi"
18638  [(set (reg:CCFPU 17)
18639	(match_operator:CCFPU 2 "sse_comparison_operator"
18640			[(vec_select:SF
18641			  (match_operand:V4SF 0 "register_operand" "x")
18642			  (parallel [(const_int 0)]))
18643			 (vec_select:SF
18644			  (match_operand:V4SF 1 "register_operand" "x")
18645			  (parallel [(const_int 0)]))]))]
18646  "TARGET_SSE"
18647  "ucomiss\t{%1, %0|%0, %1}"
18648  [(set_attr "type" "sse")])
18649
18650
18651;; SSE unpack
18652
18653(define_insn "sse_unpckhps"
18654  [(set (match_operand:V4SF 0 "register_operand" "=x")
18655	(vec_merge:V4SF
18656	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18657			  (parallel [(const_int 2)
18658				     (const_int 0)
18659				     (const_int 3)
18660				     (const_int 1)]))
18661	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18662			  (parallel [(const_int 0)
18663				     (const_int 2)
18664				     (const_int 1)
18665				     (const_int 3)]))
18666	 (const_int 5)))]
18667  "TARGET_SSE"
18668  "unpckhps\t{%2, %0|%0, %2}"
18669  [(set_attr "type" "sse")])
18670
18671(define_insn "sse_unpcklps"
18672  [(set (match_operand:V4SF 0 "register_operand" "=x")
18673	(vec_merge:V4SF
18674	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18675			  (parallel [(const_int 0)
18676				     (const_int 2)
18677				     (const_int 1)
18678				     (const_int 3)]))
18679	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18680			  (parallel [(const_int 2)
18681				     (const_int 0)
18682				     (const_int 3)
18683				     (const_int 1)]))
18684	 (const_int 5)))]
18685  "TARGET_SSE"
18686  "unpcklps\t{%2, %0|%0, %2}"
18687  [(set_attr "type" "sse")])
18688
18689
18690;; SSE min/max
18691
18692(define_insn "smaxv4sf3"
18693  [(set (match_operand:V4SF 0 "register_operand" "=x")
18694        (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18695		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18696  "TARGET_SSE"
18697  "maxps\t{%2, %0|%0, %2}"
18698  [(set_attr "type" "sse")])
18699
18700(define_insn "vmsmaxv4sf3"
18701  [(set (match_operand:V4SF 0 "register_operand" "=x")
18702	(vec_merge:V4SF
18703	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18704		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18705	 (match_dup 1)
18706	 (const_int 1)))]
18707  "TARGET_SSE"
18708  "maxss\t{%2, %0|%0, %2}"
18709  [(set_attr "type" "sse")])
18710
18711(define_insn "sminv4sf3"
18712  [(set (match_operand:V4SF 0 "register_operand" "=x")
18713        (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18714		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18715  "TARGET_SSE"
18716  "minps\t{%2, %0|%0, %2}"
18717  [(set_attr "type" "sse")])
18718
18719(define_insn "vmsminv4sf3"
18720  [(set (match_operand:V4SF 0 "register_operand" "=x")
18721	(vec_merge:V4SF
18722	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18723		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18724	 (match_dup 1)
18725	 (const_int 1)))]
18726  "TARGET_SSE"
18727  "minss\t{%2, %0|%0, %2}"
18728  [(set_attr "type" "sse")])
18729
18730
18731;; SSE <-> integer/MMX conversions
18732
18733(define_insn "cvtpi2ps"
18734  [(set (match_operand:V4SF 0 "register_operand" "=x")
18735	(vec_merge:V4SF
18736	 (match_operand:V4SF 1 "register_operand" "0")
18737	 (vec_duplicate:V4SF
18738	  (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
18739	 (const_int 12)))]
18740  "TARGET_SSE"
18741  "cvtpi2ps\t{%2, %0|%0, %2}"
18742  [(set_attr "type" "sse")])
18743
18744(define_insn "cvtps2pi"
18745  [(set (match_operand:V2SI 0 "register_operand" "=y")
18746	(vec_select:V2SI
18747	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18748	 (parallel [(const_int 0) (const_int 1)])))]
18749  "TARGET_SSE"
18750  "cvtps2pi\t{%1, %0|%0, %1}"
18751  [(set_attr "type" "sse")])
18752
18753(define_insn "cvttps2pi"
18754  [(set (match_operand:V2SI 0 "register_operand" "=y")
18755	(vec_select:V2SI
18756	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
18757	 (parallel [(const_int 0) (const_int 1)])))]
18758  "TARGET_SSE"
18759  "cvttps2pi\t{%1, %0|%0, %1}"
18760  [(set_attr "type" "sse")])
18761
18762(define_insn "cvtsi2ss"
18763  [(set (match_operand:V4SF 0 "register_operand" "=x")
18764	(vec_merge:V4SF
18765	 (match_operand:V4SF 1 "register_operand" "0")
18766	 (vec_duplicate:V4SF
18767	  (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
18768	 (const_int 14)))]
18769  "TARGET_SSE"
18770  "cvtsi2ss\t{%2, %0|%0, %2}"
18771  [(set_attr "type" "sse")])
18772
18773(define_insn "cvtss2si"
18774  [(set (match_operand:SI 0 "register_operand" "=r")
18775	(vec_select:SI
18776	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18777	 (parallel [(const_int 0)])))]
18778  "TARGET_SSE"
18779  "cvtss2si\t{%1, %0|%0, %1}"
18780  [(set_attr "type" "sse")])
18781
18782(define_insn "cvttss2si"
18783  [(set (match_operand:SI 0 "register_operand" "=r")
18784	(vec_select:SI
18785	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
18786	 (parallel [(const_int 0)])))]
18787  "TARGET_SSE"
18788  "cvttss2si\t{%1, %0|%0, %1}"
18789  [(set_attr "type" "sse")])
18790
18791
18792;; MMX insns
18793
18794;; MMX arithmetic
18795
18796(define_insn "addv8qi3"
18797  [(set (match_operand:V8QI 0 "register_operand" "=y")
18798        (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18799	           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18800  "TARGET_MMX"
18801  "paddb\t{%2, %0|%0, %2}"
18802  [(set_attr "type" "mmx")])
18803
18804(define_insn "addv4hi3"
18805  [(set (match_operand:V4HI 0 "register_operand" "=y")
18806        (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18807	           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18808  "TARGET_MMX"
18809  "paddw\t{%2, %0|%0, %2}"
18810  [(set_attr "type" "mmx")])
18811
18812(define_insn "addv2si3"
18813  [(set (match_operand:V2SI 0 "register_operand" "=y")
18814        (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18815	           (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18816  "TARGET_MMX"
18817  "paddd\t{%2, %0|%0, %2}"
18818  [(set_attr "type" "mmx")])
18819
18820(define_insn "ssaddv8qi3"
18821  [(set (match_operand:V8QI 0 "register_operand" "=y")
18822        (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18823		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18824  "TARGET_MMX"
18825  "paddsb\t{%2, %0|%0, %2}"
18826  [(set_attr "type" "mmx")])
18827
18828(define_insn "ssaddv4hi3"
18829  [(set (match_operand:V4HI 0 "register_operand" "=y")
18830        (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18831		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18832  "TARGET_MMX"
18833  "paddsw\t{%2, %0|%0, %2}"
18834  [(set_attr "type" "mmx")])
18835
18836(define_insn "usaddv8qi3"
18837  [(set (match_operand:V8QI 0 "register_operand" "=y")
18838        (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18839		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18840  "TARGET_MMX"
18841  "paddusb\t{%2, %0|%0, %2}"
18842  [(set_attr "type" "mmx")])
18843
18844(define_insn "usaddv4hi3"
18845  [(set (match_operand:V4HI 0 "register_operand" "=y")
18846        (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18847		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18848  "TARGET_MMX"
18849  "paddusw\t{%2, %0|%0, %2}"
18850  [(set_attr "type" "mmx")])
18851
18852(define_insn "subv8qi3"
18853  [(set (match_operand:V8QI 0 "register_operand" "=y")
18854        (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18855		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18856  "TARGET_MMX"
18857  "psubb\t{%2, %0|%0, %2}"
18858  [(set_attr "type" "mmx")])
18859
18860(define_insn "subv4hi3"
18861  [(set (match_operand:V4HI 0 "register_operand" "=y")
18862        (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18863		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18864  "TARGET_MMX"
18865  "psubw\t{%2, %0|%0, %2}"
18866  [(set_attr "type" "mmx")])
18867
18868(define_insn "subv2si3"
18869  [(set (match_operand:V2SI 0 "register_operand" "=y")
18870        (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18871		    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18872  "TARGET_MMX"
18873  "psubd\t{%2, %0|%0, %2}"
18874  [(set_attr "type" "mmx")])
18875
18876(define_insn "sssubv8qi3"
18877  [(set (match_operand:V8QI 0 "register_operand" "=y")
18878        (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18879		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18880  "TARGET_MMX"
18881  "psubsb\t{%2, %0|%0, %2}"
18882  [(set_attr "type" "mmx")])
18883
18884(define_insn "sssubv4hi3"
18885  [(set (match_operand:V4HI 0 "register_operand" "=y")
18886        (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18887		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18888  "TARGET_MMX"
18889  "psubsw\t{%2, %0|%0, %2}"
18890  [(set_attr "type" "mmx")])
18891
18892(define_insn "ussubv8qi3"
18893  [(set (match_operand:V8QI 0 "register_operand" "=y")
18894        (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18895		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18896  "TARGET_MMX"
18897  "psubusb\t{%2, %0|%0, %2}"
18898  [(set_attr "type" "mmx")])
18899
18900(define_insn "ussubv4hi3"
18901  [(set (match_operand:V4HI 0 "register_operand" "=y")
18902        (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18903		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18904  "TARGET_MMX"
18905  "psubusw\t{%2, %0|%0, %2}"
18906  [(set_attr "type" "mmx")])
18907
18908(define_insn "mulv4hi3"
18909  [(set (match_operand:V4HI 0 "register_operand" "=y")
18910        (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18911		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18912  "TARGET_MMX"
18913  "pmullw\t{%2, %0|%0, %2}"
18914  [(set_attr "type" "mmx")])
18915
18916(define_insn "smulv4hi3_highpart"
18917  [(set (match_operand:V4HI 0 "register_operand" "=y")
18918	(truncate:V4HI
18919	 (lshiftrt:V4SI
18920	  (mult:V4SI (sign_extend:V4SI
18921		      (match_operand:V4HI 1 "register_operand" "0"))
18922		     (sign_extend:V4SI
18923		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18924	  (const_int 16))))]
18925  "TARGET_MMX"
18926  "pmulhw\t{%2, %0|%0, %2}"
18927  [(set_attr "type" "mmx")])
18928
18929(define_insn "umulv4hi3_highpart"
18930  [(set (match_operand:V4HI 0 "register_operand" "=y")
18931	(truncate:V4HI
18932	 (lshiftrt:V4SI
18933	  (mult:V4SI (zero_extend:V4SI
18934		      (match_operand:V4HI 1 "register_operand" "0"))
18935		     (zero_extend:V4SI
18936		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18937	  (const_int 16))))]
18938  "TARGET_SSE || TARGET_3DNOW_A"
18939  "pmulhuw\t{%2, %0|%0, %2}"
18940  [(set_attr "type" "mmx")])
18941
18942(define_insn "mmx_pmaddwd"
18943  [(set (match_operand:V2SI 0 "register_operand" "=y")
18944        (plus:V2SI
18945	 (mult:V2SI
18946	  (sign_extend:V2SI
18947	   (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18948			    (parallel [(const_int 0) (const_int 2)])))
18949	  (sign_extend:V2SI
18950	   (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18951			    (parallel [(const_int 0) (const_int 2)]))))
18952	 (mult:V2SI
18953	  (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18954					     (parallel [(const_int 1)
18955							(const_int 3)])))
18956	  (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18957					     (parallel [(const_int 1)
18958							(const_int 3)]))))))]
18959  "TARGET_MMX"
18960  "pmaddwd\t{%2, %0|%0, %2}"
18961  [(set_attr "type" "mmx")])
18962
18963
18964;; MMX logical operations
18965;; Note we don't want to declare these as regular iordi3 insns to prevent
18966;; normal code that also wants to use the FPU from getting broken.
18967;; The UNSPECs are there to prevent the combiner from getting overly clever.
18968(define_insn "mmx_iordi3"
18969  [(set (match_operand:DI 0 "register_operand" "=y")
18970        (unspec:DI
18971	 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18972		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18973  "TARGET_MMX"
18974  "por\t{%2, %0|%0, %2}"
18975  [(set_attr "type" "mmx")])
18976
18977(define_insn "mmx_xordi3"
18978  [(set (match_operand:DI 0 "register_operand" "=y")
18979        (unspec:DI
18980	 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18981		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18982  "TARGET_MMX"
18983  "pxor\t{%2, %0|%0, %2}"
18984  [(set_attr "type" "mmx")
18985   (set_attr "memory" "none")])
18986
18987;; Same as pxor, but don't show input operands so that we don't think
18988;; they are live.
18989(define_insn "mmx_clrdi"
18990  [(set (match_operand:DI 0 "register_operand" "=y")
18991        (unspec:DI [(const_int 0)] 45))]
18992  "TARGET_MMX"
18993  "pxor\t{%0, %0|%0, %0}"
18994  [(set_attr "type" "mmx")
18995   (set_attr "memory" "none")])
18996
18997(define_insn "mmx_anddi3"
18998  [(set (match_operand:DI 0 "register_operand" "=y")
18999        (unspec:DI
19000	 [(and:DI (match_operand:DI 1 "register_operand" "0")
19001		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
19002  "TARGET_MMX"
19003  "pand\t{%2, %0|%0, %2}"
19004  [(set_attr "type" "mmx")])
19005
19006(define_insn "mmx_nanddi3"
19007  [(set (match_operand:DI 0 "register_operand" "=y")
19008        (unspec:DI
19009	 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
19010			  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
19011  "TARGET_MMX"
19012  "pandn\t{%2, %0|%0, %2}"
19013  [(set_attr "type" "mmx")])
19014
19015
19016;; MMX unsigned averages/sum of absolute differences
19017
19018(define_insn "mmx_uavgv8qi3"
19019  [(set (match_operand:V8QI 0 "register_operand" "=y")
19020        (ashiftrt:V8QI
19021	 (plus:V8QI (plus:V8QI
19022		     (match_operand:V8QI 1 "register_operand" "0")
19023		     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
19024		    (const_vector:V8QI [(const_int 1)
19025					(const_int 1)
19026					(const_int 1)
19027					(const_int 1)
19028					(const_int 1)
19029					(const_int 1)
19030					(const_int 1)
19031					(const_int 1)]))
19032	 (const_int 1)))]
19033  "TARGET_SSE || TARGET_3DNOW_A"
19034  "pavgb\t{%2, %0|%0, %2}"
19035  [(set_attr "type" "sse")])
19036
19037(define_insn "mmx_uavgv4hi3"
19038  [(set (match_operand:V4HI 0 "register_operand" "=y")
19039        (ashiftrt:V4HI
19040	 (plus:V4HI (plus:V4HI
19041		     (match_operand:V4HI 1 "register_operand" "0")
19042		     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
19043		    (const_vector:V4HI [(const_int 1)
19044					(const_int 1)
19045					(const_int 1)
19046					(const_int 1)]))
19047	 (const_int 1)))]
19048  "TARGET_SSE || TARGET_3DNOW_A"
19049  "pavgw\t{%2, %0|%0, %2}"
19050  [(set_attr "type" "sse")])
19051
19052(define_insn "mmx_psadbw"
19053  [(set (match_operand:V8QI 0 "register_operand" "=y")
19054        (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19055			      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
19056  "TARGET_SSE || TARGET_3DNOW_A"
19057  "psadbw\t{%2, %0|%0, %2}"
19058  [(set_attr "type" "sse")])
19059
19060
19061;; MMX insert/extract/shuffle
19062
19063(define_insn "mmx_pinsrw"
19064  [(set (match_operand:V4HI 0 "register_operand" "=y")
19065        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
19066			(vec_duplicate:V4HI
19067			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
19068			(match_operand:SI 3 "immediate_operand" "i")))]
19069  "TARGET_SSE || TARGET_3DNOW_A"
19070  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
19071  [(set_attr "type" "sse")])
19072
19073(define_insn "mmx_pextrw"
19074  [(set (match_operand:SI 0 "register_operand" "=r")
19075        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
19076				       (parallel
19077					[(match_operand:SI 2 "immediate_operand" "i")]))))]
19078  "TARGET_SSE || TARGET_3DNOW_A"
19079  "pextrw\t{%2, %1, %0|%0, %1, %2}"
19080  [(set_attr "type" "sse")])
19081
19082(define_insn "mmx_pshufw"
19083  [(set (match_operand:V4HI 0 "register_operand" "=y")
19084        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
19085		      (match_operand:SI 2 "immediate_operand" "i")] 41))]
19086  "TARGET_SSE || TARGET_3DNOW_A"
19087  "pshufw\t{%2, %1, %0|%0, %1, %2}"
19088  [(set_attr "type" "sse")])
19089
19090
19091;; MMX mask-generating comparisons
19092
19093(define_insn "eqv8qi3"
19094  [(set (match_operand:V8QI 0 "register_operand" "=y")
19095        (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
19096		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19097  "TARGET_MMX"
19098  "pcmpeqb\t{%2, %0|%0, %2}"
19099  [(set_attr "type" "mmx")])
19100
19101(define_insn "eqv4hi3"
19102  [(set (match_operand:V4HI 0 "register_operand" "=y")
19103        (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
19104		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19105  "TARGET_MMX"
19106  "pcmpeqw\t{%2, %0|%0, %2}"
19107  [(set_attr "type" "mmx")])
19108
19109(define_insn "eqv2si3"
19110  [(set (match_operand:V2SI 0 "register_operand" "=y")
19111        (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
19112		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19113  "TARGET_MMX"
19114  "pcmpeqd\t{%2, %0|%0, %2}"
19115  [(set_attr "type" "mmx")])
19116
19117(define_insn "gtv8qi3"
19118  [(set (match_operand:V8QI 0 "register_operand" "=y")
19119        (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
19120		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19121  "TARGET_MMX"
19122  "pcmpgtb\t{%2, %0|%0, %2}"
19123  [(set_attr "type" "mmx")])
19124
19125(define_insn "gtv4hi3"
19126  [(set (match_operand:V4HI 0 "register_operand" "=y")
19127        (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19128		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19129  "TARGET_MMX"
19130  "pcmpgtw\t{%2, %0|%0, %2}"
19131  [(set_attr "type" "mmx")])
19132
19133(define_insn "gtv2si3"
19134  [(set (match_operand:V2SI 0 "register_operand" "=y")
19135        (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19136		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19137  "TARGET_MMX"
19138  "pcmpgtd\t{%2, %0|%0, %2}"
19139  [(set_attr "type" "mmx")])
19140
19141
19142;; MMX max/min insns
19143
19144(define_insn "umaxv8qi3"
19145  [(set (match_operand:V8QI 0 "register_operand" "=y")
19146        (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
19147		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19148  "TARGET_SSE || TARGET_3DNOW_A"
19149  "pmaxub\t{%2, %0|%0, %2}"
19150  [(set_attr "type" "sse")])
19151
19152(define_insn "smaxv4hi3"
19153  [(set (match_operand:V4HI 0 "register_operand" "=y")
19154        (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
19155		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19156  "TARGET_SSE || TARGET_3DNOW_A"
19157  "pmaxsw\t{%2, %0|%0, %2}"
19158  [(set_attr "type" "sse")])
19159
19160(define_insn "uminv8qi3"
19161  [(set (match_operand:V8QI 0 "register_operand" "=y")
19162        (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
19163		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19164  "TARGET_SSE || TARGET_3DNOW_A"
19165  "pminub\t{%2, %0|%0, %2}"
19166  [(set_attr "type" "sse")])
19167
19168(define_insn "sminv4hi3"
19169  [(set (match_operand:V4HI 0 "register_operand" "=y")
19170        (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
19171		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19172  "TARGET_SSE || TARGET_3DNOW_A"
19173  "pminsw\t{%2, %0|%0, %2}"
19174  [(set_attr "type" "sse")])
19175
19176
19177;; MMX shifts
19178
19179(define_insn "ashrv4hi3"
19180  [(set (match_operand:V4HI 0 "register_operand" "=y")
19181        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19182		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
19183  "TARGET_MMX"
19184  "psraw\t{%2, %0|%0, %2}"
19185  [(set_attr "type" "mmx")])
19186
19187(define_insn "ashrv2si3"
19188  [(set (match_operand:V2SI 0 "register_operand" "=y")
19189        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19190		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
19191  "TARGET_MMX"
19192  "psrad\t{%2, %0|%0, %2}"
19193  [(set_attr "type" "mmx")])
19194
19195(define_insn "lshrv4hi3"
19196  [(set (match_operand:V4HI 0 "register_operand" "=y")
19197        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19198		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
19199  "TARGET_MMX"
19200  "psrlw\t{%2, %0|%0, %2}"
19201  [(set_attr "type" "mmx")])
19202
19203(define_insn "lshrv2si3"
19204  [(set (match_operand:V2SI 0 "register_operand" "=y")
19205        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19206		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
19207  "TARGET_MMX"
19208  "psrld\t{%2, %0|%0, %2}"
19209  [(set_attr "type" "mmx")])
19210
19211;; See logical MMX insns.
19212(define_insn "mmx_lshrdi3"
19213  [(set (match_operand:DI 0 "register_operand" "=y")
19214        (unspec:DI
19215	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
19216		       (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19217  "TARGET_MMX"
19218  "psrlq\t{%2, %0|%0, %2}"
19219  [(set_attr "type" "mmx")])
19220
19221(define_insn "ashlv4hi3"
19222  [(set (match_operand:V4HI 0 "register_operand" "=y")
19223        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
19224		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
19225  "TARGET_MMX"
19226  "psllw\t{%2, %0|%0, %2}"
19227  [(set_attr "type" "mmx")])
19228
19229(define_insn "ashlv2si3"
19230  [(set (match_operand:V2SI 0 "register_operand" "=y")
19231        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
19232		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
19233  "TARGET_MMX"
19234  "pslld\t{%2, %0|%0, %2}"
19235  [(set_attr "type" "mmx")])
19236
19237;; See logical MMX insns.
19238(define_insn "mmx_ashldi3"
19239  [(set (match_operand:DI 0 "register_operand" "=y")
19240        (unspec:DI
19241	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
19242		     (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19243  "TARGET_MMX"
19244  "psllq\t{%2, %0|%0, %2}"
19245  [(set_attr "type" "mmx")])
19246
19247
19248;; MMX pack/unpack insns.
19249
19250(define_insn "mmx_packsswb"
19251  [(set (match_operand:V8QI 0 "register_operand" "=y")
19252	(vec_concat:V8QI
19253	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19254	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19255  "TARGET_MMX"
19256  "packsswb\t{%2, %0|%0, %2}"
19257  [(set_attr "type" "mmx")])
19258
19259(define_insn "mmx_packssdw"
19260  [(set (match_operand:V4HI 0 "register_operand" "=y")
19261	(vec_concat:V4HI
19262	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
19263	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
19264  "TARGET_MMX"
19265  "packssdw\t{%2, %0|%0, %2}"
19266  [(set_attr "type" "mmx")])
19267
19268(define_insn "mmx_packuswb"
19269  [(set (match_operand:V8QI 0 "register_operand" "=y")
19270	(vec_concat:V8QI
19271	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19272	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19273  "TARGET_MMX"
19274  "packuswb\t{%2, %0|%0, %2}"
19275  [(set_attr "type" "mmx")])
19276
19277(define_insn "mmx_punpckhbw"
19278  [(set (match_operand:V8QI 0 "register_operand" "=y")
19279	(vec_merge:V8QI
19280	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19281			  (parallel [(const_int 4)
19282				     (const_int 0)
19283				     (const_int 5)
19284				     (const_int 1)
19285				     (const_int 6)
19286				     (const_int 2)
19287				     (const_int 7)
19288				     (const_int 3)]))
19289	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19290			  (parallel [(const_int 0)
19291				     (const_int 4)
19292				     (const_int 1)
19293				     (const_int 5)
19294				     (const_int 2)
19295				     (const_int 6)
19296				     (const_int 3)
19297				     (const_int 7)]))
19298	 (const_int 85)))]
19299  "TARGET_MMX"
19300  "punpckhbw\t{%2, %0|%0, %2}"
19301  [(set_attr "type" "mmx")])
19302
19303(define_insn "mmx_punpckhwd"
19304  [(set (match_operand:V4HI 0 "register_operand" "=y")
19305	(vec_merge:V4HI
19306	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19307			  (parallel [(const_int 0)
19308				     (const_int 2)
19309				     (const_int 1)
19310				     (const_int 3)]))
19311	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19312			  (parallel [(const_int 2)
19313				     (const_int 0)
19314				     (const_int 3)
19315				     (const_int 1)]))
19316	 (const_int 5)))]
19317  "TARGET_MMX"
19318  "punpckhwd\t{%2, %0|%0, %2}"
19319  [(set_attr "type" "mmx")])
19320
19321(define_insn "mmx_punpckhdq"
19322  [(set (match_operand:V2SI 0 "register_operand" "=y")
19323	(vec_merge:V2SI
19324	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19325			  (parallel [(const_int 0)
19326				     (const_int 1)]))
19327	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19328			  (parallel [(const_int 1)
19329				     (const_int 0)]))
19330	 (const_int 1)))]
19331  "TARGET_MMX"
19332  "punpckhdq\t{%2, %0|%0, %2}"
19333  [(set_attr "type" "mmx")])
19334
19335(define_insn "mmx_punpcklbw"
19336  [(set (match_operand:V8QI 0 "register_operand" "=y")
19337	(vec_merge:V8QI
19338	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19339			  (parallel [(const_int 0)
19340				     (const_int 4)
19341				     (const_int 1)
19342				     (const_int 5)
19343				     (const_int 2)
19344				     (const_int 6)
19345				     (const_int 3)
19346				     (const_int 7)]))
19347	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19348			  (parallel [(const_int 4)
19349				     (const_int 0)
19350				     (const_int 5)
19351				     (const_int 1)
19352				     (const_int 6)
19353				     (const_int 2)
19354				     (const_int 7)
19355				     (const_int 3)]))
19356	 (const_int 85)))]
19357  "TARGET_MMX"
19358  "punpcklbw\t{%2, %0|%0, %2}"
19359  [(set_attr "type" "mmx")])
19360
19361(define_insn "mmx_punpcklwd"
19362  [(set (match_operand:V4HI 0 "register_operand" "=y")
19363	(vec_merge:V4HI
19364	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19365			  (parallel [(const_int 2)
19366				     (const_int 0)
19367				     (const_int 3)
19368				     (const_int 1)]))
19369	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19370			  (parallel [(const_int 0)
19371				     (const_int 2)
19372				     (const_int 1)
19373				     (const_int 3)]))
19374	 (const_int 5)))]
19375  "TARGET_MMX"
19376  "punpcklwd\t{%2, %0|%0, %2}"
19377  [(set_attr "type" "mmx")])
19378
19379(define_insn "mmx_punpckldq"
19380  [(set (match_operand:V2SI 0 "register_operand" "=y")
19381	(vec_merge:V2SI
19382	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19383			   (parallel [(const_int 1)
19384				      (const_int 0)]))
19385	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19386			  (parallel [(const_int 0)
19387				     (const_int 1)]))
19388	 (const_int 1)))]
19389  "TARGET_MMX"
19390  "punpckldq\t{%2, %0|%0, %2}"
19391  [(set_attr "type" "mmx")])
19392
19393
19394;; Miscellaneous stuff
19395
19396(define_insn "emms"
19397  [(unspec_volatile [(const_int 0)] 31)
19398   (clobber (reg:XF 8))
19399   (clobber (reg:XF 9))
19400   (clobber (reg:XF 10))
19401   (clobber (reg:XF 11))
19402   (clobber (reg:XF 12))
19403   (clobber (reg:XF 13))
19404   (clobber (reg:XF 14))
19405   (clobber (reg:XF 15))
19406   (clobber (reg:DI 29))
19407   (clobber (reg:DI 30))
19408   (clobber (reg:DI 31))
19409   (clobber (reg:DI 32))
19410   (clobber (reg:DI 33))
19411   (clobber (reg:DI 34))
19412   (clobber (reg:DI 35))
19413   (clobber (reg:DI 36))]
19414  "TARGET_MMX"
19415  "emms"
19416  [(set_attr "type" "mmx")
19417   (set_attr "memory" "unknown")])
19418
19419(define_insn "ldmxcsr"
19420  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
19421  "TARGET_MMX"
19422  "ldmxcsr\t%0"
19423  [(set_attr "type" "mmx")
19424   (set_attr "memory" "load")])
19425
19426(define_insn "stmxcsr"
19427  [(set (match_operand:SI 0 "memory_operand" "=m")
19428	(unspec_volatile:SI [(const_int 0)] 40))]
19429  "TARGET_MMX"
19430  "stmxcsr\t%0"
19431  [(set_attr "type" "mmx")
19432   (set_attr "memory" "store")])
19433
19434(define_expand "sfence"
19435  [(set (match_dup 0)
19436	(unspec:BLK [(match_dup 0)] 44))]
19437  "TARGET_SSE || TARGET_3DNOW_A"
19438{
19439  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19440  MEM_VOLATILE_P (operands[0]) = 1;
19441})
19442
19443(define_insn "*sfence_insn"
19444  [(set (match_operand:BLK 0 "" "")
19445	(unspec:BLK [(match_dup 0)] 44))]
19446  "TARGET_SSE || TARGET_3DNOW_A"
19447  "sfence"
19448  [(set_attr "type" "sse")
19449   (set_attr "memory" "unknown")])
19450
19451(define_expand "sse_prologue_save"
19452  [(parallel [(set (match_operand:BLK 0 "" "")
19453		   (unspec:BLK [(reg:DI 21)
19454				(reg:DI 22)
19455				(reg:DI 23)
19456				(reg:DI 24)
19457				(reg:DI 25)
19458				(reg:DI 26)
19459				(reg:DI 27)
19460				(reg:DI 28)] 13))
19461	      (use (match_operand:DI 1 "register_operand" ""))
19462	      (use (match_operand:DI 2 "immediate_operand" ""))
19463	      (use (label_ref:DI (match_operand 3 "" "")))])]
19464  "TARGET_64BIT"
19465  "")
19466
19467(define_insn "*sse_prologue_save_insn"
19468  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19469			  (match_operand:DI 4 "const_int_operand" "n")))
19470	(unspec:BLK [(reg:DI 21)
19471		     (reg:DI 22)
19472		     (reg:DI 23)
19473		     (reg:DI 24)
19474		     (reg:DI 25)
19475		     (reg:DI 26)
19476		     (reg:DI 27)
19477		     (reg:DI 28)] 13))
19478   (use (match_operand:DI 1 "register_operand" "r"))
19479   (use (match_operand:DI 2 "const_int_operand" "i"))
19480   (use (label_ref:DI (match_operand 3 "" "X")))]
19481  "TARGET_64BIT
19482   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19483   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19484  "*
19485{
19486  int i;
19487  operands[0] = gen_rtx_MEM (Pmode,
19488			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19489  output_asm_insn (\"jmp\\t%A1\", operands);
19490  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19491    {
19492      operands[4] = adjust_address (operands[0], DImode, i*16);
19493      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19494      PUT_MODE (operands[4], TImode);
19495      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19496        output_asm_insn (\"rex\", operands);
19497      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19498    }
19499  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19500			     CODE_LABEL_NUMBER (operands[3]));
19501  RET;
19502}
19503  "
19504  [(set_attr "type" "other")
19505   (set_attr "length_immediate" "0")
19506   (set_attr "length_address" "0")
19507   (set_attr "length" "135")
19508   (set_attr "memory" "store")
19509   (set_attr "modrm" "0")
19510   (set_attr "mode" "DI")])
19511
19512;; 3Dnow! instructions
19513
19514(define_insn "addv2sf3"
19515  [(set (match_operand:V2SF 0 "register_operand" "=y")
19516	(plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19517		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19518  "TARGET_3DNOW"
19519  "pfadd\\t{%2, %0|%0, %2}"
19520  [(set_attr "type" "mmx")])
19521
19522(define_insn "subv2sf3"
19523  [(set (match_operand:V2SF 0 "register_operand" "=y")
19524        (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19525		    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19526  "TARGET_3DNOW"
19527  "pfsub\\t{%2, %0|%0, %2}"
19528  [(set_attr "type" "mmx")])
19529
19530(define_insn "subrv2sf3"
19531  [(set (match_operand:V2SF 0 "register_operand" "=y")
19532        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19533                    (match_operand:V2SF 1 "register_operand" "0")))]
19534  "TARGET_3DNOW"
19535  "pfsubr\\t{%2, %0|%0, %2}"
19536  [(set_attr "type" "mmx")])
19537
19538(define_insn "gtv2sf3"
19539  [(set (match_operand:V2SI 0 "register_operand" "=y")
19540	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19541		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19542 "TARGET_3DNOW"
19543  "pfcmpgt\\t{%2, %0|%0, %2}"
19544  [(set_attr "type" "mmx")])
19545
19546(define_insn "gev2sf3"
19547  [(set (match_operand:V2SI 0 "register_operand" "=y")
19548	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19549		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19550  "TARGET_3DNOW"
19551  "pfcmpge\\t{%2, %0|%0, %2}"
19552  [(set_attr "type" "mmx")])
19553
19554(define_insn "eqv2sf3"
19555  [(set (match_operand:V2SI 0 "register_operand" "=y")
19556	(eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19557		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19558  "TARGET_3DNOW"
19559  "pfcmpeq\\t{%2, %0|%0, %2}"
19560  [(set_attr "type" "mmx")])
19561
19562(define_insn "pfmaxv2sf3"
19563  [(set (match_operand:V2SF 0 "register_operand" "=y")
19564        (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19565                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19566  "TARGET_3DNOW"
19567  "pfmax\\t{%2, %0|%0, %2}"
19568  [(set_attr "type" "mmx")])
19569
19570(define_insn "pfminv2sf3"
19571  [(set (match_operand:V2SF 0 "register_operand" "=y")
19572        (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19573                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19574  "TARGET_3DNOW"
19575  "pfmin\\t{%2, %0|%0, %2}"
19576  [(set_attr "type" "mmx")])
19577
19578(define_insn "mulv2sf3"
19579  [(set (match_operand:V2SF 0 "register_operand" "=y")
19580	(mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19581		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19582  "TARGET_3DNOW"
19583  "pfmul\\t{%2, %0|%0, %2}"
19584  [(set_attr "type" "mmx")])
19585
19586(define_insn "femms"
19587  [(unspec_volatile [(const_int 0)] 46)
19588   (clobber (reg:XF 8))
19589   (clobber (reg:XF 9))
19590   (clobber (reg:XF 10))
19591   (clobber (reg:XF 11))
19592   (clobber (reg:XF 12))
19593   (clobber (reg:XF 13))
19594   (clobber (reg:XF 14))
19595   (clobber (reg:XF 15))
19596   (clobber (reg:DI 29))
19597   (clobber (reg:DI 30))
19598   (clobber (reg:DI 31))
19599   (clobber (reg:DI 32))
19600   (clobber (reg:DI 33))
19601   (clobber (reg:DI 34))
19602   (clobber (reg:DI 35))
19603   (clobber (reg:DI 36))]
19604  "TARGET_3DNOW"
19605  "femms"
19606  [(set_attr "type" "mmx")])
19607
19608(define_insn "pf2id"
19609  [(set (match_operand:V2SI 0 "register_operand" "=y")
19610	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19611  "TARGET_3DNOW"
19612  "pf2id\\t{%1, %0|%0, %1}"
19613  [(set_attr "type" "mmx")])
19614
19615(define_insn "pf2iw"
19616  [(set (match_operand:V2SI 0 "register_operand" "=y")
19617	(sign_extend:V2SI
19618	   (ss_truncate:V2HI
19619	      (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19620  "TARGET_3DNOW_A"
19621  "pf2iw\\t{%1, %0|%0, %1}"
19622  [(set_attr "type" "mmx")])
19623
19624(define_insn "pfacc"
19625  [(set (match_operand:V2SF 0 "register_operand" "=y")
19626	(vec_concat:V2SF
19627	   (plus:SF
19628	      (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19629			     (parallel [(const_int  0)]))
19630	      (vec_select:SF (match_dup 1)
19631			     (parallel [(const_int 1)])))
19632           (plus:SF
19633              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19634			     (parallel [(const_int  0)]))
19635              (vec_select:SF (match_dup 2)
19636			     (parallel [(const_int 1)])))))]
19637  "TARGET_3DNOW"
19638  "pfacc\\t{%2, %0|%0, %2}"
19639  [(set_attr "type" "mmx")])
19640
19641(define_insn "pfnacc"
19642  [(set (match_operand:V2SF 0 "register_operand" "=y")
19643  	(vec_concat:V2SF
19644           (minus:SF
19645              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19646			     (parallel [(const_int 0)]))
19647              (vec_select:SF (match_dup 1)
19648			     (parallel [(const_int 1)])))
19649           (minus:SF
19650              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19651			     (parallel [(const_int  0)]))
19652              (vec_select:SF (match_dup 2)
19653			     (parallel [(const_int 1)])))))]
19654  "TARGET_3DNOW_A"
19655  "pfnacc\\t{%2, %0|%0, %2}"
19656  [(set_attr "type" "mmx")])
19657
19658(define_insn "pfpnacc"
19659  [(set (match_operand:V2SF 0 "register_operand" "=y")
19660        (vec_concat:V2SF
19661           (minus:SF
19662              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19663			     (parallel [(const_int 0)]))
19664              (vec_select:SF (match_dup 1)
19665			     (parallel [(const_int 1)])))
19666           (plus:SF
19667              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19668			     (parallel [(const_int 0)]))
19669              (vec_select:SF (match_dup 2)
19670			     (parallel [(const_int 1)])))))]
19671  "TARGET_3DNOW_A"
19672  "pfpnacc\\t{%2, %0|%0, %2}"
19673  [(set_attr "type" "mmx")])
19674
19675(define_insn "pi2fw"
19676  [(set (match_operand:V2SF 0 "register_operand" "=y")
19677	(float:V2SF
19678	   (vec_concat:V2SI
19679	      (sign_extend:SI
19680		 (truncate:HI
19681		    (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19682				   (parallel [(const_int 0)]))))
19683              (sign_extend:SI
19684		 (truncate:HI
19685                    (vec_select:SI (match_dup 1)
19686				   (parallel [(const_int  1)])))))))]
19687  "TARGET_3DNOW_A"
19688  "pi2fw\\t{%1, %0|%0, %1}"
19689  [(set_attr "type" "mmx")])
19690
19691(define_insn "floatv2si2"
19692  [(set (match_operand:V2SF 0 "register_operand" "=y")
19693	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19694  "TARGET_3DNOW"
19695  "pi2fd\\t{%1, %0|%0, %1}"
19696  [(set_attr "type" "mmx")])
19697
19698;; This insn is identical to pavgb in operation, but the opcode is
19699;; different.  To avoid accidentally matching pavgb, use an unspec.
19700
19701(define_insn "pavgusb"
19702 [(set (match_operand:V8QI 0 "register_operand" "=y")
19703       (unspec:V8QI
19704          [(match_operand:V8QI 1 "register_operand" "0")
19705           (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
19706  "TARGET_3DNOW"
19707  "pavgusb\\t{%2, %0|%0, %2}"
19708  [(set_attr "type" "mmx")])
19709
19710;; 3DNow reciprical and sqrt
19711 
19712(define_insn "pfrcpv2sf2"
19713  [(set (match_operand:V2SF 0 "register_operand" "=y")
19714        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
19715  "TARGET_3DNOW"
19716  "pfrcp\\t{%1, %0|%0, %1}"
19717  [(set_attr "type" "mmx")])
19718
19719(define_insn "pfrcpit1v2sf3"
19720  [(set (match_operand:V2SF 0 "register_operand" "=y")
19721	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19722		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
19723  "TARGET_3DNOW"
19724  "pfrcpit1\\t{%2, %0|%0, %2}"
19725  [(set_attr "type" "mmx")])
19726
19727(define_insn "pfrcpit2v2sf3"
19728  [(set (match_operand:V2SF 0 "register_operand" "=y")
19729	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19730		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
19731  "TARGET_3DNOW"
19732  "pfrcpit2\\t{%2, %0|%0, %2}"
19733  [(set_attr "type" "mmx")])
19734
19735(define_insn "pfrsqrtv2sf2"
19736  [(set (match_operand:V2SF 0 "register_operand" "=y")
19737	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
19738  "TARGET_3DNOW"
19739   "pfrsqrt\\t{%1, %0|%0, %1}"
19740   [(set_attr "type" "mmx")])
19741		
19742(define_insn "pfrsqit1v2sf3"
19743  [(set (match_operand:V2SF 0 "register_operand" "=y")
19744	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19745		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
19746  "TARGET_3DNOW"
19747  "pfrsqit1\\t{%2, %0|%0, %2}"
19748  [(set_attr "type" "mmx")])
19749
19750(define_insn "pmulhrwv4hi3"
19751  [(set (match_operand:V4HI 0 "register_operand" "=y")
19752	(truncate:V4HI
19753	   (lshiftrt:V4SI
19754	      (plus:V4SI
19755	         (mult:V4SI
19756	            (sign_extend:V4SI
19757		       (match_operand:V4HI 1 "register_operand" "0"))
19758	            (sign_extend:V4SI
19759		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19760		 (const_vector:V4SI [(const_int 32768)
19761				     (const_int 32768)
19762				     (const_int 32768)
19763				     (const_int 32768)]))
19764	      (const_int 16))))]
19765  "TARGET_3DNOW"
19766  "pmulhrw\\t{%2, %0|%0, %2}"
19767  [(set_attr "type" "mmx")])
19768
19769(define_insn "pswapdv2si2"
19770  [(set (match_operand:V2SI 0 "register_operand" "=y")
19771	(vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19772			 (parallel [(const_int 1) (const_int 0)])))]
19773  "TARGET_3DNOW_A"
19774  "pswapd\\t{%1, %0|%0, %1}"
19775  [(set_attr "type" "mmx")])
19776
19777(define_insn "pswapdv2sf2"
19778  [(set (match_operand:V2SF 0 "register_operand" "=y")
19779	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19780			 (parallel [(const_int 1) (const_int 0)])))]
19781  "TARGET_3DNOW_A"
19782  "pswapd\\t{%1, %0|%0, %1}"
19783  [(set_attr "type" "mmx")])
19784
19785(define_expand "prefetch"
19786  [(prefetch (match_operand 0 "address_operand" "")
19787	     (match_operand:SI 1 "const_int_operand" "")
19788	     (match_operand:SI 2 "const_int_operand" ""))]
19789  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19790{
19791  int rw = INTVAL (operands[1]);
19792  int locality = INTVAL (operands[2]);
19793
19794  if (rw != 0 && rw != 1)
19795    abort ();
19796  if (locality < 0 || locality > 3)
19797    abort ();
19798  if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19799    abort ();
19800
19801  /* Use 3dNOW prefetch in case we are asking for write prefetch not
19802     suported by SSE counterpart or the SSE prefetch is not available
19803     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19804     of locality.  */
19805  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19806    operands[2] = GEN_INT (3);
19807  else
19808    operands[1] = const0_rtx;
19809})
19810
19811(define_insn "*prefetch_sse"
19812  [(prefetch (match_operand:SI 0 "address_operand" "p")
19813	     (const_int 0)
19814	     (match_operand:SI 1 "const_int_operand" ""))]
19815  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19816{
19817  static const char * const patterns[4] = {
19818   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19819  };
19820
19821  int locality = INTVAL (operands[1]);
19822  if (locality < 0 || locality > 3)
19823    abort ();
19824
19825  return patterns[locality];  
19826}
19827  [(set_attr "type" "sse")
19828   (set_attr "memory" "none")])
19829
19830(define_insn "*prefetch_sse_rex"
19831  [(prefetch (match_operand:DI 0 "address_operand" "p")
19832	     (const_int 0)
19833	     (match_operand:SI 1 "const_int_operand" ""))]
19834  "TARGET_PREFETCH_SSE && TARGET_64BIT"
19835{
19836  static const char * const patterns[4] = {
19837   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19838  };
19839
19840  int locality = INTVAL (operands[1]);
19841  if (locality < 0 || locality > 3)
19842    abort ();
19843
19844  return patterns[locality];  
19845}
19846  [(set_attr "type" "sse")])
19847
19848(define_insn "*prefetch_3dnow"
19849  [(prefetch (match_operand:SI 0 "address_operand" "p")
19850	     (match_operand:SI 1 "const_int_operand" "n")
19851	     (const_int 3))]
19852  "TARGET_3DNOW && !TARGET_64BIT"
19853{
19854  if (INTVAL (operands[1]) == 0)
19855    return "prefetch\t%a0";
19856  else
19857    return "prefetchw\t%a0";
19858}
19859  [(set_attr "type" "mmx")
19860   (set_attr "memory" "none")])
19861
19862(define_insn "*prefetch_3dnow_rex"
19863  [(prefetch (match_operand:DI 0 "address_operand" "p")
19864	     (match_operand:SI 1 "const_int_operand" "n")
19865	     (const_int 3))]
19866  "TARGET_3DNOW && TARGET_64BIT"
19867{
19868  if (INTVAL (operands[1]) == 0)
19869    return "prefetch\t%a0";
19870  else
19871    return "prefetchw\t%a0";
19872}
19873  [(set_attr "type" "mmx")])
19874