1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3;; 2001, 2002, 2003, 2004, 2005
4;; Free Software Foundation, Inc.
5;; Mostly by William Schelter.
6;; x86_64 support added by Jan Hubicka
7;;
8;; This file is part of GCC.
9;;
10;; GCC is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14;;
15;; GCC is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18;; GNU General Public License for more details.
19;;
20;; You should have received a copy of the GNU General Public License
21;; along with GCC; see the file COPYING.  If not, write to
22;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23;; Boston, MA 02110-1301, USA.  */
24;;
25;; The original PO technology requires these to be ordered by speed,
26;; so that assigner will pick the fastest.
27;;
28;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29;;
30;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31;; constraint letters.
32;;
33;; The special asm out single letter directives following a '%' are:
34;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35;;     operands[1].
36;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40;; 'S' Print the opcode suffix for a 32-bit float opcode.
41;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42;; 'J' Print the appropriate jump operand.
43;;
44;; 'b' Print the QImode name of the register for the indicated operand.
45;;     %b0 would print %al if operands[0] is reg 0.
46;; 'w' Likewise, print the HImode name of the register.
47;; 'k' Likewise, print the SImode name of the register.
48;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49;; 'y' Print "st(0)" instead of "st" as a register.
50
51;; UNSPEC usage:
52
53(define_constants
54  [; Relocation specifiers
55   (UNSPEC_GOT			0)
56   (UNSPEC_GOTOFF		1)
57   (UNSPEC_GOTPCREL		2)
58   (UNSPEC_GOTTPOFF		3)
59   (UNSPEC_TPOFF		4)
60   (UNSPEC_NTPOFF		5)
61   (UNSPEC_DTPOFF		6)
62   (UNSPEC_GOTNTPOFF		7)
63   (UNSPEC_INDNTPOFF		8)
64
65   ; Prologue support
66   (UNSPEC_STACK_ALLOC		11)
67   (UNSPEC_SET_GOT		12)
68   (UNSPEC_SSE_PROLOGUE_SAVE	13)
69   (UNSPEC_REG_SAVE		14)
70   (UNSPEC_DEF_CFA		15)
71
72   ; TLS support
73   (UNSPEC_TP			16)
74   (UNSPEC_TLS_GD		17)
75   (UNSPEC_TLS_LD_BASE		18)
76
77   ; Other random patterns
78   (UNSPEC_SCAS			20)
79   (UNSPEC_FNSTSW		21)
80   (UNSPEC_SAHF			22)
81   (UNSPEC_FSTCW		23)
82   (UNSPEC_ADD_CARRY		24)
83   (UNSPEC_FLDCW		25)
84   (UNSPEC_REP			26)
85   (UNSPEC_EH_RETURN		27)
86
87   ; For SSE/MMX support:
88   (UNSPEC_FIX_NOTRUNC		30)
89   (UNSPEC_MASKMOV		31)
90   (UNSPEC_MOVMSK		32)
91   (UNSPEC_MOVNT		33)
92   (UNSPEC_MOVU			34)
93   (UNSPEC_RCP			35)
94   (UNSPEC_RSQRT		36)
95   (UNSPEC_SFENCE		37)
96   (UNSPEC_NOP			38)	; prevents combiner cleverness
97   (UNSPEC_PFRCP		39)
98   (UNSPEC_PFRCPIT1		40)
99   (UNSPEC_PFRCPIT2		41)
100   (UNSPEC_PFRSQRT		42)
101   (UNSPEC_PFRSQIT1		43)
102   (UNSPEC_MFENCE		44)
103   (UNSPEC_LFENCE		45)
104   (UNSPEC_PSADBW		46)
105   (UNSPEC_LDQQU		47)
106
107   ; Generic math support
108   (UNSPEC_COPYSIGN		50)
109   (UNSPEC_IEEE_MIN		51)	; not commutative
110   (UNSPEC_IEEE_MAX		52)	; not commutative
111
112   ; x87 Floating point
113   (UNSPEC_SIN			60)
114   (UNSPEC_COS			61)
115   (UNSPEC_FPATAN		62)
116   (UNSPEC_FYL2X		63)
117   (UNSPEC_FYL2XP1		64)
118   (UNSPEC_FRNDINT		65)
119   (UNSPEC_FIST			66)
120   (UNSPEC_F2XM1		67)
121
122   ; x87 Rounding
123   (UNSPEC_FRNDINT_FLOOR	70)
124   (UNSPEC_FRNDINT_CEIL 	71)
125   (UNSPEC_FRNDINT_TRUNC	72)
126   (UNSPEC_FRNDINT_MASK_PM	73)
127   (UNSPEC_FIST_FLOOR		74)
128   (UNSPEC_FIST_CEIL 		75)
129
130   ; x87 Double output FP
131   (UNSPEC_SINCOS_COS		80)
132   (UNSPEC_SINCOS_SIN		81)
133   (UNSPEC_TAN_ONE		82)
134   (UNSPEC_TAN_TAN		83)
135   (UNSPEC_XTRACT_FRACT		84)
136   (UNSPEC_XTRACT_EXP		85)
137   (UNSPEC_FSCALE_FRACT		86)
138   (UNSPEC_FSCALE_EXP		87)
139   (UNSPEC_FPREM_F		88)
140   (UNSPEC_FPREM_U		89)
141   (UNSPEC_FPREM1_F		90)
142   (UNSPEC_FPREM1_U		91)
143
144   ; SSP patterns
145   (UNSPEC_SP_SET		100)
146   (UNSPEC_SP_TEST		101)
147   (UNSPEC_SP_TLS_SET		102)
148   (UNSPEC_SP_TLS_TEST		103)
149  ])
150
151(define_constants
152  [(UNSPECV_BLOCKAGE		0)
153   (UNSPECV_STACK_PROBE		1)
154   (UNSPECV_EMMS		2)
155   (UNSPECV_LDMXCSR		3)
156   (UNSPECV_STMXCSR		4)
157   (UNSPECV_FEMMS		5)
158   (UNSPECV_CLFLUSH		6)
159   (UNSPECV_ALIGN		7)
160   (UNSPECV_MONITOR		8)
161   (UNSPECV_MWAIT		9)
162   (UNSPECV_CMPXCHG_1		10)
163   (UNSPECV_CMPXCHG_2		11)
164   (UNSPECV_XCHG		12)
165   (UNSPECV_LOCK		13)
166  ])
167
168;; Registers by name.
169(define_constants
170  [(BP_REG			 6)
171   (SP_REG			 7)
172   (FLAGS_REG			17)
173   (FPSR_REG			18)
174   (DIRFLAG_REG			19)
175  ])
176
177;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
178;; from i386.c.
179
180;; In C guard expressions, put expressions which may be compile-time
181;; constants first.  This allows for better optimization.  For
182;; example, write "TARGET_64BIT && reload_completed", not
183;; "reload_completed && TARGET_64BIT".
184
185
186;; Processor type.  This attribute must exactly match the processor_type
187;; enumeration in i386.h.
188(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189  (const (symbol_ref "ix86_tune")))
190
191;; A basic instruction type.  Refinements due to arguments to be
192;; provided in other attributes.
193(define_attr "type"
194  "other,multi,
195   alu,alu1,negnot,imov,imovx,lea,
196   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197   icmp,test,ibr,setcc,icmov,
198   push,pop,call,callv,leave,
199   str,cld,
200   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201   sselog,sselog1,sseiadd,sseishft,sseimul,
202   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204  (const_string "other"))
205
206;; Main data type used by the insn
207(define_attr "mode"
208  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209  (const_string "unknown"))
210
211;; The CPU unit operations uses.
212(define_attr "unit" "integer,i387,sse,mmx,unknown"
213  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214	   (const_string "i387")
215	 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
217	   (const_string "sse")
218	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
219	   (const_string "mmx")
220	 (eq_attr "type" "other")
221	   (const_string "unknown")]
222	 (const_string "integer")))
223
224;; The (bounding maximum) length of an instruction immediate.
225(define_attr "length_immediate" ""
226  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
227	   (const_int 0)
228	 (eq_attr "unit" "i387,sse,mmx")
229	   (const_int 0)
230	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
231			  imul,icmp,push,pop")
232	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233	 (eq_attr "type" "imov,test")
234	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235	 (eq_attr "type" "call")
236	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
237	     (const_int 4)
238	     (const_int 0))
239	 (eq_attr "type" "callv")
240	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
241	     (const_int 4)
242	     (const_int 0))
243	 ;; We don't know the size before shorten_branches.  Expect
244	 ;; the instruction to fit for better scheduling.
245	 (eq_attr "type" "ibr")
246	   (const_int 1)
247	 ]
248	 (symbol_ref "/* Update immediate_length and other attributes! */
249		      gcc_unreachable (),1")))
250
251;; The (bounding maximum) length of an instruction address.
252(define_attr "length_address" ""
253  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
254	   (const_int 0)
255	 (and (eq_attr "type" "call")
256	      (match_operand 0 "constant_call_address_operand" ""))
257	     (const_int 0)
258	 (and (eq_attr "type" "callv")
259	      (match_operand 1 "constant_call_address_operand" ""))
260	     (const_int 0)
261	 ]
262	 (symbol_ref "ix86_attr_length_address_default (insn)")))
263
264;; Set when length prefix is used.
265(define_attr "prefix_data16" ""
266  (if_then_else (ior (eq_attr "mode" "HI")
267		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
268    (const_int 1)
269    (const_int 0)))
270
271;; Set when string REP prefix is used.
272(define_attr "prefix_rep" "" 
273  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
274    (const_int 1)
275    (const_int 0)))
276
277;; Set when 0f opcode prefix is used.
278(define_attr "prefix_0f" ""
279  (if_then_else 
280    (ior (eq_attr "type" "imovx,setcc,icmov")
281	 (eq_attr "unit" "sse,mmx"))
282    (const_int 1)
283    (const_int 0)))
284
285;; Set when REX opcode prefix is used.
286(define_attr "prefix_rex" ""
287  (cond [(and (eq_attr "mode" "DI")
288  	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
289	   (const_int 1)
290	 (and (eq_attr "mode" "QI")
291	      (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
292		  (const_int 0)))
293	   (const_int 1)
294	 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
295	     (const_int 0))
296	   (const_int 1)
297	]
298	(const_int 0)))
299
300;; Set when modrm byte is used.
301(define_attr "modrm" ""
302  (cond [(eq_attr "type" "str,cld,leave")
303	   (const_int 0)
304	 (eq_attr "unit" "i387")
305	   (const_int 0)
306         (and (eq_attr "type" "incdec")
307	      (ior (match_operand:SI 1 "register_operand" "")
308		   (match_operand:HI 1 "register_operand" "")))
309	   (const_int 0)
310	 (and (eq_attr "type" "push")
311	      (not (match_operand 1 "memory_operand" "")))
312	   (const_int 0)
313	 (and (eq_attr "type" "pop")
314	      (not (match_operand 0 "memory_operand" "")))
315	   (const_int 0)
316	 (and (eq_attr "type" "imov")
317	      (and (match_operand 0 "register_operand" "")
318	           (match_operand 1 "immediate_operand" "")))
319	   (const_int 0)
320	 (and (eq_attr "type" "call")
321	      (match_operand 0 "constant_call_address_operand" ""))
322	     (const_int 0)
323	 (and (eq_attr "type" "callv")
324	      (match_operand 1 "constant_call_address_operand" ""))
325	     (const_int 0)
326	 ]
327	 (const_int 1)))
328
329;; The (bounding maximum) length of an instruction in bytes.
330;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
331;; Later we may want to split them and compute proper length as for
332;; other insns.
333(define_attr "length" ""
334  (cond [(eq_attr "type" "other,multi,fistp,frndint")
335	   (const_int 16)
336	 (eq_attr "type" "fcmp")
337	   (const_int 4)
338	 (eq_attr "unit" "i387")
339	   (plus (const_int 2)
340		 (plus (attr "prefix_data16")
341		       (attr "length_address")))]
342	 (plus (plus (attr "modrm")
343		     (plus (attr "prefix_0f")
344			   (plus (attr "prefix_rex")
345				 (const_int 1))))
346	       (plus (attr "prefix_rep")
347		     (plus (attr "prefix_data16")
348			   (plus (attr "length_immediate")
349				 (attr "length_address")))))))
350
351;; The `memory' attribute is `none' if no memory is referenced, `load' or
352;; `store' if there is a simple memory reference therein, or `unknown'
353;; if the instruction is complex.
354
355(define_attr "memory" "none,load,store,both,unknown"
356  (cond [(eq_attr "type" "other,multi,str")
357	   (const_string "unknown")
358	 (eq_attr "type" "lea,fcmov,fpspc,cld")
359	   (const_string "none")
360	 (eq_attr "type" "fistp,leave")
361	   (const_string "both")
362	 (eq_attr "type" "frndint")
363	   (const_string "load")
364	 (eq_attr "type" "push")
365	   (if_then_else (match_operand 1 "memory_operand" "")
366	     (const_string "both")
367	     (const_string "store"))
368	 (eq_attr "type" "pop")
369	   (if_then_else (match_operand 0 "memory_operand" "")
370	     (const_string "both")
371	     (const_string "load"))
372	 (eq_attr "type" "setcc")
373	   (if_then_else (match_operand 0 "memory_operand" "")
374	     (const_string "store")
375	     (const_string "none"))
376	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
377	   (if_then_else (ior (match_operand 0 "memory_operand" "")
378			      (match_operand 1 "memory_operand" ""))
379	     (const_string "load")
380	     (const_string "none"))
381	 (eq_attr "type" "ibr")
382	   (if_then_else (match_operand 0 "memory_operand" "")
383	     (const_string "load")
384	     (const_string "none"))
385	 (eq_attr "type" "call")
386	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
387	     (const_string "none")
388	     (const_string "load"))
389	 (eq_attr "type" "callv")
390	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
391	     (const_string "none")
392	     (const_string "load"))
393	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
394	      (match_operand 1 "memory_operand" ""))
395	   (const_string "both")
396	 (and (match_operand 0 "memory_operand" "")
397	      (match_operand 1 "memory_operand" ""))
398	   (const_string "both")
399	 (match_operand 0 "memory_operand" "")
400	   (const_string "store")
401	 (match_operand 1 "memory_operand" "")
402	   (const_string "load")
403	 (and (eq_attr "type"
404		 "!alu1,negnot,ishift1,
405		   imov,imovx,icmp,test,
406		   fmov,fcmp,fsgn,
407		   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
408		   mmx,mmxmov,mmxcmp,mmxcvt")
409	      (match_operand 2 "memory_operand" ""))
410	   (const_string "load")
411	 (and (eq_attr "type" "icmov")
412	      (match_operand 3 "memory_operand" ""))
413	   (const_string "load")
414	]
415	(const_string "none")))
416
417;; Indicates if an instruction has both an immediate and a displacement.
418
419(define_attr "imm_disp" "false,true,unknown"
420  (cond [(eq_attr "type" "other,multi")
421	   (const_string "unknown")
422	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
423	      (and (match_operand 0 "memory_displacement_operand" "")
424		   (match_operand 1 "immediate_operand" "")))
425	   (const_string "true")
426	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
427	      (and (match_operand 0 "memory_displacement_operand" "")
428		   (match_operand 2 "immediate_operand" "")))
429	   (const_string "true")
430	]
431	(const_string "false")))
432
433;; Indicates if an FP operation has an integer source.
434
435(define_attr "fp_int_src" "false,true"
436  (const_string "false"))
437
438;; Defines rounding mode of an FP operation.
439
440(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
441  (const_string "any"))
442
443;; Describe a user's asm statement.
444(define_asm_attributes
445  [(set_attr "length" "128")
446   (set_attr "type" "multi")])
447
448;; All x87 floating point modes
449(define_mode_macro X87MODEF [SF DF XF])
450 
451;; All integer modes handled by x87 fisttp operator.
452(define_mode_macro X87MODEI [HI SI DI])
453
454;; All integer modes handled by integer x87 operators.
455(define_mode_macro X87MODEI12 [HI SI])
456
457;; All SSE floating point modes
458(define_mode_macro SSEMODEF [SF DF])
459 
460;; All integer modes handled by SSE cvtts?2si* operators.
461(define_mode_macro SSEMODEI24 [SI DI])
462
463
464;; Scheduling descriptions
465
466(include "pentium.md")
467(include "ppro.md")
468(include "k6.md")
469(include "athlon.md")
470
471
472;; Operand and operator predicates
473
474(include "predicates.md")
475
476
477;; Compare instructions.
478
479;; All compare insns have expanders that save the operands away without
480;; actually generating RTL.  The bCOND or sCOND (emitted immediately
481;; after the cmp) will actually emit the cmpM.
482
483(define_expand "cmpti"
484  [(set (reg:CC FLAGS_REG)
485	(compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
486		    (match_operand:TI 1 "x86_64_general_operand" "")))]
487  "TARGET_64BIT"
488{
489  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
490    operands[0] = force_reg (TImode, operands[0]);
491  ix86_compare_op0 = operands[0];
492  ix86_compare_op1 = operands[1];
493  DONE;
494})
495
496(define_expand "cmpdi"
497  [(set (reg:CC FLAGS_REG)
498	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
499		    (match_operand:DI 1 "x86_64_general_operand" "")))]
500  ""
501{
502  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503    operands[0] = force_reg (DImode, operands[0]);
504  ix86_compare_op0 = operands[0];
505  ix86_compare_op1 = operands[1];
506  DONE;
507})
508
509(define_expand "cmpsi"
510  [(set (reg:CC FLAGS_REG)
511	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
512		    (match_operand:SI 1 "general_operand" "")))]
513  ""
514{
515  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516    operands[0] = force_reg (SImode, operands[0]);
517  ix86_compare_op0 = operands[0];
518  ix86_compare_op1 = operands[1];
519  DONE;
520})
521
522(define_expand "cmphi"
523  [(set (reg:CC FLAGS_REG)
524	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
525		    (match_operand:HI 1 "general_operand" "")))]
526  ""
527{
528  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529    operands[0] = force_reg (HImode, operands[0]);
530  ix86_compare_op0 = operands[0];
531  ix86_compare_op1 = operands[1];
532  DONE;
533})
534
535(define_expand "cmpqi"
536  [(set (reg:CC FLAGS_REG)
537	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
538		    (match_operand:QI 1 "general_operand" "")))]
539  "TARGET_QIMODE_MATH"
540{
541  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542    operands[0] = force_reg (QImode, operands[0]);
543  ix86_compare_op0 = operands[0];
544  ix86_compare_op1 = operands[1];
545  DONE;
546})
547
548(define_insn "cmpdi_ccno_1_rex64"
549  [(set (reg FLAGS_REG)
550	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
551		 (match_operand:DI 1 "const0_operand" "n,n")))]
552  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
553  "@
554   test{q}\t{%0, %0|%0, %0}
555   cmp{q}\t{%1, %0|%0, %1}"
556  [(set_attr "type" "test,icmp")
557   (set_attr "length_immediate" "0,1")
558   (set_attr "mode" "DI")])
559
560(define_insn "*cmpdi_minus_1_rex64"
561  [(set (reg FLAGS_REG)
562	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
563			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
564		 (const_int 0)))]
565  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
566  "cmp{q}\t{%1, %0|%0, %1}"
567  [(set_attr "type" "icmp")
568   (set_attr "mode" "DI")])
569
570(define_expand "cmpdi_1_rex64"
571  [(set (reg:CC FLAGS_REG)
572	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
573		    (match_operand:DI 1 "general_operand" "")))]
574  "TARGET_64BIT"
575  "")
576
577(define_insn "cmpdi_1_insn_rex64"
578  [(set (reg FLAGS_REG)
579	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
580		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
581  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
582  "cmp{q}\t{%1, %0|%0, %1}"
583  [(set_attr "type" "icmp")
584   (set_attr "mode" "DI")])
585
586
587(define_insn "*cmpsi_ccno_1"
588  [(set (reg FLAGS_REG)
589	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
590		 (match_operand:SI 1 "const0_operand" "n,n")))]
591  "ix86_match_ccmode (insn, CCNOmode)"
592  "@
593   test{l}\t{%0, %0|%0, %0}
594   cmp{l}\t{%1, %0|%0, %1}"
595  [(set_attr "type" "test,icmp")
596   (set_attr "length_immediate" "0,1")
597   (set_attr "mode" "SI")])
598
599(define_insn "*cmpsi_minus_1"
600  [(set (reg FLAGS_REG)
601	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
602			   (match_operand:SI 1 "general_operand" "ri,mr"))
603		 (const_int 0)))]
604  "ix86_match_ccmode (insn, CCGOCmode)"
605  "cmp{l}\t{%1, %0|%0, %1}"
606  [(set_attr "type" "icmp")
607   (set_attr "mode" "SI")])
608
609(define_expand "cmpsi_1"
610  [(set (reg:CC FLAGS_REG)
611	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
612		    (match_operand:SI 1 "general_operand" "ri,mr")))]
613  ""
614  "")
615
616(define_insn "*cmpsi_1_insn"
617  [(set (reg FLAGS_REG)
618	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619		 (match_operand:SI 1 "general_operand" "ri,mr")))]
620  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
621    && ix86_match_ccmode (insn, CCmode)"
622  "cmp{l}\t{%1, %0|%0, %1}"
623  [(set_attr "type" "icmp")
624   (set_attr "mode" "SI")])
625
626(define_insn "*cmphi_ccno_1"
627  [(set (reg FLAGS_REG)
628	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
629		 (match_operand:HI 1 "const0_operand" "n,n")))]
630  "ix86_match_ccmode (insn, CCNOmode)"
631  "@
632   test{w}\t{%0, %0|%0, %0}
633   cmp{w}\t{%1, %0|%0, %1}"
634  [(set_attr "type" "test,icmp")
635   (set_attr "length_immediate" "0,1")
636   (set_attr "mode" "HI")])
637
638(define_insn "*cmphi_minus_1"
639  [(set (reg FLAGS_REG)
640	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
641			   (match_operand:HI 1 "general_operand" "ri,mr"))
642		 (const_int 0)))]
643  "ix86_match_ccmode (insn, CCGOCmode)"
644  "cmp{w}\t{%1, %0|%0, %1}"
645  [(set_attr "type" "icmp")
646   (set_attr "mode" "HI")])
647
648(define_insn "*cmphi_1"
649  [(set (reg FLAGS_REG)
650	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
651		 (match_operand:HI 1 "general_operand" "ri,mr")))]
652  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
653   && ix86_match_ccmode (insn, CCmode)"
654  "cmp{w}\t{%1, %0|%0, %1}"
655  [(set_attr "type" "icmp")
656   (set_attr "mode" "HI")])
657
658(define_insn "*cmpqi_ccno_1"
659  [(set (reg FLAGS_REG)
660	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
661		 (match_operand:QI 1 "const0_operand" "n,n")))]
662  "ix86_match_ccmode (insn, CCNOmode)"
663  "@
664   test{b}\t{%0, %0|%0, %0}
665   cmp{b}\t{$0, %0|%0, 0}"
666  [(set_attr "type" "test,icmp")
667   (set_attr "length_immediate" "0,1")
668   (set_attr "mode" "QI")])
669
670(define_insn "*cmpqi_1"
671  [(set (reg FLAGS_REG)
672	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
673		 (match_operand:QI 1 "general_operand" "qi,mq")))]
674  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675    && ix86_match_ccmode (insn, CCmode)"
676  "cmp{b}\t{%1, %0|%0, %1}"
677  [(set_attr "type" "icmp")
678   (set_attr "mode" "QI")])
679
680(define_insn "*cmpqi_minus_1"
681  [(set (reg FLAGS_REG)
682	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
683			   (match_operand:QI 1 "general_operand" "qi,mq"))
684		 (const_int 0)))]
685  "ix86_match_ccmode (insn, CCGOCmode)"
686  "cmp{b}\t{%1, %0|%0, %1}"
687  [(set_attr "type" "icmp")
688   (set_attr "mode" "QI")])
689
690(define_insn "*cmpqi_ext_1"
691  [(set (reg FLAGS_REG)
692	(compare
693	  (match_operand:QI 0 "general_operand" "Qm")
694	  (subreg:QI
695	    (zero_extract:SI
696	      (match_operand 1 "ext_register_operand" "Q")
697	      (const_int 8)
698	      (const_int 8)) 0)))]
699  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
700  "cmp{b}\t{%h1, %0|%0, %h1}"
701  [(set_attr "type" "icmp")
702   (set_attr "mode" "QI")])
703
704(define_insn "*cmpqi_ext_1_rex64"
705  [(set (reg FLAGS_REG)
706	(compare
707	  (match_operand:QI 0 "register_operand" "Q")
708	  (subreg:QI
709	    (zero_extract:SI
710	      (match_operand 1 "ext_register_operand" "Q")
711	      (const_int 8)
712	      (const_int 8)) 0)))]
713  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
714  "cmp{b}\t{%h1, %0|%0, %h1}"
715  [(set_attr "type" "icmp")
716   (set_attr "mode" "QI")])
717
718(define_insn "*cmpqi_ext_2"
719  [(set (reg FLAGS_REG)
720	(compare
721	  (subreg:QI
722	    (zero_extract:SI
723	      (match_operand 0 "ext_register_operand" "Q")
724	      (const_int 8)
725	      (const_int 8)) 0)
726	  (match_operand:QI 1 "const0_operand" "n")))]
727  "ix86_match_ccmode (insn, CCNOmode)"
728  "test{b}\t%h0, %h0"
729  [(set_attr "type" "test")
730   (set_attr "length_immediate" "0")
731   (set_attr "mode" "QI")])
732
733(define_expand "cmpqi_ext_3"
734  [(set (reg:CC FLAGS_REG)
735	(compare:CC
736	  (subreg:QI
737	    (zero_extract:SI
738	      (match_operand 0 "ext_register_operand" "")
739	      (const_int 8)
740	      (const_int 8)) 0)
741	  (match_operand:QI 1 "general_operand" "")))]
742  ""
743  "")
744
745(define_insn "cmpqi_ext_3_insn"
746  [(set (reg FLAGS_REG)
747	(compare
748	  (subreg:QI
749	    (zero_extract:SI
750	      (match_operand 0 "ext_register_operand" "Q")
751	      (const_int 8)
752	      (const_int 8)) 0)
753	  (match_operand:QI 1 "general_operand" "Qmn")))]
754  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
755  "cmp{b}\t{%1, %h0|%h0, %1}"
756  [(set_attr "type" "icmp")
757   (set_attr "mode" "QI")])
758
759(define_insn "cmpqi_ext_3_insn_rex64"
760  [(set (reg FLAGS_REG)
761	(compare
762	  (subreg:QI
763	    (zero_extract:SI
764	      (match_operand 0 "ext_register_operand" "Q")
765	      (const_int 8)
766	      (const_int 8)) 0)
767	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
768  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
769  "cmp{b}\t{%1, %h0|%h0, %1}"
770  [(set_attr "type" "icmp")
771   (set_attr "mode" "QI")])
772
773(define_insn "*cmpqi_ext_4"
774  [(set (reg FLAGS_REG)
775	(compare
776	  (subreg:QI
777	    (zero_extract:SI
778	      (match_operand 0 "ext_register_operand" "Q")
779	      (const_int 8)
780	      (const_int 8)) 0)
781	  (subreg:QI
782	    (zero_extract:SI
783	      (match_operand 1 "ext_register_operand" "Q")
784	      (const_int 8)
785	      (const_int 8)) 0)))]
786  "ix86_match_ccmode (insn, CCmode)"
787  "cmp{b}\t{%h1, %h0|%h0, %h1}"
788  [(set_attr "type" "icmp")
789   (set_attr "mode" "QI")])
790
791;; These implement float point compares.
792;; %%% See if we can get away with VOIDmode operands on the actual insns,
793;; which would allow mix and match FP modes on the compares.  Which is what
794;; the old patterns did, but with many more of them.
795
796(define_expand "cmpxf"
797  [(set (reg:CC FLAGS_REG)
798	(compare:CC (match_operand:XF 0 "nonmemory_operand" "")
799		    (match_operand:XF 1 "nonmemory_operand" "")))]
800  "TARGET_80387"
801{
802  ix86_compare_op0 = operands[0];
803  ix86_compare_op1 = operands[1];
804  DONE;
805})
806
807(define_expand "cmpdf"
808  [(set (reg:CC FLAGS_REG)
809	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
810		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
811  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
812{
813  ix86_compare_op0 = operands[0];
814  ix86_compare_op1 = operands[1];
815  DONE;
816})
817
818(define_expand "cmpsf"
819  [(set (reg:CC FLAGS_REG)
820	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
821		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
822  "TARGET_80387 || TARGET_SSE_MATH"
823{
824  ix86_compare_op0 = operands[0];
825  ix86_compare_op1 = operands[1];
826  DONE;
827})
828
829;; FP compares, step 1:
830;; Set the FP condition codes.
831;;
832;; CCFPmode	compare with exceptions
833;; CCFPUmode	compare with no exceptions
834
835;; We may not use "#" to split and emit these, since the REG_DEAD notes
836;; used to manage the reg stack popping would not be preserved.
837
838(define_insn "*cmpfp_0"
839  [(set (match_operand:HI 0 "register_operand" "=a")
840	(unspec:HI
841	  [(compare:CCFP
842	     (match_operand 1 "register_operand" "f")
843	     (match_operand 2 "const0_operand" "X"))]
844	UNSPEC_FNSTSW))]
845  "TARGET_80387
846   && FLOAT_MODE_P (GET_MODE (operands[1]))
847   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
848  "* return output_fp_compare (insn, operands, 0, 0);"
849  [(set_attr "type" "multi")
850   (set_attr "unit" "i387")
851   (set (attr "mode")
852     (cond [(match_operand:SF 1 "" "")
853	      (const_string "SF")
854	    (match_operand:DF 1 "" "")
855	      (const_string "DF")
856	   ]
857	   (const_string "XF")))])
858
859(define_insn "*cmpfp_sf"
860  [(set (match_operand:HI 0 "register_operand" "=a")
861	(unspec:HI
862	  [(compare:CCFP
863	     (match_operand:SF 1 "register_operand" "f")
864	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
865	  UNSPEC_FNSTSW))]
866  "TARGET_80387"
867  "* return output_fp_compare (insn, operands, 0, 0);"
868  [(set_attr "type" "multi")
869   (set_attr "unit" "i387")
870   (set_attr "mode" "SF")])
871
872(define_insn "*cmpfp_df"
873  [(set (match_operand:HI 0 "register_operand" "=a")
874	(unspec:HI
875	  [(compare:CCFP
876	     (match_operand:DF 1 "register_operand" "f")
877	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
878	  UNSPEC_FNSTSW))]
879  "TARGET_80387"
880  "* return output_fp_compare (insn, operands, 0, 0);"
881  [(set_attr "type" "multi")
882   (set_attr "unit" "i387")
883   (set_attr "mode" "DF")])
884
885(define_insn "*cmpfp_xf"
886  [(set (match_operand:HI 0 "register_operand" "=a")
887	(unspec:HI
888	  [(compare:CCFP
889	     (match_operand:XF 1 "register_operand" "f")
890	     (match_operand:XF 2 "register_operand" "f"))]
891	  UNSPEC_FNSTSW))]
892  "TARGET_80387"
893  "* return output_fp_compare (insn, operands, 0, 0);"
894  [(set_attr "type" "multi")
895   (set_attr "unit" "i387")
896   (set_attr "mode" "XF")])
897
898(define_insn "*cmpfp_u"
899  [(set (match_operand:HI 0 "register_operand" "=a")
900	(unspec:HI
901	  [(compare:CCFPU
902	     (match_operand 1 "register_operand" "f")
903	     (match_operand 2 "register_operand" "f"))]
904	  UNSPEC_FNSTSW))]
905  "TARGET_80387
906   && FLOAT_MODE_P (GET_MODE (operands[1]))
907   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
908  "* return output_fp_compare (insn, operands, 0, 1);"
909  [(set_attr "type" "multi")
910   (set_attr "unit" "i387")
911   (set (attr "mode")
912     (cond [(match_operand:SF 1 "" "")
913	      (const_string "SF")
914	    (match_operand:DF 1 "" "")
915	      (const_string "DF")
916	   ]
917	   (const_string "XF")))])
918
919(define_insn "*cmpfp_<mode>"
920  [(set (match_operand:HI 0 "register_operand" "=a")
921	(unspec:HI
922	  [(compare:CCFP
923	     (match_operand 1 "register_operand" "f")
924	     (match_operator 3 "float_operator"
925	       [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
926	  UNSPEC_FNSTSW))]
927  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
928   && FLOAT_MODE_P (GET_MODE (operands[1]))
929   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
930  "* return output_fp_compare (insn, operands, 0, 0);"
931  [(set_attr "type" "multi")
932   (set_attr "unit" "i387")
933   (set_attr "fp_int_src" "true")
934   (set_attr "mode" "<MODE>")])
935
936;; FP compares, step 2
937;; Move the fpsw to ax.
938
939(define_insn "x86_fnstsw_1"
940  [(set (match_operand:HI 0 "register_operand" "=a")
941	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
942  "TARGET_80387"
943  "fnstsw\t%0"
944  [(set_attr "length" "2")
945   (set_attr "mode" "SI")
946   (set_attr "unit" "i387")])
947
948;; FP compares, step 3
949;; Get ax into flags, general case.
950
951(define_insn "x86_sahf_1"
952  [(set (reg:CC FLAGS_REG)
953	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
954  "!TARGET_64BIT"
955  "sahf"
956  [(set_attr "length" "1")
957   (set_attr "athlon_decode" "vector")
958   (set_attr "mode" "SI")])
959
960;; Pentium Pro can do steps 1 through 3 in one go.
961
962(define_insn "*cmpfp_i_mixed"
963  [(set (reg:CCFP FLAGS_REG)
964	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
965		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
966  "TARGET_MIX_SSE_I387
967   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969  "* return output_fp_compare (insn, operands, 1, 0);"
970  [(set_attr "type" "fcmp,ssecomi")
971   (set (attr "mode")
972     (if_then_else (match_operand:SF 1 "" "")
973        (const_string "SF")
974        (const_string "DF")))
975   (set_attr "athlon_decode" "vector")])
976
977(define_insn "*cmpfp_i_sse"
978  [(set (reg:CCFP FLAGS_REG)
979	(compare:CCFP (match_operand 0 "register_operand" "x")
980		      (match_operand 1 "nonimmediate_operand" "xm")))]
981  "TARGET_SSE_MATH
982   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984  "* return output_fp_compare (insn, operands, 1, 0);"
985  [(set_attr "type" "ssecomi")
986   (set (attr "mode")
987     (if_then_else (match_operand:SF 1 "" "")
988        (const_string "SF")
989        (const_string "DF")))
990   (set_attr "athlon_decode" "vector")])
991
992(define_insn "*cmpfp_i_i387"
993  [(set (reg:CCFP FLAGS_REG)
994	(compare:CCFP (match_operand 0 "register_operand" "f")
995		      (match_operand 1 "register_operand" "f")))]
996  "TARGET_80387 && TARGET_CMOVE
997   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
998   && FLOAT_MODE_P (GET_MODE (operands[0]))
999   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000  "* return output_fp_compare (insn, operands, 1, 0);"
1001  [(set_attr "type" "fcmp")
1002   (set (attr "mode")
1003     (cond [(match_operand:SF 1 "" "")
1004	      (const_string "SF")
1005	    (match_operand:DF 1 "" "")
1006	      (const_string "DF")
1007	   ]
1008	   (const_string "XF")))
1009   (set_attr "athlon_decode" "vector")])
1010
1011(define_insn "*cmpfp_iu_mixed"
1012  [(set (reg:CCFPU FLAGS_REG)
1013	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1014		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1015  "TARGET_MIX_SSE_I387
1016   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018  "* return output_fp_compare (insn, operands, 1, 1);"
1019  [(set_attr "type" "fcmp,ssecomi")
1020   (set (attr "mode")
1021     (if_then_else (match_operand:SF 1 "" "")
1022        (const_string "SF")
1023        (const_string "DF")))
1024   (set_attr "athlon_decode" "vector")])
1025
1026(define_insn "*cmpfp_iu_sse"
1027  [(set (reg:CCFPU FLAGS_REG)
1028	(compare:CCFPU (match_operand 0 "register_operand" "x")
1029		       (match_operand 1 "nonimmediate_operand" "xm")))]
1030  "TARGET_SSE_MATH
1031   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033  "* return output_fp_compare (insn, operands, 1, 1);"
1034  [(set_attr "type" "ssecomi")
1035   (set (attr "mode")
1036     (if_then_else (match_operand:SF 1 "" "")
1037        (const_string "SF")
1038        (const_string "DF")))
1039   (set_attr "athlon_decode" "vector")])
1040
1041(define_insn "*cmpfp_iu_387"
1042  [(set (reg:CCFPU FLAGS_REG)
1043	(compare:CCFPU (match_operand 0 "register_operand" "f")
1044		       (match_operand 1 "register_operand" "f")))]
1045  "TARGET_80387 && TARGET_CMOVE
1046   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1047   && FLOAT_MODE_P (GET_MODE (operands[0]))
1048   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1049  "* return output_fp_compare (insn, operands, 1, 1);"
1050  [(set_attr "type" "fcmp")
1051   (set (attr "mode")
1052     (cond [(match_operand:SF 1 "" "")
1053	      (const_string "SF")
1054	    (match_operand:DF 1 "" "")
1055	      (const_string "DF")
1056	   ]
1057	   (const_string "XF")))
1058   (set_attr "athlon_decode" "vector")])
1059
1060;; Move instructions.
1061
1062;; General case of fullword move.
1063
1064(define_expand "movsi"
1065  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1066	(match_operand:SI 1 "general_operand" ""))]
1067  ""
1068  "ix86_expand_move (SImode, operands); DONE;")
1069
1070;; Push/pop instructions.  They are separate since autoinc/dec is not a
1071;; general_operand.
1072;;
1073;; %%% We don't use a post-inc memory reference because x86 is not a 
1074;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1075;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1076;; targets without our curiosities, and it is just as easy to represent
1077;; this differently.
1078
1079(define_insn "*pushsi2"
1080  [(set (match_operand:SI 0 "push_operand" "=<")
1081	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1082  "!TARGET_64BIT"
1083  "push{l}\t%1"
1084  [(set_attr "type" "push")
1085   (set_attr "mode" "SI")])
1086
1087;; For 64BIT abi we always round up to 8 bytes.
1088(define_insn "*pushsi2_rex64"
1089  [(set (match_operand:SI 0 "push_operand" "=X")
1090	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1091  "TARGET_64BIT"
1092  "push{q}\t%q1"
1093  [(set_attr "type" "push")
1094   (set_attr "mode" "SI")])
1095
1096(define_insn "*pushsi2_prologue"
1097  [(set (match_operand:SI 0 "push_operand" "=<")
1098	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1099   (clobber (mem:BLK (scratch)))]
1100  "!TARGET_64BIT"
1101  "push{l}\t%1"
1102  [(set_attr "type" "push")
1103   (set_attr "mode" "SI")])
1104
1105(define_insn "*popsi1_epilogue"
1106  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1107	(mem:SI (reg:SI SP_REG)))
1108   (set (reg:SI SP_REG)
1109	(plus:SI (reg:SI SP_REG) (const_int 4)))
1110   (clobber (mem:BLK (scratch)))]
1111  "!TARGET_64BIT"
1112  "pop{l}\t%0"
1113  [(set_attr "type" "pop")
1114   (set_attr "mode" "SI")])
1115
1116(define_insn "popsi1"
1117  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1118	(mem:SI (reg:SI SP_REG)))
1119   (set (reg:SI SP_REG)
1120	(plus:SI (reg:SI SP_REG) (const_int 4)))]
1121  "!TARGET_64BIT"
1122  "pop{l}\t%0"
1123  [(set_attr "type" "pop")
1124   (set_attr "mode" "SI")])
1125
1126(define_insn "*movsi_xor"
1127  [(set (match_operand:SI 0 "register_operand" "=r")
1128	(match_operand:SI 1 "const0_operand" "i"))
1129   (clobber (reg:CC FLAGS_REG))]
1130  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1131  "xor{l}\t{%0, %0|%0, %0}"
1132  [(set_attr "type" "alu1")
1133   (set_attr "mode" "SI")
1134   (set_attr "length_immediate" "0")])
1135 
1136(define_insn "*movsi_or"
1137  [(set (match_operand:SI 0 "register_operand" "=r")
1138	(match_operand:SI 1 "immediate_operand" "i"))
1139   (clobber (reg:CC FLAGS_REG))]
1140  "reload_completed
1141   && operands[1] == constm1_rtx
1142   && (TARGET_PENTIUM || optimize_size)"
1143{
1144  operands[1] = constm1_rtx;
1145  return "or{l}\t{%1, %0|%0, %1}";
1146}
1147  [(set_attr "type" "alu1")
1148   (set_attr "mode" "SI")
1149   (set_attr "length_immediate" "1")])
1150
1151(define_insn "*movsi_1"
1152  [(set (match_operand:SI 0 "nonimmediate_operand"
1153			"=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1154	(match_operand:SI 1 "general_operand"
1155			"rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1156  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1157{
1158  switch (get_attr_type (insn))
1159    {
1160    case TYPE_SSELOG1:
1161      if (get_attr_mode (insn) == MODE_TI)
1162        return "pxor\t%0, %0";
1163      return "xorps\t%0, %0";
1164
1165    case TYPE_SSEMOV:
1166      switch (get_attr_mode (insn))
1167	{
1168	case MODE_TI:
1169	  return "movdqa\t{%1, %0|%0, %1}";
1170	case MODE_V4SF:
1171	  return "movaps\t{%1, %0|%0, %1}";
1172	case MODE_SI:
1173          return "movd\t{%1, %0|%0, %1}";
1174	case MODE_SF:
1175          return "movss\t{%1, %0|%0, %1}";
1176	default:
1177	  gcc_unreachable ();
1178	}
1179
1180    case TYPE_MMXADD:
1181      return "pxor\t%0, %0";
1182
1183    case TYPE_MMXMOV:
1184      if (get_attr_mode (insn) == MODE_DI)
1185	return "movq\t{%1, %0|%0, %1}";
1186      return "movd\t{%1, %0|%0, %1}";
1187
1188    case TYPE_LEA:
1189      return "lea{l}\t{%1, %0|%0, %1}";
1190
1191    default:
1192      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1193      return "mov{l}\t{%1, %0|%0, %1}";
1194    }
1195}
1196  [(set (attr "type")
1197     (cond [(eq_attr "alternative" "2")
1198	      (const_string "mmxadd")
1199	    (eq_attr "alternative" "3,4,5")
1200	      (const_string "mmxmov")
1201	    (eq_attr "alternative" "6")
1202	      (const_string "sselog1")
1203	    (eq_attr "alternative" "7,8,9,10,11")
1204	      (const_string "ssemov")
1205 	    (match_operand:DI 1 "pic_32bit_operand" "")
1206	      (const_string "lea")
1207	   ]
1208	   (const_string "imov")))
1209   (set (attr "mode")
1210     (cond [(eq_attr "alternative" "2,3")
1211	      (const_string "DI")
1212	    (eq_attr "alternative" "6,7")
1213	      (if_then_else
1214	        (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1215	        (const_string "V4SF")
1216	        (const_string "TI"))
1217	    (and (eq_attr "alternative" "8,9,10,11")
1218	         (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1219	      (const_string "SF")
1220	   ]
1221	   (const_string "SI")))])
1222
1223;; Stores and loads of ax to arbitrary constant address.
1224;; We fake an second form of instruction to force reload to load address
1225;; into register when rax is not available
1226(define_insn "*movabssi_1_rex64"
1227  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1228	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1229  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1230  "@
1231   movabs{l}\t{%1, %P0|%P0, %1}
1232   mov{l}\t{%1, %a0|%a0, %1}"
1233  [(set_attr "type" "imov")
1234   (set_attr "modrm" "0,*")
1235   (set_attr "length_address" "8,0")
1236   (set_attr "length_immediate" "0,*")
1237   (set_attr "memory" "store")
1238   (set_attr "mode" "SI")])
1239
1240(define_insn "*movabssi_2_rex64"
1241  [(set (match_operand:SI 0 "register_operand" "=a,r")
1242        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1243  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1244  "@
1245   movabs{l}\t{%P1, %0|%0, %P1}
1246   mov{l}\t{%a1, %0|%0, %a1}"
1247  [(set_attr "type" "imov")
1248   (set_attr "modrm" "0,*")
1249   (set_attr "length_address" "8,0")
1250   (set_attr "length_immediate" "0")
1251   (set_attr "memory" "load")
1252   (set_attr "mode" "SI")])
1253
1254(define_insn "*swapsi"
1255  [(set (match_operand:SI 0 "register_operand" "+r")
1256	(match_operand:SI 1 "register_operand" "+r"))
1257   (set (match_dup 1)
1258	(match_dup 0))]
1259  ""
1260  "xchg{l}\t%1, %0"
1261  [(set_attr "type" "imov")
1262   (set_attr "mode" "SI")
1263   (set_attr "pent_pair" "np")
1264   (set_attr "athlon_decode" "vector")])
1265
1266(define_expand "movhi"
1267  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1268        (match_operand:HI 1 "general_operand" ""))]
1269  ""
1270  "ix86_expand_move (HImode, operands); DONE;")
1271
1272(define_insn "*pushhi2"
1273  [(set (match_operand:HI 0 "push_operand" "=X")
1274	(match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1275  "!TARGET_64BIT"
1276  "push{l}\t%k1"
1277  [(set_attr "type" "push")
1278   (set_attr "mode" "SI")])
1279
1280;; For 64BIT abi we always round up to 8 bytes.
1281(define_insn "*pushhi2_rex64"
1282  [(set (match_operand:HI 0 "push_operand" "=X")
1283	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1284  "TARGET_64BIT"
1285  "push{q}\t%q1"
1286  [(set_attr "type" "push")
1287   (set_attr "mode" "DI")])
1288
1289(define_insn "*movhi_1"
1290  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1291	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1292  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1293{
1294  switch (get_attr_type (insn))
1295    {
1296    case TYPE_IMOVX:
1297      /* movzwl is faster than movw on p2 due to partial word stalls,
1298	 though not as fast as an aligned movl.  */
1299      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1300    default:
1301      if (get_attr_mode (insn) == MODE_SI)
1302        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1303      else
1304        return "mov{w}\t{%1, %0|%0, %1}";
1305    }
1306}
1307  [(set (attr "type")
1308     (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1309	      (const_string "imov")
1310	    (and (eq_attr "alternative" "0")
1311		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1312			  (const_int 0))
1313		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1314			  (const_int 0))))
1315	      (const_string "imov")
1316	    (and (eq_attr "alternative" "1,2")
1317		 (match_operand:HI 1 "aligned_operand" ""))
1318	      (const_string "imov")
1319	    (and (ne (symbol_ref "TARGET_MOVX")
1320		     (const_int 0))
1321		 (eq_attr "alternative" "0,2"))
1322	      (const_string "imovx")
1323	   ]
1324	   (const_string "imov")))
1325    (set (attr "mode")
1326      (cond [(eq_attr "type" "imovx")
1327	       (const_string "SI")
1328	     (and (eq_attr "alternative" "1,2")
1329		  (match_operand:HI 1 "aligned_operand" ""))
1330	       (const_string "SI")
1331	     (and (eq_attr "alternative" "0")
1332		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333			   (const_int 0))
1334		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1335			   (const_int 0))))
1336	       (const_string "SI")
1337	    ]
1338	    (const_string "HI")))])
1339
1340;; Stores and loads of ax to arbitrary constant address.
1341;; We fake an second form of instruction to force reload to load address
1342;; into register when rax is not available
1343(define_insn "*movabshi_1_rex64"
1344  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1345	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1346  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1347  "@
1348   movabs{w}\t{%1, %P0|%P0, %1}
1349   mov{w}\t{%1, %a0|%a0, %1}"
1350  [(set_attr "type" "imov")
1351   (set_attr "modrm" "0,*")
1352   (set_attr "length_address" "8,0")
1353   (set_attr "length_immediate" "0,*")
1354   (set_attr "memory" "store")
1355   (set_attr "mode" "HI")])
1356
1357(define_insn "*movabshi_2_rex64"
1358  [(set (match_operand:HI 0 "register_operand" "=a,r")
1359        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1360  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1361  "@
1362   movabs{w}\t{%P1, %0|%0, %P1}
1363   mov{w}\t{%a1, %0|%0, %a1}"
1364  [(set_attr "type" "imov")
1365   (set_attr "modrm" "0,*")
1366   (set_attr "length_address" "8,0")
1367   (set_attr "length_immediate" "0")
1368   (set_attr "memory" "load")
1369   (set_attr "mode" "HI")])
1370
1371(define_insn "*swaphi_1"
1372  [(set (match_operand:HI 0 "register_operand" "+r")
1373	(match_operand:HI 1 "register_operand" "+r"))
1374   (set (match_dup 1)
1375	(match_dup 0))]
1376  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1377  "xchg{l}\t%k1, %k0"
1378  [(set_attr "type" "imov")
1379   (set_attr "mode" "SI")
1380   (set_attr "pent_pair" "np")
1381   (set_attr "athlon_decode" "vector")])
1382
1383(define_insn "*swaphi_2"
1384  [(set (match_operand:HI 0 "register_operand" "+r")
1385	(match_operand:HI 1 "register_operand" "+r"))
1386   (set (match_dup 1)
1387	(match_dup 0))]
1388  "TARGET_PARTIAL_REG_STALL"
1389  "xchg{w}\t%1, %0"
1390  [(set_attr "type" "imov")
1391   (set_attr "mode" "HI")
1392   (set_attr "pent_pair" "np")
1393   (set_attr "athlon_decode" "vector")])
1394
1395(define_expand "movstricthi"
1396  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1397	(match_operand:HI 1 "general_operand" ""))]
1398  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1399{
1400  /* Don't generate memory->memory moves, go through a register */
1401  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1402    operands[1] = force_reg (HImode, operands[1]);
1403})
1404
1405(define_insn "*movstricthi_1"
1406  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1407	(match_operand:HI 1 "general_operand" "rn,m"))]
1408  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1409   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1410  "mov{w}\t{%1, %0|%0, %1}"
1411  [(set_attr "type" "imov")
1412   (set_attr "mode" "HI")])
1413
1414(define_insn "*movstricthi_xor"
1415  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1416	(match_operand:HI 1 "const0_operand" "i"))
1417   (clobber (reg:CC FLAGS_REG))]
1418  "reload_completed
1419   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1420  "xor{w}\t{%0, %0|%0, %0}"
1421  [(set_attr "type" "alu1")
1422   (set_attr "mode" "HI")
1423   (set_attr "length_immediate" "0")])
1424
1425(define_expand "movqi"
1426  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1427	(match_operand:QI 1 "general_operand" ""))]
1428  ""
1429  "ix86_expand_move (QImode, operands); DONE;")
1430
1431;; emit_push_insn when it calls move_by_pieces requires an insn to
1432;; "push a byte".  But actually we use pushl, which has the effect
1433;; of rounding the amount pushed up to a word.
1434
1435(define_insn "*pushqi2"
1436  [(set (match_operand:QI 0 "push_operand" "=X")
1437	(match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1438  "!TARGET_64BIT"
1439  "push{l}\t%k1"
1440  [(set_attr "type" "push")
1441   (set_attr "mode" "SI")])
1442
1443;; For 64BIT abi we always round up to 8 bytes.
1444(define_insn "*pushqi2_rex64"
1445  [(set (match_operand:QI 0 "push_operand" "=X")
1446	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1447  "TARGET_64BIT"
1448  "push{q}\t%q1"
1449  [(set_attr "type" "push")
1450   (set_attr "mode" "DI")])
1451
1452;; Situation is quite tricky about when to choose full sized (SImode) move
1453;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1454;; partial register dependency machines (such as AMD Athlon), where QImode
1455;; moves issue extra dependency and for partial register stalls machines
1456;; that don't use QImode patterns (and QImode move cause stall on the next
1457;; instruction).
1458;;
1459;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1460;; register stall machines with, where we use QImode instructions, since
1461;; partial register stall can be caused there.  Then we use movzx.
1462(define_insn "*movqi_1"
1463  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1464	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1465  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1466{
1467  switch (get_attr_type (insn))
1468    {
1469    case TYPE_IMOVX:
1470      gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1471      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1472    default:
1473      if (get_attr_mode (insn) == MODE_SI)
1474        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1475      else
1476        return "mov{b}\t{%1, %0|%0, %1}";
1477    }
1478}
1479  [(set (attr "type")
1480     (cond [(and (eq_attr "alternative" "5")
1481		 (not (match_operand:QI 1 "aligned_operand" "")))
1482	      (const_string "imovx")
1483	    (ne (symbol_ref "optimize_size") (const_int 0))
1484	      (const_string "imov")
1485	    (and (eq_attr "alternative" "3")
1486		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1487			  (const_int 0))
1488		      (eq (symbol_ref "TARGET_QIMODE_MATH")
1489			  (const_int 0))))
1490	      (const_string "imov")
1491	    (eq_attr "alternative" "3,5")
1492	      (const_string "imovx")
1493	    (and (ne (symbol_ref "TARGET_MOVX")
1494		     (const_int 0))
1495		 (eq_attr "alternative" "2"))
1496	      (const_string "imovx")
1497	   ]
1498	   (const_string "imov")))
1499   (set (attr "mode")
1500      (cond [(eq_attr "alternative" "3,4,5")
1501	       (const_string "SI")
1502	     (eq_attr "alternative" "6")
1503	       (const_string "QI")
1504	     (eq_attr "type" "imovx")
1505	       (const_string "SI")
1506	     (and (eq_attr "type" "imov")
1507		  (and (eq_attr "alternative" "0,1")
1508		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1509			   (const_int 0))))
1510	       (const_string "SI")
1511	     ;; Avoid partial register stalls when not using QImode arithmetic
1512	     (and (eq_attr "type" "imov")
1513		  (and (eq_attr "alternative" "0,1")
1514		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1515				(const_int 0))
1516			    (eq (symbol_ref "TARGET_QIMODE_MATH")
1517				(const_int 0)))))
1518	       (const_string "SI")
1519	   ]
1520	   (const_string "QI")))])
1521
1522(define_expand "reload_outqi"
1523  [(parallel [(match_operand:QI 0 "" "=m")
1524              (match_operand:QI 1 "register_operand" "r")
1525              (match_operand:QI 2 "register_operand" "=&q")])]
1526  ""
1527{
1528  rtx op0, op1, op2;
1529  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1530
1531  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1532  if (! q_regs_operand (op1, QImode))
1533    {
1534      emit_insn (gen_movqi (op2, op1));
1535      op1 = op2;
1536    }
1537  emit_insn (gen_movqi (op0, op1));
1538  DONE;
1539})
1540
1541(define_insn "*swapqi_1"
1542  [(set (match_operand:QI 0 "register_operand" "+r")
1543	(match_operand:QI 1 "register_operand" "+r"))
1544   (set (match_dup 1)
1545	(match_dup 0))]
1546  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1547  "xchg{l}\t%k1, %k0"
1548  [(set_attr "type" "imov")
1549   (set_attr "mode" "SI")
1550   (set_attr "pent_pair" "np")
1551   (set_attr "athlon_decode" "vector")])
1552
1553(define_insn "*swapqi_2"
1554  [(set (match_operand:QI 0 "register_operand" "+q")
1555	(match_operand:QI 1 "register_operand" "+q"))
1556   (set (match_dup 1)
1557	(match_dup 0))]
1558  "TARGET_PARTIAL_REG_STALL"
1559  "xchg{b}\t%1, %0"
1560  [(set_attr "type" "imov")
1561   (set_attr "mode" "QI")
1562   (set_attr "pent_pair" "np")
1563   (set_attr "athlon_decode" "vector")])
1564
1565(define_expand "movstrictqi"
1566  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1567	(match_operand:QI 1 "general_operand" ""))]
1568  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1569{
1570  /* Don't generate memory->memory moves, go through a register.  */
1571  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1572    operands[1] = force_reg (QImode, operands[1]);
1573})
1574
1575(define_insn "*movstrictqi_1"
1576  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1577	(match_operand:QI 1 "general_operand" "*qn,m"))]
1578  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1579   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1580  "mov{b}\t{%1, %0|%0, %1}"
1581  [(set_attr "type" "imov")
1582   (set_attr "mode" "QI")])
1583
1584(define_insn "*movstrictqi_xor"
1585  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1586	(match_operand:QI 1 "const0_operand" "i"))
1587   (clobber (reg:CC FLAGS_REG))]
1588  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1589  "xor{b}\t{%0, %0|%0, %0}"
1590  [(set_attr "type" "alu1")
1591   (set_attr "mode" "QI")
1592   (set_attr "length_immediate" "0")])
1593
1594(define_insn "*movsi_extv_1"
1595  [(set (match_operand:SI 0 "register_operand" "=R")
1596	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1597			 (const_int 8)
1598			 (const_int 8)))]
1599  ""
1600  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1601  [(set_attr "type" "imovx")
1602   (set_attr "mode" "SI")])
1603
1604(define_insn "*movhi_extv_1"
1605  [(set (match_operand:HI 0 "register_operand" "=R")
1606	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1607			 (const_int 8)
1608			 (const_int 8)))]
1609  ""
1610  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1611  [(set_attr "type" "imovx")
1612   (set_attr "mode" "SI")])
1613
1614(define_insn "*movqi_extv_1"
1615  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1616        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1617                         (const_int 8)
1618                         (const_int 8)))]
1619  "!TARGET_64BIT"
1620{
1621  switch (get_attr_type (insn))
1622    {
1623    case TYPE_IMOVX:
1624      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1625    default:
1626      return "mov{b}\t{%h1, %0|%0, %h1}";
1627    }
1628}
1629  [(set (attr "type")
1630     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1631			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1632			     (ne (symbol_ref "TARGET_MOVX")
1633				 (const_int 0))))
1634	(const_string "imovx")
1635	(const_string "imov")))
1636   (set (attr "mode")
1637     (if_then_else (eq_attr "type" "imovx")
1638	(const_string "SI")
1639	(const_string "QI")))])
1640
1641(define_insn "*movqi_extv_1_rex64"
1642  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1643        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1644                         (const_int 8)
1645                         (const_int 8)))]
1646  "TARGET_64BIT"
1647{
1648  switch (get_attr_type (insn))
1649    {
1650    case TYPE_IMOVX:
1651      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652    default:
1653      return "mov{b}\t{%h1, %0|%0, %h1}";
1654    }
1655}
1656  [(set (attr "type")
1657     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659			     (ne (symbol_ref "TARGET_MOVX")
1660				 (const_int 0))))
1661	(const_string "imovx")
1662	(const_string "imov")))
1663   (set (attr "mode")
1664     (if_then_else (eq_attr "type" "imovx")
1665	(const_string "SI")
1666	(const_string "QI")))])
1667
1668;; Stores and loads of ax to arbitrary constant address.
1669;; We fake an second form of instruction to force reload to load address
1670;; into register when rax is not available
1671(define_insn "*movabsqi_1_rex64"
1672  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1673	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1674  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1675  "@
1676   movabs{b}\t{%1, %P0|%P0, %1}
1677   mov{b}\t{%1, %a0|%a0, %1}"
1678  [(set_attr "type" "imov")
1679   (set_attr "modrm" "0,*")
1680   (set_attr "length_address" "8,0")
1681   (set_attr "length_immediate" "0,*")
1682   (set_attr "memory" "store")
1683   (set_attr "mode" "QI")])
1684
1685(define_insn "*movabsqi_2_rex64"
1686  [(set (match_operand:QI 0 "register_operand" "=a,r")
1687        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1688  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1689  "@
1690   movabs{b}\t{%P1, %0|%0, %P1}
1691   mov{b}\t{%a1, %0|%0, %a1}"
1692  [(set_attr "type" "imov")
1693   (set_attr "modrm" "0,*")
1694   (set_attr "length_address" "8,0")
1695   (set_attr "length_immediate" "0")
1696   (set_attr "memory" "load")
1697   (set_attr "mode" "QI")])
1698
1699(define_insn "*movdi_extzv_1"
1700  [(set (match_operand:DI 0 "register_operand" "=R")
1701	(zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1702			 (const_int 8)
1703			 (const_int 8)))]
1704  "TARGET_64BIT"
1705  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1706  [(set_attr "type" "imovx")
1707   (set_attr "mode" "DI")])
1708
1709(define_insn "*movsi_extzv_1"
1710  [(set (match_operand:SI 0 "register_operand" "=R")
1711	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1712			 (const_int 8)
1713			 (const_int 8)))]
1714  ""
1715  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1716  [(set_attr "type" "imovx")
1717   (set_attr "mode" "SI")])
1718
1719(define_insn "*movqi_extzv_2"
1720  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1721        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1722				    (const_int 8)
1723				    (const_int 8)) 0))]
1724  "!TARGET_64BIT"
1725{
1726  switch (get_attr_type (insn))
1727    {
1728    case TYPE_IMOVX:
1729      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1730    default:
1731      return "mov{b}\t{%h1, %0|%0, %h1}";
1732    }
1733}
1734  [(set (attr "type")
1735     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1736			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1737			     (ne (symbol_ref "TARGET_MOVX")
1738				 (const_int 0))))
1739	(const_string "imovx")
1740	(const_string "imov")))
1741   (set (attr "mode")
1742     (if_then_else (eq_attr "type" "imovx")
1743	(const_string "SI")
1744	(const_string "QI")))])
1745
1746(define_insn "*movqi_extzv_2_rex64"
1747  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1748        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1749				    (const_int 8)
1750				    (const_int 8)) 0))]
1751  "TARGET_64BIT"
1752{
1753  switch (get_attr_type (insn))
1754    {
1755    case TYPE_IMOVX:
1756      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1757    default:
1758      return "mov{b}\t{%h1, %0|%0, %h1}";
1759    }
1760}
1761  [(set (attr "type")
1762     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763			(ne (symbol_ref "TARGET_MOVX")
1764			    (const_int 0)))
1765	(const_string "imovx")
1766	(const_string "imov")))
1767   (set (attr "mode")
1768     (if_then_else (eq_attr "type" "imovx")
1769	(const_string "SI")
1770	(const_string "QI")))])
1771
1772(define_insn "movsi_insv_1"
1773  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1774			 (const_int 8)
1775			 (const_int 8))
1776	(match_operand:SI 1 "general_operand" "Qmn"))]
1777  "!TARGET_64BIT"
1778  "mov{b}\t{%b1, %h0|%h0, %b1}"
1779  [(set_attr "type" "imov")
1780   (set_attr "mode" "QI")])
1781
1782(define_insn "movdi_insv_1_rex64"
1783  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1784			 (const_int 8)
1785			 (const_int 8))
1786	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
1787  "TARGET_64BIT"
1788  "mov{b}\t{%b1, %h0|%h0, %b1}"
1789  [(set_attr "type" "imov")
1790   (set_attr "mode" "QI")])
1791
1792(define_insn "*movqi_insv_2"
1793  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1794			 (const_int 8)
1795			 (const_int 8))
1796	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1797		     (const_int 8)))]
1798  ""
1799  "mov{b}\t{%h1, %h0|%h0, %h1}"
1800  [(set_attr "type" "imov")
1801   (set_attr "mode" "QI")])
1802
1803(define_expand "movdi"
1804  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1805	(match_operand:DI 1 "general_operand" ""))]
1806  ""
1807  "ix86_expand_move (DImode, operands); DONE;")
1808
1809(define_insn "*pushdi"
1810  [(set (match_operand:DI 0 "push_operand" "=<")
1811	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1812  "!TARGET_64BIT"
1813  "#")
1814
1815(define_insn "*pushdi2_rex64"
1816  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1817	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1818  "TARGET_64BIT"
1819  "@
1820   push{q}\t%1
1821   #"
1822  [(set_attr "type" "push,multi")
1823   (set_attr "mode" "DI")])
1824
1825;; Convert impossible pushes of immediate to existing instructions.
1826;; First try to get scratch register and go through it.  In case this
1827;; fails, push sign extended lower part first and then overwrite
1828;; upper part by 32bit move.
1829(define_peephole2
1830  [(match_scratch:DI 2 "r")
1831   (set (match_operand:DI 0 "push_operand" "")
1832        (match_operand:DI 1 "immediate_operand" ""))]
1833  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1834   && !x86_64_immediate_operand (operands[1], DImode)"
1835  [(set (match_dup 2) (match_dup 1))
1836   (set (match_dup 0) (match_dup 2))]
1837  "")
1838
1839;; We need to define this as both peepholer and splitter for case
1840;; peephole2 pass is not run.
1841;; "&& 1" is needed to keep it from matching the previous pattern.
1842(define_peephole2
1843  [(set (match_operand:DI 0 "push_operand" "")
1844        (match_operand:DI 1 "immediate_operand" ""))]
1845  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1846   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1847  [(set (match_dup 0) (match_dup 1))
1848   (set (match_dup 2) (match_dup 3))]
1849  "split_di (operands + 1, 1, operands + 2, operands + 3);
1850   operands[1] = gen_lowpart (DImode, operands[2]);
1851   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1852						    GEN_INT (4)));
1853  ")
1854
1855(define_split
1856  [(set (match_operand:DI 0 "push_operand" "")
1857        (match_operand:DI 1 "immediate_operand" ""))]
1858  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1859		    ? flow2_completed : reload_completed)
1860   && !symbolic_operand (operands[1], DImode)
1861   && !x86_64_immediate_operand (operands[1], DImode)"
1862  [(set (match_dup 0) (match_dup 1))
1863   (set (match_dup 2) (match_dup 3))]
1864  "split_di (operands + 1, 1, operands + 2, operands + 3);
1865   operands[1] = gen_lowpart (DImode, operands[2]);
1866   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867						    GEN_INT (4)));
1868  ")
1869
1870(define_insn "*pushdi2_prologue_rex64"
1871  [(set (match_operand:DI 0 "push_operand" "=<")
1872	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
1873   (clobber (mem:BLK (scratch)))]
1874  "TARGET_64BIT"
1875  "push{q}\t%1"
1876  [(set_attr "type" "push")
1877   (set_attr "mode" "DI")])
1878
1879(define_insn "*popdi1_epilogue_rex64"
1880  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881	(mem:DI (reg:DI SP_REG)))
1882   (set (reg:DI SP_REG)
1883	(plus:DI (reg:DI SP_REG) (const_int 8)))
1884   (clobber (mem:BLK (scratch)))]
1885  "TARGET_64BIT"
1886  "pop{q}\t%0"
1887  [(set_attr "type" "pop")
1888   (set_attr "mode" "DI")])
1889
1890(define_insn "popdi1"
1891  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892	(mem:DI (reg:DI SP_REG)))
1893   (set (reg:DI SP_REG)
1894	(plus:DI (reg:DI SP_REG) (const_int 8)))]
1895  "TARGET_64BIT"
1896  "pop{q}\t%0"
1897  [(set_attr "type" "pop")
1898   (set_attr "mode" "DI")])
1899
1900(define_insn "*movdi_xor_rex64"
1901  [(set (match_operand:DI 0 "register_operand" "=r")
1902	(match_operand:DI 1 "const0_operand" "i"))
1903   (clobber (reg:CC FLAGS_REG))]
1904  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1905   && reload_completed"
1906  "xor{l}\t{%k0, %k0|%k0, %k0}"
1907  [(set_attr "type" "alu1")
1908   (set_attr "mode" "SI")
1909   (set_attr "length_immediate" "0")])
1910
1911(define_insn "*movdi_or_rex64"
1912  [(set (match_operand:DI 0 "register_operand" "=r")
1913	(match_operand:DI 1 "const_int_operand" "i"))
1914   (clobber (reg:CC FLAGS_REG))]
1915  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1916   && reload_completed
1917   && operands[1] == constm1_rtx"
1918{
1919  operands[1] = constm1_rtx;
1920  return "or{q}\t{%1, %0|%0, %1}";
1921}
1922  [(set_attr "type" "alu1")
1923   (set_attr "mode" "DI")
1924   (set_attr "length_immediate" "1")])
1925
1926(define_insn "*movdi_2"
1927  [(set (match_operand:DI 0 "nonimmediate_operand"
1928				"=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1929	(match_operand:DI 1 "general_operand"
1930				"riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1931  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932  "@
1933   #
1934   #
1935   pxor\t%0, %0
1936   movq\t{%1, %0|%0, %1}
1937   movq\t{%1, %0|%0, %1}
1938   pxor\t%0, %0
1939   movq\t{%1, %0|%0, %1}
1940   movdqa\t{%1, %0|%0, %1}
1941   movq\t{%1, %0|%0, %1}
1942   xorps\t%0, %0
1943   movlps\t{%1, %0|%0, %1}
1944   movaps\t{%1, %0|%0, %1}
1945   movlps\t{%1, %0|%0, %1}"
1946  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1947   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1948
1949(define_split
1950  [(set (match_operand:DI 0 "push_operand" "")
1951        (match_operand:DI 1 "general_operand" ""))]
1952  "!TARGET_64BIT && reload_completed
1953   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1954  [(const_int 0)]
1955  "ix86_split_long_move (operands); DONE;")
1956
1957;; %%% This multiword shite has got to go.
1958(define_split
1959  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1960        (match_operand:DI 1 "general_operand" ""))]
1961  "!TARGET_64BIT && reload_completed
1962   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1963   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964  [(const_int 0)]
1965  "ix86_split_long_move (operands); DONE;")
1966
1967(define_insn "*movdi_1_rex64"
1968  [(set (match_operand:DI 0 "nonimmediate_operand"
1969		"=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1970	(match_operand:DI 1 "general_operand"
1971		"Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1972  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1973{
1974  switch (get_attr_type (insn))
1975    {
1976    case TYPE_SSECVT:
1977      if (which_alternative == 13)
1978	return "movq2dq\t{%1, %0|%0, %1}";
1979      else
1980	return "movdq2q\t{%1, %0|%0, %1}";
1981    case TYPE_SSEMOV:
1982      if (get_attr_mode (insn) == MODE_TI)
1983	  return "movdqa\t{%1, %0|%0, %1}";
1984      /* FALLTHRU */
1985    case TYPE_MMXMOV:
1986      /* Moves from and into integer register is done using movd opcode with
1987 	 REX prefix.  */
1988      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1989	  return "movd\t{%1, %0|%0, %1}";
1990      return "movq\t{%1, %0|%0, %1}";
1991    case TYPE_SSELOG1:
1992    case TYPE_MMXADD:
1993      return "pxor\t%0, %0";
1994    case TYPE_MULTI:
1995      return "#";
1996    case TYPE_LEA:
1997      return "lea{q}\t{%a1, %0|%0, %a1}";
1998    default:
1999      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2000      if (get_attr_mode (insn) == MODE_SI)
2001	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002      else if (which_alternative == 2)
2003	return "movabs{q}\t{%1, %0|%0, %1}";
2004      else
2005	return "mov{q}\t{%1, %0|%0, %1}";
2006    }
2007}
2008  [(set (attr "type")
2009     (cond [(eq_attr "alternative" "5")
2010	      (const_string "mmxadd")
2011	    (eq_attr "alternative" "6,7,8")
2012	      (const_string "mmxmov")
2013	    (eq_attr "alternative" "9")
2014	      (const_string "sselog1")
2015	    (eq_attr "alternative" "10,11,12")
2016	      (const_string "ssemov")
2017	    (eq_attr "alternative" "13,14")
2018	      (const_string "ssecvt")
2019	    (eq_attr "alternative" "4")
2020	      (const_string "multi")
2021 	    (match_operand:DI 1 "pic_32bit_operand" "")
2022	      (const_string "lea")
2023	   ]
2024	   (const_string "imov")))
2025   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2026   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2027   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2028
2029;; Stores and loads of ax to arbitrary constant address.
2030;; We fake an second form of instruction to force reload to load address
2031;; into register when rax is not available
2032(define_insn "*movabsdi_1_rex64"
2033  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2034	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2035  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2036  "@
2037   movabs{q}\t{%1, %P0|%P0, %1}
2038   mov{q}\t{%1, %a0|%a0, %1}"
2039  [(set_attr "type" "imov")
2040   (set_attr "modrm" "0,*")
2041   (set_attr "length_address" "8,0")
2042   (set_attr "length_immediate" "0,*")
2043   (set_attr "memory" "store")
2044   (set_attr "mode" "DI")])
2045
2046(define_insn "*movabsdi_2_rex64"
2047  [(set (match_operand:DI 0 "register_operand" "=a,r")
2048        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2049  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2050  "@
2051   movabs{q}\t{%P1, %0|%0, %P1}
2052   mov{q}\t{%a1, %0|%0, %a1}"
2053  [(set_attr "type" "imov")
2054   (set_attr "modrm" "0,*")
2055   (set_attr "length_address" "8,0")
2056   (set_attr "length_immediate" "0")
2057   (set_attr "memory" "load")
2058   (set_attr "mode" "DI")])
2059
2060;; Convert impossible stores of immediate to existing instructions.
2061;; First try to get scratch register and go through it.  In case this
2062;; fails, move by 32bit parts.
2063(define_peephole2
2064  [(match_scratch:DI 2 "r")
2065   (set (match_operand:DI 0 "memory_operand" "")
2066        (match_operand:DI 1 "immediate_operand" ""))]
2067  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2068   && !x86_64_immediate_operand (operands[1], DImode)"
2069  [(set (match_dup 2) (match_dup 1))
2070   (set (match_dup 0) (match_dup 2))]
2071  "")
2072
2073;; We need to define this as both peepholer and splitter for case
2074;; peephole2 pass is not run.
2075;; "&& 1" is needed to keep it from matching the previous pattern.
2076(define_peephole2
2077  [(set (match_operand:DI 0 "memory_operand" "")
2078        (match_operand:DI 1 "immediate_operand" ""))]
2079  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2081  [(set (match_dup 2) (match_dup 3))
2082   (set (match_dup 4) (match_dup 5))]
2083  "split_di (operands, 2, operands + 2, operands + 4);")
2084
2085(define_split
2086  [(set (match_operand:DI 0 "memory_operand" "")
2087        (match_operand:DI 1 "immediate_operand" ""))]
2088  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2089		    ? flow2_completed : reload_completed)
2090   && !symbolic_operand (operands[1], DImode)
2091   && !x86_64_immediate_operand (operands[1], DImode)"
2092  [(set (match_dup 2) (match_dup 3))
2093   (set (match_dup 4) (match_dup 5))]
2094  "split_di (operands, 2, operands + 2, operands + 4);")
2095
2096(define_insn "*swapdi_rex64"
2097  [(set (match_operand:DI 0 "register_operand" "+r")
2098	(match_operand:DI 1 "register_operand" "+r"))
2099   (set (match_dup 1)
2100	(match_dup 0))]
2101  "TARGET_64BIT"
2102  "xchg{q}\t%1, %0"
2103  [(set_attr "type" "imov")
2104   (set_attr "mode" "DI")
2105   (set_attr "pent_pair" "np")
2106   (set_attr "athlon_decode" "vector")])
2107
2108(define_expand "movti"
2109  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2110	(match_operand:TI 1 "nonimmediate_operand" ""))]
2111  "TARGET_SSE || TARGET_64BIT"
2112{
2113  if (TARGET_64BIT)
2114    ix86_expand_move (TImode, operands);
2115  else
2116    ix86_expand_vector_move (TImode, operands);
2117  DONE;
2118})
2119
2120(define_insn "*movti_internal"
2121  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2122	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2123  "TARGET_SSE && !TARGET_64BIT
2124   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2125{
2126  switch (which_alternative)
2127    {
2128    case 0:
2129      if (get_attr_mode (insn) == MODE_V4SF)
2130	return "xorps\t%0, %0";
2131      else
2132	return "pxor\t%0, %0";
2133    case 1:
2134    case 2:
2135      if (get_attr_mode (insn) == MODE_V4SF)
2136	return "movaps\t{%1, %0|%0, %1}";
2137      else
2138	return "movdqa\t{%1, %0|%0, %1}";
2139    default:
2140      gcc_unreachable ();
2141    }
2142}
2143  [(set_attr "type" "ssemov,ssemov,ssemov")
2144   (set (attr "mode")
2145        (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2146		 (const_string "V4SF")
2147
2148	       (eq_attr "alternative" "0,1")
2149		 (if_then_else
2150		   (ne (symbol_ref "optimize_size")
2151		       (const_int 0))
2152		   (const_string "V4SF")
2153		   (const_string "TI"))
2154	       (eq_attr "alternative" "2")
2155		 (if_then_else
2156		   (ne (symbol_ref "optimize_size")
2157		       (const_int 0))
2158		   (const_string "V4SF")
2159		   (const_string "TI"))]
2160	       (const_string "TI")))])
2161
2162(define_insn "*movti_rex64"
2163  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2164	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2165  "TARGET_64BIT
2166   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2167{
2168  switch (which_alternative)
2169    {
2170    case 0:
2171    case 1:
2172      return "#";
2173    case 2:
2174      if (get_attr_mode (insn) == MODE_V4SF)
2175	return "xorps\t%0, %0";
2176      else
2177	return "pxor\t%0, %0";
2178    case 3:
2179    case 4:
2180      if (get_attr_mode (insn) == MODE_V4SF)
2181	return "movaps\t{%1, %0|%0, %1}";
2182      else
2183	return "movdqa\t{%1, %0|%0, %1}";
2184    default:
2185      gcc_unreachable ();
2186    }
2187}
2188  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2189   (set (attr "mode")
2190        (cond [(eq_attr "alternative" "2,3")
2191		 (if_then_else
2192		   (ne (symbol_ref "optimize_size")
2193		       (const_int 0))
2194		   (const_string "V4SF")
2195		   (const_string "TI"))
2196	       (eq_attr "alternative" "4")
2197		 (if_then_else
2198		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2199			    (const_int 0))
2200			(ne (symbol_ref "optimize_size")
2201			    (const_int 0)))
2202		   (const_string "V4SF")
2203		   (const_string "TI"))]
2204	       (const_string "DI")))])
2205
2206(define_split
2207  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2208        (match_operand:TI 1 "general_operand" ""))]
2209  "reload_completed && !SSE_REG_P (operands[0])
2210   && !SSE_REG_P (operands[1])"
2211  [(const_int 0)]
2212  "ix86_split_long_move (operands); DONE;")
2213
2214(define_expand "movsf"
2215  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2216	(match_operand:SF 1 "general_operand" ""))]
2217  ""
2218  "ix86_expand_move (SFmode, operands); DONE;")
2219
2220(define_insn "*pushsf"
2221  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2222	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2223  "!TARGET_64BIT"
2224{
2225  /* Anything else should be already split before reg-stack.  */
2226  gcc_assert (which_alternative == 1);
2227  return "push{l}\t%1";
2228}
2229  [(set_attr "type" "multi,push,multi")
2230   (set_attr "unit" "i387,*,*")
2231   (set_attr "mode" "SF,SI,SF")])
2232
2233(define_insn "*pushsf_rex64"
2234  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2235	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2236  "TARGET_64BIT"
2237{
2238  /* Anything else should be already split before reg-stack.  */
2239  gcc_assert (which_alternative == 1);
2240  return "push{q}\t%q1";
2241}
2242  [(set_attr "type" "multi,push,multi")
2243   (set_attr "unit" "i387,*,*")
2244   (set_attr "mode" "SF,DI,SF")])
2245
2246(define_split
2247  [(set (match_operand:SF 0 "push_operand" "")
2248	(match_operand:SF 1 "memory_operand" ""))]
2249  "reload_completed
2250   && GET_CODE (operands[1]) == MEM
2251   && constant_pool_reference_p (operands[1])"
2252  [(set (match_dup 0)
2253	(match_dup 1))]
2254  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2255
2256
2257;; %%% Kill this when call knows how to work this out.
2258(define_split
2259  [(set (match_operand:SF 0 "push_operand" "")
2260	(match_operand:SF 1 "any_fp_register_operand" ""))]
2261  "!TARGET_64BIT"
2262  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2263   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2264
2265(define_split
2266  [(set (match_operand:SF 0 "push_operand" "")
2267	(match_operand:SF 1 "any_fp_register_operand" ""))]
2268  "TARGET_64BIT"
2269  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2270   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2271
2272(define_insn "*movsf_1"
2273  [(set (match_operand:SF 0 "nonimmediate_operand"
2274	  "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2275	(match_operand:SF 1 "general_operand"
2276	  "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2277  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2278   && (reload_in_progress || reload_completed
2279       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2280       || GET_CODE (operands[1]) != CONST_DOUBLE
2281       || memory_operand (operands[0], SFmode))" 
2282{
2283  switch (which_alternative)
2284    {
2285    case 0:
2286      return output_387_reg_move (insn, operands);
2287
2288    case 1:
2289      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2290        return "fstp%z0\t%y0";
2291      else
2292        return "fst%z0\t%y0";
2293
2294    case 2:
2295      return standard_80387_constant_opcode (operands[1]);
2296
2297    case 3:
2298    case 4:
2299      return "mov{l}\t{%1, %0|%0, %1}";
2300    case 5:
2301      if (get_attr_mode (insn) == MODE_TI)
2302	return "pxor\t%0, %0";
2303      else
2304	return "xorps\t%0, %0";
2305    case 6:
2306      if (get_attr_mode (insn) == MODE_V4SF)
2307	return "movaps\t{%1, %0|%0, %1}";
2308      else
2309	return "movss\t{%1, %0|%0, %1}";
2310    case 7:
2311    case 8:
2312      return "movss\t{%1, %0|%0, %1}";
2313
2314    case 9:
2315    case 10:
2316      return "movd\t{%1, %0|%0, %1}";
2317
2318    case 11:
2319      return "movq\t{%1, %0|%0, %1}";
2320
2321    default:
2322      gcc_unreachable ();
2323    }
2324}
2325  [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2326   (set (attr "mode")
2327        (cond [(eq_attr "alternative" "3,4,9,10")
2328		 (const_string "SI")
2329	       (eq_attr "alternative" "5")
2330		 (if_then_else
2331		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2332			    	 (const_int 0))
2333			     (ne (symbol_ref "TARGET_SSE2")
2334				 (const_int 0)))
2335			(eq (symbol_ref "optimize_size")
2336			    (const_int 0)))
2337		   (const_string "TI")
2338		   (const_string "V4SF"))
2339	       /* For architectures resolving dependencies on
2340		  whole SSE registers use APS move to break dependency
2341		  chains, otherwise use short move to avoid extra work. 
2342
2343		  Do the same for architectures resolving dependencies on
2344		  the parts.  While in DF mode it is better to always handle
2345		  just register parts, the SF mode is different due to lack
2346		  of instructions to load just part of the register.  It is
2347		  better to maintain the whole registers in single format
2348		  to avoid problems on using packed logical operations.  */
2349	       (eq_attr "alternative" "6")
2350		 (if_then_else
2351		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2352			    (const_int 0))
2353			(ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2354			    (const_int 0)))
2355		   (const_string "V4SF")
2356		   (const_string "SF"))
2357	       (eq_attr "alternative" "11")
2358		 (const_string "DI")]
2359	       (const_string "SF")))])
2360
2361(define_insn "*swapsf"
2362  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2363	(match_operand:SF 1 "fp_register_operand" "+f"))
2364   (set (match_dup 1)
2365	(match_dup 0))]
2366  "reload_completed || TARGET_80387"
2367{
2368  if (STACK_TOP_P (operands[0]))
2369    return "fxch\t%1";
2370  else
2371    return "fxch\t%0";
2372}
2373  [(set_attr "type" "fxch")
2374   (set_attr "mode" "SF")])
2375
2376(define_expand "movdf"
2377  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2378	(match_operand:DF 1 "general_operand" ""))]
2379  ""
2380  "ix86_expand_move (DFmode, operands); DONE;")
2381
2382;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2383;; Size of pushdf using integer instructions is 2+2*memory operand size
2384;; On the average, pushdf using integers can be still shorter.  Allow this
2385;; pattern for optimize_size too.
2386
2387(define_insn "*pushdf_nointeger"
2388  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2389	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2390  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2391{
2392  /* This insn should be already split before reg-stack.  */
2393  gcc_unreachable ();
2394}
2395  [(set_attr "type" "multi")
2396   (set_attr "unit" "i387,*,*,*")
2397   (set_attr "mode" "DF,SI,SI,DF")])
2398
2399(define_insn "*pushdf_integer"
2400  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2401	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2402  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2403{
2404  /* This insn should be already split before reg-stack.  */
2405  gcc_unreachable ();
2406}
2407  [(set_attr "type" "multi")
2408   (set_attr "unit" "i387,*,*")
2409   (set_attr "mode" "DF,SI,DF")])
2410
2411;; %%% Kill this when call knows how to work this out.
2412(define_split
2413  [(set (match_operand:DF 0 "push_operand" "")
2414	(match_operand:DF 1 "any_fp_register_operand" ""))]
2415  "!TARGET_64BIT && reload_completed"
2416  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2417   (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2418  "")
2419
2420(define_split
2421  [(set (match_operand:DF 0 "push_operand" "")
2422	(match_operand:DF 1 "any_fp_register_operand" ""))]
2423  "TARGET_64BIT && reload_completed"
2424  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2425   (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2426  "")
2427
2428(define_split
2429  [(set (match_operand:DF 0 "push_operand" "")
2430	(match_operand:DF 1 "general_operand" ""))]
2431  "reload_completed"
2432  [(const_int 0)]
2433  "ix86_split_long_move (operands); DONE;")
2434
2435;; Moving is usually shorter when only FP registers are used. This separate
2436;; movdf pattern avoids the use of integer registers for FP operations
2437;; when optimizing for size.
2438
2439(define_insn "*movdf_nointeger"
2440  [(set (match_operand:DF 0 "nonimmediate_operand"
2441			"=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2442	(match_operand:DF 1 "general_operand"
2443			"fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2444  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2445   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2446   && (reload_in_progress || reload_completed
2447       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2448       || GET_CODE (operands[1]) != CONST_DOUBLE
2449       || memory_operand (operands[0], DFmode))" 
2450{
2451  switch (which_alternative)
2452    {
2453    case 0:
2454      return output_387_reg_move (insn, operands);
2455
2456    case 1:
2457      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2458        return "fstp%z0\t%y0";
2459      else
2460        return "fst%z0\t%y0";
2461
2462    case 2:
2463      return standard_80387_constant_opcode (operands[1]);
2464
2465    case 3:
2466    case 4:
2467      return "#";
2468    case 5:
2469      switch (get_attr_mode (insn))
2470	{
2471	case MODE_V4SF:
2472	  return "xorps\t%0, %0";
2473	case MODE_V2DF:
2474	  return "xorpd\t%0, %0";
2475	case MODE_TI:
2476	  return "pxor\t%0, %0";
2477	default:
2478	  gcc_unreachable ();
2479	}
2480    case 6:
2481    case 7:
2482    case 8:
2483      switch (get_attr_mode (insn))
2484	{
2485	case MODE_V4SF:
2486	  return "movaps\t{%1, %0|%0, %1}";
2487	case MODE_V2DF:
2488	  return "movapd\t{%1, %0|%0, %1}";
2489	case MODE_TI:
2490	  return "movdqa\t{%1, %0|%0, %1}";
2491	case MODE_DI:
2492	  return "movq\t{%1, %0|%0, %1}";
2493	case MODE_DF:
2494	  return "movsd\t{%1, %0|%0, %1}";
2495	case MODE_V1DF:
2496	  return "movlpd\t{%1, %0|%0, %1}";
2497	case MODE_V2SF:
2498	  return "movlps\t{%1, %0|%0, %1}";
2499	default:
2500	  gcc_unreachable ();
2501	}
2502
2503    default:
2504      gcc_unreachable ();
2505    }
2506}
2507  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2508   (set (attr "mode")
2509        (cond [(eq_attr "alternative" "0,1,2")
2510		 (const_string "DF")
2511	       (eq_attr "alternative" "3,4")
2512		 (const_string "SI")
2513
2514	       /* For SSE1, we have many fewer alternatives.  */
2515	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2516		 (cond [(eq_attr "alternative" "5,6")
2517			  (const_string "V4SF")
2518		       ]
2519		   (const_string "V2SF"))
2520
2521	       /* xorps is one byte shorter.  */
2522	       (eq_attr "alternative" "5")
2523		 (cond [(ne (symbol_ref "optimize_size")
2524			    (const_int 0))
2525			  (const_string "V4SF")
2526			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2527			    (const_int 0))
2528			  (const_string "TI")
2529		       ]
2530		       (const_string "V2DF"))
2531
2532	       /* For architectures resolving dependencies on
2533		  whole SSE registers use APD move to break dependency
2534		  chains, otherwise use short move to avoid extra work.
2535
2536		  movaps encodes one byte shorter.  */
2537	       (eq_attr "alternative" "6")
2538		 (cond
2539		   [(ne (symbol_ref "optimize_size")
2540		        (const_int 0))
2541		      (const_string "V4SF")
2542		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2543		        (const_int 0))
2544		      (const_string "V2DF")
2545		   ]
2546		   (const_string "DF"))
2547	       /* For architectures resolving dependencies on register
2548		  parts we may avoid extra work to zero out upper part
2549		  of register.  */
2550	       (eq_attr "alternative" "7")
2551		 (if_then_else
2552		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2553		       (const_int 0))
2554		   (const_string "V1DF")
2555		   (const_string "DF"))
2556	      ]
2557	      (const_string "DF")))])
2558
2559(define_insn "*movdf_integer"
2560  [(set (match_operand:DF 0 "nonimmediate_operand"
2561		"=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2562	(match_operand:DF 1 "general_operand"
2563		"fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2564  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2565   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2566   && (reload_in_progress || reload_completed
2567       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2568       || GET_CODE (operands[1]) != CONST_DOUBLE
2569       || memory_operand (operands[0], DFmode))" 
2570{
2571  switch (which_alternative)
2572    {
2573    case 0:
2574      return output_387_reg_move (insn, operands);
2575
2576    case 1:
2577      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2578        return "fstp%z0\t%y0";
2579      else
2580        return "fst%z0\t%y0";
2581
2582    case 2:
2583      return standard_80387_constant_opcode (operands[1]);
2584
2585    case 3:
2586    case 4:
2587      return "#";
2588
2589    case 5:
2590      switch (get_attr_mode (insn))
2591	{
2592	case MODE_V4SF:
2593	  return "xorps\t%0, %0";
2594	case MODE_V2DF:
2595	  return "xorpd\t%0, %0";
2596	case MODE_TI:
2597	  return "pxor\t%0, %0";
2598	default:
2599	  gcc_unreachable ();
2600	}
2601    case 6:
2602    case 7:
2603    case 8:
2604      switch (get_attr_mode (insn))
2605	{
2606	case MODE_V4SF:
2607	  return "movaps\t{%1, %0|%0, %1}";
2608	case MODE_V2DF:
2609	  return "movapd\t{%1, %0|%0, %1}";
2610	case MODE_TI:
2611	  return "movdqa\t{%1, %0|%0, %1}";
2612	case MODE_DI:
2613	  return "movq\t{%1, %0|%0, %1}";
2614	case MODE_DF:
2615	  return "movsd\t{%1, %0|%0, %1}";
2616	case MODE_V1DF:
2617	  return "movlpd\t{%1, %0|%0, %1}";
2618	case MODE_V2SF:
2619	  return "movlps\t{%1, %0|%0, %1}";
2620	default:
2621	  gcc_unreachable ();
2622	}
2623
2624    default:
2625      gcc_unreachable();
2626    }
2627}
2628  [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2629   (set (attr "mode")
2630        (cond [(eq_attr "alternative" "0,1,2")
2631		 (const_string "DF")
2632	       (eq_attr "alternative" "3,4")
2633		 (const_string "SI")
2634
2635	       /* For SSE1, we have many fewer alternatives.  */
2636	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2637		 (cond [(eq_attr "alternative" "5,6")
2638			  (const_string "V4SF")
2639		       ]
2640		   (const_string "V2SF"))
2641
2642	       /* xorps is one byte shorter.  */
2643	       (eq_attr "alternative" "5")
2644		 (cond [(ne (symbol_ref "optimize_size")
2645			    (const_int 0))
2646			  (const_string "V4SF")
2647			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2648			    (const_int 0))
2649			  (const_string "TI")
2650		       ]
2651		       (const_string "V2DF"))
2652
2653	       /* For architectures resolving dependencies on
2654		  whole SSE registers use APD move to break dependency
2655		  chains, otherwise use short move to avoid extra work.
2656
2657		  movaps encodes one byte shorter.  */
2658	       (eq_attr "alternative" "6")
2659		 (cond
2660		   [(ne (symbol_ref "optimize_size")
2661		        (const_int 0))
2662		      (const_string "V4SF")
2663		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2664		        (const_int 0))
2665		      (const_string "V2DF")
2666		   ]
2667		   (const_string "DF"))
2668	       /* For architectures resolving dependencies on register
2669		  parts we may avoid extra work to zero out upper part
2670		  of register.  */
2671	       (eq_attr "alternative" "7")
2672		 (if_then_else
2673		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2674		       (const_int 0))
2675		   (const_string "V1DF")
2676		   (const_string "DF"))
2677	      ]
2678	      (const_string "DF")))])
2679
2680(define_split
2681  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2682	(match_operand:DF 1 "general_operand" ""))]
2683  "reload_completed
2684   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685   && ! (ANY_FP_REG_P (operands[0]) || 
2686	 (GET_CODE (operands[0]) == SUBREG
2687	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2688   && ! (ANY_FP_REG_P (operands[1]) || 
2689	 (GET_CODE (operands[1]) == SUBREG
2690	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2691  [(const_int 0)]
2692  "ix86_split_long_move (operands); DONE;")
2693
2694(define_insn "*swapdf"
2695  [(set (match_operand:DF 0 "fp_register_operand" "+f")
2696	(match_operand:DF 1 "fp_register_operand" "+f"))
2697   (set (match_dup 1)
2698	(match_dup 0))]
2699  "reload_completed || TARGET_80387"
2700{
2701  if (STACK_TOP_P (operands[0]))
2702    return "fxch\t%1";
2703  else
2704    return "fxch\t%0";
2705}
2706  [(set_attr "type" "fxch")
2707   (set_attr "mode" "DF")])
2708
2709(define_expand "movxf"
2710  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2711	(match_operand:XF 1 "general_operand" ""))]
2712  ""
2713  "ix86_expand_move (XFmode, operands); DONE;")
2714
2715;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2716;; Size of pushdf using integer instructions is 3+3*memory operand size
2717;; Pushing using integer instructions is longer except for constants
2718;; and direct memory references.
2719;; (assuming that any given constant is pushed only once, but this ought to be
2720;;  handled elsewhere).
2721
2722(define_insn "*pushxf_nointeger"
2723  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2724	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2725  "optimize_size"
2726{
2727  /* This insn should be already split before reg-stack.  */
2728  gcc_unreachable ();
2729}
2730  [(set_attr "type" "multi")
2731   (set_attr "unit" "i387,*,*")
2732   (set_attr "mode" "XF,SI,SI")])
2733
2734(define_insn "*pushxf_integer"
2735  [(set (match_operand:XF 0 "push_operand" "=<,<")
2736	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2737  "!optimize_size"
2738{
2739  /* This insn should be already split before reg-stack.  */
2740  gcc_unreachable ();
2741}
2742  [(set_attr "type" "multi")
2743   (set_attr "unit" "i387,*")
2744   (set_attr "mode" "XF,SI")])
2745
2746(define_split
2747  [(set (match_operand 0 "push_operand" "")
2748	(match_operand 1 "general_operand" ""))]
2749  "reload_completed
2750   && (GET_MODE (operands[0]) == XFmode
2751       || GET_MODE (operands[0]) == DFmode)
2752   && !ANY_FP_REG_P (operands[1])"
2753  [(const_int 0)]
2754  "ix86_split_long_move (operands); DONE;")
2755
2756(define_split
2757  [(set (match_operand:XF 0 "push_operand" "")
2758	(match_operand:XF 1 "any_fp_register_operand" ""))]
2759  "!TARGET_64BIT"
2760  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2761   (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2762  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2763
2764(define_split
2765  [(set (match_operand:XF 0 "push_operand" "")
2766	(match_operand:XF 1 "any_fp_register_operand" ""))]
2767  "TARGET_64BIT"
2768  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2769   (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2770  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772;; Do not use integer registers when optimizing for size
2773(define_insn "*movxf_nointeger"
2774  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2775	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2776  "optimize_size
2777   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778   && (reload_in_progress || reload_completed
2779       || GET_CODE (operands[1]) != CONST_DOUBLE
2780       || memory_operand (operands[0], XFmode))" 
2781{
2782  switch (which_alternative)
2783    {
2784    case 0:
2785      return output_387_reg_move (insn, operands);
2786
2787    case 1:
2788      /* There is no non-popping store to memory for XFmode.  So if
2789	 we need one, follow the store with a load.  */
2790      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2791        return "fstp%z0\t%y0\;fld%z0\t%y0";
2792      else
2793        return "fstp%z0\t%y0";
2794
2795    case 2:
2796      return standard_80387_constant_opcode (operands[1]);
2797
2798    case 3: case 4:
2799      return "#";
2800    default:
2801      gcc_unreachable ();
2802    }
2803}
2804  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2805   (set_attr "mode" "XF,XF,XF,SI,SI")])
2806
2807(define_insn "*movxf_integer"
2808  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2809	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2810  "!optimize_size
2811   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812   && (reload_in_progress || reload_completed
2813       || GET_CODE (operands[1]) != CONST_DOUBLE
2814       || memory_operand (operands[0], XFmode))" 
2815{
2816  switch (which_alternative)
2817    {
2818    case 0:
2819      return output_387_reg_move (insn, operands);
2820
2821    case 1:
2822      /* There is no non-popping store to memory for XFmode.  So if
2823	 we need one, follow the store with a load.  */
2824      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825        return "fstp%z0\t%y0\;fld%z0\t%y0";
2826      else
2827        return "fstp%z0\t%y0";
2828
2829    case 2:
2830      return standard_80387_constant_opcode (operands[1]);
2831
2832    case 3: case 4:
2833      return "#";
2834
2835    default:
2836      gcc_unreachable ();
2837    }
2838}
2839  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2840   (set_attr "mode" "XF,XF,XF,SI,SI")])
2841
2842(define_split
2843  [(set (match_operand 0 "nonimmediate_operand" "")
2844	(match_operand 1 "general_operand" ""))]
2845  "reload_completed
2846   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2847   && GET_MODE (operands[0]) == XFmode
2848   && ! (ANY_FP_REG_P (operands[0]) || 
2849	 (GET_CODE (operands[0]) == SUBREG
2850	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2851   && ! (ANY_FP_REG_P (operands[1]) || 
2852	 (GET_CODE (operands[1]) == SUBREG
2853	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2854  [(const_int 0)]
2855  "ix86_split_long_move (operands); DONE;")
2856
2857(define_split
2858  [(set (match_operand 0 "register_operand" "")
2859	(match_operand 1 "memory_operand" ""))]
2860  "reload_completed
2861   && GET_CODE (operands[1]) == MEM
2862   && (GET_MODE (operands[0]) == XFmode
2863       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2864   && constant_pool_reference_p (operands[1])"
2865  [(set (match_dup 0) (match_dup 1))]
2866{
2867  rtx c = avoid_constant_pool_reference (operands[1]);
2868  rtx r = operands[0];
2869
2870  if (GET_CODE (r) == SUBREG)
2871    r = SUBREG_REG (r);
2872
2873  if (SSE_REG_P (r))
2874    {
2875      if (!standard_sse_constant_p (c))
2876	FAIL;
2877    }
2878  else if (FP_REG_P (r))
2879    {
2880      if (!standard_80387_constant_p (c))
2881	FAIL;
2882    }
2883  else if (MMX_REG_P (r))
2884    FAIL;
2885
2886  operands[1] = c;
2887})
2888
2889(define_insn "swapxf"
2890  [(set (match_operand:XF 0 "register_operand" "+f")
2891	(match_operand:XF 1 "register_operand" "+f"))
2892   (set (match_dup 1)
2893	(match_dup 0))]
2894  "TARGET_80387"
2895{
2896  if (STACK_TOP_P (operands[0]))
2897    return "fxch\t%1";
2898  else
2899    return "fxch\t%0";
2900}
2901  [(set_attr "type" "fxch")
2902   (set_attr "mode" "XF")])
2903
2904(define_expand "movtf"
2905  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2906	(match_operand:TF 1 "nonimmediate_operand" ""))]
2907  "TARGET_64BIT"
2908{
2909  ix86_expand_move (TFmode, operands);
2910  DONE;
2911})
2912
2913(define_insn "*movtf_internal"
2914  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2915	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2916  "TARGET_64BIT
2917   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2918{
2919  switch (which_alternative)
2920    {
2921    case 0:
2922    case 1:
2923      return "#";
2924    case 2:
2925      if (get_attr_mode (insn) == MODE_V4SF)
2926	return "xorps\t%0, %0";
2927      else
2928	return "pxor\t%0, %0";
2929    case 3:
2930    case 4:
2931      if (get_attr_mode (insn) == MODE_V4SF)
2932	return "movaps\t{%1, %0|%0, %1}";
2933      else
2934	return "movdqa\t{%1, %0|%0, %1}";
2935    default:
2936      gcc_unreachable ();
2937    }
2938}
2939  [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2940   (set (attr "mode")
2941        (cond [(eq_attr "alternative" "2,3")
2942		 (if_then_else
2943		   (ne (symbol_ref "optimize_size")
2944		       (const_int 0))
2945		   (const_string "V4SF")
2946		   (const_string "TI"))
2947	       (eq_attr "alternative" "4")
2948		 (if_then_else
2949		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2950			    (const_int 0))
2951			(ne (symbol_ref "optimize_size")
2952			    (const_int 0)))
2953		   (const_string "V4SF")
2954		   (const_string "TI"))]
2955	       (const_string "DI")))])
2956
2957(define_split
2958  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2959        (match_operand:TF 1 "general_operand" ""))]
2960  "reload_completed && !SSE_REG_P (operands[0])
2961   && !SSE_REG_P (operands[1])"
2962  [(const_int 0)]
2963  "ix86_split_long_move (operands); DONE;")
2964
2965;; Zero extension instructions
2966
2967(define_expand "zero_extendhisi2"
2968  [(set (match_operand:SI 0 "register_operand" "")
2969     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2970  ""
2971{
2972  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2973    {
2974      operands[1] = force_reg (HImode, operands[1]);
2975      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2976      DONE;
2977    }
2978})
2979
2980(define_insn "zero_extendhisi2_and"
2981  [(set (match_operand:SI 0 "register_operand" "=r")
2982     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2983   (clobber (reg:CC FLAGS_REG))]
2984  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2985  "#"
2986  [(set_attr "type" "alu1")
2987   (set_attr "mode" "SI")])
2988
2989(define_split
2990  [(set (match_operand:SI 0 "register_operand" "")
2991	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2992   (clobber (reg:CC FLAGS_REG))]
2993  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2995	      (clobber (reg:CC FLAGS_REG))])]
2996  "")
2997
2998(define_insn "*zero_extendhisi2_movzwl"
2999  [(set (match_operand:SI 0 "register_operand" "=r")
3000     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3001  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3002  "movz{wl|x}\t{%1, %0|%0, %1}"
3003  [(set_attr "type" "imovx")
3004   (set_attr "mode" "SI")])
3005
3006(define_expand "zero_extendqihi2"
3007  [(parallel
3008    [(set (match_operand:HI 0 "register_operand" "")
3009       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3010     (clobber (reg:CC FLAGS_REG))])]
3011  ""
3012  "")
3013
3014(define_insn "*zero_extendqihi2_and"
3015  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3016     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3017   (clobber (reg:CC FLAGS_REG))]
3018  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3019  "#"
3020  [(set_attr "type" "alu1")
3021   (set_attr "mode" "HI")])
3022
3023(define_insn "*zero_extendqihi2_movzbw_and"
3024  [(set (match_operand:HI 0 "register_operand" "=r,r")
3025     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3026   (clobber (reg:CC FLAGS_REG))]
3027  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3028  "#"
3029  [(set_attr "type" "imovx,alu1")
3030   (set_attr "mode" "HI")])
3031
3032(define_insn "*zero_extendqihi2_movzbw"
3033  [(set (match_operand:HI 0 "register_operand" "=r")
3034     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3035  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3036  "movz{bw|x}\t{%1, %0|%0, %1}"
3037  [(set_attr "type" "imovx")
3038   (set_attr "mode" "HI")])
3039
3040;; For the movzbw case strip only the clobber
3041(define_split
3042  [(set (match_operand:HI 0 "register_operand" "")
3043	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3044   (clobber (reg:CC FLAGS_REG))]
3045  "reload_completed 
3046   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3047   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3048  [(set (match_operand:HI 0 "register_operand" "")
3049	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3050
3051;; When source and destination does not overlap, clear destination
3052;; first and then do the movb
3053(define_split
3054  [(set (match_operand:HI 0 "register_operand" "")
3055	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3056   (clobber (reg:CC FLAGS_REG))]
3057  "reload_completed
3058   && ANY_QI_REG_P (operands[0])
3059   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3060   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3061  [(set (match_dup 0) (const_int 0))
3062   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3063  "operands[2] = gen_lowpart (QImode, operands[0]);")
3064
3065;; Rest is handled by single and.
3066(define_split
3067  [(set (match_operand:HI 0 "register_operand" "")
3068	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3069   (clobber (reg:CC FLAGS_REG))]
3070  "reload_completed
3071   && true_regnum (operands[0]) == true_regnum (operands[1])"
3072  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3073	      (clobber (reg:CC FLAGS_REG))])]
3074  "")
3075
3076(define_expand "zero_extendqisi2"
3077  [(parallel
3078    [(set (match_operand:SI 0 "register_operand" "")
3079       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3080     (clobber (reg:CC FLAGS_REG))])]
3081  ""
3082  "")
3083
3084(define_insn "*zero_extendqisi2_and"
3085  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3086     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3087   (clobber (reg:CC FLAGS_REG))]
3088  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3089  "#"
3090  [(set_attr "type" "alu1")
3091   (set_attr "mode" "SI")])
3092
3093(define_insn "*zero_extendqisi2_movzbw_and"
3094  [(set (match_operand:SI 0 "register_operand" "=r,r")
3095     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3096   (clobber (reg:CC FLAGS_REG))]
3097  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3098  "#"
3099  [(set_attr "type" "imovx,alu1")
3100   (set_attr "mode" "SI")])
3101
3102(define_insn "*zero_extendqisi2_movzbw"
3103  [(set (match_operand:SI 0 "register_operand" "=r")
3104     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3105  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3106  "movz{bl|x}\t{%1, %0|%0, %1}"
3107  [(set_attr "type" "imovx")
3108   (set_attr "mode" "SI")])
3109
3110;; For the movzbl case strip only the clobber
3111(define_split
3112  [(set (match_operand:SI 0 "register_operand" "")
3113	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3114   (clobber (reg:CC FLAGS_REG))]
3115  "reload_completed 
3116   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3117   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3118  [(set (match_dup 0)
3119	(zero_extend:SI (match_dup 1)))])
3120
3121;; When source and destination does not overlap, clear destination
3122;; first and then do the movb
3123(define_split
3124  [(set (match_operand:SI 0 "register_operand" "")
3125	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3126   (clobber (reg:CC FLAGS_REG))]
3127  "reload_completed
3128   && ANY_QI_REG_P (operands[0])
3129   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3130   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3131   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3132  [(set (match_dup 0) (const_int 0))
3133   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3134  "operands[2] = gen_lowpart (QImode, operands[0]);")
3135
3136;; Rest is handled by single and.
3137(define_split
3138  [(set (match_operand:SI 0 "register_operand" "")
3139	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3140   (clobber (reg:CC FLAGS_REG))]
3141  "reload_completed
3142   && true_regnum (operands[0]) == true_regnum (operands[1])"
3143  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3144	      (clobber (reg:CC FLAGS_REG))])]
3145  "")
3146
3147;; %%% Kill me once multi-word ops are sane.
3148(define_expand "zero_extendsidi2"
3149  [(set (match_operand:DI 0 "register_operand" "=r")
3150     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3151  ""
3152  "if (!TARGET_64BIT)
3153     {
3154       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3155       DONE;
3156     }
3157  ")
3158
3159(define_insn "zero_extendsidi2_32"
3160  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3161	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3162   (clobber (reg:CC FLAGS_REG))]
3163  "!TARGET_64BIT"
3164  "@
3165   #
3166   #
3167   #
3168   movd\t{%1, %0|%0, %1}
3169   movd\t{%1, %0|%0, %1}"
3170  [(set_attr "mode" "SI,SI,SI,DI,TI")
3171   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3172
3173(define_insn "zero_extendsidi2_rex64"
3174  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3175     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3176  "TARGET_64BIT"
3177  "@
3178   mov\t{%k1, %k0|%k0, %k1}
3179   #
3180   movd\t{%1, %0|%0, %1}
3181   movd\t{%1, %0|%0, %1}"
3182  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3183   (set_attr "mode" "SI,DI,SI,SI")])
3184
3185(define_split
3186  [(set (match_operand:DI 0 "memory_operand" "")
3187     (zero_extend:DI (match_dup 0)))]
3188  "TARGET_64BIT"
3189  [(set (match_dup 4) (const_int 0))]
3190  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3191
3192(define_split 
3193  [(set (match_operand:DI 0 "register_operand" "")
3194	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3195   (clobber (reg:CC FLAGS_REG))]
3196  "!TARGET_64BIT && reload_completed
3197   && true_regnum (operands[0]) == true_regnum (operands[1])"
3198  [(set (match_dup 4) (const_int 0))]
3199  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200
3201(define_split 
3202  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3203	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3204   (clobber (reg:CC FLAGS_REG))]
3205  "!TARGET_64BIT && reload_completed
3206   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3207  [(set (match_dup 3) (match_dup 1))
3208   (set (match_dup 4) (const_int 0))]
3209  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3210
3211(define_insn "zero_extendhidi2"
3212  [(set (match_operand:DI 0 "register_operand" "=r")
3213     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3214  "TARGET_64BIT"
3215  "movz{wl|x}\t{%1, %k0|%k0, %1}"
3216  [(set_attr "type" "imovx")
3217   (set_attr "mode" "DI")])
3218
3219(define_insn "zero_extendqidi2"
3220  [(set (match_operand:DI 0 "register_operand" "=r")
3221     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3222  "TARGET_64BIT"
3223  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3224  [(set_attr "type" "imovx")
3225   (set_attr "mode" "DI")])
3226
3227;; Sign extension instructions
3228
3229(define_expand "extendsidi2"
3230  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3231		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3232	      (clobber (reg:CC FLAGS_REG))
3233	      (clobber (match_scratch:SI 2 ""))])]
3234  ""
3235{
3236  if (TARGET_64BIT)
3237    {
3238      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3239      DONE;
3240    }
3241})
3242
3243(define_insn "*extendsidi2_1"
3244  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3245	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3246   (clobber (reg:CC FLAGS_REG))
3247   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3248  "!TARGET_64BIT"
3249  "#")
3250
3251(define_insn "extendsidi2_rex64"
3252  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3253	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3254  "TARGET_64BIT"
3255  "@
3256   {cltq|cdqe}
3257   movs{lq|x}\t{%1,%0|%0, %1}"
3258  [(set_attr "type" "imovx")
3259   (set_attr "mode" "DI")
3260   (set_attr "prefix_0f" "0")
3261   (set_attr "modrm" "0,1")])
3262
3263(define_insn "extendhidi2"
3264  [(set (match_operand:DI 0 "register_operand" "=r")
3265	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3266  "TARGET_64BIT"
3267  "movs{wq|x}\t{%1,%0|%0, %1}"
3268  [(set_attr "type" "imovx")
3269   (set_attr "mode" "DI")])
3270
3271(define_insn "extendqidi2"
3272  [(set (match_operand:DI 0 "register_operand" "=r")
3273	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3274  "TARGET_64BIT"
3275  "movs{bq|x}\t{%1,%0|%0, %1}"
3276   [(set_attr "type" "imovx")
3277    (set_attr "mode" "DI")])
3278
3279;; Extend to memory case when source register does die.
3280(define_split 
3281  [(set (match_operand:DI 0 "memory_operand" "")
3282	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3283   (clobber (reg:CC FLAGS_REG))
3284   (clobber (match_operand:SI 2 "register_operand" ""))]
3285  "(reload_completed
3286    && dead_or_set_p (insn, operands[1])
3287    && !reg_mentioned_p (operands[1], operands[0]))"
3288  [(set (match_dup 3) (match_dup 1))
3289   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3290	      (clobber (reg:CC FLAGS_REG))])
3291   (set (match_dup 4) (match_dup 1))]
3292  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3293
3294;; Extend to memory case when source register does not die.
3295(define_split 
3296  [(set (match_operand:DI 0 "memory_operand" "")
3297	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3298   (clobber (reg:CC FLAGS_REG))
3299   (clobber (match_operand:SI 2 "register_operand" ""))]
3300  "reload_completed"
3301  [(const_int 0)]
3302{
3303  split_di (&operands[0], 1, &operands[3], &operands[4]);
3304
3305  emit_move_insn (operands[3], operands[1]);
3306
3307  /* Generate a cltd if possible and doing so it profitable.  */
3308  if (true_regnum (operands[1]) == 0
3309      && true_regnum (operands[2]) == 1
3310      && (optimize_size || TARGET_USE_CLTD))
3311    {
3312      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3313    }
3314  else
3315    {
3316      emit_move_insn (operands[2], operands[1]);
3317      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3318    }
3319  emit_move_insn (operands[4], operands[2]);
3320  DONE;
3321})
3322
3323;; Extend to register case.  Optimize case where source and destination
3324;; registers match and cases where we can use cltd.
3325(define_split 
3326  [(set (match_operand:DI 0 "register_operand" "")
3327	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3328   (clobber (reg:CC FLAGS_REG))
3329   (clobber (match_scratch:SI 2 ""))]
3330  "reload_completed"
3331  [(const_int 0)]
3332{
3333  split_di (&operands[0], 1, &operands[3], &operands[4]);
3334
3335  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3336    emit_move_insn (operands[3], operands[1]);
3337
3338  /* Generate a cltd if possible and doing so it profitable.  */
3339  if (true_regnum (operands[3]) == 0
3340      && (optimize_size || TARGET_USE_CLTD))
3341    {
3342      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3343      DONE;
3344    }
3345
3346  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3347    emit_move_insn (operands[4], operands[1]);
3348
3349  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3350  DONE;
3351})
3352
3353(define_insn "extendhisi2"
3354  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3355	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3356  ""
3357{
3358  switch (get_attr_prefix_0f (insn))
3359    {
3360    case 0:
3361      return "{cwtl|cwde}";
3362    default:
3363      return "movs{wl|x}\t{%1,%0|%0, %1}";
3364    }
3365}
3366  [(set_attr "type" "imovx")
3367   (set_attr "mode" "SI")
3368   (set (attr "prefix_0f")
3369     ;; movsx is short decodable while cwtl is vector decoded.
3370     (if_then_else (and (eq_attr "cpu" "!k6")
3371			(eq_attr "alternative" "0"))
3372	(const_string "0")
3373	(const_string "1")))
3374   (set (attr "modrm")
3375     (if_then_else (eq_attr "prefix_0f" "0")
3376	(const_string "0")
3377	(const_string "1")))])
3378
3379(define_insn "*extendhisi2_zext"
3380  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3381	(zero_extend:DI
3382	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3383  "TARGET_64BIT"
3384{
3385  switch (get_attr_prefix_0f (insn))
3386    {
3387    case 0:
3388      return "{cwtl|cwde}";
3389    default:
3390      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3391    }
3392}
3393  [(set_attr "type" "imovx")
3394   (set_attr "mode" "SI")
3395   (set (attr "prefix_0f")
3396     ;; movsx is short decodable while cwtl is vector decoded.
3397     (if_then_else (and (eq_attr "cpu" "!k6")
3398			(eq_attr "alternative" "0"))
3399	(const_string "0")
3400	(const_string "1")))
3401   (set (attr "modrm")
3402     (if_then_else (eq_attr "prefix_0f" "0")
3403	(const_string "0")
3404	(const_string "1")))])
3405
3406(define_insn "extendqihi2"
3407  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3408	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3409  ""
3410{
3411  switch (get_attr_prefix_0f (insn))
3412    {
3413    case 0:
3414      return "{cbtw|cbw}";
3415    default:
3416      return "movs{bw|x}\t{%1,%0|%0, %1}";
3417    }
3418}
3419  [(set_attr "type" "imovx")
3420   (set_attr "mode" "HI")
3421   (set (attr "prefix_0f")
3422     ;; movsx is short decodable while cwtl is vector decoded.
3423     (if_then_else (and (eq_attr "cpu" "!k6")
3424			(eq_attr "alternative" "0"))
3425	(const_string "0")
3426	(const_string "1")))
3427   (set (attr "modrm")
3428     (if_then_else (eq_attr "prefix_0f" "0")
3429	(const_string "0")
3430	(const_string "1")))])
3431
3432(define_insn "extendqisi2"
3433  [(set (match_operand:SI 0 "register_operand" "=r")
3434	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3435  ""
3436  "movs{bl|x}\t{%1,%0|%0, %1}"
3437   [(set_attr "type" "imovx")
3438    (set_attr "mode" "SI")])
3439
3440(define_insn "*extendqisi2_zext"
3441  [(set (match_operand:DI 0 "register_operand" "=r")
3442	(zero_extend:DI
3443	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3444  "TARGET_64BIT"
3445  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3446   [(set_attr "type" "imovx")
3447    (set_attr "mode" "SI")])
3448
3449;; Conversions between float and double.
3450
3451;; These are all no-ops in the model used for the 80387.  So just
3452;; emit moves.
3453
3454;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3455(define_insn "*dummy_extendsfdf2"
3456  [(set (match_operand:DF 0 "push_operand" "=<")
3457	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3458  "0"
3459  "#")
3460
3461(define_split
3462  [(set (match_operand:DF 0 "push_operand" "")
3463	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3464  "!TARGET_64BIT"
3465  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3466   (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3467
3468(define_split
3469  [(set (match_operand:DF 0 "push_operand" "")
3470	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3471  "TARGET_64BIT"
3472  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3473   (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3474
3475(define_insn "*dummy_extendsfxf2"
3476  [(set (match_operand:XF 0 "push_operand" "=<")
3477	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3478  "0"
3479  "#")
3480
3481(define_split
3482  [(set (match_operand:XF 0 "push_operand" "")
3483	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3484  ""
3485  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3486   (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3487  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488
3489(define_split
3490  [(set (match_operand:XF 0 "push_operand" "")
3491	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3492  "TARGET_64BIT"
3493  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3494   (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3495  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3496
3497(define_split
3498  [(set (match_operand:XF 0 "push_operand" "")
3499	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3500  ""
3501  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3502   (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3503  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3504
3505(define_split
3506  [(set (match_operand:XF 0 "push_operand" "")
3507	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3508  "TARGET_64BIT"
3509  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3510   (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3511  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3512
3513(define_expand "extendsfdf2"
3514  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3515        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3516  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3517{
3518  /* ??? Needed for compress_float_constant since all fp constants
3519     are LEGITIMATE_CONSTANT_P.  */
3520  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3522  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523    operands[1] = force_reg (SFmode, operands[1]);
3524})
3525
3526(define_insn "*extendsfdf2_mixed"
3527  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3528        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3529  "TARGET_SSE2 && TARGET_MIX_SSE_I387
3530   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531{
3532  switch (which_alternative)
3533    {
3534    case 0:
3535      return output_387_reg_move (insn, operands);
3536
3537    case 1:
3538      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3539        return "fstp%z0\t%y0";
3540      else
3541        return "fst%z0\t%y0";
3542
3543    case 2:
3544      return "cvtss2sd\t{%1, %0|%0, %1}";
3545
3546    default:
3547      gcc_unreachable ();
3548    }
3549}
3550  [(set_attr "type" "fmov,fmov,ssecvt")
3551   (set_attr "mode" "SF,XF,DF")])
3552
3553(define_insn "*extendsfdf2_sse"
3554  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3555        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3556  "TARGET_SSE2 && TARGET_SSE_MATH
3557   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3558  "cvtss2sd\t{%1, %0|%0, %1}"
3559  [(set_attr "type" "ssecvt")
3560   (set_attr "mode" "DF")])
3561
3562(define_insn "*extendsfdf2_i387"
3563  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3564        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3565  "TARGET_80387
3566   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3567{
3568  switch (which_alternative)
3569    {
3570    case 0:
3571      return output_387_reg_move (insn, operands);
3572
3573    case 1:
3574      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3575        return "fstp%z0\t%y0";
3576      else
3577        return "fst%z0\t%y0";
3578
3579    default:
3580      gcc_unreachable ();
3581    }
3582}
3583  [(set_attr "type" "fmov")
3584   (set_attr "mode" "SF,XF")])
3585
3586(define_expand "extendsfxf2"
3587  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3588        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3589  "TARGET_80387"
3590{
3591  /* ??? Needed for compress_float_constant since all fp constants
3592     are LEGITIMATE_CONSTANT_P.  */
3593  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3594    operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3595  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3596    operands[1] = force_reg (SFmode, operands[1]);
3597})
3598
3599(define_insn "*extendsfxf2_i387"
3600  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3601        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3602  "TARGET_80387
3603   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3604{
3605  switch (which_alternative)
3606    {
3607    case 0:
3608      return output_387_reg_move (insn, operands);
3609
3610    case 1:
3611      /* There is no non-popping store to memory for XFmode.  So if
3612	 we need one, follow the store with a load.  */
3613      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614        return "fstp%z0\t%y0";
3615      else
3616        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3617
3618    default:
3619      gcc_unreachable ();
3620    }
3621}
3622  [(set_attr "type" "fmov")
3623   (set_attr "mode" "SF,XF")])
3624
3625(define_expand "extenddfxf2"
3626  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3627        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3628  "TARGET_80387"
3629{
3630  /* ??? Needed for compress_float_constant since all fp constants
3631     are LEGITIMATE_CONSTANT_P.  */
3632  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3633    operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3634  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3635    operands[1] = force_reg (DFmode, operands[1]);
3636})
3637
3638(define_insn "*extenddfxf2_i387"
3639  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3640        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3641  "TARGET_80387
3642   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3643{
3644  switch (which_alternative)
3645    {
3646    case 0:
3647      return output_387_reg_move (insn, operands);
3648
3649    case 1:
3650      /* There is no non-popping store to memory for XFmode.  So if
3651	 we need one, follow the store with a load.  */
3652      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3653        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3654      else
3655        return "fstp%z0\t%y0";
3656
3657    default:
3658      gcc_unreachable ();
3659    }
3660}
3661  [(set_attr "type" "fmov")
3662   (set_attr "mode" "DF,XF")])
3663
3664;; %%% This seems bad bad news.
3665;; This cannot output into an f-reg because there is no way to be sure
3666;; of truncating in that case.  Otherwise this is just like a simple move
3667;; insn.  So we pretend we can output to a reg in order to get better
3668;; register preferencing, but we really use a stack slot.
3669
3670;; Conversion from DFmode to SFmode.
3671
3672(define_expand "truncdfsf2"
3673  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3674	(float_truncate:SF
3675	  (match_operand:DF 1 "nonimmediate_operand" "")))]
3676  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3677{
3678  if (MEM_P (operands[0]) && MEM_P (operands[1]))
3679    operands[1] = force_reg (DFmode, operands[1]);
3680
3681  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3682    ;
3683  else if (flag_unsafe_math_optimizations)
3684    ;
3685  else
3686    {
3687      rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3688      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3689      DONE;
3690    }
3691})
3692
3693(define_expand "truncdfsf2_with_temp"
3694  [(parallel [(set (match_operand:SF 0 "" "")
3695		   (float_truncate:SF (match_operand:DF 1 "" "")))
3696	      (clobber (match_operand:SF 2 "" ""))])]
3697  "")
3698
3699(define_insn "*truncdfsf_fast_mixed"
3700  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3701        (float_truncate:SF
3702          (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3703  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3704{
3705  switch (which_alternative)
3706    {
3707    case 0:
3708      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3709	return "fstp%z0\t%y0";
3710      else
3711	return "fst%z0\t%y0";
3712    case 1:
3713      return output_387_reg_move (insn, operands);
3714    case 2:
3715      return "cvtsd2ss\t{%1, %0|%0, %1}";
3716    default:
3717      gcc_unreachable ();
3718    }
3719}
3720  [(set_attr "type" "fmov,fmov,ssecvt")
3721   (set_attr "mode" "SF")])
3722
3723;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3724;; because nothing we do here is unsafe.
3725(define_insn "*truncdfsf_fast_sse"
3726  [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3727        (float_truncate:SF
3728          (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3729  "TARGET_SSE2 && TARGET_SSE_MATH"
3730  "cvtsd2ss\t{%1, %0|%0, %1}"
3731  [(set_attr "type" "ssecvt")
3732   (set_attr "mode" "SF")])
3733
3734(define_insn "*truncdfsf_fast_i387"
3735  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3736        (float_truncate:SF
3737          (match_operand:DF 1 "nonimmediate_operand" "f")))]
3738  "TARGET_80387 && flag_unsafe_math_optimizations"
3739  "* return output_387_reg_move (insn, operands);"
3740  [(set_attr "type" "fmov")
3741   (set_attr "mode" "SF")])
3742
3743(define_insn "*truncdfsf_mixed"
3744  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3745	(float_truncate:SF
3746	  (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3747   (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3748  "TARGET_MIX_SSE_I387"
3749{
3750  switch (which_alternative)
3751    {
3752    case 0:
3753      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3754	return "fstp%z0\t%y0";
3755      else
3756	return "fst%z0\t%y0";
3757    case 1:
3758      return "#";
3759    case 2:
3760      return "cvtsd2ss\t{%1, %0|%0, %1}";
3761    default:
3762      gcc_unreachable ();
3763    }
3764}
3765  [(set_attr "type" "fmov,multi,ssecvt")
3766   (set_attr "unit" "*,i387,*")
3767   (set_attr "mode" "SF")])
3768
3769(define_insn "*truncdfsf_i387"
3770  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3771	(float_truncate:SF
3772	  (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3773   (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3774  "TARGET_80387"
3775{
3776  switch (which_alternative)
3777    {
3778    case 0:
3779      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780	return "fstp%z0\t%y0";
3781      else
3782	return "fst%z0\t%y0";
3783    case 1:
3784      return "#";
3785    default:
3786      gcc_unreachable ();
3787    }
3788}
3789  [(set_attr "type" "fmov,multi")
3790   (set_attr "unit" "*,i387")
3791   (set_attr "mode" "SF")])
3792
3793(define_insn "*truncdfsf2_i387_1"
3794  [(set (match_operand:SF 0 "memory_operand" "=m")
3795	(float_truncate:SF
3796	  (match_operand:DF 1 "register_operand" "f")))]
3797  "TARGET_80387
3798   && !(TARGET_SSE2 && TARGET_SSE_MATH)
3799   && !TARGET_MIX_SSE_I387"
3800{
3801  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3802    return "fstp%z0\t%y0";
3803  else
3804    return "fst%z0\t%y0";
3805}
3806  [(set_attr "type" "fmov")
3807   (set_attr "mode" "SF")])
3808
3809(define_split
3810  [(set (match_operand:SF 0 "register_operand" "")
3811	(float_truncate:SF
3812	 (match_operand:DF 1 "fp_register_operand" "")))
3813   (clobber (match_operand 2 "" ""))]
3814  "reload_completed"
3815  [(set (match_dup 2) (match_dup 1))
3816   (set (match_dup 0) (match_dup 2))]
3817{
3818  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3819})
3820
3821;; Conversion from XFmode to SFmode.
3822
3823(define_expand "truncxfsf2"
3824  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3825		   (float_truncate:SF
3826		    (match_operand:XF 1 "register_operand" "")))
3827	      (clobber (match_dup 2))])]
3828  "TARGET_80387"
3829{
3830  if (flag_unsafe_math_optimizations)
3831    {
3832      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3833      emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3834      if (reg != operands[0])
3835	emit_move_insn (operands[0], reg);
3836      DONE;
3837    }
3838  else
3839    operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3840})
3841
3842(define_insn "*truncxfsf2_mixed"
3843  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3844	(float_truncate:SF
3845	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3846   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3847  "TARGET_MIX_SSE_I387"
3848{
3849  gcc_assert (!which_alternative);
3850  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3851    return "fstp%z0\t%y0";
3852  else
3853    return "fst%z0\t%y0";
3854}
3855  [(set_attr "type" "fmov,multi,multi,multi")
3856   (set_attr "unit" "*,i387,i387,i387")
3857   (set_attr "mode" "SF")])
3858
3859(define_insn "truncxfsf2_i387_noop"
3860  [(set (match_operand:SF 0 "register_operand" "=f")
3861	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3862  "TARGET_80387 && flag_unsafe_math_optimizations"
3863{
3864  return output_387_reg_move (insn, operands);
3865}
3866  [(set_attr "type" "fmov")
3867   (set_attr "mode" "SF")])
3868
3869(define_insn "*truncxfsf2_i387"
3870  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3871	(float_truncate:SF
3872	 (match_operand:XF 1 "register_operand" "f,f,f")))
3873   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3874  "TARGET_80387"
3875{
3876  gcc_assert (!which_alternative);
3877  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3878    return "fstp%z0\t%y0";
3879   else
3880     return "fst%z0\t%y0";
3881}
3882  [(set_attr "type" "fmov,multi,multi")
3883   (set_attr "unit" "*,i387,i387")
3884   (set_attr "mode" "SF")])
3885
3886(define_insn "*truncxfsf2_i387_1"
3887  [(set (match_operand:SF 0 "memory_operand" "=m")
3888	(float_truncate:SF
3889	 (match_operand:XF 1 "register_operand" "f")))]
3890  "TARGET_80387"
3891{
3892  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3893    return "fstp%z0\t%y0";
3894  else
3895    return "fst%z0\t%y0";
3896}
3897  [(set_attr "type" "fmov")
3898   (set_attr "mode" "SF")])
3899
3900(define_split
3901  [(set (match_operand:SF 0 "register_operand" "")
3902	(float_truncate:SF
3903	 (match_operand:XF 1 "register_operand" "")))
3904   (clobber (match_operand:SF 2 "memory_operand" ""))]
3905  "TARGET_80387 && reload_completed"
3906  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3907   (set (match_dup 0) (match_dup 2))]
3908  "")
3909
3910(define_split
3911  [(set (match_operand:SF 0 "memory_operand" "")
3912	(float_truncate:SF
3913	 (match_operand:XF 1 "register_operand" "")))
3914   (clobber (match_operand:SF 2 "memory_operand" ""))]
3915  "TARGET_80387"
3916  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3917  "")
3918
3919;; Conversion from XFmode to DFmode.
3920
3921(define_expand "truncxfdf2"
3922  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3923		   (float_truncate:DF
3924		    (match_operand:XF 1 "register_operand" "")))
3925	      (clobber (match_dup 2))])]
3926  "TARGET_80387"
3927{
3928  if (flag_unsafe_math_optimizations)
3929    {
3930      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3931      emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3932      if (reg != operands[0])
3933	emit_move_insn (operands[0], reg);
3934      DONE;
3935    }
3936  else
3937    operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3938})
3939
3940(define_insn "*truncxfdf2_mixed"
3941  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3942	(float_truncate:DF
3943	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3944   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3945  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3946{
3947  gcc_assert (!which_alternative);
3948  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3949    return "fstp%z0\t%y0";
3950  else
3951    return "fst%z0\t%y0";
3952}
3953  [(set_attr "type" "fmov,multi,multi,multi")
3954   (set_attr "unit" "*,i387,i387,i387")
3955   (set_attr "mode" "DF")])
3956
3957(define_insn "truncxfdf2_i387_noop"
3958  [(set (match_operand:DF 0 "register_operand" "=f")
3959	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3960  "TARGET_80387 && flag_unsafe_math_optimizations"
3961{
3962  return output_387_reg_move (insn, operands);
3963}
3964  [(set_attr "type" "fmov")
3965   (set_attr "mode" "DF")])
3966
3967(define_insn "*truncxfdf2_i387"
3968  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3969	(float_truncate:DF
3970	 (match_operand:XF 1 "register_operand" "f,f,f")))
3971   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3972  "TARGET_80387"
3973{
3974  gcc_assert (!which_alternative);
3975  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3976    return "fstp%z0\t%y0";
3977  else
3978    return "fst%z0\t%y0";
3979}
3980  [(set_attr "type" "fmov,multi,multi")
3981   (set_attr "unit" "*,i387,i387")
3982   (set_attr "mode" "DF")])
3983
3984(define_insn "*truncxfdf2_i387_1"
3985  [(set (match_operand:DF 0 "memory_operand" "=m")
3986	(float_truncate:DF
3987	  (match_operand:XF 1 "register_operand" "f")))]
3988  "TARGET_80387"
3989{
3990  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3991    return "fstp%z0\t%y0";
3992  else
3993    return "fst%z0\t%y0";
3994}
3995  [(set_attr "type" "fmov")
3996   (set_attr "mode" "DF")])
3997
3998(define_split
3999  [(set (match_operand:DF 0 "register_operand" "")
4000	(float_truncate:DF
4001	 (match_operand:XF 1 "register_operand" "")))
4002   (clobber (match_operand:DF 2 "memory_operand" ""))]
4003  "TARGET_80387 && reload_completed"
4004  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4005   (set (match_dup 0) (match_dup 2))]
4006  "")
4007
4008(define_split
4009  [(set (match_operand:DF 0 "memory_operand" "")
4010	(float_truncate:DF
4011	 (match_operand:XF 1 "register_operand" "")))
4012   (clobber (match_operand:DF 2 "memory_operand" ""))]
4013  "TARGET_80387"
4014  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4015  "")
4016
4017;; Signed conversion to DImode.
4018
4019(define_expand "fix_truncxfdi2"
4020  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4021                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4022	      (clobber (reg:CC FLAGS_REG))])]
4023  "TARGET_80387"
4024{
4025  if (TARGET_FISTTP)
4026   {
4027     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4028     DONE;
4029   }
4030})
4031
4032(define_expand "fix_trunc<mode>di2"
4033  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4034                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4035              (clobber (reg:CC FLAGS_REG))])]
4036  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4037{
4038  if (TARGET_FISTTP
4039      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4040   {
4041     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4042     DONE;
4043   }
4044  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4045   {
4046     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4047     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4048     if (out != operands[0])
4049	emit_move_insn (operands[0], out);
4050     DONE;
4051   }
4052})
4053
4054;; Signed conversion to SImode.
4055
4056(define_expand "fix_truncxfsi2"
4057  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4058                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4059	      (clobber (reg:CC FLAGS_REG))])]
4060  "TARGET_80387"
4061{
4062  if (TARGET_FISTTP)
4063   {
4064     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4065     DONE;
4066   }
4067})
4068
4069(define_expand "fix_trunc<mode>si2"
4070  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4071	           (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4072	      (clobber (reg:CC FLAGS_REG))])]
4073  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4074{
4075  if (TARGET_FISTTP
4076      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4077   {
4078     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4079     DONE;
4080   }
4081  if (SSE_FLOAT_MODE_P (<MODE>mode))
4082   {
4083     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4084     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4085     if (out != operands[0])
4086	emit_move_insn (operands[0], out);
4087     DONE;
4088   }
4089})
4090
4091;; Signed conversion to HImode.
4092
4093(define_expand "fix_trunc<mode>hi2"
4094  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4095	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4096              (clobber (reg:CC FLAGS_REG))])]
4097  "TARGET_80387
4098   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4099{
4100  if (TARGET_FISTTP)
4101   {
4102     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4103     DONE;
4104   }
4105})
4106
4107;; When SSE is available, it is always faster to use it!
4108(define_insn "fix_truncsfdi_sse"
4109  [(set (match_operand:DI 0 "register_operand" "=r,r")
4110	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4111  "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4112  "cvttss2si{q}\t{%1, %0|%0, %1}"
4113  [(set_attr "type" "sseicvt")
4114   (set_attr "mode" "SF")
4115   (set_attr "athlon_decode" "double,vector")])
4116
4117(define_insn "fix_truncdfdi_sse"
4118  [(set (match_operand:DI 0 "register_operand" "=r,r")
4119	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4120  "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4121  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4122  [(set_attr "type" "sseicvt")
4123   (set_attr "mode" "DF")
4124   (set_attr "athlon_decode" "double,vector")])
4125
4126(define_insn "fix_truncsfsi_sse"
4127  [(set (match_operand:SI 0 "register_operand" "=r,r")
4128	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129  "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130  "cvttss2si\t{%1, %0|%0, %1}"
4131  [(set_attr "type" "sseicvt")
4132   (set_attr "mode" "DF")
4133   (set_attr "athlon_decode" "double,vector")])
4134
4135(define_insn "fix_truncdfsi_sse"
4136  [(set (match_operand:SI 0 "register_operand" "=r,r")
4137	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4138  "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139  "cvttsd2si\t{%1, %0|%0, %1}"
4140  [(set_attr "type" "sseicvt")
4141   (set_attr "mode" "DF")
4142   (set_attr "athlon_decode" "double,vector")])
4143
4144;; Avoid vector decoded forms of the instruction.
4145(define_peephole2
4146  [(match_scratch:DF 2 "Y")
4147   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4148	(fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4149  "TARGET_K8 && !optimize_size"
4150  [(set (match_dup 2) (match_dup 1))
4151   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4152  "")
4153
4154(define_peephole2
4155  [(match_scratch:SF 2 "x")
4156   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4157	(fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4158  "TARGET_K8 && !optimize_size"
4159  [(set (match_dup 2) (match_dup 1))
4160   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4161  "")
4162
4163(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4164  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4165	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4166  "TARGET_FISTTP
4167   && FLOAT_MODE_P (GET_MODE (operands[1]))
4168   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4169	 && (TARGET_64BIT || <MODE>mode != DImode))
4170	&& TARGET_SSE_MATH)
4171   && !(reload_completed || reload_in_progress)"
4172  "#"
4173  "&& 1"
4174  [(const_int 0)]
4175{
4176  if (memory_operand (operands[0], VOIDmode))
4177    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4178  else
4179    {
4180      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4181      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4182							    operands[1],
4183							    operands[2]));
4184    }
4185  DONE;
4186}
4187  [(set_attr "type" "fisttp")
4188   (set_attr "mode" "<MODE>")])
4189
4190(define_insn "fix_trunc<mode>_i387_fisttp"
4191  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4192	(fix:X87MODEI (match_operand 1 "register_operand" "f")))
4193   (clobber (match_scratch:XF 2 "=&1f"))]
4194  "TARGET_FISTTP
4195   && FLOAT_MODE_P (GET_MODE (operands[1]))
4196   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4197	 && (TARGET_64BIT || <MODE>mode != DImode))
4198	&& TARGET_SSE_MATH)"
4199  "* return output_fix_trunc (insn, operands, 1);"
4200  [(set_attr "type" "fisttp")
4201   (set_attr "mode" "<MODE>")])
4202
4203(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4204  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4205	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4206   (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4207   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4208  "TARGET_FISTTP
4209   && FLOAT_MODE_P (GET_MODE (operands[1]))
4210   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4211	&& (TARGET_64BIT || <MODE>mode != DImode))
4212	&& TARGET_SSE_MATH)"
4213  "#"
4214  [(set_attr "type" "fisttp")
4215   (set_attr "mode" "<MODE>")])
4216
4217(define_split
4218  [(set (match_operand:X87MODEI 0 "register_operand" "")
4219	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4220   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4221   (clobber (match_scratch 3 ""))]
4222  "reload_completed"
4223  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4224	      (clobber (match_dup 3))])
4225   (set (match_dup 0) (match_dup 2))]
4226  "")
4227
4228(define_split
4229  [(set (match_operand:X87MODEI 0 "memory_operand" "")
4230	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4231   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4232   (clobber (match_scratch 3 ""))]
4233  "reload_completed"
4234  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4235	      (clobber (match_dup 3))])]
4236  "")
4237
4238;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4239;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4240;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4241;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4242;; function in i386.c.
4243(define_insn_and_split "*fix_trunc<mode>_i387_1"
4244  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4245	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4246   (clobber (reg:CC FLAGS_REG))]
4247  "TARGET_80387 && !TARGET_FISTTP
4248   && FLOAT_MODE_P (GET_MODE (operands[1]))
4249   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4250	 && (TARGET_64BIT || <MODE>mode != DImode))
4251   && !(reload_completed || reload_in_progress)"
4252  "#"
4253  "&& 1"
4254  [(const_int 0)]
4255{
4256  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4257
4258  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4259  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4260  if (memory_operand (operands[0], VOIDmode))
4261    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4262					 operands[2], operands[3]));
4263  else
4264    {
4265      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4266      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4267						     operands[2], operands[3],
4268						     operands[4]));
4269    }
4270  DONE;
4271}
4272  [(set_attr "type" "fistp")
4273   (set_attr "i387_cw" "trunc")
4274   (set_attr "mode" "<MODE>")])
4275
4276(define_insn "fix_truncdi_i387"
4277  [(set (match_operand:DI 0 "memory_operand" "=m")
4278	(fix:DI (match_operand 1 "register_operand" "f")))
4279   (use (match_operand:HI 2 "memory_operand" "m"))
4280   (use (match_operand:HI 3 "memory_operand" "m"))
4281   (clobber (match_scratch:XF 4 "=&1f"))]
4282  "TARGET_80387 && !TARGET_FISTTP
4283   && FLOAT_MODE_P (GET_MODE (operands[1]))
4284   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4285  "* return output_fix_trunc (insn, operands, 0);"
4286  [(set_attr "type" "fistp")
4287   (set_attr "i387_cw" "trunc")
4288   (set_attr "mode" "DI")])
4289
4290(define_insn "fix_truncdi_i387_with_temp"
4291  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4292	(fix:DI (match_operand 1 "register_operand" "f,f")))
4293   (use (match_operand:HI 2 "memory_operand" "m,m"))
4294   (use (match_operand:HI 3 "memory_operand" "m,m"))
4295   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4296   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4297  "TARGET_80387 && !TARGET_FISTTP
4298   && FLOAT_MODE_P (GET_MODE (operands[1]))
4299   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4300  "#"
4301  [(set_attr "type" "fistp")
4302   (set_attr "i387_cw" "trunc")
4303   (set_attr "mode" "DI")])
4304
4305(define_split 
4306  [(set (match_operand:DI 0 "register_operand" "")
4307	(fix:DI (match_operand 1 "register_operand" "")))
4308   (use (match_operand:HI 2 "memory_operand" ""))
4309   (use (match_operand:HI 3 "memory_operand" ""))
4310   (clobber (match_operand:DI 4 "memory_operand" ""))
4311   (clobber (match_scratch 5 ""))]
4312  "reload_completed"
4313  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4314	      (use (match_dup 2))
4315	      (use (match_dup 3))
4316	      (clobber (match_dup 5))])
4317   (set (match_dup 0) (match_dup 4))]
4318  "")
4319
4320(define_split 
4321  [(set (match_operand:DI 0 "memory_operand" "")
4322	(fix:DI (match_operand 1 "register_operand" "")))
4323   (use (match_operand:HI 2 "memory_operand" ""))
4324   (use (match_operand:HI 3 "memory_operand" ""))
4325   (clobber (match_operand:DI 4 "memory_operand" ""))
4326   (clobber (match_scratch 5 ""))]
4327  "reload_completed"
4328  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4329	      (use (match_dup 2))
4330	      (use (match_dup 3))
4331	      (clobber (match_dup 5))])]
4332  "")
4333
4334(define_insn "fix_trunc<mode>_i387"
4335  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4336	(fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4337   (use (match_operand:HI 2 "memory_operand" "m"))
4338   (use (match_operand:HI 3 "memory_operand" "m"))]
4339  "TARGET_80387 && !TARGET_FISTTP
4340   && FLOAT_MODE_P (GET_MODE (operands[1]))
4341   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342  "* return output_fix_trunc (insn, operands, 0);"
4343  [(set_attr "type" "fistp")
4344   (set_attr "i387_cw" "trunc")
4345   (set_attr "mode" "<MODE>")])
4346
4347(define_insn "fix_trunc<mode>_i387_with_temp"
4348  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4349	(fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4350   (use (match_operand:HI 2 "memory_operand" "m,m"))
4351   (use (match_operand:HI 3 "memory_operand" "m,m"))
4352   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4353  "TARGET_80387 && !TARGET_FISTTP
4354   && FLOAT_MODE_P (GET_MODE (operands[1]))
4355   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356  "#"
4357  [(set_attr "type" "fistp")
4358   (set_attr "i387_cw" "trunc")
4359   (set_attr "mode" "<MODE>")])
4360
4361(define_split 
4362  [(set (match_operand:X87MODEI12 0 "register_operand" "")
4363	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4364   (use (match_operand:HI 2 "memory_operand" ""))
4365   (use (match_operand:HI 3 "memory_operand" ""))
4366   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4367  "reload_completed"
4368  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4369	      (use (match_dup 2))
4370	      (use (match_dup 3))])
4371   (set (match_dup 0) (match_dup 4))]
4372  "")
4373
4374(define_split 
4375  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4376	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4377   (use (match_operand:HI 2 "memory_operand" ""))
4378   (use (match_operand:HI 3 "memory_operand" ""))
4379   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4380  "reload_completed"
4381  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4382	      (use (match_dup 2))
4383	      (use (match_dup 3))])]
4384  "")
4385
4386(define_insn "x86_fnstcw_1"
4387  [(set (match_operand:HI 0 "memory_operand" "=m")
4388	(unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4389  "TARGET_80387"
4390  "fnstcw\t%0"
4391  [(set_attr "length" "2")
4392   (set_attr "mode" "HI")
4393   (set_attr "unit" "i387")])
4394
4395(define_insn "x86_fldcw_1"
4396  [(set (reg:HI FPSR_REG)
4397	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4398  "TARGET_80387"
4399  "fldcw\t%0"
4400  [(set_attr "length" "2")
4401   (set_attr "mode" "HI")
4402   (set_attr "unit" "i387")
4403   (set_attr "athlon_decode" "vector")])
4404
4405;; Conversion between fixed point and floating point.
4406
4407;; Even though we only accept memory inputs, the backend _really_
4408;; wants to be able to do this between registers.
4409
4410(define_expand "floathisf2"
4411  [(set (match_operand:SF 0 "register_operand" "")
4412	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4413  "TARGET_80387 || TARGET_SSE_MATH"
4414{
4415  if (TARGET_SSE_MATH)
4416    {
4417      emit_insn (gen_floatsisf2 (operands[0],
4418				 convert_to_mode (SImode, operands[1], 0)));
4419      DONE;
4420    }
4421})
4422
4423(define_insn "*floathisf2_i387"
4424  [(set (match_operand:SF 0 "register_operand" "=f,f")
4425	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4426  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4427  "@
4428   fild%z1\t%1
4429   #"
4430  [(set_attr "type" "fmov,multi")
4431   (set_attr "mode" "SF")
4432   (set_attr "unit" "*,i387")
4433   (set_attr "fp_int_src" "true")])
4434
4435(define_expand "floatsisf2"
4436  [(set (match_operand:SF 0 "register_operand" "")
4437	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4438  "TARGET_80387 || TARGET_SSE_MATH"
4439  "")
4440
4441(define_insn "*floatsisf2_mixed"
4442  [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4443	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4444  "TARGET_MIX_SSE_I387"
4445  "@
4446   fild%z1\t%1
4447   #
4448   cvtsi2ss\t{%1, %0|%0, %1}
4449   cvtsi2ss\t{%1, %0|%0, %1}"
4450  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4451   (set_attr "mode" "SF")
4452   (set_attr "unit" "*,i387,*,*")
4453   (set_attr "athlon_decode" "*,*,vector,double")
4454   (set_attr "fp_int_src" "true")])
4455
4456(define_insn "*floatsisf2_sse"
4457  [(set (match_operand:SF 0 "register_operand" "=x,x")
4458	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4459  "TARGET_SSE_MATH"
4460  "cvtsi2ss\t{%1, %0|%0, %1}"
4461  [(set_attr "type" "sseicvt")
4462   (set_attr "mode" "SF")
4463   (set_attr "athlon_decode" "vector,double")
4464   (set_attr "fp_int_src" "true")])
4465
4466(define_insn "*floatsisf2_i387"
4467  [(set (match_operand:SF 0 "register_operand" "=f,f")
4468	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4469  "TARGET_80387"
4470  "@
4471   fild%z1\t%1
4472   #"
4473  [(set_attr "type" "fmov,multi")
4474   (set_attr "mode" "SF")
4475   (set_attr "unit" "*,i387")
4476   (set_attr "fp_int_src" "true")])
4477
4478(define_expand "floatdisf2"
4479  [(set (match_operand:SF 0 "register_operand" "")
4480	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4481  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4482  "")
4483
4484(define_insn "*floatdisf2_mixed"
4485  [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487  "TARGET_64BIT && TARGET_MIX_SSE_I387"
4488  "@
4489   fild%z1\t%1
4490   #
4491   cvtsi2ss{q}\t{%1, %0|%0, %1}
4492   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4493  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494   (set_attr "mode" "SF")
4495   (set_attr "unit" "*,i387,*,*")
4496   (set_attr "athlon_decode" "*,*,vector,double")
4497   (set_attr "fp_int_src" "true")])
4498
4499(define_insn "*floatdisf2_sse"
4500  [(set (match_operand:SF 0 "register_operand" "=x,x")
4501	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4502  "TARGET_64BIT && TARGET_SSE_MATH"
4503  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4504  [(set_attr "type" "sseicvt")
4505   (set_attr "mode" "SF")
4506   (set_attr "athlon_decode" "vector,double")
4507   (set_attr "fp_int_src" "true")])
4508
4509(define_insn "*floatdisf2_i387"
4510  [(set (match_operand:SF 0 "register_operand" "=f,f")
4511	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4512  "TARGET_80387"
4513  "@
4514   fild%z1\t%1
4515   #"
4516  [(set_attr "type" "fmov,multi")
4517   (set_attr "mode" "SF")
4518   (set_attr "unit" "*,i387")
4519   (set_attr "fp_int_src" "true")])
4520
4521(define_expand "floathidf2"
4522  [(set (match_operand:DF 0 "register_operand" "")
4523	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4524  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4525{
4526  if (TARGET_SSE2 && TARGET_SSE_MATH)
4527    {
4528      emit_insn (gen_floatsidf2 (operands[0],
4529				 convert_to_mode (SImode, operands[1], 0)));
4530      DONE;
4531    }
4532})
4533
4534(define_insn "*floathidf2_i387"
4535  [(set (match_operand:DF 0 "register_operand" "=f,f")
4536	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4537  "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4538  "@
4539   fild%z1\t%1
4540   #"
4541  [(set_attr "type" "fmov,multi")
4542   (set_attr "mode" "DF")
4543   (set_attr "unit" "*,i387")
4544   (set_attr "fp_int_src" "true")])
4545
4546(define_expand "floatsidf2"
4547  [(set (match_operand:DF 0 "register_operand" "")
4548	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4549  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4550  "")
4551
4552(define_insn "*floatsidf2_mixed"
4553  [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4554	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4555  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4556  "@
4557   fild%z1\t%1
4558   #
4559   cvtsi2sd\t{%1, %0|%0, %1}
4560   cvtsi2sd\t{%1, %0|%0, %1}"
4561  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4562   (set_attr "mode" "DF")
4563   (set_attr "unit" "*,i387,*,*")
4564   (set_attr "athlon_decode" "*,*,double,direct")
4565   (set_attr "fp_int_src" "true")])
4566
4567(define_insn "*floatsidf2_sse"
4568  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4569	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4570  "TARGET_SSE2 && TARGET_SSE_MATH"
4571  "cvtsi2sd\t{%1, %0|%0, %1}"
4572  [(set_attr "type" "sseicvt")
4573   (set_attr "mode" "DF")
4574   (set_attr "athlon_decode" "double,direct")
4575   (set_attr "fp_int_src" "true")])
4576
4577(define_insn "*floatsidf2_i387"
4578  [(set (match_operand:DF 0 "register_operand" "=f,f")
4579	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4580  "TARGET_80387"
4581  "@
4582   fild%z1\t%1
4583   #"
4584  [(set_attr "type" "fmov,multi")
4585   (set_attr "mode" "DF")
4586   (set_attr "unit" "*,i387")
4587   (set_attr "fp_int_src" "true")])
4588
4589(define_expand "floatdidf2"
4590  [(set (match_operand:DF 0 "register_operand" "")
4591	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4592  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4593  "")
4594
4595(define_insn "*floatdidf2_mixed"
4596  [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4597	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4598  "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4599  "@
4600   fild%z1\t%1
4601   #
4602   cvtsi2sd{q}\t{%1, %0|%0, %1}
4603   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4604  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4605   (set_attr "mode" "DF")
4606   (set_attr "unit" "*,i387,*,*")
4607   (set_attr "athlon_decode" "*,*,double,direct")
4608   (set_attr "fp_int_src" "true")])
4609
4610(define_insn "*floatdidf2_sse"
4611  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4612	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4613  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4614  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4615  [(set_attr "type" "sseicvt")
4616   (set_attr "mode" "DF")
4617   (set_attr "athlon_decode" "double,direct")
4618   (set_attr "fp_int_src" "true")])
4619
4620(define_insn "*floatdidf2_i387"
4621  [(set (match_operand:DF 0 "register_operand" "=f,f")
4622	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4623  "TARGET_80387"
4624  "@
4625   fild%z1\t%1
4626   #"
4627  [(set_attr "type" "fmov,multi")
4628   (set_attr "mode" "DF")
4629   (set_attr "unit" "*,i387")
4630   (set_attr "fp_int_src" "true")])
4631
4632(define_insn "floathixf2"
4633  [(set (match_operand:XF 0 "register_operand" "=f,f")
4634	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4635  "TARGET_80387"
4636  "@
4637   fild%z1\t%1
4638   #"
4639  [(set_attr "type" "fmov,multi")
4640   (set_attr "mode" "XF")
4641   (set_attr "unit" "*,i387")
4642   (set_attr "fp_int_src" "true")])
4643
4644(define_insn "floatsixf2"
4645  [(set (match_operand:XF 0 "register_operand" "=f,f")
4646	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4647  "TARGET_80387"
4648  "@
4649   fild%z1\t%1
4650   #"
4651  [(set_attr "type" "fmov,multi")
4652   (set_attr "mode" "XF")
4653   (set_attr "unit" "*,i387")
4654   (set_attr "fp_int_src" "true")])
4655
4656(define_insn "floatdixf2"
4657  [(set (match_operand:XF 0 "register_operand" "=f,f")
4658	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4659  "TARGET_80387"
4660  "@
4661   fild%z1\t%1
4662   #"
4663  [(set_attr "type" "fmov,multi")
4664   (set_attr "mode" "XF")
4665   (set_attr "unit" "*,i387")
4666   (set_attr "fp_int_src" "true")])
4667
4668;; %%% Kill these when reload knows how to do it.
4669(define_split
4670  [(set (match_operand 0 "fp_register_operand" "")
4671	(float (match_operand 1 "register_operand" "")))]
4672  "reload_completed
4673   && TARGET_80387
4674   && FLOAT_MODE_P (GET_MODE (operands[0]))"
4675  [(const_int 0)]
4676{
4677  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4678  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4679  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4680  ix86_free_from_memory (GET_MODE (operands[1]));
4681  DONE;
4682})
4683
4684(define_expand "floatunssisf2"
4685  [(use (match_operand:SF 0 "register_operand" ""))
4686   (use (match_operand:SI 1 "register_operand" ""))]
4687  "!TARGET_64BIT && TARGET_SSE_MATH"
4688  "x86_emit_floatuns (operands); DONE;")
4689
4690(define_expand "floatunsdisf2"
4691  [(use (match_operand:SF 0 "register_operand" ""))
4692   (use (match_operand:DI 1 "register_operand" ""))]
4693  "TARGET_64BIT && TARGET_SSE_MATH"
4694  "x86_emit_floatuns (operands); DONE;")
4695
4696(define_expand "floatunsdidf2"
4697  [(use (match_operand:DF 0 "register_operand" ""))
4698   (use (match_operand:DI 1 "register_operand" ""))]
4699  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4700  "x86_emit_floatuns (operands); DONE;")
4701
4702;; SSE extract/set expanders
4703
4704
4705;; Add instructions
4706
4707;; %%% splits for addditi3
4708
4709(define_expand "addti3"
4710  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4711	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4712		 (match_operand:TI 2 "x86_64_general_operand" "")))
4713   (clobber (reg:CC FLAGS_REG))]
4714  "TARGET_64BIT"
4715  "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4716
4717(define_insn "*addti3_1"
4718  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4719	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4720		 (match_operand:TI 2 "general_operand" "roiF,riF")))
4721   (clobber (reg:CC FLAGS_REG))]
4722  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4723  "#")
4724
4725(define_split
4726  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4727	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4728		 (match_operand:TI 2 "general_operand" "")))
4729   (clobber (reg:CC FLAGS_REG))]
4730  "TARGET_64BIT && reload_completed"
4731  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4732					  UNSPEC_ADD_CARRY))
4733	      (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4734   (parallel [(set (match_dup 3)
4735		   (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4736				     (match_dup 4))
4737			    (match_dup 5)))
4738	      (clobber (reg:CC FLAGS_REG))])]
4739  "split_ti (operands+0, 1, operands+0, operands+3);
4740   split_ti (operands+1, 1, operands+1, operands+4);
4741   split_ti (operands+2, 1, operands+2, operands+5);")
4742
4743;; %%% splits for addsidi3
4744;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4745;	(plus:DI (match_operand:DI 1 "general_operand" "")
4746;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4747
4748(define_expand "adddi3"
4749  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4750	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4751		 (match_operand:DI 2 "x86_64_general_operand" "")))
4752   (clobber (reg:CC FLAGS_REG))]
4753  ""
4754  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4755
4756(define_insn "*adddi3_1"
4757  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4758	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4759		 (match_operand:DI 2 "general_operand" "roiF,riF")))
4760   (clobber (reg:CC FLAGS_REG))]
4761  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4762  "#")
4763
4764(define_split
4765  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4766	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4767		 (match_operand:DI 2 "general_operand" "")))
4768   (clobber (reg:CC FLAGS_REG))]
4769  "!TARGET_64BIT && reload_completed"
4770  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4771					  UNSPEC_ADD_CARRY))
4772	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4773   (parallel [(set (match_dup 3)
4774		   (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4775				     (match_dup 4))
4776			    (match_dup 5)))
4777	      (clobber (reg:CC FLAGS_REG))])]
4778  "split_di (operands+0, 1, operands+0, operands+3);
4779   split_di (operands+1, 1, operands+1, operands+4);
4780   split_di (operands+2, 1, operands+2, operands+5);")
4781
4782(define_insn "adddi3_carry_rex64"
4783  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4784	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4785			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4786		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4787   (clobber (reg:CC FLAGS_REG))]
4788  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4789  "adc{q}\t{%2, %0|%0, %2}"
4790  [(set_attr "type" "alu")
4791   (set_attr "pent_pair" "pu")
4792   (set_attr "mode" "DI")])
4793
4794(define_insn "*adddi3_cc_rex64"
4795  [(set (reg:CC FLAGS_REG)
4796	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4797		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4798		   UNSPEC_ADD_CARRY))
4799   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4800	(plus:DI (match_dup 1) (match_dup 2)))]
4801  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4802  "add{q}\t{%2, %0|%0, %2}"
4803  [(set_attr "type" "alu")
4804   (set_attr "mode" "DI")])
4805
4806(define_insn "addqi3_carry"
4807  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4808	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4809			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4810		   (match_operand:QI 2 "general_operand" "qi,qm")))
4811   (clobber (reg:CC FLAGS_REG))]
4812  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4813  "adc{b}\t{%2, %0|%0, %2}"
4814  [(set_attr "type" "alu")
4815   (set_attr "pent_pair" "pu")
4816   (set_attr "mode" "QI")])
4817
4818(define_insn "addhi3_carry"
4819  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4820	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4821			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4822		   (match_operand:HI 2 "general_operand" "ri,rm")))
4823   (clobber (reg:CC FLAGS_REG))]
4824  "ix86_binary_operator_ok (PLUS, HImode, operands)"
4825  "adc{w}\t{%2, %0|%0, %2}"
4826  [(set_attr "type" "alu")
4827   (set_attr "pent_pair" "pu")
4828   (set_attr "mode" "HI")])
4829
4830(define_insn "addsi3_carry"
4831  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4832	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4833			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4834		   (match_operand:SI 2 "general_operand" "ri,rm")))
4835   (clobber (reg:CC FLAGS_REG))]
4836  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4837  "adc{l}\t{%2, %0|%0, %2}"
4838  [(set_attr "type" "alu")
4839   (set_attr "pent_pair" "pu")
4840   (set_attr "mode" "SI")])
4841
4842(define_insn "*addsi3_carry_zext"
4843  [(set (match_operand:DI 0 "register_operand" "=r")
4844	  (zero_extend:DI 
4845	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4846			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
4847		     (match_operand:SI 2 "general_operand" "rim"))))
4848   (clobber (reg:CC FLAGS_REG))]
4849  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4850  "adc{l}\t{%2, %k0|%k0, %2}"
4851  [(set_attr "type" "alu")
4852   (set_attr "pent_pair" "pu")
4853   (set_attr "mode" "SI")])
4854
4855(define_insn "*addsi3_cc"
4856  [(set (reg:CC FLAGS_REG)
4857	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4858		    (match_operand:SI 2 "general_operand" "ri,rm")]
4859		   UNSPEC_ADD_CARRY))
4860   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4861	(plus:SI (match_dup 1) (match_dup 2)))]
4862  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4863  "add{l}\t{%2, %0|%0, %2}"
4864  [(set_attr "type" "alu")
4865   (set_attr "mode" "SI")])
4866
4867(define_insn "addqi3_cc"
4868  [(set (reg:CC FLAGS_REG)
4869	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4870		    (match_operand:QI 2 "general_operand" "qi,qm")]
4871		   UNSPEC_ADD_CARRY))
4872   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4873	(plus:QI (match_dup 1) (match_dup 2)))]
4874  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4875  "add{b}\t{%2, %0|%0, %2}"
4876  [(set_attr "type" "alu")
4877   (set_attr "mode" "QI")])
4878
4879(define_expand "addsi3"
4880  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4881		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4882			    (match_operand:SI 2 "general_operand" "")))
4883	      (clobber (reg:CC FLAGS_REG))])]
4884  ""
4885  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4886
4887(define_insn "*lea_1"
4888  [(set (match_operand:SI 0 "register_operand" "=r")
4889	(match_operand:SI 1 "no_seg_address_operand" "p"))]
4890  "!TARGET_64BIT"
4891  "lea{l}\t{%a1, %0|%0, %a1}"
4892  [(set_attr "type" "lea")
4893   (set_attr "mode" "SI")])
4894
4895(define_insn "*lea_1_rex64"
4896  [(set (match_operand:SI 0 "register_operand" "=r")
4897	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4898  "TARGET_64BIT"
4899  "lea{l}\t{%a1, %0|%0, %a1}"
4900  [(set_attr "type" "lea")
4901   (set_attr "mode" "SI")])
4902
4903(define_insn "*lea_1_zext"
4904  [(set (match_operand:DI 0 "register_operand" "=r")
4905	(zero_extend:DI
4906	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4907  "TARGET_64BIT"
4908  "lea{l}\t{%a1, %k0|%k0, %a1}"
4909  [(set_attr "type" "lea")
4910   (set_attr "mode" "SI")])
4911
4912(define_insn "*lea_2_rex64"
4913  [(set (match_operand:DI 0 "register_operand" "=r")
4914	(match_operand:DI 1 "no_seg_address_operand" "p"))]
4915  "TARGET_64BIT"
4916  "lea{q}\t{%a1, %0|%0, %a1}"
4917  [(set_attr "type" "lea")
4918   (set_attr "mode" "DI")])
4919
4920;; The lea patterns for non-Pmodes needs to be matched by several
4921;; insns converted to real lea by splitters.
4922
4923(define_insn_and_split "*lea_general_1"
4924  [(set (match_operand 0 "register_operand" "=r")
4925	(plus (plus (match_operand 1 "index_register_operand" "l")
4926		    (match_operand 2 "register_operand" "r"))
4927	      (match_operand 3 "immediate_operand" "i")))]
4928  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4929    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4930   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4931   && GET_MODE (operands[0]) == GET_MODE (operands[1])
4932   && GET_MODE (operands[0]) == GET_MODE (operands[2])
4933   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4934       || GET_MODE (operands[3]) == VOIDmode)"
4935  "#"
4936  "&& reload_completed"
4937  [(const_int 0)]
4938{
4939  rtx pat;
4940  operands[0] = gen_lowpart (SImode, operands[0]);
4941  operands[1] = gen_lowpart (Pmode, operands[1]);
4942  operands[2] = gen_lowpart (Pmode, operands[2]);
4943  operands[3] = gen_lowpart (Pmode, operands[3]);
4944  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4945  		      operands[3]);
4946  if (Pmode != SImode)
4947    pat = gen_rtx_SUBREG (SImode, pat, 0);
4948  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4949  DONE;
4950}
4951  [(set_attr "type" "lea")
4952   (set_attr "mode" "SI")])
4953
4954(define_insn_and_split "*lea_general_1_zext"
4955  [(set (match_operand:DI 0 "register_operand" "=r")
4956	(zero_extend:DI
4957	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4958			    (match_operand:SI 2 "register_operand" "r"))
4959		   (match_operand:SI 3 "immediate_operand" "i"))))]
4960  "TARGET_64BIT"
4961  "#"
4962  "&& reload_completed"
4963  [(set (match_dup 0)
4964	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4965						     (match_dup 2))
4966					    (match_dup 3)) 0)))]
4967{
4968  operands[1] = gen_lowpart (Pmode, operands[1]);
4969  operands[2] = gen_lowpart (Pmode, operands[2]);
4970  operands[3] = gen_lowpart (Pmode, operands[3]);
4971}
4972  [(set_attr "type" "lea")
4973   (set_attr "mode" "SI")])
4974
4975(define_insn_and_split "*lea_general_2"
4976  [(set (match_operand 0 "register_operand" "=r")
4977	(plus (mult (match_operand 1 "index_register_operand" "l")
4978		    (match_operand 2 "const248_operand" "i"))
4979	      (match_operand 3 "nonmemory_operand" "ri")))]
4980  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4981    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4982   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4983   && GET_MODE (operands[0]) == GET_MODE (operands[1])
4984   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4985       || GET_MODE (operands[3]) == VOIDmode)"
4986  "#"
4987  "&& reload_completed"
4988  [(const_int 0)]
4989{
4990  rtx pat;
4991  operands[0] = gen_lowpart (SImode, operands[0]);
4992  operands[1] = gen_lowpart (Pmode, operands[1]);
4993  operands[3] = gen_lowpart (Pmode, operands[3]);
4994  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4995  		      operands[3]);
4996  if (Pmode != SImode)
4997    pat = gen_rtx_SUBREG (SImode, pat, 0);
4998  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4999  DONE;
5000}
5001  [(set_attr "type" "lea")
5002   (set_attr "mode" "SI")])
5003
5004(define_insn_and_split "*lea_general_2_zext"
5005  [(set (match_operand:DI 0 "register_operand" "=r")
5006	(zero_extend:DI
5007	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5008			    (match_operand:SI 2 "const248_operand" "n"))
5009		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5010  "TARGET_64BIT"
5011  "#"
5012  "&& reload_completed"
5013  [(set (match_dup 0)
5014	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5015						     (match_dup 2))
5016					    (match_dup 3)) 0)))]
5017{
5018  operands[1] = gen_lowpart (Pmode, operands[1]);
5019  operands[3] = gen_lowpart (Pmode, operands[3]);
5020}
5021  [(set_attr "type" "lea")
5022   (set_attr "mode" "SI")])
5023
5024(define_insn_and_split "*lea_general_3"
5025  [(set (match_operand 0 "register_operand" "=r")
5026	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
5027			  (match_operand 2 "const248_operand" "i"))
5028		    (match_operand 3 "register_operand" "r"))
5029	      (match_operand 4 "immediate_operand" "i")))]
5030  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5031    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5032   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5033   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5034   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5035  "#"
5036  "&& reload_completed"
5037  [(const_int 0)]
5038{
5039  rtx pat;
5040  operands[0] = gen_lowpart (SImode, operands[0]);
5041  operands[1] = gen_lowpart (Pmode, operands[1]);
5042  operands[3] = gen_lowpart (Pmode, operands[3]);
5043  operands[4] = gen_lowpart (Pmode, operands[4]);
5044  pat = gen_rtx_PLUS (Pmode,
5045  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5046		      					 operands[2]),
5047				    operands[3]),
5048  		      operands[4]);
5049  if (Pmode != SImode)
5050    pat = gen_rtx_SUBREG (SImode, pat, 0);
5051  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5052  DONE;
5053}
5054  [(set_attr "type" "lea")
5055   (set_attr "mode" "SI")])
5056
5057(define_insn_and_split "*lea_general_3_zext"
5058  [(set (match_operand:DI 0 "register_operand" "=r")
5059	(zero_extend:DI
5060	  (plus:SI (plus:SI (mult:SI
5061			      (match_operand:SI 1 "index_register_operand" "l")
5062			      (match_operand:SI 2 "const248_operand" "n"))
5063			    (match_operand:SI 3 "register_operand" "r"))
5064		   (match_operand:SI 4 "immediate_operand" "i"))))]
5065  "TARGET_64BIT"
5066  "#"
5067  "&& reload_completed"
5068  [(set (match_dup 0)
5069	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5070							      (match_dup 2))
5071						     (match_dup 3))
5072					    (match_dup 4)) 0)))]
5073{
5074  operands[1] = gen_lowpart (Pmode, operands[1]);
5075  operands[3] = gen_lowpart (Pmode, operands[3]);
5076  operands[4] = gen_lowpart (Pmode, operands[4]);
5077}
5078  [(set_attr "type" "lea")
5079   (set_attr "mode" "SI")])
5080
5081(define_insn "*adddi_1_rex64"
5082  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5083	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5084		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5085   (clobber (reg:CC FLAGS_REG))]
5086  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5087{
5088  switch (get_attr_type (insn))
5089    {
5090    case TYPE_LEA:
5091      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5092      return "lea{q}\t{%a2, %0|%0, %a2}";
5093
5094    case TYPE_INCDEC:
5095      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5096      if (operands[2] == const1_rtx)
5097        return "inc{q}\t%0";
5098      else
5099        {
5100	  gcc_assert (operands[2] == constm1_rtx);
5101          return "dec{q}\t%0";
5102	}
5103
5104    default:
5105      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5106
5107      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5108	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5109      if (GET_CODE (operands[2]) == CONST_INT
5110	  /* Avoid overflows.  */
5111	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5112          && (INTVAL (operands[2]) == 128
5113	      || (INTVAL (operands[2]) < 0
5114		  && INTVAL (operands[2]) != -128)))
5115        {
5116          operands[2] = GEN_INT (-INTVAL (operands[2]));
5117          return "sub{q}\t{%2, %0|%0, %2}";
5118        }
5119      return "add{q}\t{%2, %0|%0, %2}";
5120    }
5121}
5122  [(set (attr "type")
5123     (cond [(eq_attr "alternative" "2")
5124	      (const_string "lea")
5125	    ; Current assemblers are broken and do not allow @GOTOFF in
5126	    ; ought but a memory context.
5127	    (match_operand:DI 2 "pic_symbolic_operand" "")
5128	      (const_string "lea")
5129	    (match_operand:DI 2 "incdec_operand" "")
5130	      (const_string "incdec")
5131	   ]
5132	   (const_string "alu")))
5133   (set_attr "mode" "DI")])
5134
5135;; Convert lea to the lea pattern to avoid flags dependency.
5136(define_split
5137  [(set (match_operand:DI 0 "register_operand" "")
5138	(plus:DI (match_operand:DI 1 "register_operand" "")
5139		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5140   (clobber (reg:CC FLAGS_REG))]
5141  "TARGET_64BIT && reload_completed
5142   && true_regnum (operands[0]) != true_regnum (operands[1])"
5143  [(set (match_dup 0)
5144	(plus:DI (match_dup 1)
5145		 (match_dup 2)))]
5146  "")
5147
5148(define_insn "*adddi_2_rex64"
5149  [(set (reg FLAGS_REG)
5150	(compare
5151	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5152		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5153	  (const_int 0)))			
5154   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5155	(plus:DI (match_dup 1) (match_dup 2)))]
5156  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5157   && ix86_binary_operator_ok (PLUS, DImode, operands)
5158   /* Current assemblers are broken and do not allow @GOTOFF in
5159      ought but a memory context.  */
5160   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5161{
5162  switch (get_attr_type (insn))
5163    {
5164    case TYPE_INCDEC:
5165      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5166      if (operands[2] == const1_rtx)
5167        return "inc{q}\t%0";
5168      else
5169        {
5170	  gcc_assert (operands[2] == constm1_rtx);
5171          return "dec{q}\t%0";
5172	}
5173
5174    default:
5175      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5176      /* ???? We ought to handle there the 32bit case too
5177	 - do we need new constraint?  */
5178      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5179	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5180      if (GET_CODE (operands[2]) == CONST_INT
5181	  /* Avoid overflows.  */
5182	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5183          && (INTVAL (operands[2]) == 128
5184	      || (INTVAL (operands[2]) < 0
5185		  && INTVAL (operands[2]) != -128)))
5186        {
5187          operands[2] = GEN_INT (-INTVAL (operands[2]));
5188          return "sub{q}\t{%2, %0|%0, %2}";
5189        }
5190      return "add{q}\t{%2, %0|%0, %2}";
5191    }
5192}
5193  [(set (attr "type")
5194     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5195	(const_string "incdec")
5196	(const_string "alu")))
5197   (set_attr "mode" "DI")])
5198
5199(define_insn "*adddi_3_rex64"
5200  [(set (reg FLAGS_REG)
5201	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5202		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5203   (clobber (match_scratch:DI 0 "=r"))]
5204  "TARGET_64BIT
5205   && ix86_match_ccmode (insn, CCZmode)
5206   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5207   /* Current assemblers are broken and do not allow @GOTOFF in
5208      ought but a memory context.  */
5209   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5210{
5211  switch (get_attr_type (insn))
5212    {
5213    case TYPE_INCDEC:
5214      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5215      if (operands[2] == const1_rtx)
5216        return "inc{q}\t%0";
5217      else
5218        {
5219	  gcc_assert (operands[2] == constm1_rtx);
5220          return "dec{q}\t%0";
5221	}
5222
5223    default:
5224      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5225      /* ???? We ought to handle there the 32bit case too
5226	 - do we need new constraint?  */
5227      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5228	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5229      if (GET_CODE (operands[2]) == CONST_INT
5230	  /* Avoid overflows.  */
5231	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5232          && (INTVAL (operands[2]) == 128
5233	      || (INTVAL (operands[2]) < 0
5234		  && INTVAL (operands[2]) != -128)))
5235        {
5236          operands[2] = GEN_INT (-INTVAL (operands[2]));
5237          return "sub{q}\t{%2, %0|%0, %2}";
5238        }
5239      return "add{q}\t{%2, %0|%0, %2}";
5240    }
5241}
5242  [(set (attr "type")
5243     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5244	(const_string "incdec")
5245	(const_string "alu")))
5246   (set_attr "mode" "DI")])
5247
5248; For comparisons against 1, -1 and 128, we may generate better code
5249; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5250; is matched then.  We can't accept general immediate, because for
5251; case of overflows,  the result is messed up.
5252; This pattern also don't hold of 0x8000000000000000, since the value overflows
5253; when negated.
5254; Also carry flag is reversed compared to cmp, so this conversion is valid
5255; only for comparisons not depending on it.
5256(define_insn "*adddi_4_rex64"
5257  [(set (reg FLAGS_REG)
5258	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5259		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5260   (clobber (match_scratch:DI 0 "=rm"))]
5261  "TARGET_64BIT
5262   &&  ix86_match_ccmode (insn, CCGCmode)"
5263{
5264  switch (get_attr_type (insn))
5265    {
5266    case TYPE_INCDEC:
5267      if (operands[2] == constm1_rtx)
5268        return "inc{q}\t%0";
5269      else
5270        {
5271	  gcc_assert (operands[2] == const1_rtx);
5272          return "dec{q}\t%0";
5273	}
5274
5275    default:
5276      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5278	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5279      if ((INTVAL (operands[2]) == -128
5280	   || (INTVAL (operands[2]) > 0
5281	       && INTVAL (operands[2]) != 128))
5282	  /* Avoid overflows.  */
5283	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5284	return "sub{q}\t{%2, %0|%0, %2}";
5285      operands[2] = GEN_INT (-INTVAL (operands[2]));
5286      return "add{q}\t{%2, %0|%0, %2}";
5287    }
5288}
5289  [(set (attr "type")
5290     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5291	(const_string "incdec")
5292	(const_string "alu")))
5293   (set_attr "mode" "DI")])
5294
5295(define_insn "*adddi_5_rex64"
5296  [(set (reg FLAGS_REG)
5297	(compare
5298	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5299		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5300	  (const_int 0)))			
5301   (clobber (match_scratch:DI 0 "=r"))]
5302  "TARGET_64BIT
5303   && ix86_match_ccmode (insn, CCGOCmode)
5304   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5305   /* Current assemblers are broken and do not allow @GOTOFF in
5306      ought but a memory context.  */
5307   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5308{
5309  switch (get_attr_type (insn))
5310    {
5311    case TYPE_INCDEC:
5312      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5313      if (operands[2] == const1_rtx)
5314        return "inc{q}\t%0";
5315      else
5316        {
5317          gcc_assert (operands[2] == constm1_rtx);
5318          return "dec{q}\t%0";
5319	}
5320
5321    default:
5322      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5324	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5325      if (GET_CODE (operands[2]) == CONST_INT
5326	  /* Avoid overflows.  */
5327	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5328          && (INTVAL (operands[2]) == 128
5329	      || (INTVAL (operands[2]) < 0
5330		  && INTVAL (operands[2]) != -128)))
5331        {
5332          operands[2] = GEN_INT (-INTVAL (operands[2]));
5333          return "sub{q}\t{%2, %0|%0, %2}";
5334        }
5335      return "add{q}\t{%2, %0|%0, %2}";
5336    }
5337}
5338  [(set (attr "type")
5339     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5340	(const_string "incdec")
5341	(const_string "alu")))
5342   (set_attr "mode" "DI")])
5343
5344
5345(define_insn "*addsi_1"
5346  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5347	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5348		 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5349   (clobber (reg:CC FLAGS_REG))]
5350  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5351{
5352  switch (get_attr_type (insn))
5353    {
5354    case TYPE_LEA:
5355      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5356      return "lea{l}\t{%a2, %0|%0, %a2}";
5357
5358    case TYPE_INCDEC:
5359      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360      if (operands[2] == const1_rtx)
5361        return "inc{l}\t%0";
5362      else
5363	{
5364  	  gcc_assert (operands[2] == constm1_rtx);
5365          return "dec{l}\t%0";
5366	}
5367
5368    default:
5369      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370
5371      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5372	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5373      if (GET_CODE (operands[2]) == CONST_INT
5374          && (INTVAL (operands[2]) == 128
5375	      || (INTVAL (operands[2]) < 0
5376		  && INTVAL (operands[2]) != -128)))
5377        {
5378          operands[2] = GEN_INT (-INTVAL (operands[2]));
5379          return "sub{l}\t{%2, %0|%0, %2}";
5380        }
5381      return "add{l}\t{%2, %0|%0, %2}";
5382    }
5383}
5384  [(set (attr "type")
5385     (cond [(eq_attr "alternative" "2")
5386	      (const_string "lea")
5387	    ; Current assemblers are broken and do not allow @GOTOFF in
5388	    ; ought but a memory context.
5389	    (match_operand:SI 2 "pic_symbolic_operand" "")
5390	      (const_string "lea")
5391	    (match_operand:SI 2 "incdec_operand" "")
5392	      (const_string "incdec")
5393	   ]
5394	   (const_string "alu")))
5395   (set_attr "mode" "SI")])
5396
5397;; Convert lea to the lea pattern to avoid flags dependency.
5398(define_split
5399  [(set (match_operand 0 "register_operand" "")
5400	(plus (match_operand 1 "register_operand" "")
5401              (match_operand 2 "nonmemory_operand" "")))
5402   (clobber (reg:CC FLAGS_REG))]
5403  "reload_completed
5404   && true_regnum (operands[0]) != true_regnum (operands[1])"
5405  [(const_int 0)]
5406{
5407  rtx pat;
5408  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5409     may confuse gen_lowpart.  */
5410  if (GET_MODE (operands[0]) != Pmode)
5411    {
5412      operands[1] = gen_lowpart (Pmode, operands[1]);
5413      operands[2] = gen_lowpart (Pmode, operands[2]);
5414    }
5415  operands[0] = gen_lowpart (SImode, operands[0]);
5416  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5417  if (Pmode != SImode)
5418    pat = gen_rtx_SUBREG (SImode, pat, 0);
5419  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5420  DONE;
5421})
5422
5423;; It may seem that nonimmediate operand is proper one for operand 1.
5424;; The addsi_1 pattern allows nonimmediate operand at that place and
5425;; we take care in ix86_binary_operator_ok to not allow two memory
5426;; operands so proper swapping will be done in reload.  This allow
5427;; patterns constructed from addsi_1 to match.
5428(define_insn "addsi_1_zext"
5429  [(set (match_operand:DI 0 "register_operand" "=r,r")
5430	(zero_extend:DI
5431	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5432		   (match_operand:SI 2 "general_operand" "rmni,lni"))))
5433   (clobber (reg:CC FLAGS_REG))]
5434  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5435{
5436  switch (get_attr_type (insn))
5437    {
5438    case TYPE_LEA:
5439      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5440      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5441
5442    case TYPE_INCDEC:
5443      if (operands[2] == const1_rtx)
5444        return "inc{l}\t%k0";
5445      else
5446        {
5447	  gcc_assert (operands[2] == constm1_rtx);
5448          return "dec{l}\t%k0";
5449	}
5450
5451    default:
5452      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5453	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5454      if (GET_CODE (operands[2]) == CONST_INT
5455          && (INTVAL (operands[2]) == 128
5456	      || (INTVAL (operands[2]) < 0
5457		  && INTVAL (operands[2]) != -128)))
5458        {
5459          operands[2] = GEN_INT (-INTVAL (operands[2]));
5460          return "sub{l}\t{%2, %k0|%k0, %2}";
5461        }
5462      return "add{l}\t{%2, %k0|%k0, %2}";
5463    }
5464}
5465  [(set (attr "type")
5466     (cond [(eq_attr "alternative" "1")
5467	      (const_string "lea")
5468	    ; Current assemblers are broken and do not allow @GOTOFF in
5469	    ; ought but a memory context.
5470	    (match_operand:SI 2 "pic_symbolic_operand" "")
5471	      (const_string "lea")
5472	    (match_operand:SI 2 "incdec_operand" "")
5473	      (const_string "incdec")
5474	   ]
5475	   (const_string "alu")))
5476   (set_attr "mode" "SI")])
5477
5478;; Convert lea to the lea pattern to avoid flags dependency.
5479(define_split
5480  [(set (match_operand:DI 0 "register_operand" "")
5481	(zero_extend:DI
5482	  (plus:SI (match_operand:SI 1 "register_operand" "")
5483		   (match_operand:SI 2 "nonmemory_operand" ""))))
5484   (clobber (reg:CC FLAGS_REG))]
5485  "TARGET_64BIT && reload_completed
5486   && true_regnum (operands[0]) != true_regnum (operands[1])"
5487  [(set (match_dup 0)
5488	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5489{
5490  operands[1] = gen_lowpart (Pmode, operands[1]);
5491  operands[2] = gen_lowpart (Pmode, operands[2]);
5492})
5493
5494(define_insn "*addsi_2"
5495  [(set (reg FLAGS_REG)
5496	(compare
5497	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5498		   (match_operand:SI 2 "general_operand" "rmni,rni"))
5499	  (const_int 0)))			
5500   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5501	(plus:SI (match_dup 1) (match_dup 2)))]
5502  "ix86_match_ccmode (insn, CCGOCmode)
5503   && ix86_binary_operator_ok (PLUS, SImode, operands)
5504   /* Current assemblers are broken and do not allow @GOTOFF in
5505      ought but a memory context.  */
5506   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5507{
5508  switch (get_attr_type (insn))
5509    {
5510    case TYPE_INCDEC:
5511      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5512      if (operands[2] == const1_rtx)
5513        return "inc{l}\t%0";
5514      else
5515        {
5516	  gcc_assert (operands[2] == constm1_rtx);
5517          return "dec{l}\t%0";
5518	}
5519
5520    default:
5521      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5522      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5523	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5524      if (GET_CODE (operands[2]) == CONST_INT
5525          && (INTVAL (operands[2]) == 128
5526	      || (INTVAL (operands[2]) < 0
5527		  && INTVAL (operands[2]) != -128)))
5528        {
5529          operands[2] = GEN_INT (-INTVAL (operands[2]));
5530          return "sub{l}\t{%2, %0|%0, %2}";
5531        }
5532      return "add{l}\t{%2, %0|%0, %2}";
5533    }
5534}
5535  [(set (attr "type")
5536     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5537	(const_string "incdec")
5538	(const_string "alu")))
5539   (set_attr "mode" "SI")])
5540
5541;; See comment for addsi_1_zext why we do use nonimmediate_operand
5542(define_insn "*addsi_2_zext"
5543  [(set (reg FLAGS_REG)
5544	(compare
5545	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5546		   (match_operand:SI 2 "general_operand" "rmni"))
5547	  (const_int 0)))			
5548   (set (match_operand:DI 0 "register_operand" "=r")
5549	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5550  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5551   && ix86_binary_operator_ok (PLUS, SImode, operands)
5552   /* Current assemblers are broken and do not allow @GOTOFF in
5553      ought but a memory context.  */
5554   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555{
5556  switch (get_attr_type (insn))
5557    {
5558    case TYPE_INCDEC:
5559      if (operands[2] == const1_rtx)
5560        return "inc{l}\t%k0";
5561      else
5562	{
5563	  gcc_assert (operands[2] == constm1_rtx);
5564          return "dec{l}\t%k0";
5565	}
5566
5567    default:
5568      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5569	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5570      if (GET_CODE (operands[2]) == CONST_INT
5571          && (INTVAL (operands[2]) == 128
5572	      || (INTVAL (operands[2]) < 0
5573		  && INTVAL (operands[2]) != -128)))
5574        {
5575          operands[2] = GEN_INT (-INTVAL (operands[2]));
5576          return "sub{l}\t{%2, %k0|%k0, %2}";
5577        }
5578      return "add{l}\t{%2, %k0|%k0, %2}";
5579    }
5580}
5581  [(set (attr "type")
5582     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5583	(const_string "incdec")
5584	(const_string "alu")))
5585   (set_attr "mode" "SI")])
5586
5587(define_insn "*addsi_3"
5588  [(set (reg FLAGS_REG)
5589	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5590		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5591   (clobber (match_scratch:SI 0 "=r"))]
5592  "ix86_match_ccmode (insn, CCZmode)
5593   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5594   /* Current assemblers are broken and do not allow @GOTOFF in
5595      ought but a memory context.  */
5596   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5597{
5598  switch (get_attr_type (insn))
5599    {
5600    case TYPE_INCDEC:
5601      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5602      if (operands[2] == const1_rtx)
5603        return "inc{l}\t%0";
5604      else
5605        {
5606	  gcc_assert (operands[2] == constm1_rtx);
5607          return "dec{l}\t%0";
5608	}
5609
5610    default:
5611      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5612      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5613	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5614      if (GET_CODE (operands[2]) == CONST_INT
5615          && (INTVAL (operands[2]) == 128
5616	      || (INTVAL (operands[2]) < 0
5617		  && INTVAL (operands[2]) != -128)))
5618        {
5619          operands[2] = GEN_INT (-INTVAL (operands[2]));
5620          return "sub{l}\t{%2, %0|%0, %2}";
5621        }
5622      return "add{l}\t{%2, %0|%0, %2}";
5623    }
5624}
5625  [(set (attr "type")
5626     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5627	(const_string "incdec")
5628	(const_string "alu")))
5629   (set_attr "mode" "SI")])
5630
5631;; See comment for addsi_1_zext why we do use nonimmediate_operand
5632(define_insn "*addsi_3_zext"
5633  [(set (reg FLAGS_REG)
5634	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5635		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5636   (set (match_operand:DI 0 "register_operand" "=r")
5637	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5638  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5639   && ix86_binary_operator_ok (PLUS, SImode, operands)
5640   /* Current assemblers are broken and do not allow @GOTOFF in
5641      ought but a memory context.  */
5642   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643{
5644  switch (get_attr_type (insn))
5645    {
5646    case TYPE_INCDEC:
5647      if (operands[2] == const1_rtx)
5648        return "inc{l}\t%k0";
5649      else
5650        {
5651	  gcc_assert (operands[2] == constm1_rtx);
5652          return "dec{l}\t%k0";
5653	}
5654
5655    default:
5656      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5657	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5658      if (GET_CODE (operands[2]) == CONST_INT
5659          && (INTVAL (operands[2]) == 128
5660	      || (INTVAL (operands[2]) < 0
5661		  && INTVAL (operands[2]) != -128)))
5662        {
5663          operands[2] = GEN_INT (-INTVAL (operands[2]));
5664          return "sub{l}\t{%2, %k0|%k0, %2}";
5665        }
5666      return "add{l}\t{%2, %k0|%k0, %2}";
5667    }
5668}
5669  [(set (attr "type")
5670     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5671	(const_string "incdec")
5672	(const_string "alu")))
5673   (set_attr "mode" "SI")])
5674
5675; For comparisons against 1, -1 and 128, we may generate better code
5676; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5677; is matched then.  We can't accept general immediate, because for
5678; case of overflows,  the result is messed up.
5679; This pattern also don't hold of 0x80000000, since the value overflows
5680; when negated.
5681; Also carry flag is reversed compared to cmp, so this conversion is valid
5682; only for comparisons not depending on it.
5683(define_insn "*addsi_4"
5684  [(set (reg FLAGS_REG)
5685	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
5686		 (match_operand:SI 2 "const_int_operand" "n")))
5687   (clobber (match_scratch:SI 0 "=rm"))]
5688  "ix86_match_ccmode (insn, CCGCmode)
5689   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5690{
5691  switch (get_attr_type (insn))
5692    {
5693    case TYPE_INCDEC:
5694      if (operands[2] == constm1_rtx)
5695        return "inc{l}\t%0";
5696      else
5697        {
5698	  gcc_assert (operands[2] == const1_rtx);
5699          return "dec{l}\t%0";
5700	}
5701
5702    default:
5703      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5704      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5705	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5706      if ((INTVAL (operands[2]) == -128
5707	   || (INTVAL (operands[2]) > 0
5708	       && INTVAL (operands[2]) != 128)))
5709	return "sub{l}\t{%2, %0|%0, %2}";
5710      operands[2] = GEN_INT (-INTVAL (operands[2]));
5711      return "add{l}\t{%2, %0|%0, %2}";
5712    }
5713}
5714  [(set (attr "type")
5715     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5716	(const_string "incdec")
5717	(const_string "alu")))
5718   (set_attr "mode" "SI")])
5719
5720(define_insn "*addsi_5"
5721  [(set (reg FLAGS_REG)
5722	(compare
5723	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5724		   (match_operand:SI 2 "general_operand" "rmni"))
5725	  (const_int 0)))			
5726   (clobber (match_scratch:SI 0 "=r"))]
5727  "ix86_match_ccmode (insn, CCGOCmode)
5728   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5729   /* Current assemblers are broken and do not allow @GOTOFF in
5730      ought but a memory context.  */
5731   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5732{
5733  switch (get_attr_type (insn))
5734    {
5735    case TYPE_INCDEC:
5736      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5737      if (operands[2] == const1_rtx)
5738        return "inc{l}\t%0";
5739      else
5740        {
5741	  gcc_assert (operands[2] == constm1_rtx);
5742          return "dec{l}\t%0";
5743	}
5744
5745    default:
5746      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5747      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5748	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5749      if (GET_CODE (operands[2]) == CONST_INT
5750          && (INTVAL (operands[2]) == 128
5751	      || (INTVAL (operands[2]) < 0
5752		  && INTVAL (operands[2]) != -128)))
5753        {
5754          operands[2] = GEN_INT (-INTVAL (operands[2]));
5755          return "sub{l}\t{%2, %0|%0, %2}";
5756        }
5757      return "add{l}\t{%2, %0|%0, %2}";
5758    }
5759}
5760  [(set (attr "type")
5761     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5762	(const_string "incdec")
5763	(const_string "alu")))
5764   (set_attr "mode" "SI")])
5765
5766(define_expand "addhi3"
5767  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5768		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5769			    (match_operand:HI 2 "general_operand" "")))
5770	      (clobber (reg:CC FLAGS_REG))])]
5771  "TARGET_HIMODE_MATH"
5772  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5773
5774;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5775;; type optimizations enabled by define-splits.  This is not important
5776;; for PII, and in fact harmful because of partial register stalls.
5777
5778(define_insn "*addhi_1_lea"
5779  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5780	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5781		 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5782   (clobber (reg:CC FLAGS_REG))]
5783  "!TARGET_PARTIAL_REG_STALL
5784   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785{
5786  switch (get_attr_type (insn))
5787    {
5788    case TYPE_LEA:
5789      return "#";
5790    case TYPE_INCDEC:
5791      if (operands[2] == const1_rtx)
5792	return "inc{w}\t%0";
5793      else
5794	{
5795	  gcc_assert (operands[2] == constm1_rtx);
5796	  return "dec{w}\t%0";
5797	}
5798
5799    default:
5800      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5801	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5802      if (GET_CODE (operands[2]) == CONST_INT
5803          && (INTVAL (operands[2]) == 128
5804	      || (INTVAL (operands[2]) < 0
5805		  && INTVAL (operands[2]) != -128)))
5806	{
5807	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5808	  return "sub{w}\t{%2, %0|%0, %2}";
5809	}
5810      return "add{w}\t{%2, %0|%0, %2}";
5811    }
5812}
5813  [(set (attr "type")
5814     (if_then_else (eq_attr "alternative" "2")
5815	(const_string "lea")
5816	(if_then_else (match_operand:HI 2 "incdec_operand" "")
5817	   (const_string "incdec")
5818	   (const_string "alu"))))
5819   (set_attr "mode" "HI,HI,SI")])
5820
5821(define_insn "*addhi_1"
5822  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5823	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5824		 (match_operand:HI 2 "general_operand" "ri,rm")))
5825   (clobber (reg:CC FLAGS_REG))]
5826  "TARGET_PARTIAL_REG_STALL
5827   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5828{
5829  switch (get_attr_type (insn))
5830    {
5831    case TYPE_INCDEC:
5832      if (operands[2] == const1_rtx)
5833	return "inc{w}\t%0";
5834      else
5835        {
5836	  gcc_assert (operands[2] == constm1_rtx);
5837	  return "dec{w}\t%0";
5838	}
5839
5840    default:
5841      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843      if (GET_CODE (operands[2]) == CONST_INT
5844          && (INTVAL (operands[2]) == 128
5845	      || (INTVAL (operands[2]) < 0
5846		  && INTVAL (operands[2]) != -128)))
5847	{
5848	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5849	  return "sub{w}\t{%2, %0|%0, %2}";
5850	}
5851      return "add{w}\t{%2, %0|%0, %2}";
5852    }
5853}
5854  [(set (attr "type")
5855     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5856	(const_string "incdec")
5857	(const_string "alu")))
5858   (set_attr "mode" "HI")])
5859
5860(define_insn "*addhi_2"
5861  [(set (reg FLAGS_REG)
5862	(compare
5863	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5864		   (match_operand:HI 2 "general_operand" "rmni,rni"))
5865	  (const_int 0)))			
5866   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5867	(plus:HI (match_dup 1) (match_dup 2)))]
5868  "ix86_match_ccmode (insn, CCGOCmode)
5869   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5870{
5871  switch (get_attr_type (insn))
5872    {
5873    case TYPE_INCDEC:
5874      if (operands[2] == const1_rtx)
5875	return "inc{w}\t%0";
5876      else
5877        {
5878	  gcc_assert (operands[2] == constm1_rtx);
5879	  return "dec{w}\t%0";
5880	}
5881
5882    default:
5883      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5884	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5885      if (GET_CODE (operands[2]) == CONST_INT
5886          && (INTVAL (operands[2]) == 128
5887	      || (INTVAL (operands[2]) < 0
5888		  && INTVAL (operands[2]) != -128)))
5889	{
5890	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5891	  return "sub{w}\t{%2, %0|%0, %2}";
5892	}
5893      return "add{w}\t{%2, %0|%0, %2}";
5894    }
5895}
5896  [(set (attr "type")
5897     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5898	(const_string "incdec")
5899	(const_string "alu")))
5900   (set_attr "mode" "HI")])
5901
5902(define_insn "*addhi_3"
5903  [(set (reg FLAGS_REG)
5904	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5905		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5906   (clobber (match_scratch:HI 0 "=r"))]
5907  "ix86_match_ccmode (insn, CCZmode)
5908   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5909{
5910  switch (get_attr_type (insn))
5911    {
5912    case TYPE_INCDEC:
5913      if (operands[2] == const1_rtx)
5914	return "inc{w}\t%0";
5915      else
5916        {
5917	  gcc_assert (operands[2] == constm1_rtx);
5918	  return "dec{w}\t%0";
5919	}
5920
5921    default:
5922      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924      if (GET_CODE (operands[2]) == CONST_INT
5925          && (INTVAL (operands[2]) == 128
5926	      || (INTVAL (operands[2]) < 0
5927		  && INTVAL (operands[2]) != -128)))
5928	{
5929	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5930	  return "sub{w}\t{%2, %0|%0, %2}";
5931	}
5932      return "add{w}\t{%2, %0|%0, %2}";
5933    }
5934}
5935  [(set (attr "type")
5936     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5937	(const_string "incdec")
5938	(const_string "alu")))
5939   (set_attr "mode" "HI")])
5940
5941; See comments above addsi_4 for details.
5942(define_insn "*addhi_4"
5943  [(set (reg FLAGS_REG)
5944	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
5945		 (match_operand:HI 2 "const_int_operand" "n")))
5946   (clobber (match_scratch:HI 0 "=rm"))]
5947  "ix86_match_ccmode (insn, CCGCmode)
5948   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5949{
5950  switch (get_attr_type (insn))
5951    {
5952    case TYPE_INCDEC:
5953      if (operands[2] == constm1_rtx)
5954        return "inc{w}\t%0";
5955      else
5956	{
5957	  gcc_assert (operands[2] == const1_rtx);
5958          return "dec{w}\t%0";
5959	}
5960
5961    default:
5962      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5963      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5964	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5965      if ((INTVAL (operands[2]) == -128
5966	   || (INTVAL (operands[2]) > 0
5967	       && INTVAL (operands[2]) != 128)))
5968	return "sub{w}\t{%2, %0|%0, %2}";
5969      operands[2] = GEN_INT (-INTVAL (operands[2]));
5970      return "add{w}\t{%2, %0|%0, %2}";
5971    }
5972}
5973  [(set (attr "type")
5974     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975	(const_string "incdec")
5976	(const_string "alu")))
5977   (set_attr "mode" "SI")])
5978
5979
5980(define_insn "*addhi_5"
5981  [(set (reg FLAGS_REG)
5982	(compare
5983	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5984		   (match_operand:HI 2 "general_operand" "rmni"))
5985	  (const_int 0)))			
5986   (clobber (match_scratch:HI 0 "=r"))]
5987  "ix86_match_ccmode (insn, CCGOCmode)
5988   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5989{
5990  switch (get_attr_type (insn))
5991    {
5992    case TYPE_INCDEC:
5993      if (operands[2] == const1_rtx)
5994	return "inc{w}\t%0";
5995      else
5996	{
5997	  gcc_assert (operands[2] == constm1_rtx);
5998	  return "dec{w}\t%0";
5999	}
6000
6001    default:
6002      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6003	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6004      if (GET_CODE (operands[2]) == CONST_INT
6005          && (INTVAL (operands[2]) == 128
6006	      || (INTVAL (operands[2]) < 0
6007		  && INTVAL (operands[2]) != -128)))
6008	{
6009	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6010	  return "sub{w}\t{%2, %0|%0, %2}";
6011	}
6012      return "add{w}\t{%2, %0|%0, %2}";
6013    }
6014}
6015  [(set (attr "type")
6016     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6017	(const_string "incdec")
6018	(const_string "alu")))
6019   (set_attr "mode" "HI")])
6020
6021(define_expand "addqi3"
6022  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6023		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6024			    (match_operand:QI 2 "general_operand" "")))
6025	      (clobber (reg:CC FLAGS_REG))])]
6026  "TARGET_QIMODE_MATH"
6027  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6028
6029;; %%% Potential partial reg stall on alternative 2.  What to do?
6030(define_insn "*addqi_1_lea"
6031  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6032	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6033		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6034   (clobber (reg:CC FLAGS_REG))]
6035  "!TARGET_PARTIAL_REG_STALL
6036   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6037{
6038  int widen = (which_alternative == 2);
6039  switch (get_attr_type (insn))
6040    {
6041    case TYPE_LEA:
6042      return "#";
6043    case TYPE_INCDEC:
6044      if (operands[2] == const1_rtx)
6045	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6046      else
6047	{
6048	  gcc_assert (operands[2] == constm1_rtx);
6049	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6050	}
6051
6052    default:
6053      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6055      if (GET_CODE (operands[2]) == CONST_INT
6056          && (INTVAL (operands[2]) == 128
6057	      || (INTVAL (operands[2]) < 0
6058		  && INTVAL (operands[2]) != -128)))
6059	{
6060	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6061	  if (widen)
6062	    return "sub{l}\t{%2, %k0|%k0, %2}";
6063	  else
6064	    return "sub{b}\t{%2, %0|%0, %2}";
6065	}
6066      if (widen)
6067        return "add{l}\t{%k2, %k0|%k0, %k2}";
6068      else
6069        return "add{b}\t{%2, %0|%0, %2}";
6070    }
6071}
6072  [(set (attr "type")
6073     (if_then_else (eq_attr "alternative" "3")
6074	(const_string "lea")
6075	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6076	   (const_string "incdec")
6077	   (const_string "alu"))))
6078   (set_attr "mode" "QI,QI,SI,SI")])
6079
6080(define_insn "*addqi_1"
6081  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6082	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6083		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6084   (clobber (reg:CC FLAGS_REG))]
6085  "TARGET_PARTIAL_REG_STALL
6086   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6087{
6088  int widen = (which_alternative == 2);
6089  switch (get_attr_type (insn))
6090    {
6091    case TYPE_INCDEC:
6092      if (operands[2] == const1_rtx)
6093	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6094      else
6095	{
6096	  gcc_assert (operands[2] == constm1_rtx);
6097	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6098	}
6099
6100    default:
6101      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6102	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6103      if (GET_CODE (operands[2]) == CONST_INT
6104          && (INTVAL (operands[2]) == 128
6105	      || (INTVAL (operands[2]) < 0
6106		  && INTVAL (operands[2]) != -128)))
6107	{
6108	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6109	  if (widen)
6110	    return "sub{l}\t{%2, %k0|%k0, %2}";
6111	  else
6112	    return "sub{b}\t{%2, %0|%0, %2}";
6113	}
6114      if (widen)
6115        return "add{l}\t{%k2, %k0|%k0, %k2}";
6116      else
6117        return "add{b}\t{%2, %0|%0, %2}";
6118    }
6119}
6120  [(set (attr "type")
6121     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6122	(const_string "incdec")
6123	(const_string "alu")))
6124   (set_attr "mode" "QI,QI,SI")])
6125
6126(define_insn "*addqi_1_slp"
6127  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6128	(plus:QI (match_dup 0)
6129		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6130   (clobber (reg:CC FLAGS_REG))]
6131  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6132   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6133{
6134  switch (get_attr_type (insn))
6135    {
6136    case TYPE_INCDEC:
6137      if (operands[1] == const1_rtx)
6138	return "inc{b}\t%0";
6139      else
6140	{
6141	  gcc_assert (operands[1] == constm1_rtx);
6142	  return "dec{b}\t%0";
6143	}
6144
6145    default:
6146      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6147      if (GET_CODE (operands[1]) == CONST_INT
6148	  && INTVAL (operands[1]) < 0)
6149	{
6150	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6151	  return "sub{b}\t{%1, %0|%0, %1}";
6152	}
6153      return "add{b}\t{%1, %0|%0, %1}";
6154    }
6155}
6156  [(set (attr "type")
6157     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6158	(const_string "incdec")
6159	(const_string "alu1")))
6160   (set (attr "memory")
6161     (if_then_else (match_operand 1 "memory_operand" "")
6162        (const_string "load")
6163        (const_string "none")))
6164   (set_attr "mode" "QI")])
6165
6166(define_insn "*addqi_2"
6167  [(set (reg FLAGS_REG)
6168	(compare
6169	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6170		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6171	  (const_int 0)))
6172   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6173	(plus:QI (match_dup 1) (match_dup 2)))]
6174  "ix86_match_ccmode (insn, CCGOCmode)
6175   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6176{
6177  switch (get_attr_type (insn))
6178    {
6179    case TYPE_INCDEC:
6180      if (operands[2] == const1_rtx)
6181	return "inc{b}\t%0";
6182      else
6183        {
6184	  gcc_assert (operands[2] == constm1_rtx
6185		      || (GET_CODE (operands[2]) == CONST_INT
6186		          && INTVAL (operands[2]) == 255));
6187	  return "dec{b}\t%0";
6188	}
6189
6190    default:
6191      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6192      if (GET_CODE (operands[2]) == CONST_INT
6193          && INTVAL (operands[2]) < 0)
6194	{
6195	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6196	  return "sub{b}\t{%2, %0|%0, %2}";
6197	}
6198      return "add{b}\t{%2, %0|%0, %2}";
6199    }
6200}
6201  [(set (attr "type")
6202     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6203	(const_string "incdec")
6204	(const_string "alu")))
6205   (set_attr "mode" "QI")])
6206
6207(define_insn "*addqi_3"
6208  [(set (reg FLAGS_REG)
6209	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6210		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6211   (clobber (match_scratch:QI 0 "=q"))]
6212  "ix86_match_ccmode (insn, CCZmode)
6213   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6214{
6215  switch (get_attr_type (insn))
6216    {
6217    case TYPE_INCDEC:
6218      if (operands[2] == const1_rtx)
6219	return "inc{b}\t%0";
6220      else
6221        {
6222	  gcc_assert (operands[2] == constm1_rtx
6223		      || (GET_CODE (operands[2]) == CONST_INT
6224			  && INTVAL (operands[2]) == 255));
6225	  return "dec{b}\t%0";
6226	}
6227
6228    default:
6229      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6230      if (GET_CODE (operands[2]) == CONST_INT
6231          && INTVAL (operands[2]) < 0)
6232	{
6233	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6234	  return "sub{b}\t{%2, %0|%0, %2}";
6235	}
6236      return "add{b}\t{%2, %0|%0, %2}";
6237    }
6238}
6239  [(set (attr "type")
6240     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6241	(const_string "incdec")
6242	(const_string "alu")))
6243   (set_attr "mode" "QI")])
6244
6245; See comments above addsi_4 for details.
6246(define_insn "*addqi_4"
6247  [(set (reg FLAGS_REG)
6248	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6249		 (match_operand:QI 2 "const_int_operand" "n")))
6250   (clobber (match_scratch:QI 0 "=qm"))]
6251  "ix86_match_ccmode (insn, CCGCmode)
6252   && (INTVAL (operands[2]) & 0xff) != 0x80"
6253{
6254  switch (get_attr_type (insn))
6255    {
6256    case TYPE_INCDEC:
6257      if (operands[2] == constm1_rtx
6258	  || (GET_CODE (operands[2]) == CONST_INT
6259	      && INTVAL (operands[2]) == 255))
6260        return "inc{b}\t%0";
6261      else
6262	{
6263	  gcc_assert (operands[2] == const1_rtx);
6264          return "dec{b}\t%0";
6265	}
6266
6267    default:
6268      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6269      if (INTVAL (operands[2]) < 0)
6270        {
6271          operands[2] = GEN_INT (-INTVAL (operands[2]));
6272          return "add{b}\t{%2, %0|%0, %2}";
6273        }
6274      return "sub{b}\t{%2, %0|%0, %2}";
6275    }
6276}
6277  [(set (attr "type")
6278     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6279	(const_string "incdec")
6280	(const_string "alu")))
6281   (set_attr "mode" "QI")])
6282
6283
6284(define_insn "*addqi_5"
6285  [(set (reg FLAGS_REG)
6286	(compare
6287	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6288		   (match_operand:QI 2 "general_operand" "qmni"))
6289	  (const_int 0)))
6290   (clobber (match_scratch:QI 0 "=q"))]
6291  "ix86_match_ccmode (insn, CCGOCmode)
6292   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6293{
6294  switch (get_attr_type (insn))
6295    {
6296    case TYPE_INCDEC:
6297      if (operands[2] == const1_rtx)
6298	return "inc{b}\t%0";
6299      else
6300        {
6301	  gcc_assert (operands[2] == constm1_rtx
6302		      || (GET_CODE (operands[2]) == CONST_INT
6303			  && INTVAL (operands[2]) == 255));
6304	  return "dec{b}\t%0";
6305	}
6306
6307    default:
6308      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6309      if (GET_CODE (operands[2]) == CONST_INT
6310          && INTVAL (operands[2]) < 0)
6311	{
6312	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6313	  return "sub{b}\t{%2, %0|%0, %2}";
6314	}
6315      return "add{b}\t{%2, %0|%0, %2}";
6316    }
6317}
6318  [(set (attr "type")
6319     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6320	(const_string "incdec")
6321	(const_string "alu")))
6322   (set_attr "mode" "QI")])
6323
6324
6325(define_insn "addqi_ext_1"
6326  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6327			 (const_int 8)
6328			 (const_int 8))
6329	(plus:SI
6330	  (zero_extract:SI
6331	    (match_operand 1 "ext_register_operand" "0")
6332	    (const_int 8)
6333	    (const_int 8))
6334	  (match_operand:QI 2 "general_operand" "Qmn")))
6335   (clobber (reg:CC FLAGS_REG))]
6336  "!TARGET_64BIT"
6337{
6338  switch (get_attr_type (insn))
6339    {
6340    case TYPE_INCDEC:
6341      if (operands[2] == const1_rtx)
6342	return "inc{b}\t%h0";
6343      else
6344        {
6345	  gcc_assert (operands[2] == constm1_rtx
6346		      || (GET_CODE (operands[2]) == CONST_INT
6347			  && INTVAL (operands[2]) == 255));
6348          return "dec{b}\t%h0";
6349	}
6350
6351    default:
6352      return "add{b}\t{%2, %h0|%h0, %2}";
6353    }
6354}
6355  [(set (attr "type")
6356     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357	(const_string "incdec")
6358	(const_string "alu")))
6359   (set_attr "mode" "QI")])
6360
6361(define_insn "*addqi_ext_1_rex64"
6362  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6363			 (const_int 8)
6364			 (const_int 8))
6365	(plus:SI
6366	  (zero_extract:SI
6367	    (match_operand 1 "ext_register_operand" "0")
6368	    (const_int 8)
6369	    (const_int 8))
6370	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6371   (clobber (reg:CC FLAGS_REG))]
6372  "TARGET_64BIT"
6373{
6374  switch (get_attr_type (insn))
6375    {
6376    case TYPE_INCDEC:
6377      if (operands[2] == const1_rtx)
6378	return "inc{b}\t%h0";
6379      else
6380        {
6381	  gcc_assert (operands[2] == constm1_rtx
6382		      || (GET_CODE (operands[2]) == CONST_INT
6383			  && INTVAL (operands[2]) == 255));
6384          return "dec{b}\t%h0";
6385        }
6386
6387    default:
6388      return "add{b}\t{%2, %h0|%h0, %2}";
6389    }
6390}
6391  [(set (attr "type")
6392     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6393	(const_string "incdec")
6394	(const_string "alu")))
6395   (set_attr "mode" "QI")])
6396
6397(define_insn "*addqi_ext_2"
6398  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399			 (const_int 8)
6400			 (const_int 8))
6401	(plus:SI
6402	  (zero_extract:SI
6403	    (match_operand 1 "ext_register_operand" "%0")
6404	    (const_int 8)
6405	    (const_int 8))
6406	  (zero_extract:SI
6407	    (match_operand 2 "ext_register_operand" "Q")
6408	    (const_int 8)
6409	    (const_int 8))))
6410   (clobber (reg:CC FLAGS_REG))]
6411  ""
6412  "add{b}\t{%h2, %h0|%h0, %h2}"
6413  [(set_attr "type" "alu")
6414   (set_attr "mode" "QI")])
6415
6416;; The patterns that match these are at the end of this file.
6417
6418(define_expand "addxf3"
6419  [(set (match_operand:XF 0 "register_operand" "")
6420	(plus:XF (match_operand:XF 1 "register_operand" "")
6421		 (match_operand:XF 2 "register_operand" "")))]
6422  "TARGET_80387"
6423  "")
6424
6425(define_expand "adddf3"
6426  [(set (match_operand:DF 0 "register_operand" "")
6427	(plus:DF (match_operand:DF 1 "register_operand" "")
6428		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6429  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6430  "")
6431
6432(define_expand "addsf3"
6433  [(set (match_operand:SF 0 "register_operand" "")
6434	(plus:SF (match_operand:SF 1 "register_operand" "")
6435		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6436  "TARGET_80387 || TARGET_SSE_MATH"
6437  "")
6438
6439;; Subtract instructions
6440
6441;; %%% splits for subditi3
6442
6443(define_expand "subti3"
6444  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6445		   (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6446			     (match_operand:TI 2 "x86_64_general_operand" "")))
6447	      (clobber (reg:CC FLAGS_REG))])]
6448  "TARGET_64BIT"
6449  "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6450
6451(define_insn "*subti3_1"
6452  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6453	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6454		  (match_operand:TI 2 "general_operand" "roiF,riF")))
6455   (clobber (reg:CC FLAGS_REG))]
6456  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6457  "#")
6458
6459(define_split
6460  [(set (match_operand:TI 0 "nonimmediate_operand" "")
6461	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6462		  (match_operand:TI 2 "general_operand" "")))
6463   (clobber (reg:CC FLAGS_REG))]
6464  "TARGET_64BIT && reload_completed"
6465  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6466	      (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6467   (parallel [(set (match_dup 3)
6468		   (minus:DI (match_dup 4)
6469			     (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6470				      (match_dup 5))))
6471	      (clobber (reg:CC FLAGS_REG))])]
6472  "split_ti (operands+0, 1, operands+0, operands+3);
6473   split_ti (operands+1, 1, operands+1, operands+4);
6474   split_ti (operands+2, 1, operands+2, operands+5);")
6475
6476;; %%% splits for subsidi3
6477
6478(define_expand "subdi3"
6479  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6480		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6481			     (match_operand:DI 2 "x86_64_general_operand" "")))
6482	      (clobber (reg:CC FLAGS_REG))])]
6483  ""
6484  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6485
6486(define_insn "*subdi3_1"
6487  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6488	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6489		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6490   (clobber (reg:CC FLAGS_REG))]
6491  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6492  "#")
6493
6494(define_split
6495  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6496	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6497		  (match_operand:DI 2 "general_operand" "")))
6498   (clobber (reg:CC FLAGS_REG))]
6499  "!TARGET_64BIT && reload_completed"
6500  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6501	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6502   (parallel [(set (match_dup 3)
6503		   (minus:SI (match_dup 4)
6504			     (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6505				      (match_dup 5))))
6506	      (clobber (reg:CC FLAGS_REG))])]
6507  "split_di (operands+0, 1, operands+0, operands+3);
6508   split_di (operands+1, 1, operands+1, operands+4);
6509   split_di (operands+2, 1, operands+2, operands+5);")
6510
6511(define_insn "subdi3_carry_rex64"
6512  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6513	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6514	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6515	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6516   (clobber (reg:CC FLAGS_REG))]
6517  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6518  "sbb{q}\t{%2, %0|%0, %2}"
6519  [(set_attr "type" "alu")
6520   (set_attr "pent_pair" "pu")
6521   (set_attr "mode" "DI")])
6522
6523(define_insn "*subdi_1_rex64"
6524  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6525	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6526		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6527   (clobber (reg:CC FLAGS_REG))]
6528  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6529  "sub{q}\t{%2, %0|%0, %2}"
6530  [(set_attr "type" "alu")
6531   (set_attr "mode" "DI")])
6532
6533(define_insn "*subdi_2_rex64"
6534  [(set (reg FLAGS_REG)
6535	(compare
6536	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6537		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6538	  (const_int 0)))
6539   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6540	(minus:DI (match_dup 1) (match_dup 2)))]
6541  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6542   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6543  "sub{q}\t{%2, %0|%0, %2}"
6544  [(set_attr "type" "alu")
6545   (set_attr "mode" "DI")])
6546
6547(define_insn "*subdi_3_rex63"
6548  [(set (reg FLAGS_REG)
6549	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6550		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6551   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6552	(minus:DI (match_dup 1) (match_dup 2)))]
6553  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555  "sub{q}\t{%2, %0|%0, %2}"
6556  [(set_attr "type" "alu")
6557   (set_attr "mode" "DI")])
6558
6559(define_insn "subqi3_carry"
6560  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6561	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6562	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6563	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6564   (clobber (reg:CC FLAGS_REG))]
6565  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6566  "sbb{b}\t{%2, %0|%0, %2}"
6567  [(set_attr "type" "alu")
6568   (set_attr "pent_pair" "pu")
6569   (set_attr "mode" "QI")])
6570
6571(define_insn "subhi3_carry"
6572  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6573	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6574	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6575	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6576   (clobber (reg:CC FLAGS_REG))]
6577  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6578  "sbb{w}\t{%2, %0|%0, %2}"
6579  [(set_attr "type" "alu")
6580   (set_attr "pent_pair" "pu")
6581   (set_attr "mode" "HI")])
6582
6583(define_insn "subsi3_carry"
6584  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6585	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6586	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6587	       (match_operand:SI 2 "general_operand" "ri,rm"))))
6588   (clobber (reg:CC FLAGS_REG))]
6589  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6590  "sbb{l}\t{%2, %0|%0, %2}"
6591  [(set_attr "type" "alu")
6592   (set_attr "pent_pair" "pu")
6593   (set_attr "mode" "SI")])
6594
6595(define_insn "subsi3_carry_zext"
6596  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6597	  (zero_extend:DI
6598	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6599	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6600		 (match_operand:SI 2 "general_operand" "ri,rm")))))
6601   (clobber (reg:CC FLAGS_REG))]
6602  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6603  "sbb{l}\t{%2, %k0|%k0, %2}"
6604  [(set_attr "type" "alu")
6605   (set_attr "pent_pair" "pu")
6606   (set_attr "mode" "SI")])
6607
6608(define_expand "subsi3"
6609  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6610		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6611			     (match_operand:SI 2 "general_operand" "")))
6612	      (clobber (reg:CC FLAGS_REG))])]
6613  ""
6614  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6615
6616(define_insn "*subsi_1"
6617  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6618	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6619		  (match_operand:SI 2 "general_operand" "ri,rm")))
6620   (clobber (reg:CC FLAGS_REG))]
6621  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622  "sub{l}\t{%2, %0|%0, %2}"
6623  [(set_attr "type" "alu")
6624   (set_attr "mode" "SI")])
6625
6626(define_insn "*subsi_1_zext"
6627  [(set (match_operand:DI 0 "register_operand" "=r")
6628	(zero_extend:DI
6629	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6630		    (match_operand:SI 2 "general_operand" "rim"))))
6631   (clobber (reg:CC FLAGS_REG))]
6632  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6633  "sub{l}\t{%2, %k0|%k0, %2}"
6634  [(set_attr "type" "alu")
6635   (set_attr "mode" "SI")])
6636
6637(define_insn "*subsi_2"
6638  [(set (reg FLAGS_REG)
6639	(compare
6640	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6641		    (match_operand:SI 2 "general_operand" "ri,rm"))
6642	  (const_int 0)))
6643   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6644	(minus:SI (match_dup 1) (match_dup 2)))]
6645  "ix86_match_ccmode (insn, CCGOCmode)
6646   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6647  "sub{l}\t{%2, %0|%0, %2}"
6648  [(set_attr "type" "alu")
6649   (set_attr "mode" "SI")])
6650
6651(define_insn "*subsi_2_zext"
6652  [(set (reg FLAGS_REG)
6653	(compare
6654	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6655		    (match_operand:SI 2 "general_operand" "rim"))
6656	  (const_int 0)))
6657   (set (match_operand:DI 0 "register_operand" "=r")
6658	(zero_extend:DI
6659	  (minus:SI (match_dup 1)
6660		    (match_dup 2))))]
6661  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6662   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6663  "sub{l}\t{%2, %k0|%k0, %2}"
6664  [(set_attr "type" "alu")
6665   (set_attr "mode" "SI")])
6666
6667(define_insn "*subsi_3"
6668  [(set (reg FLAGS_REG)
6669	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670		 (match_operand:SI 2 "general_operand" "ri,rm")))
6671   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672	(minus:SI (match_dup 1) (match_dup 2)))]
6673  "ix86_match_ccmode (insn, CCmode)
6674   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675  "sub{l}\t{%2, %0|%0, %2}"
6676  [(set_attr "type" "alu")
6677   (set_attr "mode" "SI")])
6678
6679(define_insn "*subsi_3_zext"
6680  [(set (reg FLAGS_REG)
6681	(compare (match_operand:SI 1 "register_operand" "0")
6682		 (match_operand:SI 2 "general_operand" "rim")))
6683   (set (match_operand:DI 0 "register_operand" "=r")
6684	(zero_extend:DI
6685	  (minus:SI (match_dup 1)
6686		    (match_dup 2))))]
6687  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6688   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6689  "sub{q}\t{%2, %0|%0, %2}"
6690  [(set_attr "type" "alu")
6691   (set_attr "mode" "DI")])
6692
6693(define_expand "subhi3"
6694  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6695		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6696			     (match_operand:HI 2 "general_operand" "")))
6697	      (clobber (reg:CC FLAGS_REG))])]
6698  "TARGET_HIMODE_MATH"
6699  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6700
6701(define_insn "*subhi_1"
6702  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6703	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6704		  (match_operand:HI 2 "general_operand" "ri,rm")))
6705   (clobber (reg:CC FLAGS_REG))]
6706  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6707  "sub{w}\t{%2, %0|%0, %2}"
6708  [(set_attr "type" "alu")
6709   (set_attr "mode" "HI")])
6710
6711(define_insn "*subhi_2"
6712  [(set (reg FLAGS_REG)
6713	(compare
6714	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6715		    (match_operand:HI 2 "general_operand" "ri,rm"))
6716	  (const_int 0)))
6717   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6718	(minus:HI (match_dup 1) (match_dup 2)))]
6719  "ix86_match_ccmode (insn, CCGOCmode)
6720   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6721  "sub{w}\t{%2, %0|%0, %2}"
6722  [(set_attr "type" "alu")
6723   (set_attr "mode" "HI")])
6724
6725(define_insn "*subhi_3"
6726  [(set (reg FLAGS_REG)
6727	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6728		 (match_operand:HI 2 "general_operand" "ri,rm")))
6729   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6730	(minus:HI (match_dup 1) (match_dup 2)))]
6731  "ix86_match_ccmode (insn, CCmode)
6732   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6733  "sub{w}\t{%2, %0|%0, %2}"
6734  [(set_attr "type" "alu")
6735   (set_attr "mode" "HI")])
6736
6737(define_expand "subqi3"
6738  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6739		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6740			     (match_operand:QI 2 "general_operand" "")))
6741	      (clobber (reg:CC FLAGS_REG))])]
6742  "TARGET_QIMODE_MATH"
6743  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6744
6745(define_insn "*subqi_1"
6746  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6747	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6748		  (match_operand:QI 2 "general_operand" "qn,qmn")))
6749   (clobber (reg:CC FLAGS_REG))]
6750  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6751  "sub{b}\t{%2, %0|%0, %2}"
6752  [(set_attr "type" "alu")
6753   (set_attr "mode" "QI")])
6754
6755(define_insn "*subqi_1_slp"
6756  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6757	(minus:QI (match_dup 0)
6758		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6759   (clobber (reg:CC FLAGS_REG))]
6760  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6761   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6762  "sub{b}\t{%1, %0|%0, %1}"
6763  [(set_attr "type" "alu1")
6764   (set_attr "mode" "QI")])
6765
6766(define_insn "*subqi_2"
6767  [(set (reg FLAGS_REG)
6768	(compare
6769	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6770		    (match_operand:QI 2 "general_operand" "qi,qm"))
6771	  (const_int 0)))
6772   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6773	(minus:HI (match_dup 1) (match_dup 2)))]
6774  "ix86_match_ccmode (insn, CCGOCmode)
6775   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6776  "sub{b}\t{%2, %0|%0, %2}"
6777  [(set_attr "type" "alu")
6778   (set_attr "mode" "QI")])
6779
6780(define_insn "*subqi_3"
6781  [(set (reg FLAGS_REG)
6782	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6783		 (match_operand:QI 2 "general_operand" "qi,qm")))
6784   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6785	(minus:HI (match_dup 1) (match_dup 2)))]
6786  "ix86_match_ccmode (insn, CCmode)
6787   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6788  "sub{b}\t{%2, %0|%0, %2}"
6789  [(set_attr "type" "alu")
6790   (set_attr "mode" "QI")])
6791
6792;; The patterns that match these are at the end of this file.
6793
6794(define_expand "subxf3"
6795  [(set (match_operand:XF 0 "register_operand" "")
6796	(minus:XF (match_operand:XF 1 "register_operand" "")
6797		  (match_operand:XF 2 "register_operand" "")))]
6798  "TARGET_80387"
6799  "")
6800
6801(define_expand "subdf3"
6802  [(set (match_operand:DF 0 "register_operand" "")
6803	(minus:DF (match_operand:DF 1 "register_operand" "")
6804		  (match_operand:DF 2 "nonimmediate_operand" "")))]
6805  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6806  "")
6807
6808(define_expand "subsf3"
6809  [(set (match_operand:SF 0 "register_operand" "")
6810	(minus:SF (match_operand:SF 1 "register_operand" "")
6811		  (match_operand:SF 2 "nonimmediate_operand" "")))]
6812  "TARGET_80387 || TARGET_SSE_MATH"
6813  "")
6814
6815;; Multiply instructions
6816
6817(define_expand "muldi3"
6818  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6819		   (mult:DI (match_operand:DI 1 "register_operand" "")
6820			    (match_operand:DI 2 "x86_64_general_operand" "")))
6821	      (clobber (reg:CC FLAGS_REG))])]
6822  "TARGET_64BIT"
6823  "")
6824
6825(define_insn "*muldi3_1_rex64"
6826  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6827	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6828		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6829   (clobber (reg:CC FLAGS_REG))]
6830  "TARGET_64BIT
6831   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6832  "@
6833   imul{q}\t{%2, %1, %0|%0, %1, %2}
6834   imul{q}\t{%2, %1, %0|%0, %1, %2}
6835   imul{q}\t{%2, %0|%0, %2}"
6836  [(set_attr "type" "imul")
6837   (set_attr "prefix_0f" "0,0,1")
6838   (set (attr "athlon_decode")
6839	(cond [(eq_attr "cpu" "athlon")
6840		  (const_string "vector")
6841	       (eq_attr "alternative" "1")
6842		  (const_string "vector")
6843	       (and (eq_attr "alternative" "2")
6844		    (match_operand 1 "memory_operand" ""))
6845		  (const_string "vector")]
6846	      (const_string "direct")))
6847   (set_attr "mode" "DI")])
6848
6849(define_expand "mulsi3"
6850  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6851		   (mult:SI (match_operand:SI 1 "register_operand" "")
6852			    (match_operand:SI 2 "general_operand" "")))
6853	      (clobber (reg:CC FLAGS_REG))])]
6854  ""
6855  "")
6856
6857(define_insn "*mulsi3_1"
6858  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6859	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6860		 (match_operand:SI 2 "general_operand" "K,i,mr")))
6861   (clobber (reg:CC FLAGS_REG))]
6862  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6863  "@
6864   imul{l}\t{%2, %1, %0|%0, %1, %2}
6865   imul{l}\t{%2, %1, %0|%0, %1, %2}
6866   imul{l}\t{%2, %0|%0, %2}"
6867  [(set_attr "type" "imul")
6868   (set_attr "prefix_0f" "0,0,1")
6869   (set (attr "athlon_decode")
6870	(cond [(eq_attr "cpu" "athlon")
6871		  (const_string "vector")
6872	       (eq_attr "alternative" "1")
6873		  (const_string "vector")
6874	       (and (eq_attr "alternative" "2")
6875		    (match_operand 1 "memory_operand" ""))
6876		  (const_string "vector")]
6877	      (const_string "direct")))
6878   (set_attr "mode" "SI")])
6879
6880(define_insn "*mulsi3_1_zext"
6881  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6882	(zero_extend:DI
6883	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6884		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
6885   (clobber (reg:CC FLAGS_REG))]
6886  "TARGET_64BIT
6887   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6888  "@
6889   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6891   imul{l}\t{%2, %k0|%k0, %2}"
6892  [(set_attr "type" "imul")
6893   (set_attr "prefix_0f" "0,0,1")
6894   (set (attr "athlon_decode")
6895	(cond [(eq_attr "cpu" "athlon")
6896		  (const_string "vector")
6897	       (eq_attr "alternative" "1")
6898		  (const_string "vector")
6899	       (and (eq_attr "alternative" "2")
6900		    (match_operand 1 "memory_operand" ""))
6901		  (const_string "vector")]
6902	      (const_string "direct")))
6903   (set_attr "mode" "SI")])
6904
6905(define_expand "mulhi3"
6906  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6907		   (mult:HI (match_operand:HI 1 "register_operand" "")
6908			    (match_operand:HI 2 "general_operand" "")))
6909	      (clobber (reg:CC FLAGS_REG))])]
6910  "TARGET_HIMODE_MATH"
6911  "")
6912
6913(define_insn "*mulhi3_1"
6914  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6915	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6916		 (match_operand:HI 2 "general_operand" "K,i,mr")))
6917   (clobber (reg:CC FLAGS_REG))]
6918  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6919  "@
6920   imul{w}\t{%2, %1, %0|%0, %1, %2}
6921   imul{w}\t{%2, %1, %0|%0, %1, %2}
6922   imul{w}\t{%2, %0|%0, %2}"
6923  [(set_attr "type" "imul")
6924   (set_attr "prefix_0f" "0,0,1")
6925   (set (attr "athlon_decode")
6926	(cond [(eq_attr "cpu" "athlon")
6927		  (const_string "vector")
6928	       (eq_attr "alternative" "1,2")
6929		  (const_string "vector")]
6930	      (const_string "direct")))
6931   (set_attr "mode" "HI")])
6932
6933(define_expand "mulqi3"
6934  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6935		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6936			    (match_operand:QI 2 "register_operand" "")))
6937	      (clobber (reg:CC FLAGS_REG))])]
6938  "TARGET_QIMODE_MATH"
6939  "")
6940
6941(define_insn "*mulqi3_1"
6942  [(set (match_operand:QI 0 "register_operand" "=a")
6943	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6944		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6945   (clobber (reg:CC FLAGS_REG))]
6946  "TARGET_QIMODE_MATH
6947   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6948  "mul{b}\t%2"
6949  [(set_attr "type" "imul")
6950   (set_attr "length_immediate" "0")
6951   (set (attr "athlon_decode")
6952     (if_then_else (eq_attr "cpu" "athlon")
6953        (const_string "vector")
6954        (const_string "direct")))
6955   (set_attr "mode" "QI")])
6956
6957(define_expand "umulqihi3"
6958  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6959		   (mult:HI (zero_extend:HI
6960			      (match_operand:QI 1 "nonimmediate_operand" ""))
6961			    (zero_extend:HI
6962			      (match_operand:QI 2 "register_operand" ""))))
6963	      (clobber (reg:CC FLAGS_REG))])]
6964  "TARGET_QIMODE_MATH"
6965  "")
6966
6967(define_insn "*umulqihi3_1"
6968  [(set (match_operand:HI 0 "register_operand" "=a")
6969	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6970		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6971   (clobber (reg:CC FLAGS_REG))]
6972  "TARGET_QIMODE_MATH
6973   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6974  "mul{b}\t%2"
6975  [(set_attr "type" "imul")
6976   (set_attr "length_immediate" "0")
6977   (set (attr "athlon_decode")
6978     (if_then_else (eq_attr "cpu" "athlon")
6979        (const_string "vector")
6980        (const_string "direct")))
6981   (set_attr "mode" "QI")])
6982
6983(define_expand "mulqihi3"
6984  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6985		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6986			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6987	      (clobber (reg:CC FLAGS_REG))])]
6988  "TARGET_QIMODE_MATH"
6989  "")
6990
6991(define_insn "*mulqihi3_insn"
6992  [(set (match_operand:HI 0 "register_operand" "=a")
6993	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6994		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6995   (clobber (reg:CC FLAGS_REG))]
6996  "TARGET_QIMODE_MATH
6997   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6998  "imul{b}\t%2"
6999  [(set_attr "type" "imul")
7000   (set_attr "length_immediate" "0")
7001   (set (attr "athlon_decode")
7002     (if_then_else (eq_attr "cpu" "athlon")
7003        (const_string "vector")
7004        (const_string "direct")))
7005   (set_attr "mode" "QI")])
7006
7007(define_expand "umulditi3"
7008  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7009		   (mult:TI (zero_extend:TI
7010			      (match_operand:DI 1 "nonimmediate_operand" ""))
7011			    (zero_extend:TI
7012			      (match_operand:DI 2 "register_operand" ""))))
7013	      (clobber (reg:CC FLAGS_REG))])]
7014  "TARGET_64BIT"
7015  "")
7016
7017(define_insn "*umulditi3_insn"
7018  [(set (match_operand:TI 0 "register_operand" "=A")
7019	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7020		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7021   (clobber (reg:CC FLAGS_REG))]
7022  "TARGET_64BIT
7023   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7024  "mul{q}\t%2"
7025  [(set_attr "type" "imul")
7026   (set_attr "length_immediate" "0")
7027   (set (attr "athlon_decode")
7028     (if_then_else (eq_attr "cpu" "athlon")
7029        (const_string "vector")
7030        (const_string "double")))
7031   (set_attr "mode" "DI")])
7032
7033;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7034(define_expand "umulsidi3"
7035  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7036		   (mult:DI (zero_extend:DI
7037			      (match_operand:SI 1 "nonimmediate_operand" ""))
7038			    (zero_extend:DI
7039			      (match_operand:SI 2 "register_operand" ""))))
7040	      (clobber (reg:CC FLAGS_REG))])]
7041  "!TARGET_64BIT"
7042  "")
7043
7044(define_insn "*umulsidi3_insn"
7045  [(set (match_operand:DI 0 "register_operand" "=A")
7046	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7047		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7048   (clobber (reg:CC FLAGS_REG))]
7049  "!TARGET_64BIT
7050   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7051  "mul{l}\t%2"
7052  [(set_attr "type" "imul")
7053   (set_attr "length_immediate" "0")
7054   (set (attr "athlon_decode")
7055     (if_then_else (eq_attr "cpu" "athlon")
7056        (const_string "vector")
7057        (const_string "double")))
7058   (set_attr "mode" "SI")])
7059
7060(define_expand "mulditi3"
7061  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7062		   (mult:TI (sign_extend:TI
7063			      (match_operand:DI 1 "nonimmediate_operand" ""))
7064			    (sign_extend:TI
7065			      (match_operand:DI 2 "register_operand" ""))))
7066	      (clobber (reg:CC FLAGS_REG))])]
7067  "TARGET_64BIT"
7068  "")
7069
7070(define_insn "*mulditi3_insn"
7071  [(set (match_operand:TI 0 "register_operand" "=A")
7072	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7073		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7074   (clobber (reg:CC FLAGS_REG))]
7075  "TARGET_64BIT
7076   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7077  "imul{q}\t%2"
7078  [(set_attr "type" "imul")
7079   (set_attr "length_immediate" "0")
7080   (set (attr "athlon_decode")
7081     (if_then_else (eq_attr "cpu" "athlon")
7082        (const_string "vector")
7083        (const_string "double")))
7084   (set_attr "mode" "DI")])
7085
7086(define_expand "mulsidi3"
7087  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7088		   (mult:DI (sign_extend:DI
7089			      (match_operand:SI 1 "nonimmediate_operand" ""))
7090			    (sign_extend:DI
7091			      (match_operand:SI 2 "register_operand" ""))))
7092	      (clobber (reg:CC FLAGS_REG))])]
7093  "!TARGET_64BIT"
7094  "")
7095
7096(define_insn "*mulsidi3_insn"
7097  [(set (match_operand:DI 0 "register_operand" "=A")
7098	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7099		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7100   (clobber (reg:CC FLAGS_REG))]
7101  "!TARGET_64BIT
7102   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7103  "imul{l}\t%2"
7104  [(set_attr "type" "imul")
7105   (set_attr "length_immediate" "0")
7106   (set (attr "athlon_decode")
7107     (if_then_else (eq_attr "cpu" "athlon")
7108        (const_string "vector")
7109        (const_string "double")))
7110   (set_attr "mode" "SI")])
7111
7112(define_expand "umuldi3_highpart"
7113  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7114		   (truncate:DI
7115		     (lshiftrt:TI
7116		       (mult:TI (zero_extend:TI
7117				  (match_operand:DI 1 "nonimmediate_operand" ""))
7118				(zero_extend:TI
7119				  (match_operand:DI 2 "register_operand" "")))
7120		       (const_int 64))))
7121	      (clobber (match_scratch:DI 3 ""))
7122	      (clobber (reg:CC FLAGS_REG))])]
7123  "TARGET_64BIT"
7124  "")
7125
7126(define_insn "*umuldi3_highpart_rex64"
7127  [(set (match_operand:DI 0 "register_operand" "=d")
7128	(truncate:DI
7129	  (lshiftrt:TI
7130	    (mult:TI (zero_extend:TI
7131		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7132		     (zero_extend:TI
7133		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7134	    (const_int 64))))
7135   (clobber (match_scratch:DI 3 "=1"))
7136   (clobber (reg:CC FLAGS_REG))]
7137  "TARGET_64BIT
7138   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7139  "mul{q}\t%2"
7140  [(set_attr "type" "imul")
7141   (set_attr "length_immediate" "0")
7142   (set (attr "athlon_decode")
7143     (if_then_else (eq_attr "cpu" "athlon")
7144        (const_string "vector")
7145        (const_string "double")))
7146   (set_attr "mode" "DI")])
7147
7148(define_expand "umulsi3_highpart"
7149  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7150		   (truncate:SI
7151		     (lshiftrt:DI
7152		       (mult:DI (zero_extend:DI
7153				  (match_operand:SI 1 "nonimmediate_operand" ""))
7154				(zero_extend:DI
7155				  (match_operand:SI 2 "register_operand" "")))
7156		       (const_int 32))))
7157	      (clobber (match_scratch:SI 3 ""))
7158	      (clobber (reg:CC FLAGS_REG))])]
7159  ""
7160  "")
7161
7162(define_insn "*umulsi3_highpart_insn"
7163  [(set (match_operand:SI 0 "register_operand" "=d")
7164	(truncate:SI
7165	  (lshiftrt:DI
7166	    (mult:DI (zero_extend:DI
7167		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7168		     (zero_extend:DI
7169		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7170	    (const_int 32))))
7171   (clobber (match_scratch:SI 3 "=1"))
7172   (clobber (reg:CC FLAGS_REG))]
7173  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7174  "mul{l}\t%2"
7175  [(set_attr "type" "imul")
7176   (set_attr "length_immediate" "0")
7177   (set (attr "athlon_decode")
7178     (if_then_else (eq_attr "cpu" "athlon")
7179        (const_string "vector")
7180        (const_string "double")))
7181   (set_attr "mode" "SI")])
7182
7183(define_insn "*umulsi3_highpart_zext"
7184  [(set (match_operand:DI 0 "register_operand" "=d")
7185	(zero_extend:DI (truncate:SI
7186	  (lshiftrt:DI
7187	    (mult:DI (zero_extend:DI
7188		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7189		     (zero_extend:DI
7190		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7191	    (const_int 32)))))
7192   (clobber (match_scratch:SI 3 "=1"))
7193   (clobber (reg:CC FLAGS_REG))]
7194  "TARGET_64BIT
7195   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7196  "mul{l}\t%2"
7197  [(set_attr "type" "imul")
7198   (set_attr "length_immediate" "0")
7199   (set (attr "athlon_decode")
7200     (if_then_else (eq_attr "cpu" "athlon")
7201        (const_string "vector")
7202        (const_string "double")))
7203   (set_attr "mode" "SI")])
7204
7205(define_expand "smuldi3_highpart"
7206  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7207		   (truncate:DI
7208		     (lshiftrt:TI
7209		       (mult:TI (sign_extend:TI
7210				  (match_operand:DI 1 "nonimmediate_operand" ""))
7211				(sign_extend:TI
7212				  (match_operand:DI 2 "register_operand" "")))
7213		       (const_int 64))))
7214	      (clobber (match_scratch:DI 3 ""))
7215	      (clobber (reg:CC FLAGS_REG))])]
7216  "TARGET_64BIT"
7217  "")
7218
7219(define_insn "*smuldi3_highpart_rex64"
7220  [(set (match_operand:DI 0 "register_operand" "=d")
7221	(truncate:DI
7222	  (lshiftrt:TI
7223	    (mult:TI (sign_extend:TI
7224		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7225		     (sign_extend:TI
7226		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7227	    (const_int 64))))
7228   (clobber (match_scratch:DI 3 "=1"))
7229   (clobber (reg:CC FLAGS_REG))]
7230  "TARGET_64BIT
7231   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7232  "imul{q}\t%2"
7233  [(set_attr "type" "imul")
7234   (set (attr "athlon_decode")
7235     (if_then_else (eq_attr "cpu" "athlon")
7236        (const_string "vector")
7237        (const_string "double")))
7238   (set_attr "mode" "DI")])
7239
7240(define_expand "smulsi3_highpart"
7241  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7242		   (truncate:SI
7243		     (lshiftrt:DI
7244		       (mult:DI (sign_extend:DI
7245				  (match_operand:SI 1 "nonimmediate_operand" ""))
7246				(sign_extend:DI
7247				  (match_operand:SI 2 "register_operand" "")))
7248		       (const_int 32))))
7249	      (clobber (match_scratch:SI 3 ""))
7250	      (clobber (reg:CC FLAGS_REG))])]
7251  ""
7252  "")
7253
7254(define_insn "*smulsi3_highpart_insn"
7255  [(set (match_operand:SI 0 "register_operand" "=d")
7256	(truncate:SI
7257	  (lshiftrt:DI
7258	    (mult:DI (sign_extend:DI
7259		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7260		     (sign_extend:DI
7261		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7262	    (const_int 32))))
7263   (clobber (match_scratch:SI 3 "=1"))
7264   (clobber (reg:CC FLAGS_REG))]
7265  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7266  "imul{l}\t%2"
7267  [(set_attr "type" "imul")
7268   (set (attr "athlon_decode")
7269     (if_then_else (eq_attr "cpu" "athlon")
7270        (const_string "vector")
7271        (const_string "double")))
7272   (set_attr "mode" "SI")])
7273
7274(define_insn "*smulsi3_highpart_zext"
7275  [(set (match_operand:DI 0 "register_operand" "=d")
7276	(zero_extend:DI (truncate:SI
7277	  (lshiftrt:DI
7278	    (mult:DI (sign_extend:DI
7279		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7280		     (sign_extend:DI
7281		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7282	    (const_int 32)))))
7283   (clobber (match_scratch:SI 3 "=1"))
7284   (clobber (reg:CC FLAGS_REG))]
7285  "TARGET_64BIT
7286   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7287  "imul{l}\t%2"
7288  [(set_attr "type" "imul")
7289   (set (attr "athlon_decode")
7290     (if_then_else (eq_attr "cpu" "athlon")
7291        (const_string "vector")
7292        (const_string "double")))
7293   (set_attr "mode" "SI")])
7294
7295;; The patterns that match these are at the end of this file.
7296
7297(define_expand "mulxf3"
7298  [(set (match_operand:XF 0 "register_operand" "")
7299	(mult:XF (match_operand:XF 1 "register_operand" "")
7300		 (match_operand:XF 2 "register_operand" "")))]
7301  "TARGET_80387"
7302  "")
7303
7304(define_expand "muldf3"
7305  [(set (match_operand:DF 0 "register_operand" "")
7306	(mult:DF (match_operand:DF 1 "register_operand" "")
7307		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7308  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7309  "")
7310
7311(define_expand "mulsf3"
7312  [(set (match_operand:SF 0 "register_operand" "")
7313	(mult:SF (match_operand:SF 1 "register_operand" "")
7314		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7315  "TARGET_80387 || TARGET_SSE_MATH"
7316  "")
7317
7318;; Divide instructions
7319
7320(define_insn "divqi3"
7321  [(set (match_operand:QI 0 "register_operand" "=a")
7322	(div:QI (match_operand:HI 1 "register_operand" "0")
7323		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7324   (clobber (reg:CC FLAGS_REG))]
7325  "TARGET_QIMODE_MATH"
7326  "idiv{b}\t%2"
7327  [(set_attr "type" "idiv")
7328   (set_attr "mode" "QI")])
7329
7330(define_insn "udivqi3"
7331  [(set (match_operand:QI 0 "register_operand" "=a")
7332	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7333		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7334   (clobber (reg:CC FLAGS_REG))]
7335  "TARGET_QIMODE_MATH"
7336  "div{b}\t%2"
7337  [(set_attr "type" "idiv")
7338   (set_attr "mode" "QI")])
7339
7340;; The patterns that match these are at the end of this file.
7341
7342(define_expand "divxf3"
7343  [(set (match_operand:XF 0 "register_operand" "")
7344	(div:XF (match_operand:XF 1 "register_operand" "")
7345		(match_operand:XF 2 "register_operand" "")))]
7346  "TARGET_80387"
7347  "")
7348
7349(define_expand "divdf3"
7350  [(set (match_operand:DF 0 "register_operand" "")
7351 	(div:DF (match_operand:DF 1 "register_operand" "")
7352 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7353   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7354   "")
7355 
7356(define_expand "divsf3"
7357  [(set (match_operand:SF 0 "register_operand" "")
7358	(div:SF (match_operand:SF 1 "register_operand" "")
7359		(match_operand:SF 2 "nonimmediate_operand" "")))]
7360  "TARGET_80387 || TARGET_SSE_MATH"
7361  "")
7362
7363;; Remainder instructions.
7364
7365(define_expand "divmoddi4"
7366  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7367		   (div:DI (match_operand:DI 1 "register_operand" "")
7368			   (match_operand:DI 2 "nonimmediate_operand" "")))
7369	      (set (match_operand:DI 3 "register_operand" "")
7370		   (mod:DI (match_dup 1) (match_dup 2)))
7371	      (clobber (reg:CC FLAGS_REG))])]
7372  "TARGET_64BIT"
7373  "")
7374
7375;; Allow to come the parameter in eax or edx to avoid extra moves.
7376;; Penalize eax case slightly because it results in worse scheduling
7377;; of code.
7378(define_insn "*divmoddi4_nocltd_rex64"
7379  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7380	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7381		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7382   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7383	(mod:DI (match_dup 2) (match_dup 3)))
7384   (clobber (reg:CC FLAGS_REG))]
7385  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7386  "#"
7387  [(set_attr "type" "multi")])
7388
7389(define_insn "*divmoddi4_cltd_rex64"
7390  [(set (match_operand:DI 0 "register_operand" "=a")
7391	(div:DI (match_operand:DI 2 "register_operand" "a")
7392		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7393   (set (match_operand:DI 1 "register_operand" "=&d")
7394	(mod:DI (match_dup 2) (match_dup 3)))
7395   (clobber (reg:CC FLAGS_REG))]
7396  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7397  "#"
7398  [(set_attr "type" "multi")])
7399
7400(define_insn "*divmoddi_noext_rex64"
7401  [(set (match_operand:DI 0 "register_operand" "=a")
7402	(div:DI (match_operand:DI 1 "register_operand" "0")
7403		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7404   (set (match_operand:DI 3 "register_operand" "=d")
7405	(mod:DI (match_dup 1) (match_dup 2)))
7406   (use (match_operand:DI 4 "register_operand" "3"))
7407   (clobber (reg:CC FLAGS_REG))]
7408  "TARGET_64BIT"
7409  "idiv{q}\t%2"
7410  [(set_attr "type" "idiv")
7411   (set_attr "mode" "DI")])
7412
7413(define_split
7414  [(set (match_operand:DI 0 "register_operand" "")
7415	(div:DI (match_operand:DI 1 "register_operand" "")
7416		(match_operand:DI 2 "nonimmediate_operand" "")))
7417   (set (match_operand:DI 3 "register_operand" "")
7418	(mod:DI (match_dup 1) (match_dup 2)))
7419   (clobber (reg:CC FLAGS_REG))]
7420  "TARGET_64BIT && reload_completed"
7421  [(parallel [(set (match_dup 3)
7422		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7423	      (clobber (reg:CC FLAGS_REG))])
7424   (parallel [(set (match_dup 0)
7425	           (div:DI (reg:DI 0) (match_dup 2)))
7426	      (set (match_dup 3)
7427		   (mod:DI (reg:DI 0) (match_dup 2)))
7428	      (use (match_dup 3))
7429	      (clobber (reg:CC FLAGS_REG))])]
7430{
7431  /* Avoid use of cltd in favor of a mov+shift.  */
7432  if (!TARGET_USE_CLTD && !optimize_size)
7433    {
7434      if (true_regnum (operands[1]))
7435        emit_move_insn (operands[0], operands[1]);
7436      else
7437	emit_move_insn (operands[3], operands[1]);
7438      operands[4] = operands[3];
7439    }
7440  else
7441    {
7442      gcc_assert (!true_regnum (operands[1]));
7443      operands[4] = operands[1];
7444    }
7445})
7446
7447
7448(define_expand "divmodsi4"
7449  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7450		   (div:SI (match_operand:SI 1 "register_operand" "")
7451			   (match_operand:SI 2 "nonimmediate_operand" "")))
7452	      (set (match_operand:SI 3 "register_operand" "")
7453		   (mod:SI (match_dup 1) (match_dup 2)))
7454	      (clobber (reg:CC FLAGS_REG))])]
7455  ""
7456  "")
7457
7458;; Allow to come the parameter in eax or edx to avoid extra moves.
7459;; Penalize eax case slightly because it results in worse scheduling
7460;; of code.
7461(define_insn "*divmodsi4_nocltd"
7462  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7463	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7464		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7465   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7466	(mod:SI (match_dup 2) (match_dup 3)))
7467   (clobber (reg:CC FLAGS_REG))]
7468  "!optimize_size && !TARGET_USE_CLTD"
7469  "#"
7470  [(set_attr "type" "multi")])
7471
7472(define_insn "*divmodsi4_cltd"
7473  [(set (match_operand:SI 0 "register_operand" "=a")
7474	(div:SI (match_operand:SI 2 "register_operand" "a")
7475		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7476   (set (match_operand:SI 1 "register_operand" "=&d")
7477	(mod:SI (match_dup 2) (match_dup 3)))
7478   (clobber (reg:CC FLAGS_REG))]
7479  "optimize_size || TARGET_USE_CLTD"
7480  "#"
7481  [(set_attr "type" "multi")])
7482
7483(define_insn "*divmodsi_noext"
7484  [(set (match_operand:SI 0 "register_operand" "=a")
7485	(div:SI (match_operand:SI 1 "register_operand" "0")
7486		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7487   (set (match_operand:SI 3 "register_operand" "=d")
7488	(mod:SI (match_dup 1) (match_dup 2)))
7489   (use (match_operand:SI 4 "register_operand" "3"))
7490   (clobber (reg:CC FLAGS_REG))]
7491  ""
7492  "idiv{l}\t%2"
7493  [(set_attr "type" "idiv")
7494   (set_attr "mode" "SI")])
7495
7496(define_split
7497  [(set (match_operand:SI 0 "register_operand" "")
7498	(div:SI (match_operand:SI 1 "register_operand" "")
7499		(match_operand:SI 2 "nonimmediate_operand" "")))
7500   (set (match_operand:SI 3 "register_operand" "")
7501	(mod:SI (match_dup 1) (match_dup 2)))
7502   (clobber (reg:CC FLAGS_REG))]
7503  "reload_completed"
7504  [(parallel [(set (match_dup 3)
7505		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7506	      (clobber (reg:CC FLAGS_REG))])
7507   (parallel [(set (match_dup 0)
7508	           (div:SI (reg:SI 0) (match_dup 2)))
7509	      (set (match_dup 3)
7510		   (mod:SI (reg:SI 0) (match_dup 2)))
7511	      (use (match_dup 3))
7512	      (clobber (reg:CC FLAGS_REG))])]
7513{
7514  /* Avoid use of cltd in favor of a mov+shift.  */
7515  if (!TARGET_USE_CLTD && !optimize_size)
7516    {
7517      if (true_regnum (operands[1]))
7518        emit_move_insn (operands[0], operands[1]);
7519      else
7520	emit_move_insn (operands[3], operands[1]);
7521      operands[4] = operands[3];
7522    }
7523  else
7524    {
7525      gcc_assert (!true_regnum (operands[1]));
7526      operands[4] = operands[1];
7527    }
7528})
7529;; %%% Split me.
7530(define_insn "divmodhi4"
7531  [(set (match_operand:HI 0 "register_operand" "=a")
7532	(div:HI (match_operand:HI 1 "register_operand" "0")
7533		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7534   (set (match_operand:HI 3 "register_operand" "=&d")
7535	(mod:HI (match_dup 1) (match_dup 2)))
7536   (clobber (reg:CC FLAGS_REG))]
7537  "TARGET_HIMODE_MATH"
7538  "cwtd\;idiv{w}\t%2"
7539  [(set_attr "type" "multi")
7540   (set_attr "length_immediate" "0")
7541   (set_attr "mode" "SI")])
7542
7543(define_insn "udivmoddi4"
7544  [(set (match_operand:DI 0 "register_operand" "=a")
7545	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7546		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7547   (set (match_operand:DI 3 "register_operand" "=&d")
7548	(umod:DI (match_dup 1) (match_dup 2)))
7549   (clobber (reg:CC FLAGS_REG))]
7550  "TARGET_64BIT"
7551  "xor{q}\t%3, %3\;div{q}\t%2"
7552  [(set_attr "type" "multi")
7553   (set_attr "length_immediate" "0")
7554   (set_attr "mode" "DI")])
7555
7556(define_insn "*udivmoddi4_noext"
7557  [(set (match_operand:DI 0 "register_operand" "=a")
7558	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7559		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7560   (set (match_operand:DI 3 "register_operand" "=d")
7561	(umod:DI (match_dup 1) (match_dup 2)))
7562   (use (match_dup 3))
7563   (clobber (reg:CC FLAGS_REG))]
7564  "TARGET_64BIT"
7565  "div{q}\t%2"
7566  [(set_attr "type" "idiv")
7567   (set_attr "mode" "DI")])
7568
7569(define_split
7570  [(set (match_operand:DI 0 "register_operand" "")
7571	(udiv:DI (match_operand:DI 1 "register_operand" "")
7572		 (match_operand:DI 2 "nonimmediate_operand" "")))
7573   (set (match_operand:DI 3 "register_operand" "")
7574	(umod:DI (match_dup 1) (match_dup 2)))
7575   (clobber (reg:CC FLAGS_REG))]
7576  "TARGET_64BIT && reload_completed"
7577  [(set (match_dup 3) (const_int 0))
7578   (parallel [(set (match_dup 0)
7579		   (udiv:DI (match_dup 1) (match_dup 2)))
7580	      (set (match_dup 3)
7581		   (umod:DI (match_dup 1) (match_dup 2)))
7582	      (use (match_dup 3))
7583	      (clobber (reg:CC FLAGS_REG))])]
7584  "")
7585
7586(define_insn "udivmodsi4"
7587  [(set (match_operand:SI 0 "register_operand" "=a")
7588	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7589		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7590   (set (match_operand:SI 3 "register_operand" "=&d")
7591	(umod:SI (match_dup 1) (match_dup 2)))
7592   (clobber (reg:CC FLAGS_REG))]
7593  ""
7594  "xor{l}\t%3, %3\;div{l}\t%2"
7595  [(set_attr "type" "multi")
7596   (set_attr "length_immediate" "0")
7597   (set_attr "mode" "SI")])
7598
7599(define_insn "*udivmodsi4_noext"
7600  [(set (match_operand:SI 0 "register_operand" "=a")
7601	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7602		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7603   (set (match_operand:SI 3 "register_operand" "=d")
7604	(umod:SI (match_dup 1) (match_dup 2)))
7605   (use (match_dup 3))
7606   (clobber (reg:CC FLAGS_REG))]
7607  ""
7608  "div{l}\t%2"
7609  [(set_attr "type" "idiv")
7610   (set_attr "mode" "SI")])
7611
7612(define_split
7613  [(set (match_operand:SI 0 "register_operand" "")
7614	(udiv:SI (match_operand:SI 1 "register_operand" "")
7615		 (match_operand:SI 2 "nonimmediate_operand" "")))
7616   (set (match_operand:SI 3 "register_operand" "")
7617	(umod:SI (match_dup 1) (match_dup 2)))
7618   (clobber (reg:CC FLAGS_REG))]
7619  "reload_completed"
7620  [(set (match_dup 3) (const_int 0))
7621   (parallel [(set (match_dup 0)
7622		   (udiv:SI (match_dup 1) (match_dup 2)))
7623	      (set (match_dup 3)
7624		   (umod:SI (match_dup 1) (match_dup 2)))
7625	      (use (match_dup 3))
7626	      (clobber (reg:CC FLAGS_REG))])]
7627  "")
7628
7629(define_expand "udivmodhi4"
7630  [(set (match_dup 4) (const_int 0))
7631   (parallel [(set (match_operand:HI 0 "register_operand" "")
7632		   (udiv:HI (match_operand:HI 1 "register_operand" "")
7633		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
7634	      (set (match_operand:HI 3 "register_operand" "")
7635	   	   (umod:HI (match_dup 1) (match_dup 2)))
7636	      (use (match_dup 4))
7637	      (clobber (reg:CC FLAGS_REG))])]
7638  "TARGET_HIMODE_MATH"
7639  "operands[4] = gen_reg_rtx (HImode);")
7640
7641(define_insn "*udivmodhi_noext"
7642  [(set (match_operand:HI 0 "register_operand" "=a")
7643	(udiv:HI (match_operand:HI 1 "register_operand" "0")
7644		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7645   (set (match_operand:HI 3 "register_operand" "=d")
7646	(umod:HI (match_dup 1) (match_dup 2)))
7647   (use (match_operand:HI 4 "register_operand" "3"))
7648   (clobber (reg:CC FLAGS_REG))]
7649  ""
7650  "div{w}\t%2"
7651  [(set_attr "type" "idiv")
7652   (set_attr "mode" "HI")])
7653
7654;; We cannot use div/idiv for double division, because it causes
7655;; "division by zero" on the overflow and that's not what we expect
7656;; from truncate.  Because true (non truncating) double division is
7657;; never generated, we can't create this insn anyway.
7658;
7659;(define_insn ""
7660;  [(set (match_operand:SI 0 "register_operand" "=a")
7661;	(truncate:SI
7662;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7663;		   (zero_extend:DI
7664;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7665;   (set (match_operand:SI 3 "register_operand" "=d")
7666;	(truncate:SI
7667;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7668;   (clobber (reg:CC FLAGS_REG))]
7669;  ""
7670;  "div{l}\t{%2, %0|%0, %2}"
7671;  [(set_attr "type" "idiv")])
7672
7673;;- Logical AND instructions
7674
7675;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7676;; Note that this excludes ah.
7677
7678(define_insn "*testdi_1_rex64"
7679  [(set (reg FLAGS_REG)
7680	(compare
7681	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7682		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7683	  (const_int 0)))]
7684  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7685   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7686  "@
7687   test{l}\t{%k1, %k0|%k0, %k1}
7688   test{l}\t{%k1, %k0|%k0, %k1}
7689   test{q}\t{%1, %0|%0, %1}
7690   test{q}\t{%1, %0|%0, %1}
7691   test{q}\t{%1, %0|%0, %1}"
7692  [(set_attr "type" "test")
7693   (set_attr "modrm" "0,1,0,1,1")
7694   (set_attr "mode" "SI,SI,DI,DI,DI")
7695   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7696
7697(define_insn "testsi_1"
7698  [(set (reg FLAGS_REG)
7699	(compare
7700	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7701		  (match_operand:SI 1 "general_operand" "in,in,rin"))
7702	  (const_int 0)))]
7703  "ix86_match_ccmode (insn, CCNOmode)
7704   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7705  "test{l}\t{%1, %0|%0, %1}"
7706  [(set_attr "type" "test")
7707   (set_attr "modrm" "0,1,1")
7708   (set_attr "mode" "SI")
7709   (set_attr "pent_pair" "uv,np,uv")])
7710
7711(define_expand "testsi_ccno_1"
7712  [(set (reg:CCNO FLAGS_REG)
7713	(compare:CCNO
7714	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7715		  (match_operand:SI 1 "nonmemory_operand" ""))
7716	  (const_int 0)))]
7717  ""
7718  "")
7719
7720(define_insn "*testhi_1"
7721  [(set (reg FLAGS_REG)
7722        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7723			 (match_operand:HI 1 "general_operand" "n,n,rn"))
7724		 (const_int 0)))]
7725  "ix86_match_ccmode (insn, CCNOmode)
7726   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7727  "test{w}\t{%1, %0|%0, %1}"
7728  [(set_attr "type" "test")
7729   (set_attr "modrm" "0,1,1")
7730   (set_attr "mode" "HI")
7731   (set_attr "pent_pair" "uv,np,uv")])
7732
7733(define_expand "testqi_ccz_1"
7734  [(set (reg:CCZ FLAGS_REG)
7735        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7736			     (match_operand:QI 1 "nonmemory_operand" ""))
7737		 (const_int 0)))]
7738  ""
7739  "")
7740
7741(define_insn "*testqi_1_maybe_si"
7742  [(set (reg FLAGS_REG)
7743        (compare
7744	  (and:QI
7745	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7746	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7747	  (const_int 0)))]
7748   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7749    && ix86_match_ccmode (insn,
7750 			 GET_CODE (operands[1]) == CONST_INT
7751 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7752{
7753  if (which_alternative == 3)
7754    {
7755      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7756	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7757      return "test{l}\t{%1, %k0|%k0, %1}";
7758    }
7759  return "test{b}\t{%1, %0|%0, %1}";
7760}
7761  [(set_attr "type" "test")
7762   (set_attr "modrm" "0,1,1,1")
7763   (set_attr "mode" "QI,QI,QI,SI")
7764   (set_attr "pent_pair" "uv,np,uv,np")])
7765
7766(define_insn "*testqi_1"
7767  [(set (reg FLAGS_REG)
7768        (compare
7769	  (and:QI
7770	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7771	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7772	  (const_int 0)))]
7773  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7774   && ix86_match_ccmode (insn, CCNOmode)"
7775  "test{b}\t{%1, %0|%0, %1}"
7776  [(set_attr "type" "test")
7777   (set_attr "modrm" "0,1,1")
7778   (set_attr "mode" "QI")
7779   (set_attr "pent_pair" "uv,np,uv")])
7780
7781(define_expand "testqi_ext_ccno_0"
7782  [(set (reg:CCNO FLAGS_REG)
7783	(compare:CCNO
7784	  (and:SI
7785	    (zero_extract:SI
7786	      (match_operand 0 "ext_register_operand" "")
7787	      (const_int 8)
7788	      (const_int 8))
7789	    (match_operand 1 "const_int_operand" ""))
7790	  (const_int 0)))]
7791  ""
7792  "")
7793
7794(define_insn "*testqi_ext_0"
7795  [(set (reg FLAGS_REG)
7796	(compare
7797	  (and:SI
7798	    (zero_extract:SI
7799	      (match_operand 0 "ext_register_operand" "Q")
7800	      (const_int 8)
7801	      (const_int 8))
7802	    (match_operand 1 "const_int_operand" "n"))
7803	  (const_int 0)))]
7804  "ix86_match_ccmode (insn, CCNOmode)"
7805  "test{b}\t{%1, %h0|%h0, %1}"
7806  [(set_attr "type" "test")
7807   (set_attr "mode" "QI")
7808   (set_attr "length_immediate" "1")
7809   (set_attr "pent_pair" "np")])
7810
7811(define_insn "*testqi_ext_1"
7812  [(set (reg FLAGS_REG)
7813	(compare
7814	  (and:SI
7815	    (zero_extract:SI
7816	      (match_operand 0 "ext_register_operand" "Q")
7817	      (const_int 8)
7818	      (const_int 8))
7819	    (zero_extend:SI
7820	      (match_operand:QI 1 "general_operand" "Qm")))
7821	  (const_int 0)))]
7822  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7823   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7824  "test{b}\t{%1, %h0|%h0, %1}"
7825  [(set_attr "type" "test")
7826   (set_attr "mode" "QI")])
7827
7828(define_insn "*testqi_ext_1_rex64"
7829  [(set (reg FLAGS_REG)
7830	(compare
7831	  (and:SI
7832	    (zero_extract:SI
7833	      (match_operand 0 "ext_register_operand" "Q")
7834	      (const_int 8)
7835	      (const_int 8))
7836	    (zero_extend:SI
7837	      (match_operand:QI 1 "register_operand" "Q")))
7838	  (const_int 0)))]
7839  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7840  "test{b}\t{%1, %h0|%h0, %1}"
7841  [(set_attr "type" "test")
7842   (set_attr "mode" "QI")])
7843
7844(define_insn "*testqi_ext_2"
7845  [(set (reg FLAGS_REG)
7846	(compare
7847	  (and:SI
7848	    (zero_extract:SI
7849	      (match_operand 0 "ext_register_operand" "Q")
7850	      (const_int 8)
7851	      (const_int 8))
7852	    (zero_extract:SI
7853	      (match_operand 1 "ext_register_operand" "Q")
7854	      (const_int 8)
7855	      (const_int 8)))
7856	  (const_int 0)))]
7857  "ix86_match_ccmode (insn, CCNOmode)"
7858  "test{b}\t{%h1, %h0|%h0, %h1}"
7859  [(set_attr "type" "test")
7860   (set_attr "mode" "QI")])
7861
7862;; Combine likes to form bit extractions for some tests.  Humor it.
7863(define_insn "*testqi_ext_3"
7864  [(set (reg FLAGS_REG)
7865        (compare (zero_extract:SI
7866		   (match_operand 0 "nonimmediate_operand" "rm")
7867		   (match_operand:SI 1 "const_int_operand" "")
7868		   (match_operand:SI 2 "const_int_operand" ""))
7869		 (const_int 0)))]
7870  "ix86_match_ccmode (insn, CCNOmode)
7871   && INTVAL (operands[1]) > 0
7872   && INTVAL (operands[2]) >= 0
7873   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7874   && (GET_MODE (operands[0]) == SImode
7875       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7876       || GET_MODE (operands[0]) == HImode
7877       || GET_MODE (operands[0]) == QImode)"
7878  "#")
7879
7880(define_insn "*testqi_ext_3_rex64"
7881  [(set (reg FLAGS_REG)
7882        (compare (zero_extract:DI
7883		   (match_operand 0 "nonimmediate_operand" "rm")
7884		   (match_operand:DI 1 "const_int_operand" "")
7885		   (match_operand:DI 2 "const_int_operand" ""))
7886		 (const_int 0)))]
7887  "TARGET_64BIT
7888   && ix86_match_ccmode (insn, CCNOmode)
7889   && INTVAL (operands[1]) > 0
7890   && INTVAL (operands[2]) >= 0
7891   /* Ensure that resulting mask is zero or sign extended operand.  */
7892   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7893       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7894	   && INTVAL (operands[1]) > 32))
7895   && (GET_MODE (operands[0]) == SImode
7896       || GET_MODE (operands[0]) == DImode
7897       || GET_MODE (operands[0]) == HImode
7898       || GET_MODE (operands[0]) == QImode)"
7899  "#")
7900
7901(define_split
7902  [(set (match_operand 0 "flags_reg_operand" "")
7903        (match_operator 1 "compare_operator"
7904	  [(zero_extract
7905	     (match_operand 2 "nonimmediate_operand" "")
7906	     (match_operand 3 "const_int_operand" "")
7907	     (match_operand 4 "const_int_operand" ""))
7908	   (const_int 0)]))]
7909  "ix86_match_ccmode (insn, CCNOmode)"
7910  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7911{
7912  rtx val = operands[2];
7913  HOST_WIDE_INT len = INTVAL (operands[3]);
7914  HOST_WIDE_INT pos = INTVAL (operands[4]);
7915  HOST_WIDE_INT mask;
7916  enum machine_mode mode, submode;
7917
7918  mode = GET_MODE (val);
7919  if (GET_CODE (val) == MEM)
7920    {
7921      /* ??? Combine likes to put non-volatile mem extractions in QImode
7922	 no matter the size of the test.  So find a mode that works.  */
7923      if (! MEM_VOLATILE_P (val))
7924	{
7925	  mode = smallest_mode_for_size (pos + len, MODE_INT);
7926	  val = adjust_address (val, mode, 0);
7927	}
7928    }
7929  else if (GET_CODE (val) == SUBREG
7930	   && (submode = GET_MODE (SUBREG_REG (val)),
7931	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7932	   && pos + len <= GET_MODE_BITSIZE (submode))
7933    {
7934      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7935      mode = submode;
7936      val = SUBREG_REG (val);
7937    }
7938  else if (mode == HImode && pos + len <= 8)
7939    {
7940      /* Small HImode tests can be converted to QImode.  */
7941      mode = QImode;
7942      val = gen_lowpart (QImode, val);
7943    }
7944
7945  if (len == HOST_BITS_PER_WIDE_INT)
7946    mask = -1;
7947  else
7948    mask = ((HOST_WIDE_INT)1 << len) - 1;
7949  mask <<= pos;
7950
7951  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7952})
7953
7954;; Convert HImode/SImode test instructions with immediate to QImode ones.
7955;; i386 does not allow to encode test with 8bit sign extended immediate, so
7956;; this is relatively important trick.
7957;; Do the conversion only post-reload to avoid limiting of the register class
7958;; to QI regs.
7959(define_split
7960  [(set (match_operand 0 "flags_reg_operand" "")
7961	(match_operator 1 "compare_operator"
7962	  [(and (match_operand 2 "register_operand" "")
7963	        (match_operand 3 "const_int_operand" ""))
7964	   (const_int 0)]))]
7965   "reload_completed
7966    && QI_REG_P (operands[2])
7967    && GET_MODE (operands[2]) != QImode
7968    && ((ix86_match_ccmode (insn, CCZmode)
7969    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
7970	|| (ix86_match_ccmode (insn, CCNOmode)
7971	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
7972  [(set (match_dup 0)
7973	(match_op_dup 1
7974	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7975		   (match_dup 3))
7976	   (const_int 0)]))]
7977  "operands[2] = gen_lowpart (SImode, operands[2]);
7978   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7979
7980(define_split
7981  [(set (match_operand 0 "flags_reg_operand" "")
7982	(match_operator 1 "compare_operator"
7983	  [(and (match_operand 2 "nonimmediate_operand" "")
7984	        (match_operand 3 "const_int_operand" ""))
7985	   (const_int 0)]))]
7986   "reload_completed
7987    && GET_MODE (operands[2]) != QImode
7988    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7989    && ((ix86_match_ccmode (insn, CCZmode)
7990	 && !(INTVAL (operands[3]) & ~255))
7991	|| (ix86_match_ccmode (insn, CCNOmode)
7992	    && !(INTVAL (operands[3]) & ~127)))"
7993  [(set (match_dup 0)
7994	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7995			 (const_int 0)]))]
7996  "operands[2] = gen_lowpart (QImode, operands[2]);
7997   operands[3] = gen_lowpart (QImode, operands[3]);")
7998
7999
8000;; %%% This used to optimize known byte-wide and operations to memory,
8001;; and sometimes to QImode registers.  If this is considered useful,
8002;; it should be done with splitters.
8003
8004(define_expand "anddi3"
8005  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8006	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8007		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8008   (clobber (reg:CC FLAGS_REG))]
8009  "TARGET_64BIT"
8010  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8011
8012(define_insn "*anddi_1_rex64"
8013  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8014	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8015		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8016   (clobber (reg:CC FLAGS_REG))]
8017  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8018{
8019  switch (get_attr_type (insn))
8020    {
8021    case TYPE_IMOVX:
8022      {
8023	enum machine_mode mode;
8024
8025	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8026        if (INTVAL (operands[2]) == 0xff)
8027	  mode = QImode;
8028	else
8029	  {
8030	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8031	    mode = HImode;
8032	  }
8033	
8034	operands[1] = gen_lowpart (mode, operands[1]);
8035	if (mode == QImode)
8036	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8037	else
8038	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8039      }
8040
8041    default:
8042      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8043      if (get_attr_mode (insn) == MODE_SI)
8044	return "and{l}\t{%k2, %k0|%k0, %k2}";
8045      else
8046	return "and{q}\t{%2, %0|%0, %2}";
8047    }
8048}
8049  [(set_attr "type" "alu,alu,alu,imovx")
8050   (set_attr "length_immediate" "*,*,*,0")
8051   (set_attr "mode" "SI,DI,DI,DI")])
8052
8053(define_insn "*anddi_2"
8054  [(set (reg FLAGS_REG)
8055	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8056			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8057		 (const_int 0)))
8058   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8059	(and:DI (match_dup 1) (match_dup 2)))]
8060  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8061   && ix86_binary_operator_ok (AND, DImode, operands)"
8062  "@
8063   and{l}\t{%k2, %k0|%k0, %k2}
8064   and{q}\t{%2, %0|%0, %2}
8065   and{q}\t{%2, %0|%0, %2}"
8066  [(set_attr "type" "alu")
8067   (set_attr "mode" "SI,DI,DI")])
8068
8069(define_expand "andsi3"
8070  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8071	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8072		(match_operand:SI 2 "general_operand" "")))
8073   (clobber (reg:CC FLAGS_REG))]
8074  ""
8075  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8076
8077(define_insn "*andsi_1"
8078  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8079	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8080		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8081   (clobber (reg:CC FLAGS_REG))]
8082  "ix86_binary_operator_ok (AND, SImode, operands)"
8083{
8084  switch (get_attr_type (insn))
8085    {
8086    case TYPE_IMOVX:
8087      {
8088	enum machine_mode mode;
8089
8090	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8091        if (INTVAL (operands[2]) == 0xff)
8092	  mode = QImode;
8093	else
8094	  {
8095	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8096	    mode = HImode;
8097	  }
8098	
8099	operands[1] = gen_lowpart (mode, operands[1]);
8100	if (mode == QImode)
8101	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8102	else
8103	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8104      }
8105
8106    default:
8107      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8108      return "and{l}\t{%2, %0|%0, %2}";
8109    }
8110}
8111  [(set_attr "type" "alu,alu,imovx")
8112   (set_attr "length_immediate" "*,*,0")
8113   (set_attr "mode" "SI")])
8114
8115(define_split
8116  [(set (match_operand 0 "register_operand" "")
8117	(and (match_dup 0)
8118	     (const_int -65536)))
8119   (clobber (reg:CC FLAGS_REG))]
8120  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8121  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8122  "operands[1] = gen_lowpart (HImode, operands[0]);")
8123
8124(define_split
8125  [(set (match_operand 0 "ext_register_operand" "")
8126	(and (match_dup 0)
8127	     (const_int -256)))
8128   (clobber (reg:CC FLAGS_REG))]
8129  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8130  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8131  "operands[1] = gen_lowpart (QImode, operands[0]);")
8132
8133(define_split
8134  [(set (match_operand 0 "ext_register_operand" "")
8135	(and (match_dup 0)
8136	     (const_int -65281)))
8137   (clobber (reg:CC FLAGS_REG))]
8138  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8139  [(parallel [(set (zero_extract:SI (match_dup 0)
8140				    (const_int 8)
8141				    (const_int 8))
8142		   (xor:SI 
8143		     (zero_extract:SI (match_dup 0)
8144				      (const_int 8)
8145				      (const_int 8))
8146		     (zero_extract:SI (match_dup 0)
8147				      (const_int 8)
8148				      (const_int 8))))
8149	      (clobber (reg:CC FLAGS_REG))])]
8150  "operands[0] = gen_lowpart (SImode, operands[0]);")
8151
8152;; See comment for addsi_1_zext why we do use nonimmediate_operand
8153(define_insn "*andsi_1_zext"
8154  [(set (match_operand:DI 0 "register_operand" "=r")
8155	(zero_extend:DI
8156	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8157		  (match_operand:SI 2 "general_operand" "rim"))))
8158   (clobber (reg:CC FLAGS_REG))]
8159  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8160  "and{l}\t{%2, %k0|%k0, %2}"
8161  [(set_attr "type" "alu")
8162   (set_attr "mode" "SI")])
8163
8164(define_insn "*andsi_2"
8165  [(set (reg FLAGS_REG)
8166	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8167			 (match_operand:SI 2 "general_operand" "rim,ri"))
8168		 (const_int 0)))
8169   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8170	(and:SI (match_dup 1) (match_dup 2)))]
8171  "ix86_match_ccmode (insn, CCNOmode)
8172   && ix86_binary_operator_ok (AND, SImode, operands)"
8173  "and{l}\t{%2, %0|%0, %2}"
8174  [(set_attr "type" "alu")
8175   (set_attr "mode" "SI")])
8176
8177;; See comment for addsi_1_zext why we do use nonimmediate_operand
8178(define_insn "*andsi_2_zext"
8179  [(set (reg FLAGS_REG)
8180	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8181			 (match_operand:SI 2 "general_operand" "rim"))
8182		 (const_int 0)))
8183   (set (match_operand:DI 0 "register_operand" "=r")
8184	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8185  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8186   && ix86_binary_operator_ok (AND, SImode, operands)"
8187  "and{l}\t{%2, %k0|%k0, %2}"
8188  [(set_attr "type" "alu")
8189   (set_attr "mode" "SI")])
8190
8191(define_expand "andhi3"
8192  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8193	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8194		(match_operand:HI 2 "general_operand" "")))
8195   (clobber (reg:CC FLAGS_REG))]
8196  "TARGET_HIMODE_MATH"
8197  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8198
8199(define_insn "*andhi_1"
8200  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8201	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8202		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8203   (clobber (reg:CC FLAGS_REG))]
8204  "ix86_binary_operator_ok (AND, HImode, operands)"
8205{
8206  switch (get_attr_type (insn))
8207    {
8208    case TYPE_IMOVX:
8209      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8210      gcc_assert (INTVAL (operands[2]) == 0xff);
8211      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8212
8213    default:
8214      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8215
8216      return "and{w}\t{%2, %0|%0, %2}";
8217    }
8218}
8219  [(set_attr "type" "alu,alu,imovx")
8220   (set_attr "length_immediate" "*,*,0")
8221   (set_attr "mode" "HI,HI,SI")])
8222
8223(define_insn "*andhi_2"
8224  [(set (reg FLAGS_REG)
8225	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8226			 (match_operand:HI 2 "general_operand" "rim,ri"))
8227		 (const_int 0)))
8228   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8229	(and:HI (match_dup 1) (match_dup 2)))]
8230  "ix86_match_ccmode (insn, CCNOmode)
8231   && ix86_binary_operator_ok (AND, HImode, operands)"
8232  "and{w}\t{%2, %0|%0, %2}"
8233  [(set_attr "type" "alu")
8234   (set_attr "mode" "HI")])
8235
8236(define_expand "andqi3"
8237  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8238	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8239		(match_operand:QI 2 "general_operand" "")))
8240   (clobber (reg:CC FLAGS_REG))]
8241  "TARGET_QIMODE_MATH"
8242  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8243
8244;; %%% Potential partial reg stall on alternative 2.  What to do?
8245(define_insn "*andqi_1"
8246  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8247	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8248		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8249   (clobber (reg:CC FLAGS_REG))]
8250  "ix86_binary_operator_ok (AND, QImode, operands)"
8251  "@
8252   and{b}\t{%2, %0|%0, %2}
8253   and{b}\t{%2, %0|%0, %2}
8254   and{l}\t{%k2, %k0|%k0, %k2}"
8255  [(set_attr "type" "alu")
8256   (set_attr "mode" "QI,QI,SI")])
8257
8258(define_insn "*andqi_1_slp"
8259  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8260	(and:QI (match_dup 0)
8261		(match_operand:QI 1 "general_operand" "qi,qmi")))
8262   (clobber (reg:CC FLAGS_REG))]
8263  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8264   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8265  "and{b}\t{%1, %0|%0, %1}"
8266  [(set_attr "type" "alu1")
8267   (set_attr "mode" "QI")])
8268
8269(define_insn "*andqi_2_maybe_si"
8270  [(set (reg FLAGS_REG)
8271	(compare (and:QI
8272		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8273		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8274		 (const_int 0)))
8275   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8276	(and:QI (match_dup 1) (match_dup 2)))]
8277  "ix86_binary_operator_ok (AND, QImode, operands)
8278   && ix86_match_ccmode (insn,
8279			 GET_CODE (operands[2]) == CONST_INT
8280			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8281{
8282  if (which_alternative == 2)
8283    {
8284      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8285        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8286      return "and{l}\t{%2, %k0|%k0, %2}";
8287    }
8288  return "and{b}\t{%2, %0|%0, %2}";
8289}
8290  [(set_attr "type" "alu")
8291   (set_attr "mode" "QI,QI,SI")])
8292
8293(define_insn "*andqi_2"
8294  [(set (reg FLAGS_REG)
8295	(compare (and:QI
8296		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8297		   (match_operand:QI 2 "general_operand" "qim,qi"))
8298		 (const_int 0)))
8299   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8300	(and:QI (match_dup 1) (match_dup 2)))]
8301  "ix86_match_ccmode (insn, CCNOmode)
8302   && ix86_binary_operator_ok (AND, QImode, operands)"
8303  "and{b}\t{%2, %0|%0, %2}"
8304  [(set_attr "type" "alu")
8305   (set_attr "mode" "QI")])
8306
8307(define_insn "*andqi_2_slp"
8308  [(set (reg FLAGS_REG)
8309	(compare (and:QI
8310		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8311		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8312		 (const_int 0)))
8313   (set (strict_low_part (match_dup 0))
8314	(and:QI (match_dup 0) (match_dup 1)))]
8315  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8316   && ix86_match_ccmode (insn, CCNOmode)
8317   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8318  "and{b}\t{%1, %0|%0, %1}"
8319  [(set_attr "type" "alu1")
8320   (set_attr "mode" "QI")])
8321
8322;; ??? A bug in recog prevents it from recognizing a const_int as an
8323;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8324;; for a QImode operand, which of course failed.
8325
8326(define_insn "andqi_ext_0"
8327  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8328			 (const_int 8)
8329			 (const_int 8))
8330	(and:SI 
8331	  (zero_extract:SI
8332	    (match_operand 1 "ext_register_operand" "0")
8333	    (const_int 8)
8334	    (const_int 8))
8335	  (match_operand 2 "const_int_operand" "n")))
8336   (clobber (reg:CC FLAGS_REG))]
8337  ""
8338  "and{b}\t{%2, %h0|%h0, %2}"
8339  [(set_attr "type" "alu")
8340   (set_attr "length_immediate" "1")
8341   (set_attr "mode" "QI")])
8342
8343;; Generated by peephole translating test to and.  This shows up
8344;; often in fp comparisons.
8345
8346(define_insn "*andqi_ext_0_cc"
8347  [(set (reg FLAGS_REG)
8348	(compare
8349	  (and:SI
8350	    (zero_extract:SI
8351	      (match_operand 1 "ext_register_operand" "0")
8352	      (const_int 8)
8353	      (const_int 8))
8354	    (match_operand 2 "const_int_operand" "n"))
8355	  (const_int 0)))
8356   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8357			 (const_int 8)
8358			 (const_int 8))
8359	(and:SI 
8360	  (zero_extract:SI
8361	    (match_dup 1)
8362	    (const_int 8)
8363	    (const_int 8))
8364	  (match_dup 2)))]
8365  "ix86_match_ccmode (insn, CCNOmode)"
8366  "and{b}\t{%2, %h0|%h0, %2}"
8367  [(set_attr "type" "alu")
8368   (set_attr "length_immediate" "1")
8369   (set_attr "mode" "QI")])
8370
8371(define_insn "*andqi_ext_1"
8372  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8373			 (const_int 8)
8374			 (const_int 8))
8375	(and:SI 
8376	  (zero_extract:SI
8377	    (match_operand 1 "ext_register_operand" "0")
8378	    (const_int 8)
8379	    (const_int 8))
8380	  (zero_extend:SI
8381	    (match_operand:QI 2 "general_operand" "Qm"))))
8382   (clobber (reg:CC FLAGS_REG))]
8383  "!TARGET_64BIT"
8384  "and{b}\t{%2, %h0|%h0, %2}"
8385  [(set_attr "type" "alu")
8386   (set_attr "length_immediate" "0")
8387   (set_attr "mode" "QI")])
8388
8389(define_insn "*andqi_ext_1_rex64"
8390  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8391			 (const_int 8)
8392			 (const_int 8))
8393	(and:SI 
8394	  (zero_extract:SI
8395	    (match_operand 1 "ext_register_operand" "0")
8396	    (const_int 8)
8397	    (const_int 8))
8398	  (zero_extend:SI
8399	    (match_operand 2 "ext_register_operand" "Q"))))
8400   (clobber (reg:CC FLAGS_REG))]
8401  "TARGET_64BIT"
8402  "and{b}\t{%2, %h0|%h0, %2}"
8403  [(set_attr "type" "alu")
8404   (set_attr "length_immediate" "0")
8405   (set_attr "mode" "QI")])
8406
8407(define_insn "*andqi_ext_2"
8408  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8409			 (const_int 8)
8410			 (const_int 8))
8411	(and:SI
8412	  (zero_extract:SI
8413	    (match_operand 1 "ext_register_operand" "%0")
8414	    (const_int 8)
8415	    (const_int 8))
8416	  (zero_extract:SI
8417	    (match_operand 2 "ext_register_operand" "Q")
8418	    (const_int 8)
8419	    (const_int 8))))
8420   (clobber (reg:CC FLAGS_REG))]
8421  ""
8422  "and{b}\t{%h2, %h0|%h0, %h2}"
8423  [(set_attr "type" "alu")
8424   (set_attr "length_immediate" "0")
8425   (set_attr "mode" "QI")])
8426
8427;; Convert wide AND instructions with immediate operand to shorter QImode
8428;; equivalents when possible.
8429;; Don't do the splitting with memory operands, since it introduces risk
8430;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8431;; for size, but that can (should?) be handled by generic code instead.
8432(define_split
8433  [(set (match_operand 0 "register_operand" "")
8434	(and (match_operand 1 "register_operand" "")
8435	     (match_operand 2 "const_int_operand" "")))
8436   (clobber (reg:CC FLAGS_REG))]
8437   "reload_completed
8438    && QI_REG_P (operands[0])
8439    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8440    && !(~INTVAL (operands[2]) & ~(255 << 8))
8441    && GET_MODE (operands[0]) != QImode"
8442  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8443		   (and:SI (zero_extract:SI (match_dup 1)
8444					    (const_int 8) (const_int 8))
8445			   (match_dup 2)))
8446	      (clobber (reg:CC FLAGS_REG))])]
8447  "operands[0] = gen_lowpart (SImode, operands[0]);
8448   operands[1] = gen_lowpart (SImode, operands[1]);
8449   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8450
8451;; Since AND can be encoded with sign extended immediate, this is only
8452;; profitable when 7th bit is not set.
8453(define_split
8454  [(set (match_operand 0 "register_operand" "")
8455	(and (match_operand 1 "general_operand" "")
8456	     (match_operand 2 "const_int_operand" "")))
8457   (clobber (reg:CC FLAGS_REG))]
8458   "reload_completed
8459    && ANY_QI_REG_P (operands[0])
8460    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8461    && !(~INTVAL (operands[2]) & ~255)
8462    && !(INTVAL (operands[2]) & 128)
8463    && GET_MODE (operands[0]) != QImode"
8464  [(parallel [(set (strict_low_part (match_dup 0))
8465		   (and:QI (match_dup 1)
8466			   (match_dup 2)))
8467	      (clobber (reg:CC FLAGS_REG))])]
8468  "operands[0] = gen_lowpart (QImode, operands[0]);
8469   operands[1] = gen_lowpart (QImode, operands[1]);
8470   operands[2] = gen_lowpart (QImode, operands[2]);")
8471
8472;; Logical inclusive OR instructions
8473
8474;; %%% This used to optimize known byte-wide and operations to memory.
8475;; If this is considered useful, it should be done with splitters.
8476
8477(define_expand "iordi3"
8478  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8479	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8480		(match_operand:DI 2 "x86_64_general_operand" "")))
8481   (clobber (reg:CC FLAGS_REG))]
8482  "TARGET_64BIT"
8483  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8484
8485(define_insn "*iordi_1_rex64"
8486  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8487	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8488		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8489   (clobber (reg:CC FLAGS_REG))]
8490  "TARGET_64BIT
8491   && ix86_binary_operator_ok (IOR, DImode, operands)"
8492  "or{q}\t{%2, %0|%0, %2}"
8493  [(set_attr "type" "alu")
8494   (set_attr "mode" "DI")])
8495
8496(define_insn "*iordi_2_rex64"
8497  [(set (reg FLAGS_REG)
8498	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8499			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8500		 (const_int 0)))
8501   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8502	(ior:DI (match_dup 1) (match_dup 2)))]
8503  "TARGET_64BIT
8504   && ix86_match_ccmode (insn, CCNOmode)
8505   && ix86_binary_operator_ok (IOR, DImode, operands)"
8506  "or{q}\t{%2, %0|%0, %2}"
8507  [(set_attr "type" "alu")
8508   (set_attr "mode" "DI")])
8509
8510(define_insn "*iordi_3_rex64"
8511  [(set (reg FLAGS_REG)
8512	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8513			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8514		 (const_int 0)))
8515   (clobber (match_scratch:DI 0 "=r"))]
8516  "TARGET_64BIT
8517   && ix86_match_ccmode (insn, CCNOmode)
8518   && ix86_binary_operator_ok (IOR, DImode, operands)"
8519  "or{q}\t{%2, %0|%0, %2}"
8520  [(set_attr "type" "alu")
8521   (set_attr "mode" "DI")])
8522
8523
8524(define_expand "iorsi3"
8525  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8526	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8527		(match_operand:SI 2 "general_operand" "")))
8528   (clobber (reg:CC FLAGS_REG))]
8529  ""
8530  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8531
8532(define_insn "*iorsi_1"
8533  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8534	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8535		(match_operand:SI 2 "general_operand" "ri,rmi")))
8536   (clobber (reg:CC FLAGS_REG))]
8537  "ix86_binary_operator_ok (IOR, SImode, operands)"
8538  "or{l}\t{%2, %0|%0, %2}"
8539  [(set_attr "type" "alu")
8540   (set_attr "mode" "SI")])
8541
8542;; See comment for addsi_1_zext why we do use nonimmediate_operand
8543(define_insn "*iorsi_1_zext"
8544  [(set (match_operand:DI 0 "register_operand" "=rm")
8545	(zero_extend:DI
8546	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8547		  (match_operand:SI 2 "general_operand" "rim"))))
8548   (clobber (reg:CC FLAGS_REG))]
8549  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8550  "or{l}\t{%2, %k0|%k0, %2}"
8551  [(set_attr "type" "alu")
8552   (set_attr "mode" "SI")])
8553
8554(define_insn "*iorsi_1_zext_imm"
8555  [(set (match_operand:DI 0 "register_operand" "=rm")
8556	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8557		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8558   (clobber (reg:CC FLAGS_REG))]
8559  "TARGET_64BIT"
8560  "or{l}\t{%2, %k0|%k0, %2}"
8561  [(set_attr "type" "alu")
8562   (set_attr "mode" "SI")])
8563
8564(define_insn "*iorsi_2"
8565  [(set (reg FLAGS_REG)
8566	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567			 (match_operand:SI 2 "general_operand" "rim,ri"))
8568		 (const_int 0)))
8569   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8570	(ior:SI (match_dup 1) (match_dup 2)))]
8571  "ix86_match_ccmode (insn, CCNOmode)
8572   && ix86_binary_operator_ok (IOR, SImode, operands)"
8573  "or{l}\t{%2, %0|%0, %2}"
8574  [(set_attr "type" "alu")
8575   (set_attr "mode" "SI")])
8576
8577;; See comment for addsi_1_zext why we do use nonimmediate_operand
8578;; ??? Special case for immediate operand is missing - it is tricky.
8579(define_insn "*iorsi_2_zext"
8580  [(set (reg FLAGS_REG)
8581	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8582			 (match_operand:SI 2 "general_operand" "rim"))
8583		 (const_int 0)))
8584   (set (match_operand:DI 0 "register_operand" "=r")
8585	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8586  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8587   && ix86_binary_operator_ok (IOR, SImode, operands)"
8588  "or{l}\t{%2, %k0|%k0, %2}"
8589  [(set_attr "type" "alu")
8590   (set_attr "mode" "SI")])
8591
8592(define_insn "*iorsi_2_zext_imm"
8593  [(set (reg FLAGS_REG)
8594	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8595			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8596		 (const_int 0)))
8597   (set (match_operand:DI 0 "register_operand" "=r")
8598	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8599  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8600   && ix86_binary_operator_ok (IOR, SImode, operands)"
8601  "or{l}\t{%2, %k0|%k0, %2}"
8602  [(set_attr "type" "alu")
8603   (set_attr "mode" "SI")])
8604
8605(define_insn "*iorsi_3"
8606  [(set (reg FLAGS_REG)
8607	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8608			 (match_operand:SI 2 "general_operand" "rim"))
8609		 (const_int 0)))
8610   (clobber (match_scratch:SI 0 "=r"))]
8611  "ix86_match_ccmode (insn, CCNOmode)
8612   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8613  "or{l}\t{%2, %0|%0, %2}"
8614  [(set_attr "type" "alu")
8615   (set_attr "mode" "SI")])
8616
8617(define_expand "iorhi3"
8618  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8619	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8620		(match_operand:HI 2 "general_operand" "")))
8621   (clobber (reg:CC FLAGS_REG))]
8622  "TARGET_HIMODE_MATH"
8623  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8624
8625(define_insn "*iorhi_1"
8626  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8627	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8628		(match_operand:HI 2 "general_operand" "rmi,ri")))
8629   (clobber (reg:CC FLAGS_REG))]
8630  "ix86_binary_operator_ok (IOR, HImode, operands)"
8631  "or{w}\t{%2, %0|%0, %2}"
8632  [(set_attr "type" "alu")
8633   (set_attr "mode" "HI")])
8634
8635(define_insn "*iorhi_2"
8636  [(set (reg FLAGS_REG)
8637	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8638			 (match_operand:HI 2 "general_operand" "rim,ri"))
8639		 (const_int 0)))
8640   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8641	(ior:HI (match_dup 1) (match_dup 2)))]
8642  "ix86_match_ccmode (insn, CCNOmode)
8643   && ix86_binary_operator_ok (IOR, HImode, operands)"
8644  "or{w}\t{%2, %0|%0, %2}"
8645  [(set_attr "type" "alu")
8646   (set_attr "mode" "HI")])
8647
8648(define_insn "*iorhi_3"
8649  [(set (reg FLAGS_REG)
8650	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8651			 (match_operand:HI 2 "general_operand" "rim"))
8652		 (const_int 0)))
8653   (clobber (match_scratch:HI 0 "=r"))]
8654  "ix86_match_ccmode (insn, CCNOmode)
8655   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8656  "or{w}\t{%2, %0|%0, %2}"
8657  [(set_attr "type" "alu")
8658   (set_attr "mode" "HI")])
8659
8660(define_expand "iorqi3"
8661  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8662	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8663		(match_operand:QI 2 "general_operand" "")))
8664   (clobber (reg:CC FLAGS_REG))]
8665  "TARGET_QIMODE_MATH"
8666  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8667
8668;; %%% Potential partial reg stall on alternative 2.  What to do?
8669(define_insn "*iorqi_1"
8670  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8671	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8672		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8673   (clobber (reg:CC FLAGS_REG))]
8674  "ix86_binary_operator_ok (IOR, QImode, operands)"
8675  "@
8676   or{b}\t{%2, %0|%0, %2}
8677   or{b}\t{%2, %0|%0, %2}
8678   or{l}\t{%k2, %k0|%k0, %k2}"
8679  [(set_attr "type" "alu")
8680   (set_attr "mode" "QI,QI,SI")])
8681
8682(define_insn "*iorqi_1_slp"
8683  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8684	(ior:QI (match_dup 0)
8685		(match_operand:QI 1 "general_operand" "qmi,qi")))
8686   (clobber (reg:CC FLAGS_REG))]
8687  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8688   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8689  "or{b}\t{%1, %0|%0, %1}"
8690  [(set_attr "type" "alu1")
8691   (set_attr "mode" "QI")])
8692
8693(define_insn "*iorqi_2"
8694  [(set (reg FLAGS_REG)
8695	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8696			 (match_operand:QI 2 "general_operand" "qim,qi"))
8697		 (const_int 0)))
8698   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8699	(ior:QI (match_dup 1) (match_dup 2)))]
8700  "ix86_match_ccmode (insn, CCNOmode)
8701   && ix86_binary_operator_ok (IOR, QImode, operands)"
8702  "or{b}\t{%2, %0|%0, %2}"
8703  [(set_attr "type" "alu")
8704   (set_attr "mode" "QI")])
8705
8706(define_insn "*iorqi_2_slp"
8707  [(set (reg FLAGS_REG)
8708	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8709			 (match_operand:QI 1 "general_operand" "qim,qi"))
8710		 (const_int 0)))
8711   (set (strict_low_part (match_dup 0))
8712	(ior:QI (match_dup 0) (match_dup 1)))]
8713  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8714   && ix86_match_ccmode (insn, CCNOmode)
8715   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8716  "or{b}\t{%1, %0|%0, %1}"
8717  [(set_attr "type" "alu1")
8718   (set_attr "mode" "QI")])
8719
8720(define_insn "*iorqi_3"
8721  [(set (reg FLAGS_REG)
8722	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8723			 (match_operand:QI 2 "general_operand" "qim"))
8724		 (const_int 0)))
8725   (clobber (match_scratch:QI 0 "=q"))]
8726  "ix86_match_ccmode (insn, CCNOmode)
8727   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8728  "or{b}\t{%2, %0|%0, %2}"
8729  [(set_attr "type" "alu")
8730   (set_attr "mode" "QI")])
8731
8732(define_insn "iorqi_ext_0"
8733  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8734			 (const_int 8)
8735			 (const_int 8))
8736	(ior:SI 
8737	  (zero_extract:SI
8738	    (match_operand 1 "ext_register_operand" "0")
8739	    (const_int 8)
8740	    (const_int 8))
8741	  (match_operand 2 "const_int_operand" "n")))
8742   (clobber (reg:CC FLAGS_REG))]
8743  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8744  "or{b}\t{%2, %h0|%h0, %2}"
8745  [(set_attr "type" "alu")
8746   (set_attr "length_immediate" "1")
8747   (set_attr "mode" "QI")])
8748
8749(define_insn "*iorqi_ext_1"
8750  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751			 (const_int 8)
8752			 (const_int 8))
8753	(ior:SI 
8754	  (zero_extract:SI
8755	    (match_operand 1 "ext_register_operand" "0")
8756	    (const_int 8)
8757	    (const_int 8))
8758	  (zero_extend:SI
8759	    (match_operand:QI 2 "general_operand" "Qm"))))
8760   (clobber (reg:CC FLAGS_REG))]
8761  "!TARGET_64BIT
8762   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8763  "or{b}\t{%2, %h0|%h0, %2}"
8764  [(set_attr "type" "alu")
8765   (set_attr "length_immediate" "0")
8766   (set_attr "mode" "QI")])
8767
8768(define_insn "*iorqi_ext_1_rex64"
8769  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8770			 (const_int 8)
8771			 (const_int 8))
8772	(ior:SI 
8773	  (zero_extract:SI
8774	    (match_operand 1 "ext_register_operand" "0")
8775	    (const_int 8)
8776	    (const_int 8))
8777	  (zero_extend:SI
8778	    (match_operand 2 "ext_register_operand" "Q"))))
8779   (clobber (reg:CC FLAGS_REG))]
8780  "TARGET_64BIT
8781   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8782  "or{b}\t{%2, %h0|%h0, %2}"
8783  [(set_attr "type" "alu")
8784   (set_attr "length_immediate" "0")
8785   (set_attr "mode" "QI")])
8786
8787(define_insn "*iorqi_ext_2"
8788  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789			 (const_int 8)
8790			 (const_int 8))
8791	(ior:SI 
8792	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8793	  		   (const_int 8)
8794			   (const_int 8))
8795	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8796	  		   (const_int 8)
8797			   (const_int 8))))
8798   (clobber (reg:CC FLAGS_REG))]
8799  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8800  "ior{b}\t{%h2, %h0|%h0, %h2}"
8801  [(set_attr "type" "alu")
8802   (set_attr "length_immediate" "0")
8803   (set_attr "mode" "QI")])
8804
8805(define_split
8806  [(set (match_operand 0 "register_operand" "")
8807	(ior (match_operand 1 "register_operand" "")
8808	     (match_operand 2 "const_int_operand" "")))
8809   (clobber (reg:CC FLAGS_REG))]
8810   "reload_completed
8811    && QI_REG_P (operands[0])
8812    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8813    && !(INTVAL (operands[2]) & ~(255 << 8))
8814    && GET_MODE (operands[0]) != QImode"
8815  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8816		   (ior:SI (zero_extract:SI (match_dup 1)
8817					    (const_int 8) (const_int 8))
8818			   (match_dup 2)))
8819	      (clobber (reg:CC FLAGS_REG))])]
8820  "operands[0] = gen_lowpart (SImode, operands[0]);
8821   operands[1] = gen_lowpart (SImode, operands[1]);
8822   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8823
8824;; Since OR can be encoded with sign extended immediate, this is only
8825;; profitable when 7th bit is set.
8826(define_split
8827  [(set (match_operand 0 "register_operand" "")
8828	(ior (match_operand 1 "general_operand" "")
8829	     (match_operand 2 "const_int_operand" "")))
8830   (clobber (reg:CC FLAGS_REG))]
8831   "reload_completed
8832    && ANY_QI_REG_P (operands[0])
8833    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8834    && !(INTVAL (operands[2]) & ~255)
8835    && (INTVAL (operands[2]) & 128)
8836    && GET_MODE (operands[0]) != QImode"
8837  [(parallel [(set (strict_low_part (match_dup 0))
8838		   (ior:QI (match_dup 1)
8839			   (match_dup 2)))
8840	      (clobber (reg:CC FLAGS_REG))])]
8841  "operands[0] = gen_lowpart (QImode, operands[0]);
8842   operands[1] = gen_lowpart (QImode, operands[1]);
8843   operands[2] = gen_lowpart (QImode, operands[2]);")
8844
8845;; Logical XOR instructions
8846
8847;; %%% This used to optimize known byte-wide and operations to memory.
8848;; If this is considered useful, it should be done with splitters.
8849
8850(define_expand "xordi3"
8851  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8852	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8853		(match_operand:DI 2 "x86_64_general_operand" "")))
8854   (clobber (reg:CC FLAGS_REG))]
8855  "TARGET_64BIT"
8856  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8857
8858(define_insn "*xordi_1_rex64"
8859  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8860	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8861		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8862   (clobber (reg:CC FLAGS_REG))]
8863  "TARGET_64BIT
8864   && ix86_binary_operator_ok (XOR, DImode, operands)"
8865  "@
8866   xor{q}\t{%2, %0|%0, %2}
8867   xor{q}\t{%2, %0|%0, %2}"
8868  [(set_attr "type" "alu")
8869   (set_attr "mode" "DI,DI")])
8870
8871(define_insn "*xordi_2_rex64"
8872  [(set (reg FLAGS_REG)
8873	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8874			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8875		 (const_int 0)))
8876   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8877	(xor:DI (match_dup 1) (match_dup 2)))]
8878  "TARGET_64BIT
8879   && ix86_match_ccmode (insn, CCNOmode)
8880   && ix86_binary_operator_ok (XOR, DImode, operands)"
8881  "@
8882   xor{q}\t{%2, %0|%0, %2}
8883   xor{q}\t{%2, %0|%0, %2}"
8884  [(set_attr "type" "alu")
8885   (set_attr "mode" "DI,DI")])
8886
8887(define_insn "*xordi_3_rex64"
8888  [(set (reg FLAGS_REG)
8889	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8891		 (const_int 0)))
8892   (clobber (match_scratch:DI 0 "=r"))]
8893  "TARGET_64BIT
8894   && ix86_match_ccmode (insn, CCNOmode)
8895   && ix86_binary_operator_ok (XOR, DImode, operands)"
8896  "xor{q}\t{%2, %0|%0, %2}"
8897  [(set_attr "type" "alu")
8898   (set_attr "mode" "DI")])
8899
8900(define_expand "xorsi3"
8901  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8902	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8903		(match_operand:SI 2 "general_operand" "")))
8904   (clobber (reg:CC FLAGS_REG))]
8905  ""
8906  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8907
8908(define_insn "*xorsi_1"
8909  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8910	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8911		(match_operand:SI 2 "general_operand" "ri,rm")))
8912   (clobber (reg:CC FLAGS_REG))]
8913  "ix86_binary_operator_ok (XOR, SImode, operands)"
8914  "xor{l}\t{%2, %0|%0, %2}"
8915  [(set_attr "type" "alu")
8916   (set_attr "mode" "SI")])
8917
8918;; See comment for addsi_1_zext why we do use nonimmediate_operand
8919;; Add speccase for immediates
8920(define_insn "*xorsi_1_zext"
8921  [(set (match_operand:DI 0 "register_operand" "=r")
8922	(zero_extend:DI
8923	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924		  (match_operand:SI 2 "general_operand" "rim"))))
8925   (clobber (reg:CC FLAGS_REG))]
8926  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8927  "xor{l}\t{%2, %k0|%k0, %2}"
8928  [(set_attr "type" "alu")
8929   (set_attr "mode" "SI")])
8930
8931(define_insn "*xorsi_1_zext_imm"
8932  [(set (match_operand:DI 0 "register_operand" "=r")
8933	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935   (clobber (reg:CC FLAGS_REG))]
8936  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8937  "xor{l}\t{%2, %k0|%k0, %2}"
8938  [(set_attr "type" "alu")
8939   (set_attr "mode" "SI")])
8940
8941(define_insn "*xorsi_2"
8942  [(set (reg FLAGS_REG)
8943	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944			 (match_operand:SI 2 "general_operand" "rim,ri"))
8945		 (const_int 0)))
8946   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947	(xor:SI (match_dup 1) (match_dup 2)))]
8948  "ix86_match_ccmode (insn, CCNOmode)
8949   && ix86_binary_operator_ok (XOR, SImode, operands)"
8950  "xor{l}\t{%2, %0|%0, %2}"
8951  [(set_attr "type" "alu")
8952   (set_attr "mode" "SI")])
8953
8954;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955;; ??? Special case for immediate operand is missing - it is tricky.
8956(define_insn "*xorsi_2_zext"
8957  [(set (reg FLAGS_REG)
8958	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959			 (match_operand:SI 2 "general_operand" "rim"))
8960		 (const_int 0)))
8961   (set (match_operand:DI 0 "register_operand" "=r")
8962	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8963  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964   && ix86_binary_operator_ok (XOR, SImode, operands)"
8965  "xor{l}\t{%2, %k0|%k0, %2}"
8966  [(set_attr "type" "alu")
8967   (set_attr "mode" "SI")])
8968
8969(define_insn "*xorsi_2_zext_imm"
8970  [(set (reg FLAGS_REG)
8971	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8973		 (const_int 0)))
8974   (set (match_operand:DI 0 "register_operand" "=r")
8975	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977   && ix86_binary_operator_ok (XOR, SImode, operands)"
8978  "xor{l}\t{%2, %k0|%k0, %2}"
8979  [(set_attr "type" "alu")
8980   (set_attr "mode" "SI")])
8981
8982(define_insn "*xorsi_3"
8983  [(set (reg FLAGS_REG)
8984	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985			 (match_operand:SI 2 "general_operand" "rim"))
8986		 (const_int 0)))
8987   (clobber (match_scratch:SI 0 "=r"))]
8988  "ix86_match_ccmode (insn, CCNOmode)
8989   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8990  "xor{l}\t{%2, %0|%0, %2}"
8991  [(set_attr "type" "alu")
8992   (set_attr "mode" "SI")])
8993
8994(define_expand "xorhi3"
8995  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997		(match_operand:HI 2 "general_operand" "")))
8998   (clobber (reg:CC FLAGS_REG))]
8999  "TARGET_HIMODE_MATH"
9000  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9001
9002(define_insn "*xorhi_1"
9003  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005		(match_operand:HI 2 "general_operand" "rmi,ri")))
9006   (clobber (reg:CC FLAGS_REG))]
9007  "ix86_binary_operator_ok (XOR, HImode, operands)"
9008  "xor{w}\t{%2, %0|%0, %2}"
9009  [(set_attr "type" "alu")
9010   (set_attr "mode" "HI")])
9011
9012(define_insn "*xorhi_2"
9013  [(set (reg FLAGS_REG)
9014	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015			 (match_operand:HI 2 "general_operand" "rim,ri"))
9016		 (const_int 0)))
9017   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018	(xor:HI (match_dup 1) (match_dup 2)))]
9019  "ix86_match_ccmode (insn, CCNOmode)
9020   && ix86_binary_operator_ok (XOR, HImode, operands)"
9021  "xor{w}\t{%2, %0|%0, %2}"
9022  [(set_attr "type" "alu")
9023   (set_attr "mode" "HI")])
9024
9025(define_insn "*xorhi_3"
9026  [(set (reg FLAGS_REG)
9027	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028			 (match_operand:HI 2 "general_operand" "rim"))
9029		 (const_int 0)))
9030   (clobber (match_scratch:HI 0 "=r"))]
9031  "ix86_match_ccmode (insn, CCNOmode)
9032   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9033  "xor{w}\t{%2, %0|%0, %2}"
9034  [(set_attr "type" "alu")
9035   (set_attr "mode" "HI")])
9036
9037(define_expand "xorqi3"
9038  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040		(match_operand:QI 2 "general_operand" "")))
9041   (clobber (reg:CC FLAGS_REG))]
9042  "TARGET_QIMODE_MATH"
9043  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9044
9045;; %%% Potential partial reg stall on alternative 2.  What to do?
9046(define_insn "*xorqi_1"
9047  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050   (clobber (reg:CC FLAGS_REG))]
9051  "ix86_binary_operator_ok (XOR, QImode, operands)"
9052  "@
9053   xor{b}\t{%2, %0|%0, %2}
9054   xor{b}\t{%2, %0|%0, %2}
9055   xor{l}\t{%k2, %k0|%k0, %k2}"
9056  [(set_attr "type" "alu")
9057   (set_attr "mode" "QI,QI,SI")])
9058
9059(define_insn "*xorqi_1_slp"
9060  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9061	(xor:QI (match_dup 0)
9062		(match_operand:QI 1 "general_operand" "qi,qmi")))
9063   (clobber (reg:CC FLAGS_REG))]
9064  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9066  "xor{b}\t{%1, %0|%0, %1}"
9067  [(set_attr "type" "alu1")
9068   (set_attr "mode" "QI")])
9069
9070(define_insn "xorqi_ext_0"
9071  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9072			 (const_int 8)
9073			 (const_int 8))
9074	(xor:SI 
9075	  (zero_extract:SI
9076	    (match_operand 1 "ext_register_operand" "0")
9077	    (const_int 8)
9078	    (const_int 8))
9079	  (match_operand 2 "const_int_operand" "n")))
9080   (clobber (reg:CC FLAGS_REG))]
9081  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9082  "xor{b}\t{%2, %h0|%h0, %2}"
9083  [(set_attr "type" "alu")
9084   (set_attr "length_immediate" "1")
9085   (set_attr "mode" "QI")])
9086
9087(define_insn "*xorqi_ext_1"
9088  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9089			 (const_int 8)
9090			 (const_int 8))
9091	(xor:SI 
9092	  (zero_extract:SI
9093	    (match_operand 1 "ext_register_operand" "0")
9094	    (const_int 8)
9095	    (const_int 8))
9096	  (zero_extend:SI
9097	    (match_operand:QI 2 "general_operand" "Qm"))))
9098   (clobber (reg:CC FLAGS_REG))]
9099  "!TARGET_64BIT
9100   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9101  "xor{b}\t{%2, %h0|%h0, %2}"
9102  [(set_attr "type" "alu")
9103   (set_attr "length_immediate" "0")
9104   (set_attr "mode" "QI")])
9105
9106(define_insn "*xorqi_ext_1_rex64"
9107  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9108			 (const_int 8)
9109			 (const_int 8))
9110	(xor:SI 
9111	  (zero_extract:SI
9112	    (match_operand 1 "ext_register_operand" "0")
9113	    (const_int 8)
9114	    (const_int 8))
9115	  (zero_extend:SI
9116	    (match_operand 2 "ext_register_operand" "Q"))))
9117   (clobber (reg:CC FLAGS_REG))]
9118  "TARGET_64BIT
9119   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120  "xor{b}\t{%2, %h0|%h0, %2}"
9121  [(set_attr "type" "alu")
9122   (set_attr "length_immediate" "0")
9123   (set_attr "mode" "QI")])
9124
9125(define_insn "*xorqi_ext_2"
9126  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127			 (const_int 8)
9128			 (const_int 8))
9129	(xor:SI 
9130	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9131	  		   (const_int 8)
9132			   (const_int 8))
9133	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9134	  		   (const_int 8)
9135			   (const_int 8))))
9136   (clobber (reg:CC FLAGS_REG))]
9137  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138  "xor{b}\t{%h2, %h0|%h0, %h2}"
9139  [(set_attr "type" "alu")
9140   (set_attr "length_immediate" "0")
9141   (set_attr "mode" "QI")])
9142
9143(define_insn "*xorqi_cc_1"
9144  [(set (reg FLAGS_REG)
9145	(compare
9146	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9147		  (match_operand:QI 2 "general_operand" "qim,qi"))
9148	  (const_int 0)))
9149   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9150	(xor:QI (match_dup 1) (match_dup 2)))]
9151  "ix86_match_ccmode (insn, CCNOmode)
9152   && ix86_binary_operator_ok (XOR, QImode, operands)"
9153  "xor{b}\t{%2, %0|%0, %2}"
9154  [(set_attr "type" "alu")
9155   (set_attr "mode" "QI")])
9156
9157(define_insn "*xorqi_2_slp"
9158  [(set (reg FLAGS_REG)
9159	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9160			 (match_operand:QI 1 "general_operand" "qim,qi"))
9161		 (const_int 0)))
9162   (set (strict_low_part (match_dup 0))
9163	(xor:QI (match_dup 0) (match_dup 1)))]
9164  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9165   && ix86_match_ccmode (insn, CCNOmode)
9166   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9167  "xor{b}\t{%1, %0|%0, %1}"
9168  [(set_attr "type" "alu1")
9169   (set_attr "mode" "QI")])
9170
9171(define_insn "*xorqi_cc_2"
9172  [(set (reg FLAGS_REG)
9173	(compare
9174	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9175		  (match_operand:QI 2 "general_operand" "qim"))
9176	  (const_int 0)))
9177   (clobber (match_scratch:QI 0 "=q"))]
9178  "ix86_match_ccmode (insn, CCNOmode)
9179   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9180  "xor{b}\t{%2, %0|%0, %2}"
9181  [(set_attr "type" "alu")
9182   (set_attr "mode" "QI")])
9183
9184(define_insn "*xorqi_cc_ext_1"
9185  [(set (reg FLAGS_REG)
9186	(compare
9187	  (xor:SI
9188	    (zero_extract:SI
9189	      (match_operand 1 "ext_register_operand" "0")
9190	      (const_int 8)
9191	      (const_int 8))
9192	    (match_operand:QI 2 "general_operand" "qmn"))
9193	  (const_int 0)))
9194   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9195			 (const_int 8)
9196			 (const_int 8))
9197	(xor:SI 
9198	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9199	  (match_dup 2)))]
9200  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9201  "xor{b}\t{%2, %h0|%h0, %2}"
9202  [(set_attr "type" "alu")
9203   (set_attr "mode" "QI")])
9204
9205(define_insn "*xorqi_cc_ext_1_rex64"
9206  [(set (reg FLAGS_REG)
9207	(compare
9208	  (xor:SI
9209	    (zero_extract:SI
9210	      (match_operand 1 "ext_register_operand" "0")
9211	      (const_int 8)
9212	      (const_int 8))
9213	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9214	  (const_int 0)))
9215   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216			 (const_int 8)
9217			 (const_int 8))
9218	(xor:SI 
9219	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9220	  (match_dup 2)))]
9221  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9222  "xor{b}\t{%2, %h0|%h0, %2}"
9223  [(set_attr "type" "alu")
9224   (set_attr "mode" "QI")])
9225
9226(define_expand "xorqi_cc_ext_1"
9227  [(parallel [
9228     (set (reg:CCNO FLAGS_REG)
9229	  (compare:CCNO
9230	    (xor:SI
9231	      (zero_extract:SI
9232		(match_operand 1 "ext_register_operand" "")
9233		(const_int 8)
9234		(const_int 8))
9235	      (match_operand:QI 2 "general_operand" ""))
9236	    (const_int 0)))
9237     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9238			   (const_int 8)
9239			   (const_int 8))
9240	  (xor:SI 
9241	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9242	    (match_dup 2)))])]
9243  ""
9244  "")
9245
9246(define_split
9247  [(set (match_operand 0 "register_operand" "")
9248	(xor (match_operand 1 "register_operand" "")
9249	     (match_operand 2 "const_int_operand" "")))
9250   (clobber (reg:CC FLAGS_REG))]
9251   "reload_completed
9252    && QI_REG_P (operands[0])
9253    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9254    && !(INTVAL (operands[2]) & ~(255 << 8))
9255    && GET_MODE (operands[0]) != QImode"
9256  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9257		   (xor:SI (zero_extract:SI (match_dup 1)
9258					    (const_int 8) (const_int 8))
9259			   (match_dup 2)))
9260	      (clobber (reg:CC FLAGS_REG))])]
9261  "operands[0] = gen_lowpart (SImode, operands[0]);
9262   operands[1] = gen_lowpart (SImode, operands[1]);
9263   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9264
9265;; Since XOR can be encoded with sign extended immediate, this is only
9266;; profitable when 7th bit is set.
9267(define_split
9268  [(set (match_operand 0 "register_operand" "")
9269	(xor (match_operand 1 "general_operand" "")
9270	     (match_operand 2 "const_int_operand" "")))
9271   (clobber (reg:CC FLAGS_REG))]
9272   "reload_completed
9273    && ANY_QI_REG_P (operands[0])
9274    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9275    && !(INTVAL (operands[2]) & ~255)
9276    && (INTVAL (operands[2]) & 128)
9277    && GET_MODE (operands[0]) != QImode"
9278  [(parallel [(set (strict_low_part (match_dup 0))
9279		   (xor:QI (match_dup 1)
9280			   (match_dup 2)))
9281	      (clobber (reg:CC FLAGS_REG))])]
9282  "operands[0] = gen_lowpart (QImode, operands[0]);
9283   operands[1] = gen_lowpart (QImode, operands[1]);
9284   operands[2] = gen_lowpart (QImode, operands[2]);")
9285
9286;; Negation instructions
9287
9288(define_expand "negti2"
9289  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9290		   (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9291	      (clobber (reg:CC FLAGS_REG))])]
9292  "TARGET_64BIT"
9293  "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9294
9295(define_insn "*negti2_1"
9296  [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9297	(neg:TI (match_operand:TI 1 "general_operand" "0")))
9298   (clobber (reg:CC FLAGS_REG))]
9299  "TARGET_64BIT
9300   && ix86_unary_operator_ok (NEG, TImode, operands)"
9301  "#")
9302
9303(define_split
9304  [(set (match_operand:TI 0 "nonimmediate_operand" "")
9305	(neg:TI (match_operand:TI 1 "general_operand" "")))
9306   (clobber (reg:CC FLAGS_REG))]
9307  "TARGET_64BIT && reload_completed"
9308  [(parallel
9309    [(set (reg:CCZ FLAGS_REG)
9310	  (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9311     (set (match_dup 0) (neg:DI (match_dup 2)))])
9312   (parallel
9313    [(set (match_dup 1)
9314	  (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9315			    (match_dup 3))
9316		   (const_int 0)))
9317     (clobber (reg:CC FLAGS_REG))])
9318   (parallel
9319    [(set (match_dup 1)
9320	  (neg:DI (match_dup 1)))
9321     (clobber (reg:CC FLAGS_REG))])]
9322  "split_ti (operands+1, 1, operands+2, operands+3);
9323   split_ti (operands+0, 1, operands+0, operands+1);")
9324
9325(define_expand "negdi2"
9326  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9327		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9328	      (clobber (reg:CC FLAGS_REG))])]
9329  ""
9330  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9331
9332(define_insn "*negdi2_1"
9333  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9334	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9335   (clobber (reg:CC FLAGS_REG))]
9336  "!TARGET_64BIT
9337   && ix86_unary_operator_ok (NEG, DImode, operands)"
9338  "#")
9339
9340(define_split
9341  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9342	(neg:DI (match_operand:DI 1 "general_operand" "")))
9343   (clobber (reg:CC FLAGS_REG))]
9344  "!TARGET_64BIT && reload_completed"
9345  [(parallel
9346    [(set (reg:CCZ FLAGS_REG)
9347	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9348     (set (match_dup 0) (neg:SI (match_dup 2)))])
9349   (parallel
9350    [(set (match_dup 1)
9351	  (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9352			    (match_dup 3))
9353		   (const_int 0)))
9354     (clobber (reg:CC FLAGS_REG))])
9355   (parallel
9356    [(set (match_dup 1)
9357	  (neg:SI (match_dup 1)))
9358     (clobber (reg:CC FLAGS_REG))])]
9359  "split_di (operands+1, 1, operands+2, operands+3);
9360   split_di (operands+0, 1, operands+0, operands+1);")
9361
9362(define_insn "*negdi2_1_rex64"
9363  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9364	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9365   (clobber (reg:CC FLAGS_REG))]
9366  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9367  "neg{q}\t%0"
9368  [(set_attr "type" "negnot")
9369   (set_attr "mode" "DI")])
9370
9371;; The problem with neg is that it does not perform (compare x 0),
9372;; it really performs (compare 0 x), which leaves us with the zero
9373;; flag being the only useful item.
9374
9375(define_insn "*negdi2_cmpz_rex64"
9376  [(set (reg:CCZ FLAGS_REG)
9377	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9378		     (const_int 0)))
9379   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9380	(neg:DI (match_dup 1)))]
9381  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9382  "neg{q}\t%0"
9383  [(set_attr "type" "negnot")
9384   (set_attr "mode" "DI")])
9385
9386
9387(define_expand "negsi2"
9388  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9389		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9390	      (clobber (reg:CC FLAGS_REG))])]
9391  ""
9392  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9393
9394(define_insn "*negsi2_1"
9395  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9396	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9397   (clobber (reg:CC FLAGS_REG))]
9398  "ix86_unary_operator_ok (NEG, SImode, operands)"
9399  "neg{l}\t%0"
9400  [(set_attr "type" "negnot")
9401   (set_attr "mode" "SI")])
9402
9403;; Combine is quite creative about this pattern.
9404(define_insn "*negsi2_1_zext"
9405  [(set (match_operand:DI 0 "register_operand" "=r")
9406	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9407					(const_int 32)))
9408		     (const_int 32)))
9409   (clobber (reg:CC FLAGS_REG))]
9410  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9411  "neg{l}\t%k0"
9412  [(set_attr "type" "negnot")
9413   (set_attr "mode" "SI")])
9414
9415;; The problem with neg is that it does not perform (compare x 0),
9416;; it really performs (compare 0 x), which leaves us with the zero
9417;; flag being the only useful item.
9418
9419(define_insn "*negsi2_cmpz"
9420  [(set (reg:CCZ FLAGS_REG)
9421	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9422		     (const_int 0)))
9423   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9424	(neg:SI (match_dup 1)))]
9425  "ix86_unary_operator_ok (NEG, SImode, operands)"
9426  "neg{l}\t%0"
9427  [(set_attr "type" "negnot")
9428   (set_attr "mode" "SI")])
9429
9430(define_insn "*negsi2_cmpz_zext"
9431  [(set (reg:CCZ FLAGS_REG)
9432	(compare:CCZ (lshiftrt:DI
9433		       (neg:DI (ashift:DI
9434				 (match_operand:DI 1 "register_operand" "0")
9435				 (const_int 32)))
9436		       (const_int 32))
9437		     (const_int 0)))
9438   (set (match_operand:DI 0 "register_operand" "=r")
9439	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9440					(const_int 32)))
9441		     (const_int 32)))]
9442  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443  "neg{l}\t%k0"
9444  [(set_attr "type" "negnot")
9445   (set_attr "mode" "SI")])
9446
9447(define_expand "neghi2"
9448  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9449		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9450	      (clobber (reg:CC FLAGS_REG))])]
9451  "TARGET_HIMODE_MATH"
9452  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9453
9454(define_insn "*neghi2_1"
9455  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9456	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9457   (clobber (reg:CC FLAGS_REG))]
9458  "ix86_unary_operator_ok (NEG, HImode, operands)"
9459  "neg{w}\t%0"
9460  [(set_attr "type" "negnot")
9461   (set_attr "mode" "HI")])
9462
9463(define_insn "*neghi2_cmpz"
9464  [(set (reg:CCZ FLAGS_REG)
9465	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9466		     (const_int 0)))
9467   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9468	(neg:HI (match_dup 1)))]
9469  "ix86_unary_operator_ok (NEG, HImode, operands)"
9470  "neg{w}\t%0"
9471  [(set_attr "type" "negnot")
9472   (set_attr "mode" "HI")])
9473
9474(define_expand "negqi2"
9475  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9476		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9477	      (clobber (reg:CC FLAGS_REG))])]
9478  "TARGET_QIMODE_MATH"
9479  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9480
9481(define_insn "*negqi2_1"
9482  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9483	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9484   (clobber (reg:CC FLAGS_REG))]
9485  "ix86_unary_operator_ok (NEG, QImode, operands)"
9486  "neg{b}\t%0"
9487  [(set_attr "type" "negnot")
9488   (set_attr "mode" "QI")])
9489
9490(define_insn "*negqi2_cmpz"
9491  [(set (reg:CCZ FLAGS_REG)
9492	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9493		     (const_int 0)))
9494   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9495	(neg:QI (match_dup 1)))]
9496  "ix86_unary_operator_ok (NEG, QImode, operands)"
9497  "neg{b}\t%0"
9498  [(set_attr "type" "negnot")
9499   (set_attr "mode" "QI")])
9500
9501;; Changing of sign for FP values is doable using integer unit too.
9502
9503(define_expand "negsf2"
9504  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9505	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9506  "TARGET_80387 || TARGET_SSE_MATH"
9507  "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9508
9509(define_expand "abssf2"
9510  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9511	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9512  "TARGET_80387 || TARGET_SSE_MATH"
9513  "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9514
9515(define_insn "*absnegsf2_mixed"
9516  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9517	(match_operator:SF 3 "absneg_operator"
9518	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9519   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9520   (clobber (reg:CC FLAGS_REG))]
9521  "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9522   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9523  "#")
9524
9525(define_insn "*absnegsf2_sse"
9526  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9527	(match_operator:SF 3 "absneg_operator"
9528	  [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9529   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9530   (clobber (reg:CC FLAGS_REG))]
9531  "TARGET_SSE_MATH
9532   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9533  "#")
9534
9535(define_insn "*absnegsf2_i387"
9536  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9537	(match_operator:SF 3 "absneg_operator"
9538	  [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9539   (use (match_operand 2 "" ""))
9540   (clobber (reg:CC FLAGS_REG))]
9541  "TARGET_80387 && !TARGET_SSE_MATH
9542   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9543  "#")
9544
9545(define_expand "copysignsf3"
9546  [(match_operand:SF 0 "register_operand" "")
9547   (match_operand:SF 1 "nonmemory_operand" "")
9548   (match_operand:SF 2 "register_operand" "")]
9549  "TARGET_SSE_MATH"
9550{
9551  ix86_expand_copysign (operands);
9552  DONE;
9553})
9554
9555(define_insn_and_split "copysignsf3_const"
9556  [(set (match_operand:SF 0 "register_operand"          "=x")
9557	(unspec:SF
9558	  [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9559	   (match_operand:SF 2 "register_operand"       "0")
9560	   (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9561	  UNSPEC_COPYSIGN))]
9562  "TARGET_SSE_MATH"
9563  "#"
9564  "&& reload_completed"
9565  [(const_int 0)]
9566{
9567  ix86_split_copysign_const (operands);
9568  DONE;
9569})
9570
9571(define_insn "copysignsf3_var"
9572  [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9573	(unspec:SF
9574	  [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9575	   (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9576	   (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9577	   (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9578	  UNSPEC_COPYSIGN))
9579   (clobber (match_scratch:V4SF 1			"=x, x, x, x,x"))]
9580  "TARGET_SSE_MATH"
9581  "#")
9582
9583(define_split
9584  [(set (match_operand:SF 0 "register_operand" "")
9585	(unspec:SF
9586	  [(match_operand:SF 2 "register_operand" "")
9587	   (match_operand:SF 3 "register_operand" "")
9588	   (match_operand:V4SF 4 "" "")
9589	   (match_operand:V4SF 5 "" "")]
9590	  UNSPEC_COPYSIGN))
9591   (clobber (match_scratch:V4SF 1 ""))]
9592  "TARGET_SSE_MATH && reload_completed"
9593  [(const_int 0)]
9594{
9595  ix86_split_copysign_var (operands);
9596  DONE;
9597})
9598
9599(define_expand "negdf2"
9600  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9601	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9602  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9603  "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9604
9605(define_expand "absdf2"
9606  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9607	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9608  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9609  "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9610
9611(define_insn "*absnegdf2_mixed"
9612  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9613	(match_operator:DF 3 "absneg_operator"
9614	  [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9615   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9616   (clobber (reg:CC FLAGS_REG))]
9617  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9618   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9619  "#")
9620
9621(define_insn "*absnegdf2_sse"
9622  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9623	(match_operator:DF 3 "absneg_operator"
9624	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9625   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9626   (clobber (reg:CC FLAGS_REG))]
9627  "TARGET_SSE2 && TARGET_SSE_MATH
9628   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9629  "#")
9630
9631(define_insn "*absnegdf2_i387"
9632  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9633	(match_operator:DF 3 "absneg_operator"
9634	  [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9635   (use (match_operand 2 "" ""))
9636   (clobber (reg:CC FLAGS_REG))]
9637  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9638   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9639  "#")
9640
9641(define_expand "copysigndf3"
9642  [(match_operand:DF 0 "register_operand" "")
9643   (match_operand:DF 1 "nonmemory_operand" "")
9644   (match_operand:DF 2 "register_operand" "")]
9645  "TARGET_SSE2 && TARGET_SSE_MATH"
9646{
9647  ix86_expand_copysign (operands);
9648  DONE;
9649})
9650
9651(define_insn_and_split "copysigndf3_const"
9652  [(set (match_operand:DF 0 "register_operand"          "=x")
9653	(unspec:DF
9654	  [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9655	   (match_operand:DF 2 "register_operand"       "0")
9656	   (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9657	  UNSPEC_COPYSIGN))]
9658  "TARGET_SSE2 && TARGET_SSE_MATH"
9659  "#"
9660  "&& reload_completed"
9661  [(const_int 0)]
9662{
9663  ix86_split_copysign_const (operands);
9664  DONE;
9665})
9666
9667(define_insn "copysigndf3_var"
9668  [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9669	(unspec:DF
9670	  [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9671	   (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9672	   (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9673	   (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9674	  UNSPEC_COPYSIGN))
9675   (clobber (match_scratch:V2DF 1			"=x, x, x, x,x"))]
9676  "TARGET_SSE2 && TARGET_SSE_MATH"
9677  "#")
9678
9679(define_split
9680  [(set (match_operand:DF 0 "register_operand" "")
9681	(unspec:DF
9682	  [(match_operand:DF 2 "register_operand" "")
9683	   (match_operand:DF 3 "register_operand" "")
9684	   (match_operand:V2DF 4 "" "")
9685	   (match_operand:V2DF 5 "" "")]
9686	  UNSPEC_COPYSIGN))
9687   (clobber (match_scratch:V2DF 1 ""))]
9688  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9689  [(const_int 0)]
9690{
9691  ix86_split_copysign_var (operands);
9692  DONE;
9693})
9694
9695(define_expand "negxf2"
9696  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9697	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9698  "TARGET_80387"
9699  "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9700
9701(define_expand "absxf2"
9702  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9703	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9704  "TARGET_80387"
9705  "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9706
9707(define_insn "*absnegxf2_i387"
9708  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9709	(match_operator:XF 3 "absneg_operator"
9710	  [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9711   (use (match_operand 2 "" ""))
9712   (clobber (reg:CC FLAGS_REG))]
9713  "TARGET_80387
9714   && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9715  "#")
9716
9717;; Splitters for fp abs and neg.
9718
9719(define_split
9720  [(set (match_operand 0 "fp_register_operand" "")
9721	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9722   (use (match_operand 2 "" ""))
9723   (clobber (reg:CC FLAGS_REG))]
9724  "reload_completed"
9725  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9726
9727(define_split
9728  [(set (match_operand 0 "register_operand" "")
9729	(match_operator 3 "absneg_operator"
9730	  [(match_operand 1 "register_operand" "")]))
9731   (use (match_operand 2 "nonimmediate_operand" ""))
9732   (clobber (reg:CC FLAGS_REG))]
9733  "reload_completed && SSE_REG_P (operands[0])"
9734  [(set (match_dup 0) (match_dup 3))]
9735{
9736  enum machine_mode mode = GET_MODE (operands[0]);
9737  enum machine_mode vmode = GET_MODE (operands[2]);
9738  rtx tmp;
9739  
9740  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9741  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9742  if (operands_match_p (operands[0], operands[2]))
9743    {
9744      tmp = operands[1];
9745      operands[1] = operands[2];
9746      operands[2] = tmp;
9747    }
9748  if (GET_CODE (operands[3]) == ABS)
9749    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9750  else
9751    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9752  operands[3] = tmp;
9753})
9754
9755(define_split
9756  [(set (match_operand:SF 0 "register_operand" "")
9757	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9758   (use (match_operand:V4SF 2 "" ""))
9759   (clobber (reg:CC FLAGS_REG))]
9760  "reload_completed"
9761  [(parallel [(set (match_dup 0) (match_dup 1))
9762	      (clobber (reg:CC FLAGS_REG))])]
9763{ 
9764  rtx tmp;
9765  operands[0] = gen_lowpart (SImode, operands[0]);
9766  if (GET_CODE (operands[1]) == ABS)
9767    {
9768      tmp = gen_int_mode (0x7fffffff, SImode);
9769      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9770    }
9771  else
9772    {
9773      tmp = gen_int_mode (0x80000000, SImode);
9774      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9775    }
9776  operands[1] = tmp;
9777})
9778
9779(define_split
9780  [(set (match_operand:DF 0 "register_operand" "")
9781	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9782   (use (match_operand 2 "" ""))
9783   (clobber (reg:CC FLAGS_REG))]
9784  "reload_completed"
9785  [(parallel [(set (match_dup 0) (match_dup 1))
9786	      (clobber (reg:CC FLAGS_REG))])]
9787{
9788  rtx tmp;
9789  if (TARGET_64BIT)
9790    {
9791      tmp = gen_lowpart (DImode, operands[0]);
9792      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9793      operands[0] = tmp;
9794
9795      if (GET_CODE (operands[1]) == ABS)
9796	tmp = const0_rtx;
9797      else
9798	tmp = gen_rtx_NOT (DImode, tmp);
9799    }
9800  else
9801    {
9802      operands[0] = gen_highpart (SImode, operands[0]);
9803      if (GET_CODE (operands[1]) == ABS)
9804	{
9805	  tmp = gen_int_mode (0x7fffffff, SImode);
9806	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
9807	}
9808      else
9809	{
9810	  tmp = gen_int_mode (0x80000000, SImode);
9811	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9812	}
9813    }
9814  operands[1] = tmp;
9815})
9816
9817(define_split
9818  [(set (match_operand:XF 0 "register_operand" "")
9819	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9820   (use (match_operand 2 "" ""))
9821   (clobber (reg:CC FLAGS_REG))]
9822  "reload_completed"
9823  [(parallel [(set (match_dup 0) (match_dup 1))
9824	      (clobber (reg:CC FLAGS_REG))])]
9825{
9826  rtx tmp;
9827  operands[0] = gen_rtx_REG (SImode,
9828			     true_regnum (operands[0])
9829			     + (TARGET_64BIT ? 1 : 2));
9830  if (GET_CODE (operands[1]) == ABS)
9831    {
9832      tmp = GEN_INT (0x7fff);
9833      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9834    }
9835  else
9836    {
9837      tmp = GEN_INT (0x8000);
9838      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9839    }
9840  operands[1] = tmp;
9841})
9842
9843(define_split
9844  [(set (match_operand 0 "memory_operand" "")
9845	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9846   (use (match_operand 2 "" ""))
9847   (clobber (reg:CC FLAGS_REG))]
9848  "reload_completed"
9849  [(parallel [(set (match_dup 0) (match_dup 1))
9850	      (clobber (reg:CC FLAGS_REG))])]
9851{
9852  enum machine_mode mode = GET_MODE (operands[0]);
9853  int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9854  rtx tmp;
9855
9856  operands[0] = adjust_address (operands[0], QImode, size - 1);
9857  if (GET_CODE (operands[1]) == ABS)
9858    {
9859      tmp = gen_int_mode (0x7f, QImode);
9860      tmp = gen_rtx_AND (QImode, operands[0], tmp);
9861    }
9862  else
9863    {
9864      tmp = gen_int_mode (0x80, QImode);
9865      tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9866    }
9867  operands[1] = tmp;
9868})
9869
9870;; Conditionalize these after reload. If they match before reload, we 
9871;; lose the clobber and ability to use integer instructions.
9872
9873(define_insn "*negsf2_1"
9874  [(set (match_operand:SF 0 "register_operand" "=f")
9875	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
9876  "TARGET_80387 && reload_completed"
9877  "fchs"
9878  [(set_attr "type" "fsgn")
9879   (set_attr "mode" "SF")])
9880
9881(define_insn "*negdf2_1"
9882  [(set (match_operand:DF 0 "register_operand" "=f")
9883	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
9884  "TARGET_80387 && reload_completed"
9885  "fchs"
9886  [(set_attr "type" "fsgn")
9887   (set_attr "mode" "DF")])
9888
9889(define_insn "*negxf2_1"
9890  [(set (match_operand:XF 0 "register_operand" "=f")
9891	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
9892  "TARGET_80387 && reload_completed"
9893  "fchs"
9894  [(set_attr "type" "fsgn")
9895   (set_attr "mode" "XF")])
9896
9897(define_insn "*abssf2_1"
9898  [(set (match_operand:SF 0 "register_operand" "=f")
9899	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
9900  "TARGET_80387 && reload_completed"
9901  "fabs"
9902  [(set_attr "type" "fsgn")
9903   (set_attr "mode" "SF")])
9904
9905(define_insn "*absdf2_1"
9906  [(set (match_operand:DF 0 "register_operand" "=f")
9907	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
9908  "TARGET_80387 && reload_completed"
9909  "fabs"
9910  [(set_attr "type" "fsgn")
9911   (set_attr "mode" "DF")])
9912
9913(define_insn "*absxf2_1"
9914  [(set (match_operand:XF 0 "register_operand" "=f")
9915	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
9916  "TARGET_80387 && reload_completed"
9917  "fabs"
9918  [(set_attr "type" "fsgn")
9919   (set_attr "mode" "DF")])
9920
9921(define_insn "*negextendsfdf2"
9922  [(set (match_operand:DF 0 "register_operand" "=f")
9923	(neg:DF (float_extend:DF
9924		  (match_operand:SF 1 "register_operand" "0"))))]
9925  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9926  "fchs"
9927  [(set_attr "type" "fsgn")
9928   (set_attr "mode" "DF")])
9929
9930(define_insn "*negextenddfxf2"
9931  [(set (match_operand:XF 0 "register_operand" "=f")
9932	(neg:XF (float_extend:XF
9933		  (match_operand:DF 1 "register_operand" "0"))))]
9934  "TARGET_80387"
9935  "fchs"
9936  [(set_attr "type" "fsgn")
9937   (set_attr "mode" "XF")])
9938
9939(define_insn "*negextendsfxf2"
9940  [(set (match_operand:XF 0 "register_operand" "=f")
9941	(neg:XF (float_extend:XF
9942		  (match_operand:SF 1 "register_operand" "0"))))]
9943  "TARGET_80387"
9944  "fchs"
9945  [(set_attr "type" "fsgn")
9946   (set_attr "mode" "XF")])
9947
9948(define_insn "*absextendsfdf2"
9949  [(set (match_operand:DF 0 "register_operand" "=f")
9950	(abs:DF (float_extend:DF
9951		  (match_operand:SF 1 "register_operand" "0"))))]
9952  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9953  "fabs"
9954  [(set_attr "type" "fsgn")
9955   (set_attr "mode" "DF")])
9956
9957(define_insn "*absextenddfxf2"
9958  [(set (match_operand:XF 0 "register_operand" "=f")
9959	(abs:XF (float_extend:XF
9960	  (match_operand:DF 1 "register_operand" "0"))))]
9961  "TARGET_80387"
9962  "fabs"
9963  [(set_attr "type" "fsgn")
9964   (set_attr "mode" "XF")])
9965
9966(define_insn "*absextendsfxf2"
9967  [(set (match_operand:XF 0 "register_operand" "=f")
9968	(abs:XF (float_extend:XF
9969	  (match_operand:SF 1 "register_operand" "0"))))]
9970  "TARGET_80387"
9971  "fabs"
9972  [(set_attr "type" "fsgn")
9973   (set_attr "mode" "XF")])
9974
9975;; One complement instructions
9976
9977(define_expand "one_cmpldi2"
9978  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9979	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9980  "TARGET_64BIT"
9981  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9982
9983(define_insn "*one_cmpldi2_1_rex64"
9984  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9985	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9986  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9987  "not{q}\t%0"
9988  [(set_attr "type" "negnot")
9989   (set_attr "mode" "DI")])
9990
9991(define_insn "*one_cmpldi2_2_rex64"
9992  [(set (reg FLAGS_REG)
9993	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9994		 (const_int 0)))
9995   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9996	(not:DI (match_dup 1)))]
9997  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9998   && ix86_unary_operator_ok (NOT, DImode, operands)"
9999  "#"
10000  [(set_attr "type" "alu1")
10001   (set_attr "mode" "DI")])
10002
10003(define_split
10004  [(set (match_operand 0 "flags_reg_operand" "")
10005	(match_operator 2 "compare_operator"
10006	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10007	   (const_int 0)]))
10008   (set (match_operand:DI 1 "nonimmediate_operand" "")
10009	(not:DI (match_dup 3)))]
10010  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10011  [(parallel [(set (match_dup 0)
10012		   (match_op_dup 2
10013		     [(xor:DI (match_dup 3) (const_int -1))
10014		      (const_int 0)]))
10015	      (set (match_dup 1)
10016		   (xor:DI (match_dup 3) (const_int -1)))])]
10017  "")
10018
10019(define_expand "one_cmplsi2"
10020  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10021	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10022  ""
10023  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10024
10025(define_insn "*one_cmplsi2_1"
10026  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10027	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10028  "ix86_unary_operator_ok (NOT, SImode, operands)"
10029  "not{l}\t%0"
10030  [(set_attr "type" "negnot")
10031   (set_attr "mode" "SI")])
10032
10033;; ??? Currently never generated - xor is used instead.
10034(define_insn "*one_cmplsi2_1_zext"
10035  [(set (match_operand:DI 0 "register_operand" "=r")
10036	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10037  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10038  "not{l}\t%k0"
10039  [(set_attr "type" "negnot")
10040   (set_attr "mode" "SI")])
10041
10042(define_insn "*one_cmplsi2_2"
10043  [(set (reg FLAGS_REG)
10044	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10045		 (const_int 0)))
10046   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10047	(not:SI (match_dup 1)))]
10048  "ix86_match_ccmode (insn, CCNOmode)
10049   && ix86_unary_operator_ok (NOT, SImode, operands)"
10050  "#"
10051  [(set_attr "type" "alu1")
10052   (set_attr "mode" "SI")])
10053
10054(define_split
10055  [(set (match_operand 0 "flags_reg_operand" "")
10056	(match_operator 2 "compare_operator"
10057	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10058	   (const_int 0)]))
10059   (set (match_operand:SI 1 "nonimmediate_operand" "")
10060	(not:SI (match_dup 3)))]
10061  "ix86_match_ccmode (insn, CCNOmode)"
10062  [(parallel [(set (match_dup 0)
10063		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10064				    (const_int 0)]))
10065	      (set (match_dup 1)
10066		   (xor:SI (match_dup 3) (const_int -1)))])]
10067  "")
10068
10069;; ??? Currently never generated - xor is used instead.
10070(define_insn "*one_cmplsi2_2_zext"
10071  [(set (reg FLAGS_REG)
10072	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10073		 (const_int 0)))
10074   (set (match_operand:DI 0 "register_operand" "=r")
10075	(zero_extend:DI (not:SI (match_dup 1))))]
10076  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10077   && ix86_unary_operator_ok (NOT, SImode, operands)"
10078  "#"
10079  [(set_attr "type" "alu1")
10080   (set_attr "mode" "SI")])
10081
10082(define_split
10083  [(set (match_operand 0 "flags_reg_operand" "")
10084	(match_operator 2 "compare_operator"
10085	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10086	   (const_int 0)]))
10087   (set (match_operand:DI 1 "register_operand" "")
10088	(zero_extend:DI (not:SI (match_dup 3))))]
10089  "ix86_match_ccmode (insn, CCNOmode)"
10090  [(parallel [(set (match_dup 0)
10091		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10092				    (const_int 0)]))
10093	      (set (match_dup 1)
10094		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10095  "")
10096
10097(define_expand "one_cmplhi2"
10098  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10099	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10100  "TARGET_HIMODE_MATH"
10101  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10102
10103(define_insn "*one_cmplhi2_1"
10104  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10105	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10106  "ix86_unary_operator_ok (NOT, HImode, operands)"
10107  "not{w}\t%0"
10108  [(set_attr "type" "negnot")
10109   (set_attr "mode" "HI")])
10110
10111(define_insn "*one_cmplhi2_2"
10112  [(set (reg FLAGS_REG)
10113	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10114		 (const_int 0)))
10115   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10116	(not:HI (match_dup 1)))]
10117  "ix86_match_ccmode (insn, CCNOmode)
10118   && ix86_unary_operator_ok (NEG, HImode, operands)"
10119  "#"
10120  [(set_attr "type" "alu1")
10121   (set_attr "mode" "HI")])
10122
10123(define_split
10124  [(set (match_operand 0 "flags_reg_operand" "")
10125	(match_operator 2 "compare_operator"
10126	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10127	   (const_int 0)]))
10128   (set (match_operand:HI 1 "nonimmediate_operand" "")
10129	(not:HI (match_dup 3)))]
10130  "ix86_match_ccmode (insn, CCNOmode)"
10131  [(parallel [(set (match_dup 0)
10132		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10133		      		    (const_int 0)]))
10134	      (set (match_dup 1)
10135		   (xor:HI (match_dup 3) (const_int -1)))])]
10136  "")
10137
10138;; %%% Potential partial reg stall on alternative 1.  What to do?
10139(define_expand "one_cmplqi2"
10140  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10141	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10142  "TARGET_QIMODE_MATH"
10143  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10144
10145(define_insn "*one_cmplqi2_1"
10146  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10147	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10148  "ix86_unary_operator_ok (NOT, QImode, operands)"
10149  "@
10150   not{b}\t%0
10151   not{l}\t%k0"
10152  [(set_attr "type" "negnot")
10153   (set_attr "mode" "QI,SI")])
10154
10155(define_insn "*one_cmplqi2_2"
10156  [(set (reg FLAGS_REG)
10157	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10158		 (const_int 0)))
10159   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10160	(not:QI (match_dup 1)))]
10161  "ix86_match_ccmode (insn, CCNOmode)
10162   && ix86_unary_operator_ok (NOT, QImode, operands)"
10163  "#"
10164  [(set_attr "type" "alu1")
10165   (set_attr "mode" "QI")])
10166
10167(define_split
10168  [(set (match_operand 0 "flags_reg_operand" "")
10169	(match_operator 2 "compare_operator"
10170	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10171	   (const_int 0)]))
10172   (set (match_operand:QI 1 "nonimmediate_operand" "")
10173	(not:QI (match_dup 3)))]
10174  "ix86_match_ccmode (insn, CCNOmode)"
10175  [(parallel [(set (match_dup 0)
10176		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10177		      		    (const_int 0)]))
10178	      (set (match_dup 1)
10179		   (xor:QI (match_dup 3) (const_int -1)))])]
10180  "")
10181
10182;; Arithmetic shift instructions
10183
10184;; DImode shifts are implemented using the i386 "shift double" opcode,
10185;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10186;; is variable, then the count is in %cl and the "imm" operand is dropped
10187;; from the assembler input.
10188;;
10189;; This instruction shifts the target reg/mem as usual, but instead of
10190;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10191;; is a left shift double, bits are taken from the high order bits of
10192;; reg, else if the insn is a shift right double, bits are taken from the
10193;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10194;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10195;;
10196;; Since sh[lr]d does not change the `reg' operand, that is done
10197;; separately, making all shifts emit pairs of shift double and normal
10198;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10199;; support a 63 bit shift, each shift where the count is in a reg expands
10200;; to a pair of shifts, a branch, a shift by 32 and a label.
10201;;
10202;; If the shift count is a constant, we need never emit more than one
10203;; shift pair, instead using moves and sign extension for counts greater
10204;; than 31.
10205
10206(define_expand "ashlti3"
10207  [(parallel [(set (match_operand:TI 0 "register_operand" "")
10208		   (ashift:TI (match_operand:TI 1 "register_operand" "")
10209			      (match_operand:QI 2 "nonmemory_operand" "")))
10210	      (clobber (reg:CC FLAGS_REG))])]
10211  "TARGET_64BIT"
10212{
10213  if (! immediate_operand (operands[2], QImode))
10214    {
10215      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10216      DONE;
10217    }
10218  ix86_expand_binary_operator (ASHIFT, TImode, operands);
10219  DONE;
10220})
10221
10222(define_insn "ashlti3_1"
10223  [(set (match_operand:TI 0 "register_operand" "=r")
10224	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10225		   (match_operand:QI 2 "register_operand" "c")))
10226   (clobber (match_scratch:DI 3 "=&r"))
10227   (clobber (reg:CC FLAGS_REG))]
10228  "TARGET_64BIT"
10229  "#"
10230  [(set_attr "type" "multi")])
10231
10232(define_insn "*ashlti3_2"
10233  [(set (match_operand:TI 0 "register_operand" "=r")
10234	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10235		   (match_operand:QI 2 "immediate_operand" "O")))
10236   (clobber (reg:CC FLAGS_REG))]
10237  "TARGET_64BIT"
10238  "#"
10239  [(set_attr "type" "multi")])
10240
10241(define_split
10242  [(set (match_operand:TI 0 "register_operand" "")
10243	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10244		   (match_operand:QI 2 "register_operand" "")))
10245   (clobber (match_scratch:DI 3 ""))
10246   (clobber (reg:CC FLAGS_REG))]
10247  "TARGET_64BIT && reload_completed"
10248  [(const_int 0)]
10249  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10250
10251(define_split
10252  [(set (match_operand:TI 0 "register_operand" "")
10253	(ashift:TI (match_operand:TI 1 "register_operand" "")
10254		   (match_operand:QI 2 "immediate_operand" "")))
10255   (clobber (reg:CC FLAGS_REG))]
10256  "TARGET_64BIT && reload_completed"
10257  [(const_int 0)]
10258  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10259
10260(define_insn "x86_64_shld"
10261  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10262        (ior:DI (ashift:DI (match_dup 0)
10263		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
10264		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10265		  (minus:QI (const_int 64) (match_dup 2)))))
10266   (clobber (reg:CC FLAGS_REG))]
10267  "TARGET_64BIT"
10268  "@
10269   shld{q}\t{%2, %1, %0|%0, %1, %2}
10270   shld{q}\t{%s2%1, %0|%0, %1, %2}"
10271  [(set_attr "type" "ishift")
10272   (set_attr "prefix_0f" "1")
10273   (set_attr "mode" "DI")
10274   (set_attr "athlon_decode" "vector")])
10275
10276(define_expand "x86_64_shift_adj"
10277  [(set (reg:CCZ FLAGS_REG)
10278	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10279			     (const_int 64))
10280		     (const_int 0)))
10281   (set (match_operand:DI 0 "register_operand" "")
10282        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10283			 (match_operand:DI 1 "register_operand" "")
10284			 (match_dup 0)))
10285   (set (match_dup 1)
10286	(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10287			 (match_operand:DI 3 "register_operand" "r")
10288			 (match_dup 1)))]
10289  "TARGET_64BIT"
10290  "")
10291
10292(define_expand "ashldi3"
10293  [(set (match_operand:DI 0 "shiftdi_operand" "")
10294	(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10295		   (match_operand:QI 2 "nonmemory_operand" "")))]
10296  ""
10297  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10298
10299(define_insn "*ashldi3_1_rex64"
10300  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10301	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10302		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10303   (clobber (reg:CC FLAGS_REG))]
10304  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10305{
10306  switch (get_attr_type (insn))
10307    {
10308    case TYPE_ALU:
10309      gcc_assert (operands[2] == const1_rtx);
10310      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10311      return "add{q}\t{%0, %0|%0, %0}";
10312
10313    case TYPE_LEA:
10314      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10315      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10316      operands[1] = gen_rtx_MULT (DImode, operands[1],
10317				  GEN_INT (1 << INTVAL (operands[2])));
10318      return "lea{q}\t{%a1, %0|%0, %a1}";
10319
10320    default:
10321      if (REG_P (operands[2]))
10322	return "sal{q}\t{%b2, %0|%0, %b2}";
10323      else if (operands[2] == const1_rtx
10324	       && (TARGET_SHIFT1 || optimize_size))
10325	return "sal{q}\t%0";
10326      else
10327	return "sal{q}\t{%2, %0|%0, %2}";
10328    }
10329}
10330  [(set (attr "type")
10331     (cond [(eq_attr "alternative" "1")
10332	      (const_string "lea")
10333            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10334		          (const_int 0))
10335		      (match_operand 0 "register_operand" ""))
10336		 (match_operand 2 "const1_operand" ""))
10337	      (const_string "alu")
10338	   ]
10339	   (const_string "ishift")))
10340   (set_attr "mode" "DI")])
10341
10342;; Convert lea to the lea pattern to avoid flags dependency.
10343(define_split
10344  [(set (match_operand:DI 0 "register_operand" "")
10345	(ashift:DI (match_operand:DI 1 "index_register_operand" "")
10346		   (match_operand:QI 2 "immediate_operand" "")))
10347   (clobber (reg:CC FLAGS_REG))]
10348  "TARGET_64BIT && reload_completed
10349   && true_regnum (operands[0]) != true_regnum (operands[1])"
10350  [(set (match_dup 0)
10351	(mult:DI (match_dup 1)
10352		 (match_dup 2)))]
10353  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10354
10355;; This pattern can't accept a variable shift count, since shifts by
10356;; zero don't affect the flags.  We assume that shifts by constant
10357;; zero are optimized away.
10358(define_insn "*ashldi3_cmp_rex64"
10359  [(set (reg FLAGS_REG)
10360	(compare
10361	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10362		     (match_operand:QI 2 "immediate_operand" "e"))
10363	  (const_int 0)))
10364   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10365	(ashift:DI (match_dup 1) (match_dup 2)))]
10366  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10367   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10368{
10369  switch (get_attr_type (insn))
10370    {
10371    case TYPE_ALU:
10372      gcc_assert (operands[2] == const1_rtx);
10373      return "add{q}\t{%0, %0|%0, %0}";
10374
10375    default:
10376      if (REG_P (operands[2]))
10377	return "sal{q}\t{%b2, %0|%0, %b2}";
10378      else if (operands[2] == const1_rtx
10379	       && (TARGET_SHIFT1 || optimize_size))
10380	return "sal{q}\t%0";
10381      else
10382	return "sal{q}\t{%2, %0|%0, %2}";
10383    }
10384}
10385  [(set (attr "type")
10386     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10387		          (const_int 0))
10388		      (match_operand 0 "register_operand" ""))
10389		 (match_operand 2 "const1_operand" ""))
10390	      (const_string "alu")
10391	   ]
10392	   (const_string "ishift")))
10393   (set_attr "mode" "DI")])
10394
10395(define_insn "*ashldi3_cconly_rex64"
10396  [(set (reg FLAGS_REG)
10397	(compare
10398	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10399		     (match_operand:QI 2 "immediate_operand" "e"))
10400	  (const_int 0)))
10401   (clobber (match_scratch:DI 0 "=r"))]
10402  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10403   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10404{
10405  switch (get_attr_type (insn))
10406    {
10407    case TYPE_ALU:
10408      gcc_assert (operands[2] == const1_rtx);
10409      return "add{q}\t{%0, %0|%0, %0}";
10410
10411    default:
10412      if (REG_P (operands[2]))
10413	return "sal{q}\t{%b2, %0|%0, %b2}";
10414      else if (operands[2] == const1_rtx
10415	       && (TARGET_SHIFT1 || optimize_size))
10416	return "sal{q}\t%0";
10417      else
10418	return "sal{q}\t{%2, %0|%0, %2}";
10419    }
10420}
10421  [(set (attr "type")
10422     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10423		          (const_int 0))
10424		      (match_operand 0 "register_operand" ""))
10425		 (match_operand 2 "const1_operand" ""))
10426	      (const_string "alu")
10427	   ]
10428	   (const_string "ishift")))
10429   (set_attr "mode" "DI")])
10430
10431(define_insn "*ashldi3_1"
10432  [(set (match_operand:DI 0 "register_operand" "=&r,r")
10433	(ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10434		   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10435   (clobber (reg:CC FLAGS_REG))]
10436  "!TARGET_64BIT"
10437  "#"
10438  [(set_attr "type" "multi")])
10439
10440;; By default we don't ask for a scratch register, because when DImode
10441;; values are manipulated, registers are already at a premium.  But if
10442;; we have one handy, we won't turn it away.
10443(define_peephole2
10444  [(match_scratch:SI 3 "r")
10445   (parallel [(set (match_operand:DI 0 "register_operand" "")
10446		   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10447			      (match_operand:QI 2 "nonmemory_operand" "")))
10448	      (clobber (reg:CC FLAGS_REG))])
10449   (match_dup 3)]
10450  "!TARGET_64BIT && TARGET_CMOVE"
10451  [(const_int 0)]
10452  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10453
10454(define_split
10455  [(set (match_operand:DI 0 "register_operand" "")
10456	(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10457		   (match_operand:QI 2 "nonmemory_operand" "")))
10458   (clobber (reg:CC FLAGS_REG))]
10459  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10460		     ? flow2_completed : reload_completed)"
10461  [(const_int 0)]
10462  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10463
10464(define_insn "x86_shld_1"
10465  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10466        (ior:SI (ashift:SI (match_dup 0)
10467		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10468		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10469		  (minus:QI (const_int 32) (match_dup 2)))))
10470   (clobber (reg:CC FLAGS_REG))]
10471  ""
10472  "@
10473   shld{l}\t{%2, %1, %0|%0, %1, %2}
10474   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10475  [(set_attr "type" "ishift")
10476   (set_attr "prefix_0f" "1")
10477   (set_attr "mode" "SI")
10478   (set_attr "pent_pair" "np")
10479   (set_attr "athlon_decode" "vector")])
10480
10481(define_expand "x86_shift_adj_1"
10482  [(set (reg:CCZ FLAGS_REG)
10483	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10484			     (const_int 32))
10485		     (const_int 0)))
10486   (set (match_operand:SI 0 "register_operand" "")
10487        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10488			 (match_operand:SI 1 "register_operand" "")
10489			 (match_dup 0)))
10490   (set (match_dup 1)
10491	(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10492			 (match_operand:SI 3 "register_operand" "r")
10493			 (match_dup 1)))]
10494  "TARGET_CMOVE"
10495  "")
10496
10497(define_expand "x86_shift_adj_2"
10498  [(use (match_operand:SI 0 "register_operand" ""))
10499   (use (match_operand:SI 1 "register_operand" ""))
10500   (use (match_operand:QI 2 "register_operand" ""))]
10501  ""
10502{
10503  rtx label = gen_label_rtx ();
10504  rtx tmp;
10505
10506  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10507
10508  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10509  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10510  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10511			      gen_rtx_LABEL_REF (VOIDmode, label),
10512			      pc_rtx);
10513  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10514  JUMP_LABEL (tmp) = label;
10515
10516  emit_move_insn (operands[0], operands[1]);
10517  ix86_expand_clear (operands[1]);
10518
10519  emit_label (label);
10520  LABEL_NUSES (label) = 1;
10521
10522  DONE;
10523})
10524
10525(define_expand "ashlsi3"
10526  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10527	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10528		   (match_operand:QI 2 "nonmemory_operand" "")))
10529   (clobber (reg:CC FLAGS_REG))]
10530  ""
10531  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10532
10533(define_insn "*ashlsi3_1"
10534  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10535	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10536		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10537   (clobber (reg:CC FLAGS_REG))]
10538  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10539{
10540  switch (get_attr_type (insn))
10541    {
10542    case TYPE_ALU:
10543      gcc_assert (operands[2] == const1_rtx);
10544      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10545      return "add{l}\t{%0, %0|%0, %0}";
10546
10547    case TYPE_LEA:
10548      return "#";
10549
10550    default:
10551      if (REG_P (operands[2]))
10552	return "sal{l}\t{%b2, %0|%0, %b2}";
10553      else if (operands[2] == const1_rtx
10554	       && (TARGET_SHIFT1 || optimize_size))
10555	return "sal{l}\t%0";
10556      else
10557	return "sal{l}\t{%2, %0|%0, %2}";
10558    }
10559}
10560  [(set (attr "type")
10561     (cond [(eq_attr "alternative" "1")
10562	      (const_string "lea")
10563            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10564		          (const_int 0))
10565		      (match_operand 0 "register_operand" ""))
10566		 (match_operand 2 "const1_operand" ""))
10567	      (const_string "alu")
10568	   ]
10569	   (const_string "ishift")))
10570   (set_attr "mode" "SI")])
10571
10572;; Convert lea to the lea pattern to avoid flags dependency.
10573(define_split
10574  [(set (match_operand 0 "register_operand" "")
10575	(ashift (match_operand 1 "index_register_operand" "")
10576                (match_operand:QI 2 "const_int_operand" "")))
10577   (clobber (reg:CC FLAGS_REG))]
10578  "reload_completed
10579   && true_regnum (operands[0]) != true_regnum (operands[1])
10580   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10581  [(const_int 0)]
10582{
10583  rtx pat;
10584  enum machine_mode mode = GET_MODE (operands[0]);
10585
10586  if (GET_MODE_SIZE (mode) < 4)
10587    operands[0] = gen_lowpart (SImode, operands[0]);
10588  if (mode != Pmode)
10589    operands[1] = gen_lowpart (Pmode, operands[1]);
10590  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10591
10592  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10593  if (Pmode != SImode)
10594    pat = gen_rtx_SUBREG (SImode, pat, 0);
10595  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10596  DONE;
10597})
10598
10599;; Rare case of shifting RSP is handled by generating move and shift
10600(define_split
10601  [(set (match_operand 0 "register_operand" "")
10602	(ashift (match_operand 1 "register_operand" "")
10603                (match_operand:QI 2 "const_int_operand" "")))
10604   (clobber (reg:CC FLAGS_REG))]
10605  "reload_completed
10606   && true_regnum (operands[0]) != true_regnum (operands[1])"
10607  [(const_int 0)]
10608{
10609  rtx pat, clob;
10610  emit_move_insn (operands[1], operands[0]);
10611  pat = gen_rtx_SET (VOIDmode, operands[0],
10612		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10613				     operands[0], operands[2]));
10614  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10615  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10616  DONE;
10617})
10618
10619(define_insn "*ashlsi3_1_zext"
10620  [(set (match_operand:DI 0 "register_operand" "=r,r")
10621	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10622			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10623   (clobber (reg:CC FLAGS_REG))]
10624  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10625{
10626  switch (get_attr_type (insn))
10627    {
10628    case TYPE_ALU:
10629      gcc_assert (operands[2] == const1_rtx);
10630      return "add{l}\t{%k0, %k0|%k0, %k0}";
10631
10632    case TYPE_LEA:
10633      return "#";
10634
10635    default:
10636      if (REG_P (operands[2]))
10637	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10638      else if (operands[2] == const1_rtx
10639	       && (TARGET_SHIFT1 || optimize_size))
10640	return "sal{l}\t%k0";
10641      else
10642	return "sal{l}\t{%2, %k0|%k0, %2}";
10643    }
10644}
10645  [(set (attr "type")
10646     (cond [(eq_attr "alternative" "1")
10647	      (const_string "lea")
10648            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10649		     (const_int 0))
10650		 (match_operand 2 "const1_operand" ""))
10651	      (const_string "alu")
10652	   ]
10653	   (const_string "ishift")))
10654   (set_attr "mode" "SI")])
10655
10656;; Convert lea to the lea pattern to avoid flags dependency.
10657(define_split
10658  [(set (match_operand:DI 0 "register_operand" "")
10659	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10660				(match_operand:QI 2 "const_int_operand" ""))))
10661   (clobber (reg:CC FLAGS_REG))]
10662  "TARGET_64BIT && reload_completed
10663   && true_regnum (operands[0]) != true_regnum (operands[1])"
10664  [(set (match_dup 0) (zero_extend:DI
10665			(subreg:SI (mult:SI (match_dup 1)
10666					    (match_dup 2)) 0)))]
10667{
10668  operands[1] = gen_lowpart (Pmode, operands[1]);
10669  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10670})
10671
10672;; This pattern can't accept a variable shift count, since shifts by
10673;; zero don't affect the flags.  We assume that shifts by constant
10674;; zero are optimized away.
10675(define_insn "*ashlsi3_cmp"
10676  [(set (reg FLAGS_REG)
10677	(compare
10678	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10679		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10680	  (const_int 0)))
10681   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10682	(ashift:SI (match_dup 1) (match_dup 2)))]
10683  "ix86_match_ccmode (insn, CCGOCmode)
10684   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10685{
10686  switch (get_attr_type (insn))
10687    {
10688    case TYPE_ALU:
10689      gcc_assert (operands[2] == const1_rtx);
10690      return "add{l}\t{%0, %0|%0, %0}";
10691
10692    default:
10693      if (REG_P (operands[2]))
10694	return "sal{l}\t{%b2, %0|%0, %b2}";
10695      else if (operands[2] == const1_rtx
10696	       && (TARGET_SHIFT1 || optimize_size))
10697	return "sal{l}\t%0";
10698      else
10699	return "sal{l}\t{%2, %0|%0, %2}";
10700    }
10701}
10702  [(set (attr "type")
10703     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10704		          (const_int 0))
10705		      (match_operand 0 "register_operand" ""))
10706		 (match_operand 2 "const1_operand" ""))
10707	      (const_string "alu")
10708	   ]
10709	   (const_string "ishift")))
10710   (set_attr "mode" "SI")])
10711
10712(define_insn "*ashlsi3_cconly"
10713  [(set (reg FLAGS_REG)
10714	(compare
10715	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10716		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10717	  (const_int 0)))
10718   (clobber (match_scratch:SI 0 "=r"))]
10719  "ix86_match_ccmode (insn, CCGOCmode)
10720   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10721{
10722  switch (get_attr_type (insn))
10723    {
10724    case TYPE_ALU:
10725      gcc_assert (operands[2] == const1_rtx);
10726      return "add{l}\t{%0, %0|%0, %0}";
10727
10728    default:
10729      if (REG_P (operands[2]))
10730	return "sal{l}\t{%b2, %0|%0, %b2}";
10731      else if (operands[2] == const1_rtx
10732	       && (TARGET_SHIFT1 || optimize_size))
10733	return "sal{l}\t%0";
10734      else
10735	return "sal{l}\t{%2, %0|%0, %2}";
10736    }
10737}
10738  [(set (attr "type")
10739     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10740		          (const_int 0))
10741		      (match_operand 0 "register_operand" ""))
10742		 (match_operand 2 "const1_operand" ""))
10743	      (const_string "alu")
10744	   ]
10745	   (const_string "ishift")))
10746   (set_attr "mode" "SI")])
10747
10748(define_insn "*ashlsi3_cmp_zext"
10749  [(set (reg FLAGS_REG)
10750	(compare
10751	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10752		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10753	  (const_int 0)))
10754   (set (match_operand:DI 0 "register_operand" "=r")
10755	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10756  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10757   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10758{
10759  switch (get_attr_type (insn))
10760    {
10761    case TYPE_ALU:
10762      gcc_assert (operands[2] == const1_rtx);
10763      return "add{l}\t{%k0, %k0|%k0, %k0}";
10764
10765    default:
10766      if (REG_P (operands[2]))
10767	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10768      else if (operands[2] == const1_rtx
10769	       && (TARGET_SHIFT1 || optimize_size))
10770	return "sal{l}\t%k0";
10771      else
10772	return "sal{l}\t{%2, %k0|%k0, %2}";
10773    }
10774}
10775  [(set (attr "type")
10776     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10777		     (const_int 0))
10778		 (match_operand 2 "const1_operand" ""))
10779	      (const_string "alu")
10780	   ]
10781	   (const_string "ishift")))
10782   (set_attr "mode" "SI")])
10783
10784(define_expand "ashlhi3"
10785  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10786	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10787		   (match_operand:QI 2 "nonmemory_operand" "")))
10788   (clobber (reg:CC FLAGS_REG))]
10789  "TARGET_HIMODE_MATH"
10790  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10791
10792(define_insn "*ashlhi3_1_lea"
10793  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10794	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10795		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10796   (clobber (reg:CC FLAGS_REG))]
10797  "!TARGET_PARTIAL_REG_STALL
10798   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10799{
10800  switch (get_attr_type (insn))
10801    {
10802    case TYPE_LEA:
10803      return "#";
10804    case TYPE_ALU:
10805      gcc_assert (operands[2] == const1_rtx);
10806      return "add{w}\t{%0, %0|%0, %0}";
10807
10808    default:
10809      if (REG_P (operands[2]))
10810	return "sal{w}\t{%b2, %0|%0, %b2}";
10811      else if (operands[2] == const1_rtx
10812	       && (TARGET_SHIFT1 || optimize_size))
10813	return "sal{w}\t%0";
10814      else
10815	return "sal{w}\t{%2, %0|%0, %2}";
10816    }
10817}
10818  [(set (attr "type")
10819     (cond [(eq_attr "alternative" "1")
10820	      (const_string "lea")
10821            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10822		          (const_int 0))
10823		      (match_operand 0 "register_operand" ""))
10824		 (match_operand 2 "const1_operand" ""))
10825	      (const_string "alu")
10826	   ]
10827	   (const_string "ishift")))
10828   (set_attr "mode" "HI,SI")])
10829
10830(define_insn "*ashlhi3_1"
10831  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10832	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10833		   (match_operand:QI 2 "nonmemory_operand" "cI")))
10834   (clobber (reg:CC FLAGS_REG))]
10835  "TARGET_PARTIAL_REG_STALL
10836   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10837{
10838  switch (get_attr_type (insn))
10839    {
10840    case TYPE_ALU:
10841      gcc_assert (operands[2] == const1_rtx);
10842      return "add{w}\t{%0, %0|%0, %0}";
10843
10844    default:
10845      if (REG_P (operands[2]))
10846	return "sal{w}\t{%b2, %0|%0, %b2}";
10847      else if (operands[2] == const1_rtx
10848	       && (TARGET_SHIFT1 || optimize_size))
10849	return "sal{w}\t%0";
10850      else
10851	return "sal{w}\t{%2, %0|%0, %2}";
10852    }
10853}
10854  [(set (attr "type")
10855     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10856		          (const_int 0))
10857		      (match_operand 0 "register_operand" ""))
10858		 (match_operand 2 "const1_operand" ""))
10859	      (const_string "alu")
10860	   ]
10861	   (const_string "ishift")))
10862   (set_attr "mode" "HI")])
10863
10864;; This pattern can't accept a variable shift count, since shifts by
10865;; zero don't affect the flags.  We assume that shifts by constant
10866;; zero are optimized away.
10867(define_insn "*ashlhi3_cmp"
10868  [(set (reg FLAGS_REG)
10869	(compare
10870	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10871		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10872	  (const_int 0)))
10873   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10874	(ashift:HI (match_dup 1) (match_dup 2)))]
10875  "ix86_match_ccmode (insn, CCGOCmode)
10876   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10877{
10878  switch (get_attr_type (insn))
10879    {
10880    case TYPE_ALU:
10881      gcc_assert (operands[2] == const1_rtx);
10882      return "add{w}\t{%0, %0|%0, %0}";
10883
10884    default:
10885      if (REG_P (operands[2]))
10886	return "sal{w}\t{%b2, %0|%0, %b2}";
10887      else if (operands[2] == const1_rtx
10888	       && (TARGET_SHIFT1 || optimize_size))
10889	return "sal{w}\t%0";
10890      else
10891	return "sal{w}\t{%2, %0|%0, %2}";
10892    }
10893}
10894  [(set (attr "type")
10895     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10896		          (const_int 0))
10897		      (match_operand 0 "register_operand" ""))
10898		 (match_operand 2 "const1_operand" ""))
10899	      (const_string "alu")
10900	   ]
10901	   (const_string "ishift")))
10902   (set_attr "mode" "HI")])
10903
10904(define_insn "*ashlhi3_cconly"
10905  [(set (reg FLAGS_REG)
10906	(compare
10907	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10908		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10909	  (const_int 0)))
10910   (clobber (match_scratch:HI 0 "=r"))]
10911  "ix86_match_ccmode (insn, CCGOCmode)
10912   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10913{
10914  switch (get_attr_type (insn))
10915    {
10916    case TYPE_ALU:
10917      gcc_assert (operands[2] == const1_rtx);
10918      return "add{w}\t{%0, %0|%0, %0}";
10919
10920    default:
10921      if (REG_P (operands[2]))
10922	return "sal{w}\t{%b2, %0|%0, %b2}";
10923      else if (operands[2] == const1_rtx
10924	       && (TARGET_SHIFT1 || optimize_size))
10925	return "sal{w}\t%0";
10926      else
10927	return "sal{w}\t{%2, %0|%0, %2}";
10928    }
10929}
10930  [(set (attr "type")
10931     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10932		          (const_int 0))
10933		      (match_operand 0 "register_operand" ""))
10934		 (match_operand 2 "const1_operand" ""))
10935	      (const_string "alu")
10936	   ]
10937	   (const_string "ishift")))
10938   (set_attr "mode" "HI")])
10939
10940(define_expand "ashlqi3"
10941  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10942	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10943		   (match_operand:QI 2 "nonmemory_operand" "")))
10944   (clobber (reg:CC FLAGS_REG))]
10945  "TARGET_QIMODE_MATH"
10946  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10947
10948;; %%% Potential partial reg stall on alternative 2.  What to do?
10949
10950(define_insn "*ashlqi3_1_lea"
10951  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10952	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10953		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10954   (clobber (reg:CC FLAGS_REG))]
10955  "!TARGET_PARTIAL_REG_STALL
10956   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10957{
10958  switch (get_attr_type (insn))
10959    {
10960    case TYPE_LEA:
10961      return "#";
10962    case TYPE_ALU:
10963      gcc_assert (operands[2] == const1_rtx);
10964      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10965        return "add{l}\t{%k0, %k0|%k0, %k0}";
10966      else
10967        return "add{b}\t{%0, %0|%0, %0}";
10968
10969    default:
10970      if (REG_P (operands[2]))
10971	{
10972	  if (get_attr_mode (insn) == MODE_SI)
10973	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
10974	  else
10975	    return "sal{b}\t{%b2, %0|%0, %b2}";
10976	}
10977      else if (operands[2] == const1_rtx
10978	       && (TARGET_SHIFT1 || optimize_size))
10979	{
10980	  if (get_attr_mode (insn) == MODE_SI)
10981	    return "sal{l}\t%0";
10982	  else
10983	    return "sal{b}\t%0";
10984	}
10985      else
10986	{
10987	  if (get_attr_mode (insn) == MODE_SI)
10988	    return "sal{l}\t{%2, %k0|%k0, %2}";
10989	  else
10990	    return "sal{b}\t{%2, %0|%0, %2}";
10991	}
10992    }
10993}
10994  [(set (attr "type")
10995     (cond [(eq_attr "alternative" "2")
10996	      (const_string "lea")
10997            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10998		          (const_int 0))
10999		      (match_operand 0 "register_operand" ""))
11000		 (match_operand 2 "const1_operand" ""))
11001	      (const_string "alu")
11002	   ]
11003	   (const_string "ishift")))
11004   (set_attr "mode" "QI,SI,SI")])
11005
11006(define_insn "*ashlqi3_1"
11007  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11008	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11009		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11010   (clobber (reg:CC FLAGS_REG))]
11011  "TARGET_PARTIAL_REG_STALL
11012   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11013{
11014  switch (get_attr_type (insn))
11015    {
11016    case TYPE_ALU:
11017      gcc_assert (operands[2] == const1_rtx);
11018      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11019        return "add{l}\t{%k0, %k0|%k0, %k0}";
11020      else
11021        return "add{b}\t{%0, %0|%0, %0}";
11022
11023    default:
11024      if (REG_P (operands[2]))
11025	{
11026	  if (get_attr_mode (insn) == MODE_SI)
11027	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11028	  else
11029	    return "sal{b}\t{%b2, %0|%0, %b2}";
11030	}
11031      else if (operands[2] == const1_rtx
11032	       && (TARGET_SHIFT1 || optimize_size))
11033	{
11034	  if (get_attr_mode (insn) == MODE_SI)
11035	    return "sal{l}\t%0";
11036	  else
11037	    return "sal{b}\t%0";
11038	}
11039      else
11040	{
11041	  if (get_attr_mode (insn) == MODE_SI)
11042	    return "sal{l}\t{%2, %k0|%k0, %2}";
11043	  else
11044	    return "sal{b}\t{%2, %0|%0, %2}";
11045	}
11046    }
11047}
11048  [(set (attr "type")
11049     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11050		          (const_int 0))
11051		      (match_operand 0 "register_operand" ""))
11052		 (match_operand 2 "const1_operand" ""))
11053	      (const_string "alu")
11054	   ]
11055	   (const_string "ishift")))
11056   (set_attr "mode" "QI,SI")])
11057
11058;; This pattern can't accept a variable shift count, since shifts by
11059;; zero don't affect the flags.  We assume that shifts by constant
11060;; zero are optimized away.
11061(define_insn "*ashlqi3_cmp"
11062  [(set (reg FLAGS_REG)
11063	(compare
11064	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11065		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11066	  (const_int 0)))
11067   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11068	(ashift:QI (match_dup 1) (match_dup 2)))]
11069  "ix86_match_ccmode (insn, CCGOCmode)
11070   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11071{
11072  switch (get_attr_type (insn))
11073    {
11074    case TYPE_ALU:
11075      gcc_assert (operands[2] == const1_rtx);
11076      return "add{b}\t{%0, %0|%0, %0}";
11077
11078    default:
11079      if (REG_P (operands[2]))
11080	return "sal{b}\t{%b2, %0|%0, %b2}";
11081      else if (operands[2] == const1_rtx
11082	       && (TARGET_SHIFT1 || optimize_size))
11083	return "sal{b}\t%0";
11084      else
11085	return "sal{b}\t{%2, %0|%0, %2}";
11086    }
11087}
11088  [(set (attr "type")
11089     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11090		          (const_int 0))
11091		      (match_operand 0 "register_operand" ""))
11092		 (match_operand 2 "const1_operand" ""))
11093	      (const_string "alu")
11094	   ]
11095	   (const_string "ishift")))
11096   (set_attr "mode" "QI")])
11097
11098(define_insn "*ashlqi3_cconly"
11099  [(set (reg FLAGS_REG)
11100	(compare
11101	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11102		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11103	  (const_int 0)))
11104   (clobber (match_scratch:QI 0 "=q"))]
11105  "ix86_match_ccmode (insn, CCGOCmode)
11106   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11107{
11108  switch (get_attr_type (insn))
11109    {
11110    case TYPE_ALU:
11111      gcc_assert (operands[2] == const1_rtx);
11112      return "add{b}\t{%0, %0|%0, %0}";
11113
11114    default:
11115      if (REG_P (operands[2]))
11116	return "sal{b}\t{%b2, %0|%0, %b2}";
11117      else if (operands[2] == const1_rtx
11118	       && (TARGET_SHIFT1 || optimize_size))
11119	return "sal{b}\t%0";
11120      else
11121	return "sal{b}\t{%2, %0|%0, %2}";
11122    }
11123}
11124  [(set (attr "type")
11125     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11126		          (const_int 0))
11127		      (match_operand 0 "register_operand" ""))
11128		 (match_operand 2 "const1_operand" ""))
11129	      (const_string "alu")
11130	   ]
11131	   (const_string "ishift")))
11132   (set_attr "mode" "QI")])
11133
11134;; See comment above `ashldi3' about how this works.
11135
11136(define_expand "ashrti3"
11137  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11138		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11139				(match_operand:QI 2 "nonmemory_operand" "")))
11140	      (clobber (reg:CC FLAGS_REG))])]
11141  "TARGET_64BIT"
11142{
11143  if (! immediate_operand (operands[2], QImode))
11144    {
11145      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11146      DONE;
11147    }
11148  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11149  DONE;
11150})
11151
11152(define_insn "ashrti3_1"
11153  [(set (match_operand:TI 0 "register_operand" "=r")
11154	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11155		     (match_operand:QI 2 "register_operand" "c")))
11156   (clobber (match_scratch:DI 3 "=&r"))
11157   (clobber (reg:CC FLAGS_REG))]
11158  "TARGET_64BIT"
11159  "#"
11160  [(set_attr "type" "multi")])
11161
11162(define_insn "*ashrti3_2"
11163  [(set (match_operand:TI 0 "register_operand" "=r")
11164	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11165		     (match_operand:QI 2 "immediate_operand" "O")))
11166   (clobber (reg:CC FLAGS_REG))]
11167  "TARGET_64BIT"
11168  "#"
11169  [(set_attr "type" "multi")])
11170
11171(define_split
11172  [(set (match_operand:TI 0 "register_operand" "")
11173	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11174		     (match_operand:QI 2 "register_operand" "")))
11175   (clobber (match_scratch:DI 3 ""))
11176   (clobber (reg:CC FLAGS_REG))]
11177  "TARGET_64BIT && reload_completed"
11178  [(const_int 0)]
11179  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11180
11181(define_split
11182  [(set (match_operand:TI 0 "register_operand" "")
11183	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11184		     (match_operand:QI 2 "immediate_operand" "")))
11185   (clobber (reg:CC FLAGS_REG))]
11186  "TARGET_64BIT && reload_completed"
11187  [(const_int 0)]
11188  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11189
11190(define_insn "x86_64_shrd"
11191  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11192        (ior:DI (ashiftrt:DI (match_dup 0)
11193		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
11194		(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11195		  (minus:QI (const_int 64) (match_dup 2)))))
11196   (clobber (reg:CC FLAGS_REG))]
11197  "TARGET_64BIT"
11198  "@
11199   shrd{q}\t{%2, %1, %0|%0, %1, %2}
11200   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11201  [(set_attr "type" "ishift")
11202   (set_attr "prefix_0f" "1")
11203   (set_attr "mode" "DI")
11204   (set_attr "athlon_decode" "vector")])
11205
11206(define_expand "ashrdi3"
11207  [(set (match_operand:DI 0 "shiftdi_operand" "")
11208	(ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11209		     (match_operand:QI 2 "nonmemory_operand" "")))]
11210  ""
11211  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11212
11213(define_insn "*ashrdi3_63_rex64"
11214  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11215	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11216		     (match_operand:DI 2 "const_int_operand" "i,i")))
11217   (clobber (reg:CC FLAGS_REG))]
11218  "TARGET_64BIT && INTVAL (operands[2]) == 63
11219   && (TARGET_USE_CLTD || optimize_size)
11220   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11221  "@
11222   {cqto|cqo}
11223   sar{q}\t{%2, %0|%0, %2}"
11224  [(set_attr "type" "imovx,ishift")
11225   (set_attr "prefix_0f" "0,*")
11226   (set_attr "length_immediate" "0,*")
11227   (set_attr "modrm" "0,1")
11228   (set_attr "mode" "DI")])
11229
11230(define_insn "*ashrdi3_1_one_bit_rex64"
11231  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11232	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11233		     (match_operand:QI 2 "const1_operand" "")))
11234   (clobber (reg:CC FLAGS_REG))]
11235  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11236   && (TARGET_SHIFT1 || optimize_size)"
11237  "sar{q}\t%0"
11238  [(set_attr "type" "ishift")
11239   (set (attr "length") 
11240     (if_then_else (match_operand:DI 0 "register_operand" "") 
11241	(const_string "2")
11242	(const_string "*")))])
11243
11244(define_insn "*ashrdi3_1_rex64"
11245  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11246	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11247		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11248   (clobber (reg:CC FLAGS_REG))]
11249  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11250  "@
11251   sar{q}\t{%2, %0|%0, %2}
11252   sar{q}\t{%b2, %0|%0, %b2}"
11253  [(set_attr "type" "ishift")
11254   (set_attr "mode" "DI")])
11255
11256;; This pattern can't accept a variable shift count, since shifts by
11257;; zero don't affect the flags.  We assume that shifts by constant
11258;; zero are optimized away.
11259(define_insn "*ashrdi3_one_bit_cmp_rex64"
11260  [(set (reg FLAGS_REG)
11261	(compare
11262	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11263		       (match_operand:QI 2 "const1_operand" ""))
11264	  (const_int 0)))
11265   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11266	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11267  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11268   && (TARGET_SHIFT1 || optimize_size)
11269   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11270  "sar{q}\t%0"
11271  [(set_attr "type" "ishift")
11272   (set (attr "length") 
11273     (if_then_else (match_operand:DI 0 "register_operand" "") 
11274	(const_string "2")
11275	(const_string "*")))])
11276
11277(define_insn "*ashrdi3_one_bit_cconly_rex64"
11278  [(set (reg FLAGS_REG)
11279	(compare
11280	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11281		       (match_operand:QI 2 "const1_operand" ""))
11282	  (const_int 0)))
11283   (clobber (match_scratch:DI 0 "=r"))]
11284  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11285   && (TARGET_SHIFT1 || optimize_size)
11286   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11287  "sar{q}\t%0"
11288  [(set_attr "type" "ishift")
11289   (set_attr "length" "2")])
11290
11291;; This pattern can't accept a variable shift count, since shifts by
11292;; zero don't affect the flags.  We assume that shifts by constant
11293;; zero are optimized away.
11294(define_insn "*ashrdi3_cmp_rex64"
11295  [(set (reg FLAGS_REG)
11296	(compare
11297	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11298		       (match_operand:QI 2 "const_int_operand" "n"))
11299	  (const_int 0)))
11300   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11301	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11302  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11303   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11304  "sar{q}\t{%2, %0|%0, %2}"
11305  [(set_attr "type" "ishift")
11306   (set_attr "mode" "DI")])
11307
11308(define_insn "*ashrdi3_cconly_rex64"
11309  [(set (reg FLAGS_REG)
11310	(compare
11311	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11312		       (match_operand:QI 2 "const_int_operand" "n"))
11313	  (const_int 0)))
11314   (clobber (match_scratch:DI 0 "=r"))]
11315  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11316   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11317  "sar{q}\t{%2, %0|%0, %2}"
11318  [(set_attr "type" "ishift")
11319   (set_attr "mode" "DI")])
11320
11321(define_insn "*ashrdi3_1"
11322  [(set (match_operand:DI 0 "register_operand" "=r")
11323	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11324		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11325   (clobber (reg:CC FLAGS_REG))]
11326  "!TARGET_64BIT"
11327  "#"
11328  [(set_attr "type" "multi")])
11329
11330;; By default we don't ask for a scratch register, because when DImode
11331;; values are manipulated, registers are already at a premium.  But if
11332;; we have one handy, we won't turn it away.
11333(define_peephole2
11334  [(match_scratch:SI 3 "r")
11335   (parallel [(set (match_operand:DI 0 "register_operand" "")
11336		   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11337			        (match_operand:QI 2 "nonmemory_operand" "")))
11338	      (clobber (reg:CC FLAGS_REG))])
11339   (match_dup 3)]
11340  "!TARGET_64BIT && TARGET_CMOVE"
11341  [(const_int 0)]
11342  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11343
11344(define_split
11345  [(set (match_operand:DI 0 "register_operand" "")
11346	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11347		     (match_operand:QI 2 "nonmemory_operand" "")))
11348   (clobber (reg:CC FLAGS_REG))]
11349  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11350		     ? flow2_completed : reload_completed)"
11351  [(const_int 0)]
11352  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11353
11354(define_insn "x86_shrd_1"
11355  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11356        (ior:SI (ashiftrt:SI (match_dup 0)
11357		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11358		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11359		  (minus:QI (const_int 32) (match_dup 2)))))
11360   (clobber (reg:CC FLAGS_REG))]
11361  ""
11362  "@
11363   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11364   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11365  [(set_attr "type" "ishift")
11366   (set_attr "prefix_0f" "1")
11367   (set_attr "pent_pair" "np")
11368   (set_attr "mode" "SI")])
11369
11370(define_expand "x86_shift_adj_3"
11371  [(use (match_operand:SI 0 "register_operand" ""))
11372   (use (match_operand:SI 1 "register_operand" ""))
11373   (use (match_operand:QI 2 "register_operand" ""))]
11374  ""
11375{
11376  rtx label = gen_label_rtx ();
11377  rtx tmp;
11378
11379  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11380
11381  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11382  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11383  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11384			      gen_rtx_LABEL_REF (VOIDmode, label),
11385			      pc_rtx);
11386  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11387  JUMP_LABEL (tmp) = label;
11388
11389  emit_move_insn (operands[0], operands[1]);
11390  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11391
11392  emit_label (label);
11393  LABEL_NUSES (label) = 1;
11394
11395  DONE;
11396})
11397
11398(define_insn "ashrsi3_31"
11399  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11400	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11401		     (match_operand:SI 2 "const_int_operand" "i,i")))
11402   (clobber (reg:CC FLAGS_REG))]
11403  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11404   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11405  "@
11406   {cltd|cdq}
11407   sar{l}\t{%2, %0|%0, %2}"
11408  [(set_attr "type" "imovx,ishift")
11409   (set_attr "prefix_0f" "0,*")
11410   (set_attr "length_immediate" "0,*")
11411   (set_attr "modrm" "0,1")
11412   (set_attr "mode" "SI")])
11413
11414(define_insn "*ashrsi3_31_zext"
11415  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11416	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11417				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11418   (clobber (reg:CC FLAGS_REG))]
11419  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11420   && INTVAL (operands[2]) == 31
11421   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11422  "@
11423   {cltd|cdq}
11424   sar{l}\t{%2, %k0|%k0, %2}"
11425  [(set_attr "type" "imovx,ishift")
11426   (set_attr "prefix_0f" "0,*")
11427   (set_attr "length_immediate" "0,*")
11428   (set_attr "modrm" "0,1")
11429   (set_attr "mode" "SI")])
11430
11431(define_expand "ashrsi3"
11432  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11433	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11434		     (match_operand:QI 2 "nonmemory_operand" "")))
11435   (clobber (reg:CC FLAGS_REG))]
11436  ""
11437  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11438
11439(define_insn "*ashrsi3_1_one_bit"
11440  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11441	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11442		     (match_operand:QI 2 "const1_operand" "")))
11443   (clobber (reg:CC FLAGS_REG))]
11444  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11445   && (TARGET_SHIFT1 || optimize_size)"
11446  "sar{l}\t%0"
11447  [(set_attr "type" "ishift")
11448   (set (attr "length") 
11449     (if_then_else (match_operand:SI 0 "register_operand" "") 
11450	(const_string "2")
11451	(const_string "*")))])
11452
11453(define_insn "*ashrsi3_1_one_bit_zext"
11454  [(set (match_operand:DI 0 "register_operand" "=r")
11455	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11456				     (match_operand:QI 2 "const1_operand" ""))))
11457   (clobber (reg:CC FLAGS_REG))]
11458  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11459   && (TARGET_SHIFT1 || optimize_size)"
11460  "sar{l}\t%k0"
11461  [(set_attr "type" "ishift")
11462   (set_attr "length" "2")])
11463
11464(define_insn "*ashrsi3_1"
11465  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11466	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11467		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11468   (clobber (reg:CC FLAGS_REG))]
11469  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11470  "@
11471   sar{l}\t{%2, %0|%0, %2}
11472   sar{l}\t{%b2, %0|%0, %b2}"
11473  [(set_attr "type" "ishift")
11474   (set_attr "mode" "SI")])
11475
11476(define_insn "*ashrsi3_1_zext"
11477  [(set (match_operand:DI 0 "register_operand" "=r,r")
11478	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11479				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11480   (clobber (reg:CC FLAGS_REG))]
11481  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11482  "@
11483   sar{l}\t{%2, %k0|%k0, %2}
11484   sar{l}\t{%b2, %k0|%k0, %b2}"
11485  [(set_attr "type" "ishift")
11486   (set_attr "mode" "SI")])
11487
11488;; This pattern can't accept a variable shift count, since shifts by
11489;; zero don't affect the flags.  We assume that shifts by constant
11490;; zero are optimized away.
11491(define_insn "*ashrsi3_one_bit_cmp"
11492  [(set (reg FLAGS_REG)
11493	(compare
11494	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11495		       (match_operand:QI 2 "const1_operand" ""))
11496	  (const_int 0)))
11497   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11498	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11499  "ix86_match_ccmode (insn, CCGOCmode)
11500   && (TARGET_SHIFT1 || optimize_size)
11501   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11502  "sar{l}\t%0"
11503  [(set_attr "type" "ishift")
11504   (set (attr "length") 
11505     (if_then_else (match_operand:SI 0 "register_operand" "") 
11506	(const_string "2")
11507	(const_string "*")))])
11508
11509(define_insn "*ashrsi3_one_bit_cconly"
11510  [(set (reg FLAGS_REG)
11511	(compare
11512	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11513		       (match_operand:QI 2 "const1_operand" ""))
11514	  (const_int 0)))
11515   (clobber (match_scratch:SI 0 "=r"))]
11516  "ix86_match_ccmode (insn, CCGOCmode)
11517   && (TARGET_SHIFT1 || optimize_size)
11518   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11519  "sar{l}\t%0"
11520  [(set_attr "type" "ishift")
11521   (set_attr "length" "2")])
11522
11523(define_insn "*ashrsi3_one_bit_cmp_zext"
11524  [(set (reg FLAGS_REG)
11525	(compare
11526	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11527		       (match_operand:QI 2 "const1_operand" ""))
11528	  (const_int 0)))
11529   (set (match_operand:DI 0 "register_operand" "=r")
11530	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11531  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11532   && (TARGET_SHIFT1 || optimize_size)
11533   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11534  "sar{l}\t%k0"
11535  [(set_attr "type" "ishift")
11536   (set_attr "length" "2")])
11537
11538;; This pattern can't accept a variable shift count, since shifts by
11539;; zero don't affect the flags.  We assume that shifts by constant
11540;; zero are optimized away.
11541(define_insn "*ashrsi3_cmp"
11542  [(set (reg FLAGS_REG)
11543	(compare
11544	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11545		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11546	  (const_int 0)))
11547   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11548	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11549  "ix86_match_ccmode (insn, CCGOCmode)
11550   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551  "sar{l}\t{%2, %0|%0, %2}"
11552  [(set_attr "type" "ishift")
11553   (set_attr "mode" "SI")])
11554
11555(define_insn "*ashrsi3_cconly"
11556  [(set (reg FLAGS_REG)
11557	(compare
11558	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11559		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11560	  (const_int 0)))
11561   (clobber (match_scratch:SI 0 "=r"))]
11562  "ix86_match_ccmode (insn, CCGOCmode)
11563   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11564  "sar{l}\t{%2, %0|%0, %2}"
11565  [(set_attr "type" "ishift")
11566   (set_attr "mode" "SI")])
11567
11568(define_insn "*ashrsi3_cmp_zext"
11569  [(set (reg FLAGS_REG)
11570	(compare
11571	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11572		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11573	  (const_int 0)))
11574   (set (match_operand:DI 0 "register_operand" "=r")
11575	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11576  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11577   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11578  "sar{l}\t{%2, %k0|%k0, %2}"
11579  [(set_attr "type" "ishift")
11580   (set_attr "mode" "SI")])
11581
11582(define_expand "ashrhi3"
11583  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11584	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11585		     (match_operand:QI 2 "nonmemory_operand" "")))
11586   (clobber (reg:CC FLAGS_REG))]
11587  "TARGET_HIMODE_MATH"
11588  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11589
11590(define_insn "*ashrhi3_1_one_bit"
11591  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11592	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11593		     (match_operand:QI 2 "const1_operand" "")))
11594   (clobber (reg:CC FLAGS_REG))]
11595  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11596   && (TARGET_SHIFT1 || optimize_size)"
11597  "sar{w}\t%0"
11598  [(set_attr "type" "ishift")
11599   (set (attr "length") 
11600     (if_then_else (match_operand 0 "register_operand" "") 
11601	(const_string "2")
11602	(const_string "*")))])
11603
11604(define_insn "*ashrhi3_1"
11605  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11606	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11607		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11608   (clobber (reg:CC FLAGS_REG))]
11609  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11610  "@
11611   sar{w}\t{%2, %0|%0, %2}
11612   sar{w}\t{%b2, %0|%0, %b2}"
11613  [(set_attr "type" "ishift")
11614   (set_attr "mode" "HI")])
11615
11616;; This pattern can't accept a variable shift count, since shifts by
11617;; zero don't affect the flags.  We assume that shifts by constant
11618;; zero are optimized away.
11619(define_insn "*ashrhi3_one_bit_cmp"
11620  [(set (reg FLAGS_REG)
11621	(compare
11622	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11623		       (match_operand:QI 2 "const1_operand" ""))
11624	  (const_int 0)))
11625   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11626	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11627  "ix86_match_ccmode (insn, CCGOCmode)
11628   && (TARGET_SHIFT1 || optimize_size)
11629   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11630  "sar{w}\t%0"
11631  [(set_attr "type" "ishift")
11632   (set (attr "length") 
11633     (if_then_else (match_operand 0 "register_operand" "") 
11634	(const_string "2")
11635	(const_string "*")))])
11636
11637(define_insn "*ashrhi3_one_bit_cconly"
11638  [(set (reg FLAGS_REG)
11639	(compare
11640	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11641		       (match_operand:QI 2 "const1_operand" ""))
11642	  (const_int 0)))
11643   (clobber (match_scratch:HI 0 "=r"))]
11644  "ix86_match_ccmode (insn, CCGOCmode)
11645   && (TARGET_SHIFT1 || optimize_size)
11646   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11647  "sar{w}\t%0"
11648  [(set_attr "type" "ishift")
11649   (set_attr "length" "2")])
11650
11651;; This pattern can't accept a variable shift count, since shifts by
11652;; zero don't affect the flags.  We assume that shifts by constant
11653;; zero are optimized away.
11654(define_insn "*ashrhi3_cmp"
11655  [(set (reg FLAGS_REG)
11656	(compare
11657	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11658		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11659	  (const_int 0)))
11660   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11661	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11662  "ix86_match_ccmode (insn, CCGOCmode)
11663   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11664  "sar{w}\t{%2, %0|%0, %2}"
11665  [(set_attr "type" "ishift")
11666   (set_attr "mode" "HI")])
11667
11668(define_insn "*ashrhi3_cconly"
11669  [(set (reg FLAGS_REG)
11670	(compare
11671	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11672		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11673	  (const_int 0)))
11674   (clobber (match_scratch:HI 0 "=r"))]
11675  "ix86_match_ccmode (insn, CCGOCmode)
11676   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11677  "sar{w}\t{%2, %0|%0, %2}"
11678  [(set_attr "type" "ishift")
11679   (set_attr "mode" "HI")])
11680
11681(define_expand "ashrqi3"
11682  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11683	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11684		     (match_operand:QI 2 "nonmemory_operand" "")))
11685   (clobber (reg:CC FLAGS_REG))]
11686  "TARGET_QIMODE_MATH"
11687  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11688
11689(define_insn "*ashrqi3_1_one_bit"
11690  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11691	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11692		     (match_operand:QI 2 "const1_operand" "")))
11693   (clobber (reg:CC FLAGS_REG))]
11694  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11695   && (TARGET_SHIFT1 || optimize_size)"
11696  "sar{b}\t%0"
11697  [(set_attr "type" "ishift")
11698   (set (attr "length") 
11699     (if_then_else (match_operand 0 "register_operand" "") 
11700	(const_string "2")
11701	(const_string "*")))])
11702
11703(define_insn "*ashrqi3_1_one_bit_slp"
11704  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11705	(ashiftrt:QI (match_dup 0)
11706		     (match_operand:QI 1 "const1_operand" "")))
11707   (clobber (reg:CC FLAGS_REG))]
11708  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11709   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11710   && (TARGET_SHIFT1 || optimize_size)"
11711  "sar{b}\t%0"
11712  [(set_attr "type" "ishift1")
11713   (set (attr "length") 
11714     (if_then_else (match_operand 0 "register_operand" "") 
11715	(const_string "2")
11716	(const_string "*")))])
11717
11718(define_insn "*ashrqi3_1"
11719  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11720	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11721		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11722   (clobber (reg:CC FLAGS_REG))]
11723  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11724  "@
11725   sar{b}\t{%2, %0|%0, %2}
11726   sar{b}\t{%b2, %0|%0, %b2}"
11727  [(set_attr "type" "ishift")
11728   (set_attr "mode" "QI")])
11729
11730(define_insn "*ashrqi3_1_slp"
11731  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11732	(ashiftrt:QI (match_dup 0)
11733		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11734   (clobber (reg:CC FLAGS_REG))]
11735  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11736   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11737  "@
11738   sar{b}\t{%1, %0|%0, %1}
11739   sar{b}\t{%b1, %0|%0, %b1}"
11740  [(set_attr "type" "ishift1")
11741   (set_attr "mode" "QI")])
11742
11743;; This pattern can't accept a variable shift count, since shifts by
11744;; zero don't affect the flags.  We assume that shifts by constant
11745;; zero are optimized away.
11746(define_insn "*ashrqi3_one_bit_cmp"
11747  [(set (reg FLAGS_REG)
11748	(compare
11749	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11750		       (match_operand:QI 2 "const1_operand" "I"))
11751	  (const_int 0)))
11752   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11753	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11754  "ix86_match_ccmode (insn, CCGOCmode)
11755   && (TARGET_SHIFT1 || optimize_size)
11756   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11757  "sar{b}\t%0"
11758  [(set_attr "type" "ishift")
11759   (set (attr "length") 
11760     (if_then_else (match_operand 0 "register_operand" "") 
11761	(const_string "2")
11762	(const_string "*")))])
11763
11764(define_insn "*ashrqi3_one_bit_cconly"
11765  [(set (reg FLAGS_REG)
11766	(compare
11767	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11768		       (match_operand:QI 2 "const1_operand" "I"))
11769	  (const_int 0)))
11770   (clobber (match_scratch:QI 0 "=q"))]
11771  "ix86_match_ccmode (insn, CCGOCmode)
11772   && (TARGET_SHIFT1 || optimize_size)
11773   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11774  "sar{b}\t%0"
11775  [(set_attr "type" "ishift")
11776   (set_attr "length" "2")])
11777
11778;; This pattern can't accept a variable shift count, since shifts by
11779;; zero don't affect the flags.  We assume that shifts by constant
11780;; zero are optimized away.
11781(define_insn "*ashrqi3_cmp"
11782  [(set (reg FLAGS_REG)
11783	(compare
11784	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11785		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11786	  (const_int 0)))
11787   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11789  "ix86_match_ccmode (insn, CCGOCmode)
11790   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11791  "sar{b}\t{%2, %0|%0, %2}"
11792  [(set_attr "type" "ishift")
11793   (set_attr "mode" "QI")])
11794
11795(define_insn "*ashrqi3_cconly"
11796  [(set (reg FLAGS_REG)
11797	(compare
11798	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11799		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800	  (const_int 0)))
11801   (clobber (match_scratch:QI 0 "=q"))]
11802  "ix86_match_ccmode (insn, CCGOCmode)
11803   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11804  "sar{b}\t{%2, %0|%0, %2}"
11805  [(set_attr "type" "ishift")
11806   (set_attr "mode" "QI")])
11807
11808
11809;; Logical shift instructions
11810
11811;; See comment above `ashldi3' about how this works.
11812
11813(define_expand "lshrti3"
11814  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11815		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11816			        (match_operand:QI 2 "nonmemory_operand" "")))
11817	      (clobber (reg:CC FLAGS_REG))])]
11818  "TARGET_64BIT"
11819{
11820  if (! immediate_operand (operands[2], QImode))
11821    {
11822      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11823      DONE;
11824    }
11825  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11826  DONE;
11827})
11828
11829(define_insn "lshrti3_1"
11830  [(set (match_operand:TI 0 "register_operand" "=r")
11831	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11832		     (match_operand:QI 2 "register_operand" "c")))
11833   (clobber (match_scratch:DI 3 "=&r"))
11834   (clobber (reg:CC FLAGS_REG))]
11835  "TARGET_64BIT"
11836  "#"
11837  [(set_attr "type" "multi")])
11838
11839(define_insn "*lshrti3_2"
11840  [(set (match_operand:TI 0 "register_operand" "=r")
11841	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11842		     (match_operand:QI 2 "immediate_operand" "O")))
11843   (clobber (reg:CC FLAGS_REG))]
11844  "TARGET_64BIT"
11845  "#"
11846  [(set_attr "type" "multi")])
11847
11848(define_split 
11849  [(set (match_operand:TI 0 "register_operand" "")
11850	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11851		     (match_operand:QI 2 "register_operand" "")))
11852   (clobber (match_scratch:DI 3 ""))
11853   (clobber (reg:CC FLAGS_REG))]
11854  "TARGET_64BIT && reload_completed"
11855  [(const_int 0)]
11856  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11857
11858(define_split 
11859  [(set (match_operand:TI 0 "register_operand" "")
11860	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11861		     (match_operand:QI 2 "immediate_operand" "")))
11862   (clobber (reg:CC FLAGS_REG))]
11863  "TARGET_64BIT && reload_completed"
11864  [(const_int 0)]
11865  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11866
11867(define_expand "lshrdi3"
11868  [(set (match_operand:DI 0 "shiftdi_operand" "")
11869	(lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11870		     (match_operand:QI 2 "nonmemory_operand" "")))]
11871  ""
11872  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11873
11874(define_insn "*lshrdi3_1_one_bit_rex64"
11875  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11876	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11877		     (match_operand:QI 2 "const1_operand" "")))
11878   (clobber (reg:CC FLAGS_REG))]
11879  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11880   && (TARGET_SHIFT1 || optimize_size)"
11881  "shr{q}\t%0"
11882  [(set_attr "type" "ishift")
11883   (set (attr "length") 
11884     (if_then_else (match_operand:DI 0 "register_operand" "") 
11885	(const_string "2")
11886	(const_string "*")))])
11887
11888(define_insn "*lshrdi3_1_rex64"
11889  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11890	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11891		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11892   (clobber (reg:CC FLAGS_REG))]
11893  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894  "@
11895   shr{q}\t{%2, %0|%0, %2}
11896   shr{q}\t{%b2, %0|%0, %b2}"
11897  [(set_attr "type" "ishift")
11898   (set_attr "mode" "DI")])
11899
11900;; This pattern can't accept a variable shift count, since shifts by
11901;; zero don't affect the flags.  We assume that shifts by constant
11902;; zero are optimized away.
11903(define_insn "*lshrdi3_cmp_one_bit_rex64"
11904  [(set (reg FLAGS_REG)
11905	(compare
11906	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11907		       (match_operand:QI 2 "const1_operand" ""))
11908	  (const_int 0)))
11909   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11910	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
11911  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11912   && (TARGET_SHIFT1 || optimize_size)
11913   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11914  "shr{q}\t%0"
11915  [(set_attr "type" "ishift")
11916   (set (attr "length") 
11917     (if_then_else (match_operand:DI 0 "register_operand" "") 
11918	(const_string "2")
11919	(const_string "*")))])
11920
11921(define_insn "*lshrdi3_cconly_one_bit_rex64"
11922  [(set (reg FLAGS_REG)
11923	(compare
11924	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11925		       (match_operand:QI 2 "const1_operand" ""))
11926	  (const_int 0)))
11927   (clobber (match_scratch:DI 0 "=r"))]
11928  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11929   && (TARGET_SHIFT1 || optimize_size)
11930   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11931  "shr{q}\t%0"
11932  [(set_attr "type" "ishift")
11933   (set_attr "length" "2")])
11934
11935;; This pattern can't accept a variable shift count, since shifts by
11936;; zero don't affect the flags.  We assume that shifts by constant
11937;; zero are optimized away.
11938(define_insn "*lshrdi3_cmp_rex64"
11939  [(set (reg FLAGS_REG)
11940	(compare
11941	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11942		       (match_operand:QI 2 "const_int_operand" "e"))
11943	  (const_int 0)))
11944   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11945	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
11946  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11947   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11948  "shr{q}\t{%2, %0|%0, %2}"
11949  [(set_attr "type" "ishift")
11950   (set_attr "mode" "DI")])
11951
11952(define_insn "*lshrdi3_cconly_rex64"
11953  [(set (reg FLAGS_REG)
11954	(compare
11955	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11956		       (match_operand:QI 2 "const_int_operand" "e"))
11957	  (const_int 0)))
11958   (clobber (match_scratch:DI 0 "=r"))]
11959  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11960   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11961  "shr{q}\t{%2, %0|%0, %2}"
11962  [(set_attr "type" "ishift")
11963   (set_attr "mode" "DI")])
11964
11965(define_insn "*lshrdi3_1"
11966  [(set (match_operand:DI 0 "register_operand" "=r")
11967	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11968		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11969   (clobber (reg:CC FLAGS_REG))]
11970  "!TARGET_64BIT"
11971  "#"
11972  [(set_attr "type" "multi")])
11973
11974;; By default we don't ask for a scratch register, because when DImode
11975;; values are manipulated, registers are already at a premium.  But if
11976;; we have one handy, we won't turn it away.
11977(define_peephole2
11978  [(match_scratch:SI 3 "r")
11979   (parallel [(set (match_operand:DI 0 "register_operand" "")
11980		   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11981			        (match_operand:QI 2 "nonmemory_operand" "")))
11982	      (clobber (reg:CC FLAGS_REG))])
11983   (match_dup 3)]
11984  "!TARGET_64BIT && TARGET_CMOVE"
11985  [(const_int 0)]
11986  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11987
11988(define_split 
11989  [(set (match_operand:DI 0 "register_operand" "")
11990	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11991		     (match_operand:QI 2 "nonmemory_operand" "")))
11992   (clobber (reg:CC FLAGS_REG))]
11993  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11994		     ? flow2_completed : reload_completed)"
11995  [(const_int 0)]
11996  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11997
11998(define_expand "lshrsi3"
11999  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12000	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12001		     (match_operand:QI 2 "nonmemory_operand" "")))
12002   (clobber (reg:CC FLAGS_REG))]
12003  ""
12004  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12005
12006(define_insn "*lshrsi3_1_one_bit"
12007  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12008	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12009		     (match_operand:QI 2 "const1_operand" "")))
12010   (clobber (reg:CC FLAGS_REG))]
12011  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12012   && (TARGET_SHIFT1 || optimize_size)"
12013  "shr{l}\t%0"
12014  [(set_attr "type" "ishift")
12015   (set (attr "length") 
12016     (if_then_else (match_operand:SI 0 "register_operand" "") 
12017	(const_string "2")
12018	(const_string "*")))])
12019
12020(define_insn "*lshrsi3_1_one_bit_zext"
12021  [(set (match_operand:DI 0 "register_operand" "=r")
12022	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12023		     (match_operand:QI 2 "const1_operand" "")))
12024   (clobber (reg:CC FLAGS_REG))]
12025  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12026   && (TARGET_SHIFT1 || optimize_size)"
12027  "shr{l}\t%k0"
12028  [(set_attr "type" "ishift")
12029   (set_attr "length" "2")])
12030
12031(define_insn "*lshrsi3_1"
12032  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12033	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12034		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12035   (clobber (reg:CC FLAGS_REG))]
12036  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12037  "@
12038   shr{l}\t{%2, %0|%0, %2}
12039   shr{l}\t{%b2, %0|%0, %b2}"
12040  [(set_attr "type" "ishift")
12041   (set_attr "mode" "SI")])
12042
12043(define_insn "*lshrsi3_1_zext"
12044  [(set (match_operand:DI 0 "register_operand" "=r,r")
12045	(zero_extend:DI
12046	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12047		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12048   (clobber (reg:CC FLAGS_REG))]
12049  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12050  "@
12051   shr{l}\t{%2, %k0|%k0, %2}
12052   shr{l}\t{%b2, %k0|%k0, %b2}"
12053  [(set_attr "type" "ishift")
12054   (set_attr "mode" "SI")])
12055
12056;; This pattern can't accept a variable shift count, since shifts by
12057;; zero don't affect the flags.  We assume that shifts by constant
12058;; zero are optimized away.
12059(define_insn "*lshrsi3_one_bit_cmp"
12060  [(set (reg FLAGS_REG)
12061	(compare
12062	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12063		       (match_operand:QI 2 "const1_operand" ""))
12064	  (const_int 0)))
12065   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12066	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12067  "ix86_match_ccmode (insn, CCGOCmode)
12068   && (TARGET_SHIFT1 || optimize_size)
12069   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12070  "shr{l}\t%0"
12071  [(set_attr "type" "ishift")
12072   (set (attr "length") 
12073     (if_then_else (match_operand:SI 0 "register_operand" "") 
12074	(const_string "2")
12075	(const_string "*")))])
12076
12077(define_insn "*lshrsi3_one_bit_cconly"
12078  [(set (reg FLAGS_REG)
12079	(compare
12080	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12081		       (match_operand:QI 2 "const1_operand" ""))
12082	  (const_int 0)))
12083   (clobber (match_scratch:SI 0 "=r"))]
12084  "ix86_match_ccmode (insn, CCGOCmode)
12085   && (TARGET_SHIFT1 || optimize_size)
12086   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12087  "shr{l}\t%0"
12088  [(set_attr "type" "ishift")
12089   (set_attr "length" "2")])
12090
12091(define_insn "*lshrsi3_cmp_one_bit_zext"
12092  [(set (reg FLAGS_REG)
12093	(compare
12094	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12095		       (match_operand:QI 2 "const1_operand" ""))
12096	  (const_int 0)))
12097   (set (match_operand:DI 0 "register_operand" "=r")
12098	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12099  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12100   && (TARGET_SHIFT1 || optimize_size)
12101   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12102  "shr{l}\t%k0"
12103  [(set_attr "type" "ishift")
12104   (set_attr "length" "2")])
12105
12106;; This pattern can't accept a variable shift count, since shifts by
12107;; zero don't affect the flags.  We assume that shifts by constant
12108;; zero are optimized away.
12109(define_insn "*lshrsi3_cmp"
12110  [(set (reg FLAGS_REG)
12111	(compare
12112	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12113		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12114	  (const_int 0)))
12115   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12116	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12117  "ix86_match_ccmode (insn, CCGOCmode)
12118   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12119  "shr{l}\t{%2, %0|%0, %2}"
12120  [(set_attr "type" "ishift")
12121   (set_attr "mode" "SI")])
12122
12123(define_insn "*lshrsi3_cconly"
12124  [(set (reg FLAGS_REG)
12125      (compare
12126	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12127		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
12128        (const_int 0)))
12129   (clobber (match_scratch:SI 0 "=r"))]
12130  "ix86_match_ccmode (insn, CCGOCmode)
12131   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12132  "shr{l}\t{%2, %0|%0, %2}"
12133  [(set_attr "type" "ishift")
12134   (set_attr "mode" "SI")])
12135
12136(define_insn "*lshrsi3_cmp_zext"
12137  [(set (reg FLAGS_REG)
12138	(compare
12139	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12140		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12141	  (const_int 0)))
12142   (set (match_operand:DI 0 "register_operand" "=r")
12143	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12144  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12145   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12146  "shr{l}\t{%2, %k0|%k0, %2}"
12147  [(set_attr "type" "ishift")
12148   (set_attr "mode" "SI")])
12149
12150(define_expand "lshrhi3"
12151  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12152	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12153		     (match_operand:QI 2 "nonmemory_operand" "")))
12154   (clobber (reg:CC FLAGS_REG))]
12155  "TARGET_HIMODE_MATH"
12156  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12157
12158(define_insn "*lshrhi3_1_one_bit"
12159  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12160	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12161		     (match_operand:QI 2 "const1_operand" "")))
12162   (clobber (reg:CC FLAGS_REG))]
12163  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12164   && (TARGET_SHIFT1 || optimize_size)"
12165  "shr{w}\t%0"
12166  [(set_attr "type" "ishift")
12167   (set (attr "length") 
12168     (if_then_else (match_operand 0 "register_operand" "") 
12169	(const_string "2")
12170	(const_string "*")))])
12171
12172(define_insn "*lshrhi3_1"
12173  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12174	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12175		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12176   (clobber (reg:CC FLAGS_REG))]
12177  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12178  "@
12179   shr{w}\t{%2, %0|%0, %2}
12180   shr{w}\t{%b2, %0|%0, %b2}"
12181  [(set_attr "type" "ishift")
12182   (set_attr "mode" "HI")])
12183
12184;; This pattern can't accept a variable shift count, since shifts by
12185;; zero don't affect the flags.  We assume that shifts by constant
12186;; zero are optimized away.
12187(define_insn "*lshrhi3_one_bit_cmp"
12188  [(set (reg FLAGS_REG)
12189	(compare
12190	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12191		       (match_operand:QI 2 "const1_operand" ""))
12192	  (const_int 0)))
12193   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12194	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12195  "ix86_match_ccmode (insn, CCGOCmode)
12196   && (TARGET_SHIFT1 || optimize_size)
12197   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12198  "shr{w}\t%0"
12199  [(set_attr "type" "ishift")
12200   (set (attr "length") 
12201     (if_then_else (match_operand:SI 0 "register_operand" "") 
12202	(const_string "2")
12203	(const_string "*")))])
12204
12205(define_insn "*lshrhi3_one_bit_cconly"
12206  [(set (reg FLAGS_REG)
12207	(compare
12208	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12209		       (match_operand:QI 2 "const1_operand" ""))
12210	  (const_int 0)))
12211   (clobber (match_scratch:HI 0 "=r"))]
12212  "ix86_match_ccmode (insn, CCGOCmode)
12213   && (TARGET_SHIFT1 || optimize_size)
12214   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12215  "shr{w}\t%0"
12216  [(set_attr "type" "ishift")
12217   (set_attr "length" "2")])
12218
12219;; This pattern can't accept a variable shift count, since shifts by
12220;; zero don't affect the flags.  We assume that shifts by constant
12221;; zero are optimized away.
12222(define_insn "*lshrhi3_cmp"
12223  [(set (reg FLAGS_REG)
12224	(compare
12225	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12226		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12227	  (const_int 0)))
12228   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12229	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12230  "ix86_match_ccmode (insn, CCGOCmode)
12231   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12232  "shr{w}\t{%2, %0|%0, %2}"
12233  [(set_attr "type" "ishift")
12234   (set_attr "mode" "HI")])
12235
12236(define_insn "*lshrhi3_cconly"
12237  [(set (reg FLAGS_REG)
12238	(compare
12239	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12240		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12241	  (const_int 0)))
12242   (clobber (match_scratch:HI 0 "=r"))]
12243  "ix86_match_ccmode (insn, CCGOCmode)
12244   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12245  "shr{w}\t{%2, %0|%0, %2}"
12246  [(set_attr "type" "ishift")
12247   (set_attr "mode" "HI")])
12248
12249(define_expand "lshrqi3"
12250  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12251	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12252		     (match_operand:QI 2 "nonmemory_operand" "")))
12253   (clobber (reg:CC FLAGS_REG))]
12254  "TARGET_QIMODE_MATH"
12255  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12256
12257(define_insn "*lshrqi3_1_one_bit"
12258  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12259	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12260		     (match_operand:QI 2 "const1_operand" "")))
12261   (clobber (reg:CC FLAGS_REG))]
12262  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12263   && (TARGET_SHIFT1 || optimize_size)"
12264  "shr{b}\t%0"
12265  [(set_attr "type" "ishift")
12266   (set (attr "length") 
12267     (if_then_else (match_operand 0 "register_operand" "") 
12268	(const_string "2")
12269	(const_string "*")))])
12270
12271(define_insn "*lshrqi3_1_one_bit_slp"
12272  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12273	(lshiftrt:QI (match_dup 0)
12274		     (match_operand:QI 1 "const1_operand" "")))
12275   (clobber (reg:CC FLAGS_REG))]
12276  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12277   && (TARGET_SHIFT1 || optimize_size)"
12278  "shr{b}\t%0"
12279  [(set_attr "type" "ishift1")
12280   (set (attr "length") 
12281     (if_then_else (match_operand 0 "register_operand" "") 
12282	(const_string "2")
12283	(const_string "*")))])
12284
12285(define_insn "*lshrqi3_1"
12286  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12287	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12288		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12289   (clobber (reg:CC FLAGS_REG))]
12290  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12291  "@
12292   shr{b}\t{%2, %0|%0, %2}
12293   shr{b}\t{%b2, %0|%0, %b2}"
12294  [(set_attr "type" "ishift")
12295   (set_attr "mode" "QI")])
12296
12297(define_insn "*lshrqi3_1_slp"
12298  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12299	(lshiftrt:QI (match_dup 0)
12300		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12301   (clobber (reg:CC FLAGS_REG))]
12302  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12303   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12304  "@
12305   shr{b}\t{%1, %0|%0, %1}
12306   shr{b}\t{%b1, %0|%0, %b1}"
12307  [(set_attr "type" "ishift1")
12308   (set_attr "mode" "QI")])
12309
12310;; This pattern can't accept a variable shift count, since shifts by
12311;; zero don't affect the flags.  We assume that shifts by constant
12312;; zero are optimized away.
12313(define_insn "*lshrqi2_one_bit_cmp"
12314  [(set (reg FLAGS_REG)
12315	(compare
12316	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12317		       (match_operand:QI 2 "const1_operand" ""))
12318	  (const_int 0)))
12319   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12320	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12321  "ix86_match_ccmode (insn, CCGOCmode)
12322   && (TARGET_SHIFT1 || optimize_size)
12323   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12324  "shr{b}\t%0"
12325  [(set_attr "type" "ishift")
12326   (set (attr "length") 
12327     (if_then_else (match_operand:SI 0 "register_operand" "") 
12328	(const_string "2")
12329	(const_string "*")))])
12330
12331(define_insn "*lshrqi2_one_bit_cconly"
12332  [(set (reg FLAGS_REG)
12333	(compare
12334	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12335		       (match_operand:QI 2 "const1_operand" ""))
12336	  (const_int 0)))
12337   (clobber (match_scratch:QI 0 "=q"))]
12338  "ix86_match_ccmode (insn, CCGOCmode)
12339   && (TARGET_SHIFT1 || optimize_size)
12340   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12341  "shr{b}\t%0"
12342  [(set_attr "type" "ishift")
12343   (set_attr "length" "2")])
12344
12345;; This pattern can't accept a variable shift count, since shifts by
12346;; zero don't affect the flags.  We assume that shifts by constant
12347;; zero are optimized away.
12348(define_insn "*lshrqi2_cmp"
12349  [(set (reg FLAGS_REG)
12350	(compare
12351	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12352		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12353	  (const_int 0)))
12354   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12355	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12356  "ix86_match_ccmode (insn, CCGOCmode)
12357   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12358  "shr{b}\t{%2, %0|%0, %2}"
12359  [(set_attr "type" "ishift")
12360   (set_attr "mode" "QI")])
12361
12362(define_insn "*lshrqi2_cconly"
12363  [(set (reg FLAGS_REG)
12364	(compare
12365	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12366		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12367	  (const_int 0)))
12368   (clobber (match_scratch:QI 0 "=q"))]
12369  "ix86_match_ccmode (insn, CCGOCmode)
12370   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12371  "shr{b}\t{%2, %0|%0, %2}"
12372  [(set_attr "type" "ishift")
12373   (set_attr "mode" "QI")])
12374
12375;; Rotate instructions
12376
12377(define_expand "rotldi3"
12378  [(set (match_operand:DI 0 "shiftdi_operand" "")
12379	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12380		   (match_operand:QI 2 "nonmemory_operand" "")))
12381   (clobber (reg:CC FLAGS_REG))]
12382 ""
12383{
12384  if (TARGET_64BIT)
12385    {
12386      ix86_expand_binary_operator (ROTATE, DImode, operands);
12387      DONE;
12388    }
12389  if (!const_1_to_31_operand (operands[2], VOIDmode))
12390    FAIL;
12391  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12392  DONE;
12393})
12394
12395;; Implement rotation using two double-precision shift instructions
12396;; and a scratch register.   
12397(define_insn_and_split "ix86_rotldi3"
12398 [(set (match_operand:DI 0 "register_operand" "=r")
12399       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12400                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12401  (clobber (reg:CC FLAGS_REG))
12402  (clobber (match_scratch:SI 3 "=&r"))]
12403 "!TARGET_64BIT"
12404 "" 
12405 "&& reload_completed"
12406 [(set (match_dup 3) (match_dup 4))
12407  (parallel
12408   [(set (match_dup 4)
12409         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12410                 (lshiftrt:SI (match_dup 5)
12411                              (minus:QI (const_int 32) (match_dup 2)))))
12412    (clobber (reg:CC FLAGS_REG))])
12413  (parallel
12414   [(set (match_dup 5)
12415         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12416                 (lshiftrt:SI (match_dup 3)
12417                              (minus:QI (const_int 32) (match_dup 2)))))
12418    (clobber (reg:CC FLAGS_REG))])]
12419 "split_di (operands, 1, operands + 4, operands + 5);")
12420 
12421(define_insn "*rotlsi3_1_one_bit_rex64"
12422  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12423	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12424		   (match_operand:QI 2 "const1_operand" "")))
12425   (clobber (reg:CC FLAGS_REG))]
12426  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12427   && (TARGET_SHIFT1 || optimize_size)"
12428  "rol{q}\t%0"
12429  [(set_attr "type" "rotate")
12430   (set (attr "length") 
12431     (if_then_else (match_operand:DI 0 "register_operand" "") 
12432	(const_string "2")
12433	(const_string "*")))])
12434
12435(define_insn "*rotldi3_1_rex64"
12436  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12437	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12438		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12439   (clobber (reg:CC FLAGS_REG))]
12440  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12441  "@
12442   rol{q}\t{%2, %0|%0, %2}
12443   rol{q}\t{%b2, %0|%0, %b2}"
12444  [(set_attr "type" "rotate")
12445   (set_attr "mode" "DI")])
12446
12447(define_expand "rotlsi3"
12448  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12449	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12450		   (match_operand:QI 2 "nonmemory_operand" "")))
12451   (clobber (reg:CC FLAGS_REG))]
12452  ""
12453  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12454
12455(define_insn "*rotlsi3_1_one_bit"
12456  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12457	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12458		   (match_operand:QI 2 "const1_operand" "")))
12459   (clobber (reg:CC FLAGS_REG))]
12460  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12461   && (TARGET_SHIFT1 || optimize_size)"
12462  "rol{l}\t%0"
12463  [(set_attr "type" "rotate")
12464   (set (attr "length") 
12465     (if_then_else (match_operand:SI 0 "register_operand" "") 
12466	(const_string "2")
12467	(const_string "*")))])
12468
12469(define_insn "*rotlsi3_1_one_bit_zext"
12470  [(set (match_operand:DI 0 "register_operand" "=r")
12471	(zero_extend:DI
12472	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12473		     (match_operand:QI 2 "const1_operand" ""))))
12474   (clobber (reg:CC FLAGS_REG))]
12475  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12476   && (TARGET_SHIFT1 || optimize_size)"
12477  "rol{l}\t%k0"
12478  [(set_attr "type" "rotate")
12479   (set_attr "length" "2")])
12480
12481(define_insn "*rotlsi3_1"
12482  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12483	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12484		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12485   (clobber (reg:CC FLAGS_REG))]
12486  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12487  "@
12488   rol{l}\t{%2, %0|%0, %2}
12489   rol{l}\t{%b2, %0|%0, %b2}"
12490  [(set_attr "type" "rotate")
12491   (set_attr "mode" "SI")])
12492
12493(define_insn "*rotlsi3_1_zext"
12494  [(set (match_operand:DI 0 "register_operand" "=r,r")
12495	(zero_extend:DI
12496	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12497		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12498   (clobber (reg:CC FLAGS_REG))]
12499  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12500  "@
12501   rol{l}\t{%2, %k0|%k0, %2}
12502   rol{l}\t{%b2, %k0|%k0, %b2}"
12503  [(set_attr "type" "rotate")
12504   (set_attr "mode" "SI")])
12505
12506(define_expand "rotlhi3"
12507  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12508	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12509		   (match_operand:QI 2 "nonmemory_operand" "")))
12510   (clobber (reg:CC FLAGS_REG))]
12511  "TARGET_HIMODE_MATH"
12512  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12513
12514(define_insn "*rotlhi3_1_one_bit"
12515  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12516	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12517		   (match_operand:QI 2 "const1_operand" "")))
12518   (clobber (reg:CC FLAGS_REG))]
12519  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12520   && (TARGET_SHIFT1 || optimize_size)"
12521  "rol{w}\t%0"
12522  [(set_attr "type" "rotate")
12523   (set (attr "length") 
12524     (if_then_else (match_operand 0 "register_operand" "") 
12525	(const_string "2")
12526	(const_string "*")))])
12527
12528(define_insn "*rotlhi3_1"
12529  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12530	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12531		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12532   (clobber (reg:CC FLAGS_REG))]
12533  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12534  "@
12535   rol{w}\t{%2, %0|%0, %2}
12536   rol{w}\t{%b2, %0|%0, %b2}"
12537  [(set_attr "type" "rotate")
12538   (set_attr "mode" "HI")])
12539
12540(define_expand "rotlqi3"
12541  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12542	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12543		   (match_operand:QI 2 "nonmemory_operand" "")))
12544   (clobber (reg:CC FLAGS_REG))]
12545  "TARGET_QIMODE_MATH"
12546  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12547
12548(define_insn "*rotlqi3_1_one_bit_slp"
12549  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12550	(rotate:QI (match_dup 0)
12551		   (match_operand:QI 1 "const1_operand" "")))
12552   (clobber (reg:CC FLAGS_REG))]
12553  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12554   && (TARGET_SHIFT1 || optimize_size)"
12555  "rol{b}\t%0"
12556  [(set_attr "type" "rotate1")
12557   (set (attr "length") 
12558     (if_then_else (match_operand 0 "register_operand" "") 
12559	(const_string "2")
12560	(const_string "*")))])
12561
12562(define_insn "*rotlqi3_1_one_bit"
12563  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12564	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12565		   (match_operand:QI 2 "const1_operand" "")))
12566   (clobber (reg:CC FLAGS_REG))]
12567  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12568   && (TARGET_SHIFT1 || optimize_size)"
12569  "rol{b}\t%0"
12570  [(set_attr "type" "rotate")
12571   (set (attr "length") 
12572     (if_then_else (match_operand 0 "register_operand" "") 
12573	(const_string "2")
12574	(const_string "*")))])
12575
12576(define_insn "*rotlqi3_1_slp"
12577  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12578	(rotate:QI (match_dup 0)
12579		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12580   (clobber (reg:CC FLAGS_REG))]
12581  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12582   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12583  "@
12584   rol{b}\t{%1, %0|%0, %1}
12585   rol{b}\t{%b1, %0|%0, %b1}"
12586  [(set_attr "type" "rotate1")
12587   (set_attr "mode" "QI")])
12588
12589(define_insn "*rotlqi3_1"
12590  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12591	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12592		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12593   (clobber (reg:CC FLAGS_REG))]
12594  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12595  "@
12596   rol{b}\t{%2, %0|%0, %2}
12597   rol{b}\t{%b2, %0|%0, %b2}"
12598  [(set_attr "type" "rotate")
12599   (set_attr "mode" "QI")])
12600
12601(define_expand "rotrdi3"
12602  [(set (match_operand:DI 0 "shiftdi_operand" "")
12603	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12604		   (match_operand:QI 2 "nonmemory_operand" "")))
12605   (clobber (reg:CC FLAGS_REG))]
12606 ""
12607{
12608  if (TARGET_64BIT)
12609    {
12610      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12611      DONE;
12612    }
12613  if (!const_1_to_31_operand (operands[2], VOIDmode))
12614    FAIL;
12615  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12616  DONE;
12617})
12618  
12619;; Implement rotation using two double-precision shift instructions
12620;; and a scratch register.   
12621(define_insn_and_split "ix86_rotrdi3"
12622 [(set (match_operand:DI 0 "register_operand" "=r")
12623       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12624                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12625  (clobber (reg:CC FLAGS_REG))
12626  (clobber (match_scratch:SI 3 "=&r"))]
12627 "!TARGET_64BIT"
12628 ""
12629 "&& reload_completed"
12630 [(set (match_dup 3) (match_dup 4))
12631  (parallel
12632   [(set (match_dup 4)
12633         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12634                 (ashift:SI (match_dup 5)
12635                            (minus:QI (const_int 32) (match_dup 2)))))
12636    (clobber (reg:CC FLAGS_REG))])
12637  (parallel
12638   [(set (match_dup 5)
12639         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12640                 (ashift:SI (match_dup 3)
12641                            (minus:QI (const_int 32) (match_dup 2)))))
12642    (clobber (reg:CC FLAGS_REG))])]
12643 "split_di (operands, 1, operands + 4, operands + 5);")
12644
12645(define_insn "*rotrdi3_1_one_bit_rex64"
12646  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12647	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12648		     (match_operand:QI 2 "const1_operand" "")))
12649   (clobber (reg:CC FLAGS_REG))]
12650  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12651   && (TARGET_SHIFT1 || optimize_size)"
12652  "ror{q}\t%0"
12653  [(set_attr "type" "rotate")
12654   (set (attr "length") 
12655     (if_then_else (match_operand:DI 0 "register_operand" "") 
12656	(const_string "2")
12657	(const_string "*")))])
12658
12659(define_insn "*rotrdi3_1_rex64"
12660  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12661	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12662		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12663   (clobber (reg:CC FLAGS_REG))]
12664  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12665  "@
12666   ror{q}\t{%2, %0|%0, %2}
12667   ror{q}\t{%b2, %0|%0, %b2}"
12668  [(set_attr "type" "rotate")
12669   (set_attr "mode" "DI")])
12670
12671(define_expand "rotrsi3"
12672  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12673	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12674		     (match_operand:QI 2 "nonmemory_operand" "")))
12675   (clobber (reg:CC FLAGS_REG))]
12676  ""
12677  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12678
12679(define_insn "*rotrsi3_1_one_bit"
12680  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12681	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12682		     (match_operand:QI 2 "const1_operand" "")))
12683   (clobber (reg:CC FLAGS_REG))]
12684  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12685   && (TARGET_SHIFT1 || optimize_size)"
12686  "ror{l}\t%0"
12687  [(set_attr "type" "rotate")
12688   (set (attr "length") 
12689     (if_then_else (match_operand:SI 0 "register_operand" "") 
12690	(const_string "2")
12691	(const_string "*")))])
12692
12693(define_insn "*rotrsi3_1_one_bit_zext"
12694  [(set (match_operand:DI 0 "register_operand" "=r")
12695	(zero_extend:DI
12696	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12697		       (match_operand:QI 2 "const1_operand" ""))))
12698   (clobber (reg:CC FLAGS_REG))]
12699  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12700   && (TARGET_SHIFT1 || optimize_size)"
12701  "ror{l}\t%k0"
12702  [(set_attr "type" "rotate")
12703   (set (attr "length") 
12704     (if_then_else (match_operand:SI 0 "register_operand" "") 
12705	(const_string "2")
12706	(const_string "*")))])
12707
12708(define_insn "*rotrsi3_1"
12709  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12710	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12711		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12712   (clobber (reg:CC FLAGS_REG))]
12713  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12714  "@
12715   ror{l}\t{%2, %0|%0, %2}
12716   ror{l}\t{%b2, %0|%0, %b2}"
12717  [(set_attr "type" "rotate")
12718   (set_attr "mode" "SI")])
12719
12720(define_insn "*rotrsi3_1_zext"
12721  [(set (match_operand:DI 0 "register_operand" "=r,r")
12722	(zero_extend:DI
12723	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12724		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12725   (clobber (reg:CC FLAGS_REG))]
12726  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12727  "@
12728   ror{l}\t{%2, %k0|%k0, %2}
12729   ror{l}\t{%b2, %k0|%k0, %b2}"
12730  [(set_attr "type" "rotate")
12731   (set_attr "mode" "SI")])
12732
12733(define_expand "rotrhi3"
12734  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12735	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12736		     (match_operand:QI 2 "nonmemory_operand" "")))
12737   (clobber (reg:CC FLAGS_REG))]
12738  "TARGET_HIMODE_MATH"
12739  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12740
12741(define_insn "*rotrhi3_one_bit"
12742  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12743	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12744		     (match_operand:QI 2 "const1_operand" "")))
12745   (clobber (reg:CC FLAGS_REG))]
12746  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12747   && (TARGET_SHIFT1 || optimize_size)"
12748  "ror{w}\t%0"
12749  [(set_attr "type" "rotate")
12750   (set (attr "length") 
12751     (if_then_else (match_operand 0 "register_operand" "") 
12752	(const_string "2")
12753	(const_string "*")))])
12754
12755(define_insn "*rotrhi3"
12756  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12757	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12758		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12759   (clobber (reg:CC FLAGS_REG))]
12760  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12761  "@
12762   ror{w}\t{%2, %0|%0, %2}
12763   ror{w}\t{%b2, %0|%0, %b2}"
12764  [(set_attr "type" "rotate")
12765   (set_attr "mode" "HI")])
12766
12767(define_expand "rotrqi3"
12768  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12769	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12770		     (match_operand:QI 2 "nonmemory_operand" "")))
12771   (clobber (reg:CC FLAGS_REG))]
12772  "TARGET_QIMODE_MATH"
12773  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12774
12775(define_insn "*rotrqi3_1_one_bit"
12776  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12778		     (match_operand:QI 2 "const1_operand" "")))
12779   (clobber (reg:CC FLAGS_REG))]
12780  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12781   && (TARGET_SHIFT1 || optimize_size)"
12782  "ror{b}\t%0"
12783  [(set_attr "type" "rotate")
12784   (set (attr "length") 
12785     (if_then_else (match_operand 0 "register_operand" "") 
12786	(const_string "2")
12787	(const_string "*")))])
12788
12789(define_insn "*rotrqi3_1_one_bit_slp"
12790  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12791	(rotatert:QI (match_dup 0)
12792		     (match_operand:QI 1 "const1_operand" "")))
12793   (clobber (reg:CC FLAGS_REG))]
12794  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12795   && (TARGET_SHIFT1 || optimize_size)"
12796  "ror{b}\t%0"
12797  [(set_attr "type" "rotate1")
12798   (set (attr "length") 
12799     (if_then_else (match_operand 0 "register_operand" "") 
12800	(const_string "2")
12801	(const_string "*")))])
12802
12803(define_insn "*rotrqi3_1"
12804  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12805	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12806		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12807   (clobber (reg:CC FLAGS_REG))]
12808  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12809  "@
12810   ror{b}\t{%2, %0|%0, %2}
12811   ror{b}\t{%b2, %0|%0, %b2}"
12812  [(set_attr "type" "rotate")
12813   (set_attr "mode" "QI")])
12814
12815(define_insn "*rotrqi3_1_slp"
12816  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12817	(rotatert:QI (match_dup 0)
12818		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12819   (clobber (reg:CC FLAGS_REG))]
12820  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12821   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12822  "@
12823   ror{b}\t{%1, %0|%0, %1}
12824   ror{b}\t{%b1, %0|%0, %b1}"
12825  [(set_attr "type" "rotate1")
12826   (set_attr "mode" "QI")])
12827
12828;; Bit set / bit test instructions
12829
12830(define_expand "extv"
12831  [(set (match_operand:SI 0 "register_operand" "")
12832	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
12833			 (match_operand:SI 2 "const8_operand" "")
12834			 (match_operand:SI 3 "const8_operand" "")))]
12835  ""
12836{
12837  /* Handle extractions from %ah et al.  */
12838  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12839    FAIL;
12840
12841  /* From mips.md: extract_bit_field doesn't verify that our source
12842     matches the predicate, so check it again here.  */
12843  if (! ext_register_operand (operands[1], VOIDmode))
12844    FAIL;
12845})
12846
12847(define_expand "extzv"
12848  [(set (match_operand:SI 0 "register_operand" "")
12849	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
12850			 (match_operand:SI 2 "const8_operand" "")
12851			 (match_operand:SI 3 "const8_operand" "")))]
12852  ""
12853{
12854  /* Handle extractions from %ah et al.  */
12855  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12856    FAIL;
12857
12858  /* From mips.md: extract_bit_field doesn't verify that our source
12859     matches the predicate, so check it again here.  */
12860  if (! ext_register_operand (operands[1], VOIDmode))
12861    FAIL;
12862})
12863
12864(define_expand "insv"
12865  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12866		      (match_operand 1 "const8_operand" "")
12867		      (match_operand 2 "const8_operand" ""))
12868        (match_operand 3 "register_operand" ""))]
12869  ""
12870{
12871  /* Handle insertions to %ah et al.  */
12872  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12873    FAIL;
12874
12875  /* From mips.md: insert_bit_field doesn't verify that our source
12876     matches the predicate, so check it again here.  */
12877  if (! ext_register_operand (operands[0], VOIDmode))
12878    FAIL;
12879
12880  if (TARGET_64BIT)
12881    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12882  else
12883    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12884
12885  DONE;
12886})
12887
12888;; %%% bts, btr, btc, bt.
12889;; In general these instructions are *slow* when applied to memory,
12890;; since they enforce atomic operation.  When applied to registers,
12891;; it depends on the cpu implementation.  They're never faster than
12892;; the corresponding and/ior/xor operations, so with 32-bit there's
12893;; no point.  But in 64-bit, we can't hold the relevant immediates
12894;; within the instruction itself, so operating on bits in the high
12895;; 32-bits of a register becomes easier.
12896;;
12897;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12898;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12899;; negdf respectively, so they can never be disabled entirely.
12900
12901(define_insn "*btsq"
12902  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12903			 (const_int 1)
12904			 (match_operand:DI 1 "const_0_to_63_operand" ""))
12905	(const_int 1))
12906   (clobber (reg:CC FLAGS_REG))]
12907  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12908  "bts{q} %1,%0"
12909  [(set_attr "type" "alu1")])
12910
12911(define_insn "*btrq"
12912  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12913			 (const_int 1)
12914			 (match_operand:DI 1 "const_0_to_63_operand" ""))
12915	(const_int 0))
12916   (clobber (reg:CC FLAGS_REG))]
12917  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12918  "btr{q} %1,%0"
12919  [(set_attr "type" "alu1")])
12920
12921(define_insn "*btcq"
12922  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12923			 (const_int 1)
12924			 (match_operand:DI 1 "const_0_to_63_operand" ""))
12925	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12926   (clobber (reg:CC FLAGS_REG))]
12927  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12928  "btc{q} %1,%0"
12929  [(set_attr "type" "alu1")])
12930
12931;; Allow Nocona to avoid these instructions if a register is available.
12932
12933(define_peephole2
12934  [(match_scratch:DI 2 "r")
12935   (parallel [(set (zero_extract:DI
12936		     (match_operand:DI 0 "register_operand" "")
12937		     (const_int 1)
12938		     (match_operand:DI 1 "const_0_to_63_operand" ""))
12939		   (const_int 1))
12940	      (clobber (reg:CC FLAGS_REG))])]
12941  "TARGET_64BIT && !TARGET_USE_BT"
12942  [(const_int 0)]
12943{
12944  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12945  rtx op1;
12946
12947  if (HOST_BITS_PER_WIDE_INT >= 64)
12948    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12949  else if (i < HOST_BITS_PER_WIDE_INT)
12950    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12951  else
12952    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12953
12954  op1 = immed_double_const (lo, hi, DImode);
12955  if (i >= 31)
12956    {
12957      emit_move_insn (operands[2], op1);
12958      op1 = operands[2];
12959    }
12960
12961  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12962  DONE;
12963})
12964
12965(define_peephole2
12966  [(match_scratch:DI 2 "r")
12967   (parallel [(set (zero_extract:DI
12968		     (match_operand:DI 0 "register_operand" "")
12969		     (const_int 1)
12970		     (match_operand:DI 1 "const_0_to_63_operand" ""))
12971		   (const_int 0))
12972	      (clobber (reg:CC FLAGS_REG))])]
12973  "TARGET_64BIT && !TARGET_USE_BT"
12974  [(const_int 0)]
12975{
12976  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12977  rtx op1;
12978
12979  if (HOST_BITS_PER_WIDE_INT >= 64)
12980    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12981  else if (i < HOST_BITS_PER_WIDE_INT)
12982    lo = (HOST_WIDE_INT)1 << i, hi = 0;
12983  else
12984    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12985
12986  op1 = immed_double_const (~lo, ~hi, DImode);
12987  if (i >= 32)
12988    {
12989      emit_move_insn (operands[2], op1);
12990      op1 = operands[2];
12991    }
12992
12993  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12994  DONE;
12995})
12996
12997(define_peephole2
12998  [(match_scratch:DI 2 "r")
12999   (parallel [(set (zero_extract:DI
13000		     (match_operand:DI 0 "register_operand" "")
13001		     (const_int 1)
13002		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13003	      (not:DI (zero_extract:DI
13004			(match_dup 0) (const_int 1) (match_dup 1))))
13005	      (clobber (reg:CC FLAGS_REG))])]
13006  "TARGET_64BIT && !TARGET_USE_BT"
13007  [(const_int 0)]
13008{
13009  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13010  rtx op1;
13011
13012  if (HOST_BITS_PER_WIDE_INT >= 64)
13013    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13014  else if (i < HOST_BITS_PER_WIDE_INT)
13015    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13016  else
13017    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13018
13019  op1 = immed_double_const (lo, hi, DImode);
13020  if (i >= 31)
13021    {
13022      emit_move_insn (operands[2], op1);
13023      op1 = operands[2];
13024    }
13025
13026  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13027  DONE;
13028})
13029
13030;; Store-flag instructions.
13031
13032;; For all sCOND expanders, also expand the compare or test insn that
13033;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13034
13035;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13036;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13037;; way, which can later delete the movzx if only QImode is needed.
13038
13039(define_expand "seq"
13040  [(set (match_operand:QI 0 "register_operand" "")
13041        (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13042  ""
13043  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13044
13045(define_expand "sne"
13046  [(set (match_operand:QI 0 "register_operand" "")
13047        (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13048  ""
13049  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13050
13051(define_expand "sgt"
13052  [(set (match_operand:QI 0 "register_operand" "")
13053        (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13054  ""
13055  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13056
13057(define_expand "sgtu"
13058  [(set (match_operand:QI 0 "register_operand" "")
13059        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13060  ""
13061  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13062
13063(define_expand "slt"
13064  [(set (match_operand:QI 0 "register_operand" "")
13065        (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13066  ""
13067  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13068
13069(define_expand "sltu"
13070  [(set (match_operand:QI 0 "register_operand" "")
13071        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13072  ""
13073  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13074
13075(define_expand "sge"
13076  [(set (match_operand:QI 0 "register_operand" "")
13077        (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13078  ""
13079  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13080
13081(define_expand "sgeu"
13082  [(set (match_operand:QI 0 "register_operand" "")
13083        (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13084  ""
13085  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13086
13087(define_expand "sle"
13088  [(set (match_operand:QI 0 "register_operand" "")
13089        (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13090  ""
13091  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13092
13093(define_expand "sleu"
13094  [(set (match_operand:QI 0 "register_operand" "")
13095        (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13096  ""
13097  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13098
13099(define_expand "sunordered"
13100  [(set (match_operand:QI 0 "register_operand" "")
13101        (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13102  "TARGET_80387 || TARGET_SSE"
13103  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13104
13105(define_expand "sordered"
13106  [(set (match_operand:QI 0 "register_operand" "")
13107        (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13108  "TARGET_80387"
13109  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13110
13111(define_expand "suneq"
13112  [(set (match_operand:QI 0 "register_operand" "")
13113        (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13114  "TARGET_80387 || TARGET_SSE"
13115  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13116
13117(define_expand "sunge"
13118  [(set (match_operand:QI 0 "register_operand" "")
13119        (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13120  "TARGET_80387 || TARGET_SSE"
13121  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13122
13123(define_expand "sungt"
13124  [(set (match_operand:QI 0 "register_operand" "")
13125        (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13126  "TARGET_80387 || TARGET_SSE"
13127  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13128
13129(define_expand "sunle"
13130  [(set (match_operand:QI 0 "register_operand" "")
13131        (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13132  "TARGET_80387 || TARGET_SSE"
13133  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13134
13135(define_expand "sunlt"
13136  [(set (match_operand:QI 0 "register_operand" "")
13137        (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13138  "TARGET_80387 || TARGET_SSE"
13139  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13140
13141(define_expand "sltgt"
13142  [(set (match_operand:QI 0 "register_operand" "")
13143        (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13144  "TARGET_80387 || TARGET_SSE"
13145  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13146
13147(define_insn "*setcc_1"
13148  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13149	(match_operator:QI 1 "ix86_comparison_operator"
13150	  [(reg FLAGS_REG) (const_int 0)]))]
13151  ""
13152  "set%C1\t%0"
13153  [(set_attr "type" "setcc")
13154   (set_attr "mode" "QI")])
13155
13156(define_insn "*setcc_2"
13157  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13158	(match_operator:QI 1 "ix86_comparison_operator"
13159	  [(reg FLAGS_REG) (const_int 0)]))]
13160  ""
13161  "set%C1\t%0"
13162  [(set_attr "type" "setcc")
13163   (set_attr "mode" "QI")])
13164
13165;; In general it is not safe to assume too much about CCmode registers,
13166;; so simplify-rtx stops when it sees a second one.  Under certain 
13167;; conditions this is safe on x86, so help combine not create
13168;;
13169;;	seta	%al
13170;;	testb	%al, %al
13171;;	sete	%al
13172
13173(define_split 
13174  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13175	(ne:QI (match_operator 1 "ix86_comparison_operator"
13176	         [(reg FLAGS_REG) (const_int 0)])
13177	    (const_int 0)))]
13178  ""
13179  [(set (match_dup 0) (match_dup 1))]
13180{
13181  PUT_MODE (operands[1], QImode);
13182})
13183
13184(define_split 
13185  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13186	(ne:QI (match_operator 1 "ix86_comparison_operator"
13187	         [(reg FLAGS_REG) (const_int 0)])
13188	    (const_int 0)))]
13189  ""
13190  [(set (match_dup 0) (match_dup 1))]
13191{
13192  PUT_MODE (operands[1], QImode);
13193})
13194
13195(define_split 
13196  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13197	(eq:QI (match_operator 1 "ix86_comparison_operator"
13198	         [(reg FLAGS_REG) (const_int 0)])
13199	    (const_int 0)))]
13200  ""
13201  [(set (match_dup 0) (match_dup 1))]
13202{
13203  rtx new_op1 = copy_rtx (operands[1]);
13204  operands[1] = new_op1;
13205  PUT_MODE (new_op1, QImode);
13206  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13207					     GET_MODE (XEXP (new_op1, 0))));
13208
13209  /* Make sure that (a) the CCmode we have for the flags is strong
13210     enough for the reversed compare or (b) we have a valid FP compare.  */
13211  if (! ix86_comparison_operator (new_op1, VOIDmode))
13212    FAIL;
13213})
13214
13215(define_split 
13216  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13217	(eq:QI (match_operator 1 "ix86_comparison_operator"
13218	         [(reg FLAGS_REG) (const_int 0)])
13219	    (const_int 0)))]
13220  ""
13221  [(set (match_dup 0) (match_dup 1))]
13222{
13223  rtx new_op1 = copy_rtx (operands[1]);
13224  operands[1] = new_op1;
13225  PUT_MODE (new_op1, QImode);
13226  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13227					     GET_MODE (XEXP (new_op1, 0))));
13228
13229  /* Make sure that (a) the CCmode we have for the flags is strong
13230     enough for the reversed compare or (b) we have a valid FP compare.  */
13231  if (! ix86_comparison_operator (new_op1, VOIDmode))
13232    FAIL;
13233})
13234
13235;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13236;; subsequent logical operations are used to imitate conditional moves.
13237;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13238;; it directly.
13239
13240(define_insn "*sse_setccsf"
13241  [(set (match_operand:SF 0 "register_operand" "=x")
13242	(match_operator:SF 1 "sse_comparison_operator"
13243	  [(match_operand:SF 2 "register_operand" "0")
13244	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13245  "TARGET_SSE"
13246  "cmp%D1ss\t{%3, %0|%0, %3}"
13247  [(set_attr "type" "ssecmp")
13248   (set_attr "mode" "SF")])
13249
13250(define_insn "*sse_setccdf"
13251  [(set (match_operand:DF 0 "register_operand" "=Y")
13252	(match_operator:DF 1 "sse_comparison_operator"
13253	  [(match_operand:DF 2 "register_operand" "0")
13254	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13255  "TARGET_SSE2"
13256  "cmp%D1sd\t{%3, %0|%0, %3}"
13257  [(set_attr "type" "ssecmp")
13258   (set_attr "mode" "DF")])
13259
13260;; Basic conditional jump instructions.
13261;; We ignore the overflow flag for signed branch instructions.
13262
13263;; For all bCOND expanders, also expand the compare or test insn that
13264;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13265
13266(define_expand "beq"
13267  [(set (pc)
13268	(if_then_else (match_dup 1)
13269		      (label_ref (match_operand 0 "" ""))
13270		      (pc)))]
13271  ""
13272  "ix86_expand_branch (EQ, operands[0]); DONE;")
13273
13274(define_expand "bne"
13275  [(set (pc)
13276	(if_then_else (match_dup 1)
13277		      (label_ref (match_operand 0 "" ""))
13278		      (pc)))]
13279  ""
13280  "ix86_expand_branch (NE, operands[0]); DONE;")
13281
13282(define_expand "bgt"
13283  [(set (pc)
13284	(if_then_else (match_dup 1)
13285		      (label_ref (match_operand 0 "" ""))
13286		      (pc)))]
13287  ""
13288  "ix86_expand_branch (GT, operands[0]); DONE;")
13289
13290(define_expand "bgtu"
13291  [(set (pc)
13292	(if_then_else (match_dup 1)
13293		      (label_ref (match_operand 0 "" ""))
13294		      (pc)))]
13295  ""
13296  "ix86_expand_branch (GTU, operands[0]); DONE;")
13297
13298(define_expand "blt"
13299  [(set (pc)
13300	(if_then_else (match_dup 1)
13301		      (label_ref (match_operand 0 "" ""))
13302		      (pc)))]
13303  ""
13304  "ix86_expand_branch (LT, operands[0]); DONE;")
13305
13306(define_expand "bltu"
13307  [(set (pc)
13308	(if_then_else (match_dup 1)
13309		      (label_ref (match_operand 0 "" ""))
13310		      (pc)))]
13311  ""
13312  "ix86_expand_branch (LTU, operands[0]); DONE;")
13313
13314(define_expand "bge"
13315  [(set (pc)
13316	(if_then_else (match_dup 1)
13317		      (label_ref (match_operand 0 "" ""))
13318		      (pc)))]
13319  ""
13320  "ix86_expand_branch (GE, operands[0]); DONE;")
13321
13322(define_expand "bgeu"
13323  [(set (pc)
13324	(if_then_else (match_dup 1)
13325		      (label_ref (match_operand 0 "" ""))
13326		      (pc)))]
13327  ""
13328  "ix86_expand_branch (GEU, operands[0]); DONE;")
13329
13330(define_expand "ble"
13331  [(set (pc)
13332	(if_then_else (match_dup 1)
13333		      (label_ref (match_operand 0 "" ""))
13334		      (pc)))]
13335  ""
13336  "ix86_expand_branch (LE, operands[0]); DONE;")
13337
13338(define_expand "bleu"
13339  [(set (pc)
13340	(if_then_else (match_dup 1)
13341		      (label_ref (match_operand 0 "" ""))
13342		      (pc)))]
13343  ""
13344  "ix86_expand_branch (LEU, operands[0]); DONE;")
13345
13346(define_expand "bunordered"
13347  [(set (pc)
13348	(if_then_else (match_dup 1)
13349		      (label_ref (match_operand 0 "" ""))
13350		      (pc)))]
13351  "TARGET_80387 || TARGET_SSE_MATH"
13352  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13353
13354(define_expand "bordered"
13355  [(set (pc)
13356	(if_then_else (match_dup 1)
13357		      (label_ref (match_operand 0 "" ""))
13358		      (pc)))]
13359  "TARGET_80387 || TARGET_SSE_MATH"
13360  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13361
13362(define_expand "buneq"
13363  [(set (pc)
13364	(if_then_else (match_dup 1)
13365		      (label_ref (match_operand 0 "" ""))
13366		      (pc)))]
13367  "TARGET_80387 || TARGET_SSE_MATH"
13368  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13369
13370(define_expand "bunge"
13371  [(set (pc)
13372	(if_then_else (match_dup 1)
13373		      (label_ref (match_operand 0 "" ""))
13374		      (pc)))]
13375  "TARGET_80387 || TARGET_SSE_MATH"
13376  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13377
13378(define_expand "bungt"
13379  [(set (pc)
13380	(if_then_else (match_dup 1)
13381		      (label_ref (match_operand 0 "" ""))
13382		      (pc)))]
13383  "TARGET_80387 || TARGET_SSE_MATH"
13384  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13385
13386(define_expand "bunle"
13387  [(set (pc)
13388	(if_then_else (match_dup 1)
13389		      (label_ref (match_operand 0 "" ""))
13390		      (pc)))]
13391  "TARGET_80387 || TARGET_SSE_MATH"
13392  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13393
13394(define_expand "bunlt"
13395  [(set (pc)
13396	(if_then_else (match_dup 1)
13397		      (label_ref (match_operand 0 "" ""))
13398		      (pc)))]
13399  "TARGET_80387 || TARGET_SSE_MATH"
13400  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13401
13402(define_expand "bltgt"
13403  [(set (pc)
13404	(if_then_else (match_dup 1)
13405		      (label_ref (match_operand 0 "" ""))
13406		      (pc)))]
13407  "TARGET_80387 || TARGET_SSE_MATH"
13408  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13409
13410(define_insn "*jcc_1"
13411  [(set (pc)
13412	(if_then_else (match_operator 1 "ix86_comparison_operator"
13413				      [(reg FLAGS_REG) (const_int 0)])
13414		      (label_ref (match_operand 0 "" ""))
13415		      (pc)))]
13416  ""
13417  "%+j%C1\t%l0"
13418  [(set_attr "type" "ibr")
13419   (set_attr "modrm" "0")
13420   (set (attr "length")
13421	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13422				  (const_int -126))
13423			      (lt (minus (match_dup 0) (pc))
13424				  (const_int 128)))
13425	     (const_int 2)
13426	     (const_int 6)))])
13427
13428(define_insn "*jcc_2"
13429  [(set (pc)
13430	(if_then_else (match_operator 1 "ix86_comparison_operator"
13431				      [(reg FLAGS_REG) (const_int 0)])
13432		      (pc)
13433		      (label_ref (match_operand 0 "" ""))))]
13434  ""
13435  "%+j%c1\t%l0"
13436  [(set_attr "type" "ibr")
13437   (set_attr "modrm" "0")
13438   (set (attr "length")
13439	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13440				  (const_int -126))
13441			      (lt (minus (match_dup 0) (pc))
13442				  (const_int 128)))
13443	     (const_int 2)
13444	     (const_int 6)))])
13445
13446;; In general it is not safe to assume too much about CCmode registers,
13447;; so simplify-rtx stops when it sees a second one.  Under certain 
13448;; conditions this is safe on x86, so help combine not create
13449;;
13450;;	seta	%al
13451;;	testb	%al, %al
13452;;	je	Lfoo
13453
13454(define_split 
13455  [(set (pc)
13456	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13457				      [(reg FLAGS_REG) (const_int 0)])
13458			  (const_int 0))
13459		      (label_ref (match_operand 1 "" ""))
13460		      (pc)))]
13461  ""
13462  [(set (pc)
13463	(if_then_else (match_dup 0)
13464		      (label_ref (match_dup 1))
13465		      (pc)))]
13466{
13467  PUT_MODE (operands[0], VOIDmode);
13468})
13469  
13470(define_split 
13471  [(set (pc)
13472	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13473				      [(reg FLAGS_REG) (const_int 0)])
13474			  (const_int 0))
13475		      (label_ref (match_operand 1 "" ""))
13476		      (pc)))]
13477  ""
13478  [(set (pc)
13479	(if_then_else (match_dup 0)
13480		      (label_ref (match_dup 1))
13481		      (pc)))]
13482{
13483  rtx new_op0 = copy_rtx (operands[0]);
13484  operands[0] = new_op0;
13485  PUT_MODE (new_op0, VOIDmode);
13486  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13487					     GET_MODE (XEXP (new_op0, 0))));
13488
13489  /* Make sure that (a) the CCmode we have for the flags is strong
13490     enough for the reversed compare or (b) we have a valid FP compare.  */
13491  if (! ix86_comparison_operator (new_op0, VOIDmode))
13492    FAIL;
13493})
13494
13495;; Define combination compare-and-branch fp compare instructions to use
13496;; during early optimization.  Splitting the operation apart early makes
13497;; for bad code when we want to reverse the operation.
13498
13499(define_insn "*fp_jcc_1_mixed"
13500  [(set (pc)
13501	(if_then_else (match_operator 0 "comparison_operator"
13502			[(match_operand 1 "register_operand" "f#x,x#f")
13503			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13504	  (label_ref (match_operand 3 "" ""))
13505	  (pc)))
13506   (clobber (reg:CCFP FPSR_REG))
13507   (clobber (reg:CCFP FLAGS_REG))]
13508  "TARGET_MIX_SSE_I387
13509   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13510   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13511   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13512  "#")
13513
13514(define_insn "*fp_jcc_1_sse"
13515  [(set (pc)
13516	(if_then_else (match_operator 0 "comparison_operator"
13517			[(match_operand 1 "register_operand" "x")
13518			 (match_operand 2 "nonimmediate_operand" "xm")])
13519	  (label_ref (match_operand 3 "" ""))
13520	  (pc)))
13521   (clobber (reg:CCFP FPSR_REG))
13522   (clobber (reg:CCFP FLAGS_REG))]
13523  "TARGET_SSE_MATH
13524   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13525   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13526   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13527  "#")
13528
13529(define_insn "*fp_jcc_1_387"
13530  [(set (pc)
13531	(if_then_else (match_operator 0 "comparison_operator"
13532			[(match_operand 1 "register_operand" "f")
13533			 (match_operand 2 "register_operand" "f")])
13534	  (label_ref (match_operand 3 "" ""))
13535	  (pc)))
13536   (clobber (reg:CCFP FPSR_REG))
13537   (clobber (reg:CCFP FLAGS_REG))]
13538  "TARGET_CMOVE && TARGET_80387
13539   && FLOAT_MODE_P (GET_MODE (operands[1]))
13540   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13541   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13542  "#")
13543
13544(define_insn "*fp_jcc_2_mixed"
13545  [(set (pc)
13546	(if_then_else (match_operator 0 "comparison_operator"
13547			[(match_operand 1 "register_operand" "f#x,x#f")
13548			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13549	  (pc)
13550	  (label_ref (match_operand 3 "" ""))))
13551   (clobber (reg:CCFP FPSR_REG))
13552   (clobber (reg:CCFP FLAGS_REG))]
13553  "TARGET_MIX_SSE_I387
13554   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13555   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13556   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13557  "#")
13558
13559(define_insn "*fp_jcc_2_sse"
13560  [(set (pc)
13561	(if_then_else (match_operator 0 "comparison_operator"
13562			[(match_operand 1 "register_operand" "x")
13563			 (match_operand 2 "nonimmediate_operand" "xm")])
13564	  (pc)
13565	  (label_ref (match_operand 3 "" ""))))
13566   (clobber (reg:CCFP FPSR_REG))
13567   (clobber (reg:CCFP FLAGS_REG))]
13568  "TARGET_SSE_MATH
13569   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13570   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13571   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13572  "#")
13573
13574(define_insn "*fp_jcc_2_387"
13575  [(set (pc)
13576	(if_then_else (match_operator 0 "comparison_operator"
13577			[(match_operand 1 "register_operand" "f")
13578			 (match_operand 2 "register_operand" "f")])
13579	  (pc)
13580	  (label_ref (match_operand 3 "" ""))))
13581   (clobber (reg:CCFP FPSR_REG))
13582   (clobber (reg:CCFP FLAGS_REG))]
13583  "TARGET_CMOVE && TARGET_80387
13584   && FLOAT_MODE_P (GET_MODE (operands[1]))
13585   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13586   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13587  "#")
13588
13589(define_insn "*fp_jcc_3_387"
13590  [(set (pc)
13591	(if_then_else (match_operator 0 "comparison_operator"
13592			[(match_operand 1 "register_operand" "f")
13593			 (match_operand 2 "nonimmediate_operand" "fm")])
13594	  (label_ref (match_operand 3 "" ""))
13595	  (pc)))
13596   (clobber (reg:CCFP FPSR_REG))
13597   (clobber (reg:CCFP FLAGS_REG))
13598   (clobber (match_scratch:HI 4 "=a"))]
13599  "TARGET_80387
13600   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13601   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13602   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13603   && SELECT_CC_MODE (GET_CODE (operands[0]),
13604		      operands[1], operands[2]) == CCFPmode
13605   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13606  "#")
13607
13608(define_insn "*fp_jcc_4_387"
13609  [(set (pc)
13610	(if_then_else (match_operator 0 "comparison_operator"
13611			[(match_operand 1 "register_operand" "f")
13612			 (match_operand 2 "nonimmediate_operand" "fm")])
13613	  (pc)
13614	  (label_ref (match_operand 3 "" ""))))
13615   (clobber (reg:CCFP FPSR_REG))
13616   (clobber (reg:CCFP FLAGS_REG))
13617   (clobber (match_scratch:HI 4 "=a"))]
13618  "TARGET_80387
13619   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13620   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13621   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13622   && SELECT_CC_MODE (GET_CODE (operands[0]),
13623		      operands[1], operands[2]) == CCFPmode
13624   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13625  "#")
13626
13627(define_insn "*fp_jcc_5_387"
13628  [(set (pc)
13629	(if_then_else (match_operator 0 "comparison_operator"
13630			[(match_operand 1 "register_operand" "f")
13631			 (match_operand 2 "register_operand" "f")])
13632	  (label_ref (match_operand 3 "" ""))
13633	  (pc)))
13634   (clobber (reg:CCFP FPSR_REG))
13635   (clobber (reg:CCFP FLAGS_REG))
13636   (clobber (match_scratch:HI 4 "=a"))]
13637  "TARGET_80387
13638   && FLOAT_MODE_P (GET_MODE (operands[1]))
13639   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13640   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13641  "#")
13642
13643(define_insn "*fp_jcc_6_387"
13644  [(set (pc)
13645	(if_then_else (match_operator 0 "comparison_operator"
13646			[(match_operand 1 "register_operand" "f")
13647			 (match_operand 2 "register_operand" "f")])
13648	  (pc)
13649	  (label_ref (match_operand 3 "" ""))))
13650   (clobber (reg:CCFP FPSR_REG))
13651   (clobber (reg:CCFP FLAGS_REG))
13652   (clobber (match_scratch:HI 4 "=a"))]
13653  "TARGET_80387
13654   && FLOAT_MODE_P (GET_MODE (operands[1]))
13655   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13656   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13657  "#")
13658
13659(define_insn "*fp_jcc_7_387"
13660  [(set (pc)
13661	(if_then_else (match_operator 0 "comparison_operator"
13662			[(match_operand 1 "register_operand" "f")
13663			 (match_operand 2 "const0_operand" "X")])
13664	  (label_ref (match_operand 3 "" ""))
13665	  (pc)))
13666   (clobber (reg:CCFP FPSR_REG))
13667   (clobber (reg:CCFP FLAGS_REG))
13668   (clobber (match_scratch:HI 4 "=a"))]
13669  "TARGET_80387
13670   && FLOAT_MODE_P (GET_MODE (operands[1]))
13671   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13672   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13673   && SELECT_CC_MODE (GET_CODE (operands[0]),
13674		      operands[1], operands[2]) == CCFPmode
13675   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13676  "#")
13677
13678;; The order of operands in *fp_jcc_8_387 is forced by combine in
13679;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13680;; with a precedence over other operators and is always put in the first
13681;; place. Swap condition and operands to match ficom instruction.
13682
13683(define_insn "*fp_jcc_8<mode>_387"
13684  [(set (pc)
13685	(if_then_else (match_operator 0 "comparison_operator"
13686			[(match_operator 1 "float_operator"
13687			   [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13688			   (match_operand 3 "register_operand" "f,f")])
13689	  (label_ref (match_operand 4 "" ""))
13690	  (pc)))
13691   (clobber (reg:CCFP FPSR_REG))
13692   (clobber (reg:CCFP FLAGS_REG))
13693   (clobber (match_scratch:HI 5 "=a,a"))]
13694  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13695   && FLOAT_MODE_P (GET_MODE (operands[3]))
13696   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13697   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13698   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13699   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13700  "#")
13701
13702(define_split
13703  [(set (pc)
13704	(if_then_else (match_operator 0 "comparison_operator"
13705			[(match_operand 1 "register_operand" "")
13706			 (match_operand 2 "nonimmediate_operand" "")])
13707	  (match_operand 3 "" "")
13708	  (match_operand 4 "" "")))
13709   (clobber (reg:CCFP FPSR_REG))
13710   (clobber (reg:CCFP FLAGS_REG))]
13711  "reload_completed"
13712  [(const_int 0)]
13713{
13714  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13715	                operands[3], operands[4], NULL_RTX, NULL_RTX);
13716  DONE;
13717})
13718
13719(define_split
13720  [(set (pc)
13721	(if_then_else (match_operator 0 "comparison_operator"
13722			[(match_operand 1 "register_operand" "")
13723			 (match_operand 2 "general_operand" "")])
13724	  (match_operand 3 "" "")
13725	  (match_operand 4 "" "")))
13726   (clobber (reg:CCFP FPSR_REG))
13727   (clobber (reg:CCFP FLAGS_REG))
13728   (clobber (match_scratch:HI 5 "=a"))]
13729  "reload_completed"
13730  [(const_int 0)]
13731{
13732  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13733	     		operands[3], operands[4], operands[5], NULL_RTX);
13734  DONE;
13735})
13736
13737(define_split
13738  [(set (pc)
13739	(if_then_else (match_operator 0 "comparison_operator"
13740			[(match_operator 1 "float_operator"
13741			   [(match_operand:X87MODEI12 2 "memory_operand" "")])
13742			   (match_operand 3 "register_operand" "")])
13743	  (match_operand 4 "" "")
13744	  (match_operand 5 "" "")))
13745   (clobber (reg:CCFP FPSR_REG))
13746   (clobber (reg:CCFP FLAGS_REG))
13747   (clobber (match_scratch:HI 6 "=a"))]
13748  "reload_completed"
13749  [(const_int 0)]
13750{
13751  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13752  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13753			operands[3], operands[7],
13754			operands[4], operands[5], operands[6], NULL_RTX);
13755  DONE;
13756})
13757
13758;; %%% Kill this when reload knows how to do it.
13759(define_split
13760  [(set (pc)
13761	(if_then_else (match_operator 0 "comparison_operator"
13762			[(match_operator 1 "float_operator"
13763			   [(match_operand:X87MODEI12 2 "register_operand" "")])
13764			   (match_operand 3 "register_operand" "")])
13765	  (match_operand 4 "" "")
13766	  (match_operand 5 "" "")))
13767   (clobber (reg:CCFP FPSR_REG))
13768   (clobber (reg:CCFP FLAGS_REG))
13769   (clobber (match_scratch:HI 6 "=a"))]
13770  "reload_completed"
13771  [(const_int 0)]
13772{
13773  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13774  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13775  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13776			operands[3], operands[7],
13777			operands[4], operands[5], operands[6], operands[2]);
13778  DONE;
13779})
13780
13781;; Unconditional and other jump instructions
13782
13783(define_insn "jump"
13784  [(set (pc)
13785	(label_ref (match_operand 0 "" "")))]
13786  ""
13787  "jmp\t%l0"
13788  [(set_attr "type" "ibr")
13789   (set (attr "length")
13790	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13791				  (const_int -126))
13792			      (lt (minus (match_dup 0) (pc))
13793				  (const_int 128)))
13794	     (const_int 2)
13795	     (const_int 5)))
13796   (set_attr "modrm" "0")])
13797
13798(define_expand "indirect_jump"
13799  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13800  ""
13801  "")
13802
13803(define_insn "*indirect_jump"
13804  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13805  "!TARGET_64BIT"
13806  "jmp\t%A0"
13807  [(set_attr "type" "ibr")
13808   (set_attr "length_immediate" "0")])
13809
13810(define_insn "*indirect_jump_rtx64"
13811  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13812  "TARGET_64BIT"
13813  "jmp\t%A0"
13814  [(set_attr "type" "ibr")
13815   (set_attr "length_immediate" "0")])
13816
13817(define_expand "tablejump"
13818  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13819	      (use (label_ref (match_operand 1 "" "")))])]
13820  ""
13821{
13822  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13823     relative.  Convert the relative address to an absolute address.  */
13824  if (flag_pic)
13825    {
13826      rtx op0, op1;
13827      enum rtx_code code;
13828
13829      if (TARGET_64BIT)
13830	{
13831	  code = PLUS;
13832	  op0 = operands[0];
13833	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13834	}
13835      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13836	{
13837	  code = PLUS;
13838	  op0 = operands[0];
13839	  op1 = pic_offset_table_rtx;
13840	}
13841      else
13842	{
13843	  code = MINUS;
13844	  op0 = pic_offset_table_rtx;
13845	  op1 = operands[0];
13846	}
13847
13848      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13849					 OPTAB_DIRECT);
13850    }
13851})
13852
13853(define_insn "*tablejump_1"
13854  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13855   (use (label_ref (match_operand 1 "" "")))]
13856  "!TARGET_64BIT"
13857  "jmp\t%A0"
13858  [(set_attr "type" "ibr")
13859   (set_attr "length_immediate" "0")])
13860
13861(define_insn "*tablejump_1_rtx64"
13862  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13863   (use (label_ref (match_operand 1 "" "")))]
13864  "TARGET_64BIT"
13865  "jmp\t%A0"
13866  [(set_attr "type" "ibr")
13867   (set_attr "length_immediate" "0")])
13868
13869;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13870
13871(define_peephole2
13872  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13873   (set (match_operand:QI 1 "register_operand" "")
13874	(match_operator:QI 2 "ix86_comparison_operator"
13875	  [(reg FLAGS_REG) (const_int 0)]))
13876   (set (match_operand 3 "q_regs_operand" "")
13877	(zero_extend (match_dup 1)))]
13878  "(peep2_reg_dead_p (3, operands[1])
13879    || operands_match_p (operands[1], operands[3]))
13880   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13881  [(set (match_dup 4) (match_dup 0))
13882   (set (strict_low_part (match_dup 5))
13883	(match_dup 2))]
13884{
13885  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13886  operands[5] = gen_lowpart (QImode, operands[3]);
13887  ix86_expand_clear (operands[3]);
13888})
13889
13890;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13891
13892(define_peephole2
13893  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13894   (set (match_operand:QI 1 "register_operand" "")
13895	(match_operator:QI 2 "ix86_comparison_operator"
13896	  [(reg FLAGS_REG) (const_int 0)]))
13897   (parallel [(set (match_operand 3 "q_regs_operand" "")
13898		   (zero_extend (match_dup 1)))
13899	      (clobber (reg:CC FLAGS_REG))])]
13900  "(peep2_reg_dead_p (3, operands[1])
13901    || operands_match_p (operands[1], operands[3]))
13902   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13903  [(set (match_dup 4) (match_dup 0))
13904   (set (strict_low_part (match_dup 5))
13905	(match_dup 2))]
13906{
13907  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13908  operands[5] = gen_lowpart (QImode, operands[3]);
13909  ix86_expand_clear (operands[3]);
13910})
13911
13912;; Call instructions.
13913
13914;; The predicates normally associated with named expanders are not properly
13915;; checked for calls.  This is a bug in the generic code, but it isn't that
13916;; easy to fix.  Ignore it for now and be prepared to fix things up.
13917
13918;; Call subroutine returning no value.
13919
13920(define_expand "call_pop"
13921  [(parallel [(call (match_operand:QI 0 "" "")
13922		    (match_operand:SI 1 "" ""))
13923	      (set (reg:SI SP_REG)
13924		   (plus:SI (reg:SI SP_REG)
13925			    (match_operand:SI 3 "" "")))])]
13926  "!TARGET_64BIT"
13927{
13928  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13929  DONE;
13930})
13931
13932(define_insn "*call_pop_0"
13933  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13934	 (match_operand:SI 1 "" ""))
13935   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13936			    (match_operand:SI 2 "immediate_operand" "")))]
13937  "!TARGET_64BIT"
13938{
13939  if (SIBLING_CALL_P (insn))
13940    return "jmp\t%P0";
13941  else
13942    return "call\t%P0";
13943}
13944  [(set_attr "type" "call")])
13945  
13946(define_insn "*call_pop_1"
13947  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13948	 (match_operand:SI 1 "" ""))
13949   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13950			    (match_operand:SI 2 "immediate_operand" "i")))]
13951  "!TARGET_64BIT"
13952{
13953  if (constant_call_address_operand (operands[0], Pmode))
13954    {
13955      if (SIBLING_CALL_P (insn))
13956	return "jmp\t%P0";
13957      else
13958	return "call\t%P0";
13959    }
13960  if (SIBLING_CALL_P (insn))
13961    return "jmp\t%A0";
13962  else
13963    return "call\t%A0";
13964}
13965  [(set_attr "type" "call")])
13966
13967(define_expand "call"
13968  [(call (match_operand:QI 0 "" "")
13969	 (match_operand 1 "" ""))
13970   (use (match_operand 2 "" ""))]
13971  ""
13972{
13973  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13974  DONE;
13975})
13976
13977(define_expand "sibcall"
13978  [(call (match_operand:QI 0 "" "")
13979	 (match_operand 1 "" ""))
13980   (use (match_operand 2 "" ""))]
13981  ""
13982{
13983  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13984  DONE;
13985})
13986
13987(define_insn "*call_0"
13988  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13989	 (match_operand 1 "" ""))]
13990  ""
13991{
13992  if (SIBLING_CALL_P (insn))
13993    return "jmp\t%P0";
13994  else
13995    return "call\t%P0";
13996}
13997  [(set_attr "type" "call")])
13998
13999(define_insn "*call_1"
14000  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14001	 (match_operand 1 "" ""))]
14002  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14003{
14004  if (constant_call_address_operand (operands[0], Pmode))
14005    return "call\t%P0";
14006  return "call\t%A0";
14007}
14008  [(set_attr "type" "call")])
14009
14010(define_insn "*sibcall_1"
14011  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14012	 (match_operand 1 "" ""))]
14013  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14014{
14015  if (constant_call_address_operand (operands[0], Pmode))
14016    return "jmp\t%P0";
14017  return "jmp\t%A0";
14018}
14019  [(set_attr "type" "call")])
14020
14021(define_insn "*call_1_rex64"
14022  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14023	 (match_operand 1 "" ""))]
14024  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14025{
14026  if (constant_call_address_operand (operands[0], Pmode))
14027    return "call\t%P0";
14028  return "call\t%A0";
14029}
14030  [(set_attr "type" "call")])
14031
14032(define_insn "*sibcall_1_rex64"
14033  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14034	 (match_operand 1 "" ""))]
14035  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14036  "jmp\t%P0"
14037  [(set_attr "type" "call")])
14038
14039(define_insn "*sibcall_1_rex64_v"
14040  [(call (mem:QI (reg:DI 40))
14041	 (match_operand 0 "" ""))]
14042  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14043  "jmp\t*%%r11"
14044  [(set_attr "type" "call")])
14045
14046
14047;; Call subroutine, returning value in operand 0
14048
14049(define_expand "call_value_pop"
14050  [(parallel [(set (match_operand 0 "" "")
14051		   (call (match_operand:QI 1 "" "")
14052			 (match_operand:SI 2 "" "")))
14053	      (set (reg:SI SP_REG)
14054		   (plus:SI (reg:SI SP_REG)
14055			    (match_operand:SI 4 "" "")))])]
14056  "!TARGET_64BIT"
14057{
14058  ix86_expand_call (operands[0], operands[1], operands[2],
14059		    operands[3], operands[4], 0);
14060  DONE;
14061})
14062
14063(define_expand "call_value"
14064  [(set (match_operand 0 "" "")
14065	(call (match_operand:QI 1 "" "")
14066	      (match_operand:SI 2 "" "")))
14067   (use (match_operand:SI 3 "" ""))]
14068  ;; Operand 2 not used on the i386.
14069  ""
14070{
14071  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14072  DONE;
14073})
14074
14075(define_expand "sibcall_value"
14076  [(set (match_operand 0 "" "")
14077	(call (match_operand:QI 1 "" "")
14078	      (match_operand:SI 2 "" "")))
14079   (use (match_operand:SI 3 "" ""))]
14080  ;; Operand 2 not used on the i386.
14081  ""
14082{
14083  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14084  DONE;
14085})
14086
14087;; Call subroutine returning any type.
14088
14089(define_expand "untyped_call"
14090  [(parallel [(call (match_operand 0 "" "")
14091		    (const_int 0))
14092	      (match_operand 1 "" "")
14093	      (match_operand 2 "" "")])]
14094  ""
14095{
14096  int i;
14097
14098  /* In order to give reg-stack an easier job in validating two
14099     coprocessor registers as containing a possible return value,
14100     simply pretend the untyped call returns a complex long double
14101     value.  */
14102
14103  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14104		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14105		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14106		    NULL, 0);
14107
14108  for (i = 0; i < XVECLEN (operands[2], 0); i++)
14109    {
14110      rtx set = XVECEXP (operands[2], 0, i);
14111      emit_move_insn (SET_DEST (set), SET_SRC (set));
14112    }
14113
14114  /* The optimizer does not know that the call sets the function value
14115     registers we stored in the result block.  We avoid problems by
14116     claiming that all hard registers are used and clobbered at this
14117     point.  */
14118  emit_insn (gen_blockage (const0_rtx));
14119
14120  DONE;
14121})
14122
14123;; Prologue and epilogue instructions
14124
14125;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14126;; all of memory.  This blocks insns from being moved across this point.
14127
14128(define_insn "blockage"
14129  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14130  ""
14131  ""
14132  [(set_attr "length" "0")])
14133
14134;; Insn emitted into the body of a function to return from a function.
14135;; This is only done if the function's epilogue is known to be simple.
14136;; See comments for ix86_can_use_return_insn_p in i386.c.
14137
14138(define_expand "return"
14139  [(return)]
14140  "ix86_can_use_return_insn_p ()"
14141{
14142  if (current_function_pops_args)
14143    {
14144      rtx popc = GEN_INT (current_function_pops_args);
14145      emit_jump_insn (gen_return_pop_internal (popc));
14146      DONE;
14147    }
14148})
14149
14150(define_insn "return_internal"
14151  [(return)]
14152  "reload_completed"
14153  "ret"
14154  [(set_attr "length" "1")
14155   (set_attr "length_immediate" "0")
14156   (set_attr "modrm" "0")])
14157
14158;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14159;; instruction Athlon and K8 have.
14160
14161(define_insn "return_internal_long"
14162  [(return)
14163   (unspec [(const_int 0)] UNSPEC_REP)]
14164  "reload_completed"
14165  "rep {;} ret"
14166  [(set_attr "length" "1")
14167   (set_attr "length_immediate" "0")
14168   (set_attr "prefix_rep" "1")
14169   (set_attr "modrm" "0")])
14170
14171(define_insn "return_pop_internal"
14172  [(return)
14173   (use (match_operand:SI 0 "const_int_operand" ""))]
14174  "reload_completed"
14175  "ret\t%0"
14176  [(set_attr "length" "3")
14177   (set_attr "length_immediate" "2")
14178   (set_attr "modrm" "0")])
14179
14180(define_insn "return_indirect_internal"
14181  [(return)
14182   (use (match_operand:SI 0 "register_operand" "r"))]
14183  "reload_completed"
14184  "jmp\t%A0"
14185  [(set_attr "type" "ibr")
14186   (set_attr "length_immediate" "0")])
14187
14188(define_insn "nop"
14189  [(const_int 0)]
14190  ""
14191  "nop"
14192  [(set_attr "length" "1")
14193   (set_attr "length_immediate" "0")
14194   (set_attr "modrm" "0")])
14195
14196;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14197;; branch prediction penalty for the third jump in a 16-byte
14198;; block on K8.
14199
14200(define_insn "align"
14201  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14202  ""
14203{
14204#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14205  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14206#else
14207  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14208     The align insn is used to avoid 3 jump instructions in the row to improve
14209     branch prediction and the benefits hardly outweight the cost of extra 8
14210     nops on the average inserted by full alignment pseudo operation.  */
14211#endif
14212  return "";
14213}
14214  [(set_attr "length" "16")])
14215
14216(define_expand "prologue"
14217  [(const_int 1)]
14218  ""
14219  "ix86_expand_prologue (); DONE;")
14220
14221(define_insn "set_got"
14222  [(set (match_operand:SI 0 "register_operand" "=r")
14223	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14224   (clobber (reg:CC FLAGS_REG))]
14225  "!TARGET_64BIT"
14226  { return output_set_got (operands[0]); }
14227  [(set_attr "type" "multi")
14228   (set_attr "length" "12")])
14229
14230(define_insn "set_got_rex64"
14231  [(set (match_operand:DI 0 "register_operand" "=r")
14232	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14233  "TARGET_64BIT"
14234  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14235  [(set_attr "type" "lea")
14236   (set_attr "length" "6")])
14237
14238(define_expand "epilogue"
14239  [(const_int 1)]
14240  ""
14241  "ix86_expand_epilogue (1); DONE;")
14242
14243(define_expand "sibcall_epilogue"
14244  [(const_int 1)]
14245  ""
14246  "ix86_expand_epilogue (0); DONE;")
14247
14248(define_expand "eh_return"
14249  [(use (match_operand 0 "register_operand" ""))]
14250  ""
14251{
14252  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14253
14254  /* Tricky bit: we write the address of the handler to which we will
14255     be returning into someone else's stack frame, one word below the
14256     stack address we wish to restore.  */
14257  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14258  tmp = plus_constant (tmp, -UNITS_PER_WORD);
14259  tmp = gen_rtx_MEM (Pmode, tmp);
14260  emit_move_insn (tmp, ra);
14261
14262  if (Pmode == SImode)
14263    emit_jump_insn (gen_eh_return_si (sa));
14264  else
14265    emit_jump_insn (gen_eh_return_di (sa));
14266  emit_barrier ();
14267  DONE;
14268})
14269
14270(define_insn_and_split "eh_return_si"
14271  [(set (pc) 
14272        (unspec [(match_operand:SI 0 "register_operand" "c")]
14273	         UNSPEC_EH_RETURN))]
14274  "!TARGET_64BIT"
14275  "#"
14276  "reload_completed"
14277  [(const_int 1)]
14278  "ix86_expand_epilogue (2); DONE;")
14279
14280(define_insn_and_split "eh_return_di"
14281  [(set (pc) 
14282        (unspec [(match_operand:DI 0 "register_operand" "c")]
14283	         UNSPEC_EH_RETURN))]
14284  "TARGET_64BIT"
14285  "#"
14286  "reload_completed"
14287  [(const_int 1)]
14288  "ix86_expand_epilogue (2); DONE;")
14289
14290(define_insn "leave"
14291  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14292   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14293   (clobber (mem:BLK (scratch)))]
14294  "!TARGET_64BIT"
14295  "leave"
14296  [(set_attr "type" "leave")])
14297
14298(define_insn "leave_rex64"
14299  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14300   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14301   (clobber (mem:BLK (scratch)))]
14302  "TARGET_64BIT"
14303  "leave"
14304  [(set_attr "type" "leave")])
14305
14306(define_expand "ffssi2"
14307  [(parallel
14308     [(set (match_operand:SI 0 "register_operand" "") 
14309	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14310      (clobber (match_scratch:SI 2 ""))
14311      (clobber (reg:CC FLAGS_REG))])]
14312  ""
14313  "")
14314
14315(define_insn_and_split "*ffs_cmove"
14316  [(set (match_operand:SI 0 "register_operand" "=r") 
14317	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14318   (clobber (match_scratch:SI 2 "=&r"))
14319   (clobber (reg:CC FLAGS_REG))]
14320  "TARGET_CMOVE"
14321  "#"
14322  "&& reload_completed"
14323  [(set (match_dup 2) (const_int -1))
14324   (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14325	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14326   (set (match_dup 0) (if_then_else:SI
14327			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14328			(match_dup 2)
14329			(match_dup 0)))
14330   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14331	      (clobber (reg:CC FLAGS_REG))])]
14332  "")
14333
14334(define_insn_and_split "*ffs_no_cmove"
14335  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14336	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14337   (clobber (match_scratch:SI 2 "=&q"))
14338   (clobber (reg:CC FLAGS_REG))]
14339  ""
14340  "#"
14341  "reload_completed"
14342  [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14343	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14344   (set (strict_low_part (match_dup 3))
14345	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14346   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14347	      (clobber (reg:CC FLAGS_REG))])
14348   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14349	      (clobber (reg:CC FLAGS_REG))])
14350   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14351	      (clobber (reg:CC FLAGS_REG))])]
14352{
14353  operands[3] = gen_lowpart (QImode, operands[2]);
14354  ix86_expand_clear (operands[2]);
14355})
14356
14357(define_insn "*ffssi_1"
14358  [(set (reg:CCZ FLAGS_REG)
14359	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14360		     (const_int 0)))
14361   (set (match_operand:SI 0 "register_operand" "=r")
14362	(ctz:SI (match_dup 1)))]
14363  ""
14364  "bsf{l}\t{%1, %0|%0, %1}"
14365  [(set_attr "prefix_0f" "1")])
14366
14367(define_expand "ffsdi2"
14368  [(parallel
14369     [(set (match_operand:DI 0 "register_operand" "") 
14370	   (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14371      (clobber (match_scratch:DI 2 ""))
14372      (clobber (reg:CC FLAGS_REG))])]
14373  "TARGET_64BIT && TARGET_CMOVE"
14374  "")
14375
14376(define_insn_and_split "*ffs_rex64"
14377  [(set (match_operand:DI 0 "register_operand" "=r") 
14378	(ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14379   (clobber (match_scratch:DI 2 "=&r"))
14380   (clobber (reg:CC FLAGS_REG))]
14381  "TARGET_64BIT && TARGET_CMOVE"
14382  "#"
14383  "&& reload_completed"
14384  [(set (match_dup 2) (const_int -1))
14385   (parallel [(set (reg:CCZ FLAGS_REG)
14386		   (compare:CCZ (match_dup 1) (const_int 0)))
14387	      (set (match_dup 0) (ctz:DI (match_dup 1)))])
14388   (set (match_dup 0) (if_then_else:DI
14389			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14390			(match_dup 2)
14391			(match_dup 0)))
14392   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14393	      (clobber (reg:CC FLAGS_REG))])]
14394  "")
14395
14396(define_insn "*ffsdi_1"
14397  [(set (reg:CCZ FLAGS_REG)
14398	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14399		     (const_int 0)))
14400   (set (match_operand:DI 0 "register_operand" "=r")
14401	(ctz:DI (match_dup 1)))]
14402  "TARGET_64BIT"
14403  "bsf{q}\t{%1, %0|%0, %1}"
14404  [(set_attr "prefix_0f" "1")])
14405
14406(define_insn "ctzsi2"
14407  [(set (match_operand:SI 0 "register_operand" "=r")
14408	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14409   (clobber (reg:CC FLAGS_REG))]
14410  ""
14411  "bsf{l}\t{%1, %0|%0, %1}"
14412  [(set_attr "prefix_0f" "1")])
14413
14414(define_insn "ctzdi2"
14415  [(set (match_operand:DI 0 "register_operand" "=r")
14416	(ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14417   (clobber (reg:CC FLAGS_REG))]
14418  "TARGET_64BIT"
14419  "bsf{q}\t{%1, %0|%0, %1}"
14420  [(set_attr "prefix_0f" "1")])
14421
14422(define_expand "clzsi2"
14423  [(parallel
14424     [(set (match_operand:SI 0 "register_operand" "")
14425	   (minus:SI (const_int 31)
14426		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14427      (clobber (reg:CC FLAGS_REG))])
14428   (parallel
14429     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14430      (clobber (reg:CC FLAGS_REG))])]
14431  ""
14432  "")
14433
14434(define_insn "*bsr"
14435  [(set (match_operand:SI 0 "register_operand" "=r")
14436	(minus:SI (const_int 31)
14437		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14438   (clobber (reg:CC FLAGS_REG))]
14439  ""
14440  "bsr{l}\t{%1, %0|%0, %1}"
14441  [(set_attr "prefix_0f" "1")])
14442
14443(define_expand "clzdi2"
14444  [(parallel
14445     [(set (match_operand:DI 0 "register_operand" "")
14446	   (minus:DI (const_int 63)
14447		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14448      (clobber (reg:CC FLAGS_REG))])
14449   (parallel
14450     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14451      (clobber (reg:CC FLAGS_REG))])]
14452  "TARGET_64BIT"
14453  "")
14454
14455(define_insn "*bsr_rex64"
14456  [(set (match_operand:DI 0 "register_operand" "=r")
14457	(minus:DI (const_int 63)
14458		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14459   (clobber (reg:CC FLAGS_REG))]
14460  "TARGET_64BIT"
14461  "bsr{q}\t{%1, %0|%0, %1}"
14462  [(set_attr "prefix_0f" "1")])
14463
14464;; Thread-local storage patterns for ELF.
14465;;
14466;; Note that these code sequences must appear exactly as shown
14467;; in order to allow linker relaxation.
14468
14469(define_insn "*tls_global_dynamic_32_gnu"
14470  [(set (match_operand:SI 0 "register_operand" "=a")
14471	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14472		    (match_operand:SI 2 "tls_symbolic_operand" "")
14473		    (match_operand:SI 3 "call_insn_operand" "")]
14474		    UNSPEC_TLS_GD))
14475   (clobber (match_scratch:SI 4 "=d"))
14476   (clobber (match_scratch:SI 5 "=c"))
14477   (clobber (reg:CC FLAGS_REG))]
14478  "!TARGET_64BIT && TARGET_GNU_TLS"
14479  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14480  [(set_attr "type" "multi")
14481   (set_attr "length" "12")])
14482
14483(define_insn "*tls_global_dynamic_32_sun"
14484  [(set (match_operand:SI 0 "register_operand" "=a")
14485	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14486		    (match_operand:SI 2 "tls_symbolic_operand" "")
14487		    (match_operand:SI 3 "call_insn_operand" "")]
14488		    UNSPEC_TLS_GD))
14489   (clobber (match_scratch:SI 4 "=d"))
14490   (clobber (match_scratch:SI 5 "=c"))
14491   (clobber (reg:CC FLAGS_REG))]
14492  "!TARGET_64BIT && TARGET_SUN_TLS"
14493  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14494	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14495  [(set_attr "type" "multi")
14496   (set_attr "length" "14")])
14497
14498(define_expand "tls_global_dynamic_32"
14499  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14500		   (unspec:SI
14501		    [(match_dup 2)
14502		     (match_operand:SI 1 "tls_symbolic_operand" "")
14503		     (match_dup 3)]
14504		    UNSPEC_TLS_GD))
14505	      (clobber (match_scratch:SI 4 ""))
14506	      (clobber (match_scratch:SI 5 ""))
14507	      (clobber (reg:CC FLAGS_REG))])]
14508  ""
14509{
14510  if (flag_pic)
14511    operands[2] = pic_offset_table_rtx;
14512  else
14513    {
14514      operands[2] = gen_reg_rtx (Pmode);
14515      emit_insn (gen_set_got (operands[2]));
14516    }
14517  operands[3] = ix86_tls_get_addr ();
14518})
14519
14520(define_insn "*tls_global_dynamic_64"
14521  [(set (match_operand:DI 0 "register_operand" "=a")
14522	(call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14523		 (match_operand:DI 3 "" "")))
14524   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14525	      UNSPEC_TLS_GD)]
14526  "TARGET_64BIT"
14527  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14528  [(set_attr "type" "multi")
14529   (set_attr "length" "16")])
14530
14531(define_expand "tls_global_dynamic_64"
14532  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14533		   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14534	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14535			 UNSPEC_TLS_GD)])]
14536  ""
14537{
14538  operands[2] = ix86_tls_get_addr ();
14539})
14540
14541(define_insn "*tls_local_dynamic_base_32_gnu"
14542  [(set (match_operand:SI 0 "register_operand" "=a")
14543	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14544                    (match_operand:SI 2 "call_insn_operand" "")]
14545		   UNSPEC_TLS_LD_BASE))
14546   (clobber (match_scratch:SI 3 "=d"))
14547   (clobber (match_scratch:SI 4 "=c"))
14548   (clobber (reg:CC FLAGS_REG))]
14549  "!TARGET_64BIT && TARGET_GNU_TLS"
14550  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14551  [(set_attr "type" "multi")
14552   (set_attr "length" "11")])
14553
14554(define_insn "*tls_local_dynamic_base_32_sun"
14555  [(set (match_operand:SI 0 "register_operand" "=a")
14556	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14557                    (match_operand:SI 2 "call_insn_operand" "")]
14558		   UNSPEC_TLS_LD_BASE))
14559   (clobber (match_scratch:SI 3 "=d"))
14560   (clobber (match_scratch:SI 4 "=c"))
14561   (clobber (reg:CC FLAGS_REG))]
14562  "!TARGET_64BIT && TARGET_SUN_TLS"
14563  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14564	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14565  [(set_attr "type" "multi")
14566   (set_attr "length" "13")])
14567
14568(define_expand "tls_local_dynamic_base_32"
14569  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14570		   (unspec:SI [(match_dup 1) (match_dup 2)]
14571			      UNSPEC_TLS_LD_BASE))
14572	      (clobber (match_scratch:SI 3 ""))
14573	      (clobber (match_scratch:SI 4 ""))
14574	      (clobber (reg:CC FLAGS_REG))])]
14575  ""
14576{
14577  if (flag_pic)
14578    operands[1] = pic_offset_table_rtx;
14579  else
14580    {
14581      operands[1] = gen_reg_rtx (Pmode);
14582      emit_insn (gen_set_got (operands[1]));
14583    }
14584  operands[2] = ix86_tls_get_addr ();
14585})
14586
14587(define_insn "*tls_local_dynamic_base_64"
14588  [(set (match_operand:DI 0 "register_operand" "=a")
14589	(call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14590		 (match_operand:DI 2 "" "")))
14591   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14592  "TARGET_64BIT"
14593  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14594  [(set_attr "type" "multi")
14595   (set_attr "length" "12")])
14596
14597(define_expand "tls_local_dynamic_base_64"
14598  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14599		   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14600	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14601  ""
14602{
14603  operands[1] = ix86_tls_get_addr ();
14604})
14605
14606;; Local dynamic of a single variable is a lose.  Show combine how
14607;; to convert that back to global dynamic.
14608
14609(define_insn_and_split "*tls_local_dynamic_32_once"
14610  [(set (match_operand:SI 0 "register_operand" "=a")
14611	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14612			     (match_operand:SI 2 "call_insn_operand" "")]
14613			    UNSPEC_TLS_LD_BASE)
14614		 (const:SI (unspec:SI
14615			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
14616			    UNSPEC_DTPOFF))))
14617   (clobber (match_scratch:SI 4 "=d"))
14618   (clobber (match_scratch:SI 5 "=c"))
14619   (clobber (reg:CC FLAGS_REG))]
14620  ""
14621  "#"
14622  ""
14623  [(parallel [(set (match_dup 0)
14624		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14625			      UNSPEC_TLS_GD))
14626	      (clobber (match_dup 4))
14627	      (clobber (match_dup 5))
14628	      (clobber (reg:CC FLAGS_REG))])]
14629  "")
14630
14631;; Load and add the thread base pointer from %gs:0.
14632
14633(define_insn "*load_tp_si"
14634  [(set (match_operand:SI 0 "register_operand" "=r")
14635	(unspec:SI [(const_int 0)] UNSPEC_TP))]
14636  "!TARGET_64BIT"
14637  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14638  [(set_attr "type" "imov")
14639   (set_attr "modrm" "0")
14640   (set_attr "length" "7")
14641   (set_attr "memory" "load")
14642   (set_attr "imm_disp" "false")])
14643
14644(define_insn "*add_tp_si"
14645  [(set (match_operand:SI 0 "register_operand" "=r")
14646	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14647		 (match_operand:SI 1 "register_operand" "0")))
14648   (clobber (reg:CC FLAGS_REG))]
14649  "!TARGET_64BIT"
14650  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14651  [(set_attr "type" "alu")
14652   (set_attr "modrm" "0")
14653   (set_attr "length" "7")
14654   (set_attr "memory" "load")
14655   (set_attr "imm_disp" "false")])
14656
14657(define_insn "*load_tp_di"
14658  [(set (match_operand:DI 0 "register_operand" "=r")
14659	(unspec:DI [(const_int 0)] UNSPEC_TP))]
14660  "TARGET_64BIT"
14661  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14662  [(set_attr "type" "imov")
14663   (set_attr "modrm" "0")
14664   (set_attr "length" "7")
14665   (set_attr "memory" "load")
14666   (set_attr "imm_disp" "false")])
14667
14668(define_insn "*add_tp_di"
14669  [(set (match_operand:DI 0 "register_operand" "=r")
14670	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14671		 (match_operand:DI 1 "register_operand" "0")))
14672   (clobber (reg:CC FLAGS_REG))]
14673  "TARGET_64BIT"
14674  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14675  [(set_attr "type" "alu")
14676   (set_attr "modrm" "0")
14677   (set_attr "length" "7")
14678   (set_attr "memory" "load")
14679   (set_attr "imm_disp" "false")])
14680
14681;; These patterns match the binary 387 instructions for addM3, subM3,
14682;; mulM3 and divM3.  There are three patterns for each of DFmode and
14683;; SFmode.  The first is the normal insn, the second the same insn but
14684;; with one operand a conversion, and the third the same insn but with
14685;; the other operand a conversion.  The conversion may be SFmode or
14686;; SImode if the target mode DFmode, but only SImode if the target mode
14687;; is SFmode.
14688
14689;; Gcc is slightly more smart about handling normal two address instructions
14690;; so use special patterns for add and mull.
14691
14692(define_insn "*fop_sf_comm_mixed"
14693  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14694	(match_operator:SF 3 "binary_fp_operator"
14695			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14696			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14697  "TARGET_MIX_SSE_I387
14698   && COMMUTATIVE_ARITH_P (operands[3])
14699   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14700  "* return output_387_binary_op (insn, operands);"
14701  [(set (attr "type") 
14702	(if_then_else (eq_attr "alternative" "1")
14703	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14704	      (const_string "ssemul")
14705	      (const_string "sseadd"))
14706	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14707	      (const_string "fmul")
14708	      (const_string "fop"))))
14709   (set_attr "mode" "SF")])
14710
14711(define_insn "*fop_sf_comm_sse"
14712  [(set (match_operand:SF 0 "register_operand" "=x")
14713	(match_operator:SF 3 "binary_fp_operator"
14714			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14715			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14716  "TARGET_SSE_MATH
14717   && COMMUTATIVE_ARITH_P (operands[3])
14718   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14719  "* return output_387_binary_op (insn, operands);"
14720  [(set (attr "type") 
14721        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14722	   (const_string "ssemul")
14723	   (const_string "sseadd")))
14724   (set_attr "mode" "SF")])
14725
14726(define_insn "*fop_sf_comm_i387"
14727  [(set (match_operand:SF 0 "register_operand" "=f")
14728	(match_operator:SF 3 "binary_fp_operator"
14729			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14730			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14731  "TARGET_80387
14732   && COMMUTATIVE_ARITH_P (operands[3])
14733   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14734  "* return output_387_binary_op (insn, operands);"
14735  [(set (attr "type") 
14736	(if_then_else (match_operand:SF 3 "mult_operator" "") 
14737	   (const_string "fmul")
14738	   (const_string "fop")))
14739   (set_attr "mode" "SF")])
14740
14741(define_insn "*fop_sf_1_mixed"
14742  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14743	(match_operator:SF 3 "binary_fp_operator"
14744			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14745			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14746  "TARGET_MIX_SSE_I387
14747   && !COMMUTATIVE_ARITH_P (operands[3])
14748   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14749  "* return output_387_binary_op (insn, operands);"
14750  [(set (attr "type") 
14751        (cond [(and (eq_attr "alternative" "2")
14752	            (match_operand:SF 3 "mult_operator" ""))
14753                 (const_string "ssemul")
14754	       (and (eq_attr "alternative" "2")
14755	            (match_operand:SF 3 "div_operator" ""))
14756                 (const_string "ssediv")
14757	       (eq_attr "alternative" "2")
14758                 (const_string "sseadd")
14759	       (match_operand:SF 3 "mult_operator" "") 
14760                 (const_string "fmul")
14761               (match_operand:SF 3 "div_operator" "") 
14762                 (const_string "fdiv")
14763              ]
14764              (const_string "fop")))
14765   (set_attr "mode" "SF")])
14766
14767(define_insn "*fop_sf_1_sse"
14768  [(set (match_operand:SF 0 "register_operand" "=x")
14769	(match_operator:SF 3 "binary_fp_operator"
14770			[(match_operand:SF 1 "register_operand" "0")
14771			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14772  "TARGET_SSE_MATH
14773   && !COMMUTATIVE_ARITH_P (operands[3])"
14774  "* return output_387_binary_op (insn, operands);"
14775  [(set (attr "type") 
14776        (cond [(match_operand:SF 3 "mult_operator" "")
14777                 (const_string "ssemul")
14778	       (match_operand:SF 3 "div_operator" "")
14779                 (const_string "ssediv")
14780              ]
14781              (const_string "sseadd")))
14782   (set_attr "mode" "SF")])
14783
14784;; This pattern is not fully shadowed by the pattern above.
14785(define_insn "*fop_sf_1_i387"
14786  [(set (match_operand:SF 0 "register_operand" "=f,f")
14787	(match_operator:SF 3 "binary_fp_operator"
14788			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14789			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14790  "TARGET_80387 && !TARGET_SSE_MATH
14791   && !COMMUTATIVE_ARITH_P (operands[3])
14792   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14793  "* return output_387_binary_op (insn, operands);"
14794  [(set (attr "type") 
14795        (cond [(match_operand:SF 3 "mult_operator" "") 
14796                 (const_string "fmul")
14797               (match_operand:SF 3 "div_operator" "") 
14798                 (const_string "fdiv")
14799              ]
14800              (const_string "fop")))
14801   (set_attr "mode" "SF")])
14802
14803;; ??? Add SSE splitters for these!
14804(define_insn "*fop_sf_2<mode>_i387"
14805  [(set (match_operand:SF 0 "register_operand" "=f,f")
14806	(match_operator:SF 3 "binary_fp_operator"
14807	  [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14808	   (match_operand:SF 2 "register_operand" "0,0")]))]
14809  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14810  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14811  [(set (attr "type") 
14812        (cond [(match_operand:SF 3 "mult_operator" "") 
14813                 (const_string "fmul")
14814               (match_operand:SF 3 "div_operator" "") 
14815                 (const_string "fdiv")
14816              ]
14817              (const_string "fop")))
14818   (set_attr "fp_int_src" "true")
14819   (set_attr "mode" "<MODE>")])
14820
14821(define_insn "*fop_sf_3<mode>_i387"
14822  [(set (match_operand:SF 0 "register_operand" "=f,f")
14823	(match_operator:SF 3 "binary_fp_operator"
14824	  [(match_operand:SF 1 "register_operand" "0,0")
14825	   (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14826  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14827  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14828  [(set (attr "type") 
14829        (cond [(match_operand:SF 3 "mult_operator" "") 
14830                 (const_string "fmul")
14831               (match_operand:SF 3 "div_operator" "") 
14832                 (const_string "fdiv")
14833              ]
14834              (const_string "fop")))
14835   (set_attr "fp_int_src" "true")
14836   (set_attr "mode" "<MODE>")])
14837
14838(define_insn "*fop_df_comm_mixed"
14839  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14840	(match_operator:DF 3 "binary_fp_operator"
14841			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14842			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14843  "TARGET_SSE2 && TARGET_MIX_SSE_I387
14844   && COMMUTATIVE_ARITH_P (operands[3])
14845   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14846  "* return output_387_binary_op (insn, operands);"
14847  [(set (attr "type") 
14848	(if_then_else (eq_attr "alternative" "1")
14849	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14850	      (const_string "ssemul")
14851	      (const_string "sseadd"))
14852	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14853	      (const_string "fmul")
14854	      (const_string "fop"))))
14855   (set_attr "mode" "DF")])
14856
14857(define_insn "*fop_df_comm_sse"
14858  [(set (match_operand:DF 0 "register_operand" "=Y")
14859	(match_operator:DF 3 "binary_fp_operator"
14860			[(match_operand:DF 1 "nonimmediate_operand" "%0")
14861			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14862  "TARGET_SSE2 && TARGET_SSE_MATH
14863   && COMMUTATIVE_ARITH_P (operands[3])
14864   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14865  "* return output_387_binary_op (insn, operands);"
14866  [(set (attr "type") 
14867        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14868	   (const_string "ssemul")
14869	   (const_string "sseadd")))
14870   (set_attr "mode" "DF")])
14871
14872(define_insn "*fop_df_comm_i387"
14873  [(set (match_operand:DF 0 "register_operand" "=f")
14874	(match_operator:DF 3 "binary_fp_operator"
14875			[(match_operand:DF 1 "nonimmediate_operand" "%0")
14876			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14877  "TARGET_80387
14878   && COMMUTATIVE_ARITH_P (operands[3])
14879   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14880  "* return output_387_binary_op (insn, operands);"
14881  [(set (attr "type") 
14882	(if_then_else (match_operand:SF 3 "mult_operator" "") 
14883	   (const_string "fmul")
14884	   (const_string "fop")))
14885   (set_attr "mode" "DF")])
14886
14887(define_insn "*fop_df_1_mixed"
14888  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14889	(match_operator:DF 3 "binary_fp_operator"
14890			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14891			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14892  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14893   && !COMMUTATIVE_ARITH_P (operands[3])
14894   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14895  "* return output_387_binary_op (insn, operands);"
14896  [(set (attr "type") 
14897        (cond [(and (eq_attr "alternative" "2")
14898	            (match_operand:SF 3 "mult_operator" ""))
14899                 (const_string "ssemul")
14900	       (and (eq_attr "alternative" "2")
14901	            (match_operand:SF 3 "div_operator" ""))
14902                 (const_string "ssediv")
14903	       (eq_attr "alternative" "2")
14904                 (const_string "sseadd")
14905	       (match_operand:DF 3 "mult_operator" "") 
14906                 (const_string "fmul")
14907               (match_operand:DF 3 "div_operator" "") 
14908                 (const_string "fdiv")
14909              ]
14910              (const_string "fop")))
14911   (set_attr "mode" "DF")])
14912
14913(define_insn "*fop_df_1_sse"
14914  [(set (match_operand:DF 0 "register_operand" "=Y")
14915	(match_operator:DF 3 "binary_fp_operator"
14916			[(match_operand:DF 1 "register_operand" "0")
14917			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14918  "TARGET_SSE2 && TARGET_SSE_MATH
14919   && !COMMUTATIVE_ARITH_P (operands[3])"
14920  "* return output_387_binary_op (insn, operands);"
14921  [(set_attr "mode" "DF")
14922   (set (attr "type") 
14923        (cond [(match_operand:SF 3 "mult_operator" "")
14924                 (const_string "ssemul")
14925	       (match_operand:SF 3 "div_operator" "")
14926                 (const_string "ssediv")
14927              ]
14928              (const_string "sseadd")))])
14929
14930;; This pattern is not fully shadowed by the pattern above.
14931(define_insn "*fop_df_1_i387"
14932  [(set (match_operand:DF 0 "register_operand" "=f,f")
14933	(match_operator:DF 3 "binary_fp_operator"
14934			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14935			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14936  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14937   && !COMMUTATIVE_ARITH_P (operands[3])
14938   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14939  "* return output_387_binary_op (insn, operands);"
14940  [(set (attr "type") 
14941        (cond [(match_operand:DF 3 "mult_operator" "") 
14942                 (const_string "fmul")
14943               (match_operand:DF 3 "div_operator" "")
14944                 (const_string "fdiv")
14945              ]
14946              (const_string "fop")))
14947   (set_attr "mode" "DF")])
14948
14949;; ??? Add SSE splitters for these!
14950(define_insn "*fop_df_2<mode>_i387"
14951  [(set (match_operand:DF 0 "register_operand" "=f,f")
14952	(match_operator:DF 3 "binary_fp_operator"
14953	   [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14954	    (match_operand:DF 2 "register_operand" "0,0")]))]
14955  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14956   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14957  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14958  [(set (attr "type") 
14959        (cond [(match_operand:DF 3 "mult_operator" "") 
14960                 (const_string "fmul")
14961               (match_operand:DF 3 "div_operator" "") 
14962                 (const_string "fdiv")
14963              ]
14964              (const_string "fop")))
14965   (set_attr "fp_int_src" "true")
14966   (set_attr "mode" "<MODE>")])
14967
14968(define_insn "*fop_df_3<mode>_i387"
14969  [(set (match_operand:DF 0 "register_operand" "=f,f")
14970	(match_operator:DF 3 "binary_fp_operator"
14971	   [(match_operand:DF 1 "register_operand" "0,0")
14972	    (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14973  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14974   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14975  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14976  [(set (attr "type") 
14977        (cond [(match_operand:DF 3 "mult_operator" "") 
14978                 (const_string "fmul")
14979               (match_operand:DF 3 "div_operator" "") 
14980                 (const_string "fdiv")
14981              ]
14982              (const_string "fop")))
14983   (set_attr "fp_int_src" "true")
14984   (set_attr "mode" "<MODE>")])
14985
14986(define_insn "*fop_df_4_i387"
14987  [(set (match_operand:DF 0 "register_operand" "=f,f")
14988	(match_operator:DF 3 "binary_fp_operator"
14989	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14990	    (match_operand:DF 2 "register_operand" "0,f")]))]
14991  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14992   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14993  "* return output_387_binary_op (insn, operands);"
14994  [(set (attr "type") 
14995        (cond [(match_operand:DF 3 "mult_operator" "") 
14996                 (const_string "fmul")
14997               (match_operand:DF 3 "div_operator" "") 
14998                 (const_string "fdiv")
14999              ]
15000              (const_string "fop")))
15001   (set_attr "mode" "SF")])
15002
15003(define_insn "*fop_df_5_i387"
15004  [(set (match_operand:DF 0 "register_operand" "=f,f")
15005	(match_operator:DF 3 "binary_fp_operator"
15006	  [(match_operand:DF 1 "register_operand" "0,f")
15007	   (float_extend:DF
15008	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15009  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15010  "* return output_387_binary_op (insn, operands);"
15011  [(set (attr "type") 
15012        (cond [(match_operand:DF 3 "mult_operator" "") 
15013                 (const_string "fmul")
15014               (match_operand:DF 3 "div_operator" "") 
15015                 (const_string "fdiv")
15016              ]
15017              (const_string "fop")))
15018   (set_attr "mode" "SF")])
15019
15020(define_insn "*fop_df_6_i387"
15021  [(set (match_operand:DF 0 "register_operand" "=f,f")
15022	(match_operator:DF 3 "binary_fp_operator"
15023	  [(float_extend:DF
15024	    (match_operand:SF 1 "register_operand" "0,f"))
15025	   (float_extend:DF
15026	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15027  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15028  "* return output_387_binary_op (insn, operands);"
15029  [(set (attr "type") 
15030        (cond [(match_operand:DF 3 "mult_operator" "") 
15031                 (const_string "fmul")
15032               (match_operand:DF 3 "div_operator" "") 
15033                 (const_string "fdiv")
15034              ]
15035              (const_string "fop")))
15036   (set_attr "mode" "SF")])
15037
15038(define_insn "*fop_xf_comm_i387"
15039  [(set (match_operand:XF 0 "register_operand" "=f")
15040	(match_operator:XF 3 "binary_fp_operator"
15041			[(match_operand:XF 1 "register_operand" "%0")
15042			 (match_operand:XF 2 "register_operand" "f")]))]
15043  "TARGET_80387
15044   && COMMUTATIVE_ARITH_P (operands[3])"
15045  "* return output_387_binary_op (insn, operands);"
15046  [(set (attr "type") 
15047        (if_then_else (match_operand:XF 3 "mult_operator" "") 
15048           (const_string "fmul")
15049           (const_string "fop")))
15050   (set_attr "mode" "XF")])
15051
15052(define_insn "*fop_xf_1_i387"
15053  [(set (match_operand:XF 0 "register_operand" "=f,f")
15054	(match_operator:XF 3 "binary_fp_operator"
15055			[(match_operand:XF 1 "register_operand" "0,f")
15056			 (match_operand:XF 2 "register_operand" "f,0")]))]
15057  "TARGET_80387
15058   && !COMMUTATIVE_ARITH_P (operands[3])"
15059  "* return output_387_binary_op (insn, operands);"
15060  [(set (attr "type") 
15061        (cond [(match_operand:XF 3 "mult_operator" "") 
15062                 (const_string "fmul")
15063               (match_operand:XF 3 "div_operator" "") 
15064                 (const_string "fdiv")
15065              ]
15066              (const_string "fop")))
15067   (set_attr "mode" "XF")])
15068
15069(define_insn "*fop_xf_2<mode>_i387"
15070  [(set (match_operand:XF 0 "register_operand" "=f,f")
15071	(match_operator:XF 3 "binary_fp_operator"
15072	   [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15073	    (match_operand:XF 2 "register_operand" "0,0")]))]
15074  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15075  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15076  [(set (attr "type") 
15077        (cond [(match_operand:XF 3 "mult_operator" "") 
15078                 (const_string "fmul")
15079               (match_operand:XF 3 "div_operator" "") 
15080                 (const_string "fdiv")
15081              ]
15082              (const_string "fop")))
15083   (set_attr "fp_int_src" "true")
15084   (set_attr "mode" "<MODE>")])
15085
15086(define_insn "*fop_xf_3<mode>_i387"
15087  [(set (match_operand:XF 0 "register_operand" "=f,f")
15088	(match_operator:XF 3 "binary_fp_operator"
15089	  [(match_operand:XF 1 "register_operand" "0,0")
15090	   (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15091  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15092  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15093  [(set (attr "type") 
15094        (cond [(match_operand:XF 3 "mult_operator" "") 
15095                 (const_string "fmul")
15096               (match_operand:XF 3 "div_operator" "") 
15097                 (const_string "fdiv")
15098              ]
15099              (const_string "fop")))
15100   (set_attr "fp_int_src" "true")
15101   (set_attr "mode" "<MODE>")])
15102
15103(define_insn "*fop_xf_4_i387"
15104  [(set (match_operand:XF 0 "register_operand" "=f,f")
15105	(match_operator:XF 3 "binary_fp_operator"
15106	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15107	    (match_operand:XF 2 "register_operand" "0,f")]))]
15108  "TARGET_80387"
15109  "* return output_387_binary_op (insn, operands);"
15110  [(set (attr "type") 
15111        (cond [(match_operand:XF 3 "mult_operator" "") 
15112                 (const_string "fmul")
15113               (match_operand:XF 3 "div_operator" "") 
15114                 (const_string "fdiv")
15115              ]
15116              (const_string "fop")))
15117   (set_attr "mode" "SF")])
15118
15119(define_insn "*fop_xf_5_i387"
15120  [(set (match_operand:XF 0 "register_operand" "=f,f")
15121	(match_operator:XF 3 "binary_fp_operator"
15122	  [(match_operand:XF 1 "register_operand" "0,f")
15123	   (float_extend:XF
15124	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15125  "TARGET_80387"
15126  "* return output_387_binary_op (insn, operands);"
15127  [(set (attr "type") 
15128        (cond [(match_operand:XF 3 "mult_operator" "") 
15129                 (const_string "fmul")
15130               (match_operand:XF 3 "div_operator" "") 
15131                 (const_string "fdiv")
15132              ]
15133              (const_string "fop")))
15134   (set_attr "mode" "SF")])
15135
15136(define_insn "*fop_xf_6_i387"
15137  [(set (match_operand:XF 0 "register_operand" "=f,f")
15138	(match_operator:XF 3 "binary_fp_operator"
15139	  [(float_extend:XF
15140	    (match_operand 1 "register_operand" "0,f"))
15141	   (float_extend:XF
15142	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15143  "TARGET_80387"
15144  "* return output_387_binary_op (insn, operands);"
15145  [(set (attr "type") 
15146        (cond [(match_operand:XF 3 "mult_operator" "") 
15147                 (const_string "fmul")
15148               (match_operand:XF 3 "div_operator" "") 
15149                 (const_string "fdiv")
15150              ]
15151              (const_string "fop")))
15152   (set_attr "mode" "SF")])
15153
15154(define_split
15155  [(set (match_operand 0 "register_operand" "")
15156	(match_operator 3 "binary_fp_operator"
15157	   [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15158	    (match_operand 2 "register_operand" "")]))]
15159  "TARGET_80387 && reload_completed
15160   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15161  [(const_int 0)]
15162{ 
15163  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15164  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15165  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15166			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15167					  GET_MODE (operands[3]),
15168					  operands[4],
15169					  operands[2])));
15170  ix86_free_from_memory (GET_MODE (operands[1]));
15171  DONE;
15172})
15173
15174(define_split
15175  [(set (match_operand 0 "register_operand" "")
15176	(match_operator 3 "binary_fp_operator"
15177	   [(match_operand 1 "register_operand" "")
15178	    (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15179  "TARGET_80387 && reload_completed
15180   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15181  [(const_int 0)]
15182{
15183  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15184  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15185  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15186			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15187					  GET_MODE (operands[3]),
15188					  operands[1],
15189					  operands[4])));
15190  ix86_free_from_memory (GET_MODE (operands[2]));
15191  DONE;
15192})
15193
15194;; FPU special functions.
15195
15196(define_expand "sqrtsf2"
15197  [(set (match_operand:SF 0 "register_operand" "")
15198	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15199  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15200{
15201  if (!TARGET_SSE_MATH)
15202    operands[1] = force_reg (SFmode, operands[1]);
15203})
15204
15205(define_insn "*sqrtsf2_mixed"
15206  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15207	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15208  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15209  "@
15210   fsqrt
15211   sqrtss\t{%1, %0|%0, %1}"
15212  [(set_attr "type" "fpspc,sse")
15213   (set_attr "mode" "SF,SF")
15214   (set_attr "athlon_decode" "direct,*")])
15215
15216(define_insn "*sqrtsf2_sse"
15217  [(set (match_operand:SF 0 "register_operand" "=x")
15218	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15219  "TARGET_SSE_MATH"
15220  "sqrtss\t{%1, %0|%0, %1}"
15221  [(set_attr "type" "sse")
15222   (set_attr "mode" "SF")
15223   (set_attr "athlon_decode" "*")])
15224
15225(define_insn "*sqrtsf2_i387"
15226  [(set (match_operand:SF 0 "register_operand" "=f")
15227	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15228  "TARGET_USE_FANCY_MATH_387"
15229  "fsqrt"
15230  [(set_attr "type" "fpspc")
15231   (set_attr "mode" "SF")
15232   (set_attr "athlon_decode" "direct")])
15233
15234(define_expand "sqrtdf2"
15235  [(set (match_operand:DF 0 "register_operand" "")
15236	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15237  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15238{
15239  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15240    operands[1] = force_reg (DFmode, operands[1]);
15241})
15242
15243(define_insn "*sqrtdf2_mixed"
15244  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15245	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15246  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15247  "@
15248   fsqrt
15249   sqrtsd\t{%1, %0|%0, %1}"
15250  [(set_attr "type" "fpspc,sse")
15251   (set_attr "mode" "DF,DF")
15252   (set_attr "athlon_decode" "direct,*")])
15253
15254(define_insn "*sqrtdf2_sse"
15255  [(set (match_operand:DF 0 "register_operand" "=Y")
15256	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15257  "TARGET_SSE2 && TARGET_SSE_MATH"
15258  "sqrtsd\t{%1, %0|%0, %1}"
15259  [(set_attr "type" "sse")
15260   (set_attr "mode" "DF")
15261   (set_attr "athlon_decode" "*")])
15262
15263(define_insn "*sqrtdf2_i387"
15264  [(set (match_operand:DF 0 "register_operand" "=f")
15265	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15266  "TARGET_USE_FANCY_MATH_387"
15267  "fsqrt"
15268  [(set_attr "type" "fpspc")
15269   (set_attr "mode" "DF")
15270   (set_attr "athlon_decode" "direct")])
15271
15272(define_insn "*sqrtextendsfdf2_i387"
15273  [(set (match_operand:DF 0 "register_operand" "=f")
15274	(sqrt:DF (float_extend:DF
15275		  (match_operand:SF 1 "register_operand" "0"))))]
15276  "TARGET_USE_FANCY_MATH_387
15277   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15278  "fsqrt"
15279  [(set_attr "type" "fpspc")
15280   (set_attr "mode" "DF")
15281   (set_attr "athlon_decode" "direct")])
15282
15283(define_insn "sqrtxf2"
15284  [(set (match_operand:XF 0 "register_operand" "=f")
15285	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15286  "TARGET_USE_FANCY_MATH_387 
15287   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15288  "fsqrt"
15289  [(set_attr "type" "fpspc")
15290   (set_attr "mode" "XF")
15291   (set_attr "athlon_decode" "direct")])
15292
15293(define_insn "*sqrtextendsfxf2_i387"
15294  [(set (match_operand:XF 0 "register_operand" "=f")
15295	(sqrt:XF (float_extend:XF
15296		  (match_operand:SF 1 "register_operand" "0"))))]
15297  "TARGET_USE_FANCY_MATH_387"
15298  "fsqrt"
15299  [(set_attr "type" "fpspc")
15300   (set_attr "mode" "XF")
15301   (set_attr "athlon_decode" "direct")])
15302
15303(define_insn "*sqrtextenddfxf2_i387"
15304  [(set (match_operand:XF 0 "register_operand" "=f")
15305	(sqrt:XF (float_extend:XF
15306		  (match_operand:DF 1 "register_operand" "0"))))]
15307  "TARGET_USE_FANCY_MATH_387"
15308  "fsqrt"
15309  [(set_attr "type" "fpspc")
15310   (set_attr "mode" "XF")
15311   (set_attr "athlon_decode" "direct")])
15312
15313(define_insn "fpremxf4"
15314  [(set (match_operand:XF 0 "register_operand" "=f")
15315	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15316		    (match_operand:XF 3 "register_operand" "1")]
15317		   UNSPEC_FPREM_F))
15318   (set (match_operand:XF 1 "register_operand" "=u")
15319	(unspec:XF [(match_dup 2) (match_dup 3)]
15320		   UNSPEC_FPREM_U))
15321   (set (reg:CCFP FPSR_REG)
15322	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15323  "TARGET_USE_FANCY_MATH_387
15324   && flag_unsafe_math_optimizations"
15325  "fprem"
15326  [(set_attr "type" "fpspc")
15327   (set_attr "mode" "XF")])
15328
15329(define_expand "fmodsf3"
15330  [(use (match_operand:SF 0 "register_operand" ""))
15331   (use (match_operand:SF 1 "register_operand" ""))
15332   (use (match_operand:SF 2 "register_operand" ""))]
15333  "TARGET_USE_FANCY_MATH_387
15334   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15335   && flag_unsafe_math_optimizations"
15336{
15337  rtx label = gen_label_rtx ();
15338
15339  rtx op1 = gen_reg_rtx (XFmode);
15340  rtx op2 = gen_reg_rtx (XFmode);
15341
15342  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15343  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15344
15345  emit_label (label);
15346
15347  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15348  ix86_emit_fp_unordered_jump (label);
15349
15350  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15351  DONE;
15352})
15353
15354(define_expand "fmoddf3"
15355  [(use (match_operand:DF 0 "register_operand" ""))
15356   (use (match_operand:DF 1 "register_operand" ""))
15357   (use (match_operand:DF 2 "register_operand" ""))]
15358  "TARGET_USE_FANCY_MATH_387
15359   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15360   && flag_unsafe_math_optimizations"
15361{
15362  rtx label = gen_label_rtx ();
15363
15364  rtx op1 = gen_reg_rtx (XFmode);
15365  rtx op2 = gen_reg_rtx (XFmode);
15366
15367  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15368  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15369
15370  emit_label (label);
15371
15372  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15373  ix86_emit_fp_unordered_jump (label);
15374
15375  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15376  DONE;
15377})
15378
15379(define_expand "fmodxf3"
15380  [(use (match_operand:XF 0 "register_operand" ""))
15381   (use (match_operand:XF 1 "register_operand" ""))
15382   (use (match_operand:XF 2 "register_operand" ""))]
15383  "TARGET_USE_FANCY_MATH_387
15384   && flag_unsafe_math_optimizations"
15385{
15386  rtx label = gen_label_rtx ();
15387
15388  emit_label (label);
15389
15390  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15391			   operands[1], operands[2]));
15392  ix86_emit_fp_unordered_jump (label);
15393
15394  emit_move_insn (operands[0], operands[1]);
15395  DONE;
15396})
15397
15398(define_insn "fprem1xf4"
15399  [(set (match_operand:XF 0 "register_operand" "=f")
15400	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15401		    (match_operand:XF 3 "register_operand" "1")]
15402		   UNSPEC_FPREM1_F))
15403   (set (match_operand:XF 1 "register_operand" "=u")
15404	(unspec:XF [(match_dup 2) (match_dup 3)]
15405		   UNSPEC_FPREM1_U))
15406   (set (reg:CCFP FPSR_REG)
15407	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15408  "TARGET_USE_FANCY_MATH_387
15409   && flag_unsafe_math_optimizations"
15410  "fprem1"
15411  [(set_attr "type" "fpspc")
15412   (set_attr "mode" "XF")])
15413
15414(define_expand "dremsf3"
15415  [(use (match_operand:SF 0 "register_operand" ""))
15416   (use (match_operand:SF 1 "register_operand" ""))
15417   (use (match_operand:SF 2 "register_operand" ""))]
15418  "TARGET_USE_FANCY_MATH_387
15419   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15420   && flag_unsafe_math_optimizations"
15421{
15422  rtx label = gen_label_rtx ();
15423
15424  rtx op1 = gen_reg_rtx (XFmode);
15425  rtx op2 = gen_reg_rtx (XFmode);
15426
15427  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15428  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15429
15430  emit_label (label);
15431
15432  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15433  ix86_emit_fp_unordered_jump (label);
15434
15435  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15436  DONE;
15437})
15438
15439(define_expand "dremdf3"
15440  [(use (match_operand:DF 0 "register_operand" ""))
15441   (use (match_operand:DF 1 "register_operand" ""))
15442   (use (match_operand:DF 2 "register_operand" ""))]
15443  "TARGET_USE_FANCY_MATH_387
15444   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15445   && flag_unsafe_math_optimizations"
15446{
15447  rtx label = gen_label_rtx ();
15448
15449  rtx op1 = gen_reg_rtx (XFmode);
15450  rtx op2 = gen_reg_rtx (XFmode);
15451
15452  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15453  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15454
15455  emit_label (label);
15456
15457  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15458  ix86_emit_fp_unordered_jump (label);
15459
15460  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15461  DONE;
15462})
15463
15464(define_expand "dremxf3"
15465  [(use (match_operand:XF 0 "register_operand" ""))
15466   (use (match_operand:XF 1 "register_operand" ""))
15467   (use (match_operand:XF 2 "register_operand" ""))]
15468  "TARGET_USE_FANCY_MATH_387
15469   && flag_unsafe_math_optimizations"
15470{
15471  rtx label = gen_label_rtx ();
15472
15473  emit_label (label);
15474
15475  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15476			    operands[1], operands[2]));
15477  ix86_emit_fp_unordered_jump (label);
15478
15479  emit_move_insn (operands[0], operands[1]);
15480  DONE;
15481})
15482
15483(define_insn "*sindf2"
15484  [(set (match_operand:DF 0 "register_operand" "=f")
15485	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15486  "TARGET_USE_FANCY_MATH_387
15487   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15488   && flag_unsafe_math_optimizations"
15489  "fsin"
15490  [(set_attr "type" "fpspc")
15491   (set_attr "mode" "DF")])
15492
15493(define_insn "*sinsf2"
15494  [(set (match_operand:SF 0 "register_operand" "=f")
15495	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15496  "TARGET_USE_FANCY_MATH_387
15497   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15498   && flag_unsafe_math_optimizations"
15499  "fsin"
15500  [(set_attr "type" "fpspc")
15501   (set_attr "mode" "SF")])
15502
15503(define_insn "*sinextendsfdf2"
15504  [(set (match_operand:DF 0 "register_operand" "=f")
15505	(unspec:DF [(float_extend:DF
15506		     (match_operand:SF 1 "register_operand" "0"))]
15507		   UNSPEC_SIN))]
15508  "TARGET_USE_FANCY_MATH_387
15509   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15510   && flag_unsafe_math_optimizations"
15511  "fsin"
15512  [(set_attr "type" "fpspc")
15513   (set_attr "mode" "DF")])
15514
15515(define_insn "*sinxf2"
15516  [(set (match_operand:XF 0 "register_operand" "=f")
15517	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15518  "TARGET_USE_FANCY_MATH_387
15519   && flag_unsafe_math_optimizations"
15520  "fsin"
15521  [(set_attr "type" "fpspc")
15522   (set_attr "mode" "XF")])
15523
15524(define_insn "*cosdf2"
15525  [(set (match_operand:DF 0 "register_operand" "=f")
15526	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15527  "TARGET_USE_FANCY_MATH_387
15528   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15529   && flag_unsafe_math_optimizations"
15530  "fcos"
15531  [(set_attr "type" "fpspc")
15532   (set_attr "mode" "DF")])
15533
15534(define_insn "*cossf2"
15535  [(set (match_operand:SF 0 "register_operand" "=f")
15536	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15537  "TARGET_USE_FANCY_MATH_387
15538   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15539   && flag_unsafe_math_optimizations"
15540  "fcos"
15541  [(set_attr "type" "fpspc")
15542   (set_attr "mode" "SF")])
15543
15544(define_insn "*cosextendsfdf2"
15545  [(set (match_operand:DF 0 "register_operand" "=f")
15546	(unspec:DF [(float_extend:DF
15547		     (match_operand:SF 1 "register_operand" "0"))]
15548		   UNSPEC_COS))]
15549  "TARGET_USE_FANCY_MATH_387
15550   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15551   && flag_unsafe_math_optimizations"
15552  "fcos"
15553  [(set_attr "type" "fpspc")
15554   (set_attr "mode" "DF")])
15555
15556(define_insn "*cosxf2"
15557  [(set (match_operand:XF 0 "register_operand" "=f")
15558	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15559  "TARGET_USE_FANCY_MATH_387
15560   && flag_unsafe_math_optimizations"
15561  "fcos"
15562  [(set_attr "type" "fpspc")
15563   (set_attr "mode" "XF")])
15564
15565;; With sincos pattern defined, sin and cos builtin function will be
15566;; expanded to sincos pattern with one of its outputs left unused. 
15567;; Cse pass  will detected, if two sincos patterns can be combined,
15568;; otherwise sincos pattern will be split back to sin or cos pattern,
15569;; depending on the unused output.
15570
15571(define_insn "sincosdf3"
15572  [(set (match_operand:DF 0 "register_operand" "=f")
15573	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15574		   UNSPEC_SINCOS_COS))
15575   (set (match_operand:DF 1 "register_operand" "=u")
15576        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15577  "TARGET_USE_FANCY_MATH_387
15578   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15579   && flag_unsafe_math_optimizations"
15580  "fsincos"
15581  [(set_attr "type" "fpspc")
15582   (set_attr "mode" "DF")])
15583
15584(define_split
15585  [(set (match_operand:DF 0 "register_operand" "")
15586	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15587		   UNSPEC_SINCOS_COS))
15588   (set (match_operand:DF 1 "register_operand" "")
15589	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15590  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15591   && !reload_completed && !reload_in_progress"
15592  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15593  "")
15594
15595(define_split
15596  [(set (match_operand:DF 0 "register_operand" "")
15597	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15598		   UNSPEC_SINCOS_COS))
15599   (set (match_operand:DF 1 "register_operand" "")
15600	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15601  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15602   && !reload_completed && !reload_in_progress"
15603  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15604  "")
15605
15606(define_insn "sincossf3"
15607  [(set (match_operand:SF 0 "register_operand" "=f")
15608	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15609		   UNSPEC_SINCOS_COS))
15610   (set (match_operand:SF 1 "register_operand" "=u")
15611        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15612  "TARGET_USE_FANCY_MATH_387
15613   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15614   && flag_unsafe_math_optimizations"
15615  "fsincos"
15616  [(set_attr "type" "fpspc")
15617   (set_attr "mode" "SF")])
15618
15619(define_split
15620  [(set (match_operand:SF 0 "register_operand" "")
15621	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15622		   UNSPEC_SINCOS_COS))
15623   (set (match_operand:SF 1 "register_operand" "")
15624	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15625  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15626   && !reload_completed && !reload_in_progress"
15627  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15628  "")
15629
15630(define_split
15631  [(set (match_operand:SF 0 "register_operand" "")
15632	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15633		   UNSPEC_SINCOS_COS))
15634   (set (match_operand:SF 1 "register_operand" "")
15635	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15636  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15637   && !reload_completed && !reload_in_progress"
15638  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15639  "")
15640
15641(define_insn "*sincosextendsfdf3"
15642  [(set (match_operand:DF 0 "register_operand" "=f")
15643	(unspec:DF [(float_extend:DF
15644		     (match_operand:SF 2 "register_operand" "0"))]
15645		   UNSPEC_SINCOS_COS))
15646   (set (match_operand:DF 1 "register_operand" "=u")
15647        (unspec:DF [(float_extend:DF
15648		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15649  "TARGET_USE_FANCY_MATH_387
15650   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15651   && flag_unsafe_math_optimizations"
15652  "fsincos"
15653  [(set_attr "type" "fpspc")
15654   (set_attr "mode" "DF")])
15655
15656(define_split
15657  [(set (match_operand:DF 0 "register_operand" "")
15658	(unspec:DF [(float_extend:DF
15659		     (match_operand:SF 2 "register_operand" ""))]
15660		   UNSPEC_SINCOS_COS))
15661   (set (match_operand:DF 1 "register_operand" "")
15662        (unspec:DF [(float_extend:DF
15663		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15664  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15665   && !reload_completed && !reload_in_progress"
15666  [(set (match_dup 1) (unspec:DF [(float_extend:DF
15667				   (match_dup 2))] UNSPEC_SIN))]
15668  "")
15669
15670(define_split
15671  [(set (match_operand:DF 0 "register_operand" "")
15672	(unspec:DF [(float_extend:DF
15673		     (match_operand:SF 2 "register_operand" ""))]
15674		   UNSPEC_SINCOS_COS))
15675   (set (match_operand:DF 1 "register_operand" "")
15676        (unspec:DF [(float_extend:DF
15677		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15678  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15679   && !reload_completed && !reload_in_progress"
15680  [(set (match_dup 0) (unspec:DF [(float_extend:DF
15681				   (match_dup 2))] UNSPEC_COS))]
15682  "")
15683
15684(define_insn "sincosxf3"
15685  [(set (match_operand:XF 0 "register_operand" "=f")
15686	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15687		   UNSPEC_SINCOS_COS))
15688   (set (match_operand:XF 1 "register_operand" "=u")
15689        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15690  "TARGET_USE_FANCY_MATH_387
15691   && flag_unsafe_math_optimizations"
15692  "fsincos"
15693  [(set_attr "type" "fpspc")
15694   (set_attr "mode" "XF")])
15695
15696(define_split
15697  [(set (match_operand:XF 0 "register_operand" "")
15698	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15699		   UNSPEC_SINCOS_COS))
15700   (set (match_operand:XF 1 "register_operand" "")
15701	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15702  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15703   && !reload_completed && !reload_in_progress"
15704  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15705  "")
15706
15707(define_split
15708  [(set (match_operand:XF 0 "register_operand" "")
15709	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15710		   UNSPEC_SINCOS_COS))
15711   (set (match_operand:XF 1 "register_operand" "")
15712	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15713  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15714   && !reload_completed && !reload_in_progress"
15715  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15716  "")
15717
15718(define_insn "*tandf3_1"
15719  [(set (match_operand:DF 0 "register_operand" "=f")
15720	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15721		   UNSPEC_TAN_ONE))
15722   (set (match_operand:DF 1 "register_operand" "=u")
15723        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15724  "TARGET_USE_FANCY_MATH_387
15725   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15726   && flag_unsafe_math_optimizations"
15727  "fptan"
15728  [(set_attr "type" "fpspc")
15729   (set_attr "mode" "DF")])
15730
15731;; optimize sequence: fptan
15732;;		      fstp    %st(0)
15733;;		      fld1
15734;; into fptan insn.
15735
15736(define_peephole2
15737  [(parallel[(set (match_operand:DF 0 "register_operand" "")
15738		  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15739			     UNSPEC_TAN_ONE))
15740	     (set (match_operand:DF 1 "register_operand" "")
15741		  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15742   (set (match_dup 0)
15743        (match_operand:DF 3 "immediate_operand" ""))]
15744  "standard_80387_constant_p (operands[3]) == 2"
15745  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15746   	     (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15747  "")
15748
15749(define_expand "tandf2"
15750  [(parallel [(set (match_dup 2)
15751		   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15752			      UNSPEC_TAN_ONE))
15753	      (set (match_operand:DF 0 "register_operand" "")
15754		   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15755  "TARGET_USE_FANCY_MATH_387
15756   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15757   && flag_unsafe_math_optimizations"
15758{
15759  operands[2] = gen_reg_rtx (DFmode);
15760})
15761
15762(define_insn "*tansf3_1"
15763  [(set (match_operand:SF 0 "register_operand" "=f")
15764	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15765		   UNSPEC_TAN_ONE))
15766   (set (match_operand:SF 1 "register_operand" "=u")
15767        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15768  "TARGET_USE_FANCY_MATH_387
15769   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15770   && flag_unsafe_math_optimizations"
15771  "fptan"
15772  [(set_attr "type" "fpspc")
15773   (set_attr "mode" "SF")])
15774
15775;; optimize sequence: fptan
15776;;		      fstp    %st(0)
15777;;		      fld1
15778;; into fptan insn.
15779
15780(define_peephole2
15781  [(parallel[(set (match_operand:SF 0 "register_operand" "")
15782		  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15783			     UNSPEC_TAN_ONE))
15784	     (set (match_operand:SF 1 "register_operand" "")
15785		  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15786   (set (match_dup 0)
15787        (match_operand:SF 3 "immediate_operand" ""))]
15788  "standard_80387_constant_p (operands[3]) == 2"
15789  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15790   	     (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15791  "")
15792
15793(define_expand "tansf2"
15794  [(parallel [(set (match_dup 2)
15795		   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15796			      UNSPEC_TAN_ONE))
15797	      (set (match_operand:SF 0 "register_operand" "")
15798		   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15799  "TARGET_USE_FANCY_MATH_387
15800   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15801   && flag_unsafe_math_optimizations"
15802{
15803  operands[2] = gen_reg_rtx (SFmode);
15804})
15805
15806(define_insn "*tanxf3_1"
15807  [(set (match_operand:XF 0 "register_operand" "=f")
15808	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15809		   UNSPEC_TAN_ONE))
15810   (set (match_operand:XF 1 "register_operand" "=u")
15811        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15812  "TARGET_USE_FANCY_MATH_387
15813   && flag_unsafe_math_optimizations"
15814  "fptan"
15815  [(set_attr "type" "fpspc")
15816   (set_attr "mode" "XF")])
15817
15818;; optimize sequence: fptan
15819;;		      fstp    %st(0)
15820;;		      fld1
15821;; into fptan insn.
15822
15823(define_peephole2
15824  [(parallel[(set (match_operand:XF 0 "register_operand" "")
15825		  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15826			     UNSPEC_TAN_ONE))
15827	     (set (match_operand:XF 1 "register_operand" "")
15828		  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15829   (set (match_dup 0)
15830        (match_operand:XF 3 "immediate_operand" ""))]
15831  "standard_80387_constant_p (operands[3]) == 2"
15832  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15833   	     (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15834  "")
15835
15836(define_expand "tanxf2"
15837  [(parallel [(set (match_dup 2)
15838		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15839			      UNSPEC_TAN_ONE))
15840	      (set (match_operand:XF 0 "register_operand" "")
15841		   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15842  "TARGET_USE_FANCY_MATH_387
15843   && flag_unsafe_math_optimizations"
15844{
15845  operands[2] = gen_reg_rtx (XFmode);
15846})
15847
15848(define_insn "atan2df3_1"
15849  [(set (match_operand:DF 0 "register_operand" "=f")
15850	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
15851		    (match_operand:DF 1 "register_operand" "u")]
15852		   UNSPEC_FPATAN))
15853   (clobber (match_scratch:DF 3 "=1"))]
15854  "TARGET_USE_FANCY_MATH_387
15855   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15856   && flag_unsafe_math_optimizations"
15857  "fpatan"
15858  [(set_attr "type" "fpspc")
15859   (set_attr "mode" "DF")])
15860
15861(define_expand "atan2df3"
15862  [(use (match_operand:DF 0 "register_operand" ""))
15863   (use (match_operand:DF 2 "register_operand" ""))
15864   (use (match_operand:DF 1 "register_operand" ""))]
15865  "TARGET_USE_FANCY_MATH_387
15866   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15867   && flag_unsafe_math_optimizations"
15868{
15869  rtx copy = gen_reg_rtx (DFmode);
15870  emit_move_insn (copy, operands[1]);
15871  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15872  DONE;
15873})
15874
15875(define_expand "atandf2"
15876  [(parallel [(set (match_operand:DF 0 "register_operand" "")
15877		   (unspec:DF [(match_dup 2)
15878			       (match_operand:DF 1 "register_operand" "")]
15879		    UNSPEC_FPATAN))
15880	      (clobber (match_scratch:DF 3 ""))])]
15881  "TARGET_USE_FANCY_MATH_387
15882   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15883   && flag_unsafe_math_optimizations"
15884{
15885  operands[2] = gen_reg_rtx (DFmode);
15886  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15887})
15888
15889(define_insn "atan2sf3_1"
15890  [(set (match_operand:SF 0 "register_operand" "=f")
15891        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15892		    (match_operand:SF 1 "register_operand" "u")]
15893		   UNSPEC_FPATAN))
15894   (clobber (match_scratch:SF 3 "=1"))]
15895  "TARGET_USE_FANCY_MATH_387
15896   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897   && flag_unsafe_math_optimizations"
15898  "fpatan"
15899  [(set_attr "type" "fpspc")
15900   (set_attr "mode" "SF")])
15901
15902(define_expand "atan2sf3"
15903  [(use (match_operand:SF 0 "register_operand" ""))
15904   (use (match_operand:SF 2 "register_operand" ""))
15905   (use (match_operand:SF 1 "register_operand" ""))]
15906  "TARGET_USE_FANCY_MATH_387
15907   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15908   && flag_unsafe_math_optimizations"
15909{
15910  rtx copy = gen_reg_rtx (SFmode);
15911  emit_move_insn (copy, operands[1]);
15912  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15913  DONE;
15914})
15915
15916(define_expand "atansf2"
15917  [(parallel [(set (match_operand:SF 0 "register_operand" "")
15918		   (unspec:SF [(match_dup 2)
15919			       (match_operand:SF 1 "register_operand" "")]
15920		    UNSPEC_FPATAN))
15921	      (clobber (match_scratch:SF 3 ""))])]
15922  "TARGET_USE_FANCY_MATH_387
15923   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15924   && flag_unsafe_math_optimizations"
15925{
15926  operands[2] = gen_reg_rtx (SFmode);
15927  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15928})
15929
15930(define_insn "atan2xf3_1"
15931  [(set (match_operand:XF 0 "register_operand" "=f")
15932        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15933	            (match_operand:XF 1 "register_operand" "u")]
15934	           UNSPEC_FPATAN))
15935   (clobber (match_scratch:XF 3 "=1"))]
15936  "TARGET_USE_FANCY_MATH_387
15937   && flag_unsafe_math_optimizations"
15938  "fpatan"
15939  [(set_attr "type" "fpspc")
15940   (set_attr "mode" "XF")])
15941
15942(define_expand "atan2xf3"
15943  [(use (match_operand:XF 0 "register_operand" ""))
15944   (use (match_operand:XF 2 "register_operand" ""))
15945   (use (match_operand:XF 1 "register_operand" ""))]
15946  "TARGET_USE_FANCY_MATH_387
15947   && flag_unsafe_math_optimizations"
15948{
15949  rtx copy = gen_reg_rtx (XFmode);
15950  emit_move_insn (copy, operands[1]);
15951  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15952  DONE;
15953})
15954
15955(define_expand "atanxf2"
15956  [(parallel [(set (match_operand:XF 0 "register_operand" "")
15957		   (unspec:XF [(match_dup 2)
15958			       (match_operand:XF 1 "register_operand" "")]
15959		    UNSPEC_FPATAN))
15960	      (clobber (match_scratch:XF 3 ""))])]
15961  "TARGET_USE_FANCY_MATH_387
15962   && flag_unsafe_math_optimizations"
15963{
15964  operands[2] = gen_reg_rtx (XFmode);
15965  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15966})
15967
15968(define_expand "asindf2"
15969  [(set (match_dup 2)
15970	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
15971   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15972   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15973   (set (match_dup 6) (sqrt:XF (match_dup 5)))
15974   (parallel [(set (match_dup 7)
15975        	   (unspec:XF [(match_dup 6) (match_dup 2)]
15976			      UNSPEC_FPATAN))
15977   	      (clobber (match_scratch:XF 8 ""))])
15978   (set (match_operand:DF 0 "register_operand" "")
15979	(float_truncate:DF (match_dup 7)))]
15980  "TARGET_USE_FANCY_MATH_387
15981   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15982   && flag_unsafe_math_optimizations"
15983{
15984  int i;
15985
15986  for (i=2; i<8; i++)
15987    operands[i] = gen_reg_rtx (XFmode);
15988
15989  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15990})
15991
15992(define_expand "asinsf2"
15993  [(set (match_dup 2)
15994	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
15995   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15996   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15997   (set (match_dup 6) (sqrt:XF (match_dup 5)))
15998   (parallel [(set (match_dup 7)
15999        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16000			      UNSPEC_FPATAN))
16001   	      (clobber (match_scratch:XF 8 ""))])
16002   (set (match_operand:SF 0 "register_operand" "")
16003	(float_truncate:SF (match_dup 7)))]
16004  "TARGET_USE_FANCY_MATH_387
16005   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16006   && flag_unsafe_math_optimizations"
16007{
16008  int i;
16009
16010  for (i=2; i<8; i++)
16011    operands[i] = gen_reg_rtx (XFmode);
16012
16013  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16014})
16015
16016(define_expand "asinxf2"
16017  [(set (match_dup 2)
16018	(mult:XF (match_operand:XF 1 "register_operand" "")
16019		 (match_dup 1)))
16020   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16021   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16022   (parallel [(set (match_operand:XF 0 "register_operand" "")
16023        	   (unspec:XF [(match_dup 5) (match_dup 1)]
16024			      UNSPEC_FPATAN))
16025   	      (clobber (match_scratch:XF 6 ""))])]
16026  "TARGET_USE_FANCY_MATH_387
16027   && flag_unsafe_math_optimizations"
16028{
16029  int i;
16030
16031  for (i=2; i<6; i++)
16032    operands[i] = gen_reg_rtx (XFmode);
16033
16034  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16035})
16036
16037(define_expand "acosdf2"
16038  [(set (match_dup 2)
16039	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16040   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16041   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16042   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16043   (parallel [(set (match_dup 7)
16044        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16045			      UNSPEC_FPATAN))
16046   	      (clobber (match_scratch:XF 8 ""))])
16047   (set (match_operand:DF 0 "register_operand" "")
16048	(float_truncate:DF (match_dup 7)))]
16049  "TARGET_USE_FANCY_MATH_387
16050   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16051   && flag_unsafe_math_optimizations"
16052{
16053  int i;
16054
16055  for (i=2; i<8; i++)
16056    operands[i] = gen_reg_rtx (XFmode);
16057
16058  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16059})
16060
16061(define_expand "acossf2"
16062  [(set (match_dup 2)
16063	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16064   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16065   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16066   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16067   (parallel [(set (match_dup 7)
16068        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16069			      UNSPEC_FPATAN))
16070   	      (clobber (match_scratch:XF 8 ""))])
16071   (set (match_operand:SF 0 "register_operand" "")
16072	(float_truncate:SF (match_dup 7)))]
16073  "TARGET_USE_FANCY_MATH_387
16074   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16075   && flag_unsafe_math_optimizations"
16076{
16077  int i;
16078
16079  for (i=2; i<8; i++)
16080    operands[i] = gen_reg_rtx (XFmode);
16081
16082  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16083})
16084
16085(define_expand "acosxf2"
16086  [(set (match_dup 2)
16087	(mult:XF (match_operand:XF 1 "register_operand" "")
16088		 (match_dup 1)))
16089   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16090   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16091   (parallel [(set (match_operand:XF 0 "register_operand" "")
16092        	   (unspec:XF [(match_dup 1) (match_dup 5)]
16093			      UNSPEC_FPATAN))
16094   	      (clobber (match_scratch:XF 6 ""))])]
16095  "TARGET_USE_FANCY_MATH_387
16096   && flag_unsafe_math_optimizations"
16097{
16098  int i;
16099
16100  for (i=2; i<6; i++)
16101    operands[i] = gen_reg_rtx (XFmode);
16102
16103  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16104})
16105
16106(define_insn "fyl2x_xf3"
16107  [(set (match_operand:XF 0 "register_operand" "=f")
16108        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16109		    (match_operand:XF 1 "register_operand" "u")]
16110	           UNSPEC_FYL2X))
16111   (clobber (match_scratch:XF 3 "=1"))]
16112  "TARGET_USE_FANCY_MATH_387
16113   && flag_unsafe_math_optimizations"
16114  "fyl2x"
16115  [(set_attr "type" "fpspc")
16116   (set_attr "mode" "XF")])
16117
16118(define_expand "logsf2"
16119  [(set (match_dup 2)
16120	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16121   (parallel [(set (match_dup 4)
16122		   (unspec:XF [(match_dup 2)
16123			       (match_dup 3)] UNSPEC_FYL2X))
16124	      (clobber (match_scratch:XF 5 ""))])
16125   (set (match_operand:SF 0 "register_operand" "")
16126	(float_truncate:SF (match_dup 4)))]
16127  "TARGET_USE_FANCY_MATH_387
16128   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16129   && flag_unsafe_math_optimizations"
16130{
16131  rtx temp;
16132
16133  operands[2] = gen_reg_rtx (XFmode);
16134  operands[3] = gen_reg_rtx (XFmode);
16135  operands[4] = gen_reg_rtx (XFmode);
16136
16137  temp = standard_80387_constant_rtx (4); /* fldln2 */
16138  emit_move_insn (operands[3], temp);
16139})
16140
16141(define_expand "logdf2"
16142  [(set (match_dup 2)
16143	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16144   (parallel [(set (match_dup 4)
16145		   (unspec:XF [(match_dup 2)
16146			       (match_dup 3)] UNSPEC_FYL2X))
16147	      (clobber (match_scratch:XF 5 ""))])
16148   (set (match_operand:DF 0 "register_operand" "")
16149	(float_truncate:DF (match_dup 4)))]
16150  "TARGET_USE_FANCY_MATH_387
16151   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16152   && flag_unsafe_math_optimizations"
16153{
16154  rtx temp;
16155
16156  operands[2] = gen_reg_rtx (XFmode);
16157  operands[3] = gen_reg_rtx (XFmode);
16158  operands[4] = gen_reg_rtx (XFmode);
16159
16160  temp = standard_80387_constant_rtx (4); /* fldln2 */
16161  emit_move_insn (operands[3], temp);
16162})
16163
16164(define_expand "logxf2"
16165  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16166		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16167			       (match_dup 2)] UNSPEC_FYL2X))
16168	      (clobber (match_scratch:XF 3 ""))])]
16169  "TARGET_USE_FANCY_MATH_387
16170   && flag_unsafe_math_optimizations"
16171{
16172  rtx temp;
16173
16174  operands[2] = gen_reg_rtx (XFmode);
16175  temp = standard_80387_constant_rtx (4); /* fldln2 */
16176  emit_move_insn (operands[2], temp);
16177})
16178
16179(define_expand "log10sf2"
16180  [(set (match_dup 2)
16181	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16182   (parallel [(set (match_dup 4)
16183		   (unspec:XF [(match_dup 2)
16184			       (match_dup 3)] UNSPEC_FYL2X))
16185	      (clobber (match_scratch:XF 5 ""))])
16186   (set (match_operand:SF 0 "register_operand" "")
16187	(float_truncate:SF (match_dup 4)))]
16188  "TARGET_USE_FANCY_MATH_387
16189   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190   && flag_unsafe_math_optimizations"
16191{
16192  rtx temp;
16193
16194  operands[2] = gen_reg_rtx (XFmode);
16195  operands[3] = gen_reg_rtx (XFmode);
16196  operands[4] = gen_reg_rtx (XFmode);
16197
16198  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16199  emit_move_insn (operands[3], temp);
16200})
16201
16202(define_expand "log10df2"
16203  [(set (match_dup 2)
16204	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16205   (parallel [(set (match_dup 4)
16206		   (unspec:XF [(match_dup 2)
16207			       (match_dup 3)] UNSPEC_FYL2X))
16208	      (clobber (match_scratch:XF 5 ""))])
16209   (set (match_operand:DF 0 "register_operand" "")
16210	(float_truncate:DF (match_dup 4)))]
16211  "TARGET_USE_FANCY_MATH_387
16212   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16213   && flag_unsafe_math_optimizations"
16214{
16215  rtx temp;
16216
16217  operands[2] = gen_reg_rtx (XFmode);
16218  operands[3] = gen_reg_rtx (XFmode);
16219  operands[4] = gen_reg_rtx (XFmode);
16220
16221  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16222  emit_move_insn (operands[3], temp);
16223})
16224
16225(define_expand "log10xf2"
16226  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16227		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16228			       (match_dup 2)] UNSPEC_FYL2X))
16229	      (clobber (match_scratch:XF 3 ""))])]
16230  "TARGET_USE_FANCY_MATH_387
16231   && flag_unsafe_math_optimizations"
16232{
16233  rtx temp;
16234
16235  operands[2] = gen_reg_rtx (XFmode);
16236  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16237  emit_move_insn (operands[2], temp);
16238})
16239
16240(define_expand "log2sf2"
16241  [(set (match_dup 2)
16242	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16243   (parallel [(set (match_dup 4)
16244		   (unspec:XF [(match_dup 2)
16245			       (match_dup 3)] UNSPEC_FYL2X))
16246	      (clobber (match_scratch:XF 5 ""))])
16247   (set (match_operand:SF 0 "register_operand" "")
16248	(float_truncate:SF (match_dup 4)))]
16249  "TARGET_USE_FANCY_MATH_387
16250   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16251   && flag_unsafe_math_optimizations"
16252{
16253  operands[2] = gen_reg_rtx (XFmode);
16254  operands[3] = gen_reg_rtx (XFmode);
16255  operands[4] = gen_reg_rtx (XFmode);
16256
16257  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16258})
16259
16260(define_expand "log2df2"
16261  [(set (match_dup 2)
16262	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16263   (parallel [(set (match_dup 4)
16264		   (unspec:XF [(match_dup 2)
16265			       (match_dup 3)] UNSPEC_FYL2X))
16266	      (clobber (match_scratch:XF 5 ""))])
16267   (set (match_operand:DF 0 "register_operand" "")
16268	(float_truncate:DF (match_dup 4)))]
16269  "TARGET_USE_FANCY_MATH_387
16270   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16271   && flag_unsafe_math_optimizations"
16272{
16273  operands[2] = gen_reg_rtx (XFmode);
16274  operands[3] = gen_reg_rtx (XFmode);
16275  operands[4] = gen_reg_rtx (XFmode);
16276
16277  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16278})
16279
16280(define_expand "log2xf2"
16281  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16282		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16283			       (match_dup 2)] UNSPEC_FYL2X))
16284	      (clobber (match_scratch:XF 3 ""))])]
16285  "TARGET_USE_FANCY_MATH_387
16286   && flag_unsafe_math_optimizations"
16287{
16288  operands[2] = gen_reg_rtx (XFmode);
16289  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16290})
16291
16292(define_insn "fyl2xp1_xf3"
16293  [(set (match_operand:XF 0 "register_operand" "=f")
16294        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16295		    (match_operand:XF 1 "register_operand" "u")]
16296	           UNSPEC_FYL2XP1))
16297   (clobber (match_scratch:XF 3 "=1"))]
16298  "TARGET_USE_FANCY_MATH_387
16299   && flag_unsafe_math_optimizations"
16300  "fyl2xp1"
16301  [(set_attr "type" "fpspc")
16302   (set_attr "mode" "XF")])
16303
16304(define_expand "log1psf2"
16305  [(use (match_operand:SF 0 "register_operand" ""))
16306   (use (match_operand:SF 1 "register_operand" ""))]
16307  "TARGET_USE_FANCY_MATH_387
16308   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16309   && flag_unsafe_math_optimizations"
16310{
16311  rtx op0 = gen_reg_rtx (XFmode);
16312  rtx op1 = gen_reg_rtx (XFmode);
16313
16314  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16315  ix86_emit_i387_log1p (op0, op1);
16316  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16317  DONE;
16318})
16319
16320(define_expand "log1pdf2"
16321  [(use (match_operand:DF 0 "register_operand" ""))
16322   (use (match_operand:DF 1 "register_operand" ""))]
16323  "TARGET_USE_FANCY_MATH_387
16324   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16325   && flag_unsafe_math_optimizations"
16326{
16327  rtx op0 = gen_reg_rtx (XFmode);
16328  rtx op1 = gen_reg_rtx (XFmode);
16329
16330  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16331  ix86_emit_i387_log1p (op0, op1);
16332  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16333  DONE;
16334})
16335
16336(define_expand "log1pxf2"
16337  [(use (match_operand:XF 0 "register_operand" ""))
16338   (use (match_operand:XF 1 "register_operand" ""))]
16339  "TARGET_USE_FANCY_MATH_387
16340   && flag_unsafe_math_optimizations"
16341{
16342  ix86_emit_i387_log1p (operands[0], operands[1]);
16343  DONE;
16344})
16345
16346(define_insn "*fxtractxf3"
16347  [(set (match_operand:XF 0 "register_operand" "=f")
16348	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16349		   UNSPEC_XTRACT_FRACT))
16350   (set (match_operand:XF 1 "register_operand" "=u")
16351        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16352  "TARGET_USE_FANCY_MATH_387
16353   && flag_unsafe_math_optimizations"
16354  "fxtract"
16355  [(set_attr "type" "fpspc")
16356   (set_attr "mode" "XF")])
16357
16358(define_expand "logbsf2"
16359  [(set (match_dup 2)
16360	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16361   (parallel [(set (match_dup 3)
16362		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16363	      (set (match_dup 4)
16364		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16365   (set (match_operand:SF 0 "register_operand" "")
16366	(float_truncate:SF (match_dup 4)))]
16367  "TARGET_USE_FANCY_MATH_387
16368   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16369   && flag_unsafe_math_optimizations"
16370{
16371  operands[2] = gen_reg_rtx (XFmode);
16372  operands[3] = gen_reg_rtx (XFmode);
16373  operands[4] = gen_reg_rtx (XFmode);
16374})
16375
16376(define_expand "logbdf2"
16377  [(set (match_dup 2)
16378	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16379   (parallel [(set (match_dup 3)
16380		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16381	      (set (match_dup 4)
16382		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16383   (set (match_operand:DF 0 "register_operand" "")
16384	(float_truncate:DF (match_dup 4)))]
16385  "TARGET_USE_FANCY_MATH_387
16386   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16387   && flag_unsafe_math_optimizations"
16388{
16389  operands[2] = gen_reg_rtx (XFmode);
16390  operands[3] = gen_reg_rtx (XFmode);
16391  operands[4] = gen_reg_rtx (XFmode);
16392})
16393
16394(define_expand "logbxf2"
16395  [(parallel [(set (match_dup 2)
16396		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16397			      UNSPEC_XTRACT_FRACT))
16398	      (set (match_operand:XF 0 "register_operand" "")
16399		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16400  "TARGET_USE_FANCY_MATH_387
16401   && flag_unsafe_math_optimizations"
16402{
16403  operands[2] = gen_reg_rtx (XFmode);
16404})
16405
16406(define_expand "ilogbsi2"
16407  [(parallel [(set (match_dup 2)
16408		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16409			      UNSPEC_XTRACT_FRACT))
16410	      (set (match_operand:XF 3 "register_operand" "")
16411		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16412   (parallel [(set (match_operand:SI 0 "register_operand" "")
16413	           (fix:SI (match_dup 3)))
16414	      (clobber (reg:CC FLAGS_REG))])]
16415  "TARGET_USE_FANCY_MATH_387
16416   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16417   && flag_unsafe_math_optimizations"
16418{
16419  operands[2] = gen_reg_rtx (XFmode);
16420  operands[3] = gen_reg_rtx (XFmode);
16421})
16422
16423(define_insn "*f2xm1xf2"
16424  [(set (match_operand:XF 0 "register_operand" "=f")
16425	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16426	 UNSPEC_F2XM1))]
16427  "TARGET_USE_FANCY_MATH_387
16428   && flag_unsafe_math_optimizations"
16429  "f2xm1"
16430  [(set_attr "type" "fpspc")
16431   (set_attr "mode" "XF")])
16432
16433(define_insn "*fscalexf4"
16434  [(set (match_operand:XF 0 "register_operand" "=f")
16435	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16436		    (match_operand:XF 3 "register_operand" "1")]
16437		   UNSPEC_FSCALE_FRACT))
16438   (set (match_operand:XF 1 "register_operand" "=u")
16439	(unspec:XF [(match_dup 2) (match_dup 3)]
16440		   UNSPEC_FSCALE_EXP))]
16441  "TARGET_USE_FANCY_MATH_387
16442   && flag_unsafe_math_optimizations"
16443  "fscale"
16444  [(set_attr "type" "fpspc")
16445   (set_attr "mode" "XF")])
16446
16447(define_expand "expsf2"
16448  [(set (match_dup 2)
16449	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16450   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16451   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16452   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16453   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16454   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16455   (parallel [(set (match_dup 10)
16456		   (unspec:XF [(match_dup 9) (match_dup 5)]
16457			      UNSPEC_FSCALE_FRACT))
16458	      (set (match_dup 11)
16459		   (unspec:XF [(match_dup 9) (match_dup 5)]
16460			      UNSPEC_FSCALE_EXP))])
16461   (set (match_operand:SF 0 "register_operand" "")
16462	(float_truncate:SF (match_dup 10)))]
16463  "TARGET_USE_FANCY_MATH_387
16464   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16465   && flag_unsafe_math_optimizations"
16466{
16467  rtx temp;
16468  int i;
16469
16470  for (i=2; i<12; i++)
16471    operands[i] = gen_reg_rtx (XFmode);
16472  temp = standard_80387_constant_rtx (5); /* fldl2e */
16473  emit_move_insn (operands[3], temp);
16474  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16475})
16476
16477(define_expand "expdf2"
16478  [(set (match_dup 2)
16479	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16480   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16481   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16482   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16483   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16484   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16485   (parallel [(set (match_dup 10)
16486		   (unspec:XF [(match_dup 9) (match_dup 5)]
16487			      UNSPEC_FSCALE_FRACT))
16488	      (set (match_dup 11)
16489		   (unspec:XF [(match_dup 9) (match_dup 5)]
16490			      UNSPEC_FSCALE_EXP))])
16491   (set (match_operand:DF 0 "register_operand" "")
16492	(float_truncate:DF (match_dup 10)))]
16493  "TARGET_USE_FANCY_MATH_387
16494   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16495   && flag_unsafe_math_optimizations"
16496{
16497  rtx temp;
16498  int i;
16499
16500  for (i=2; i<12; i++)
16501    operands[i] = gen_reg_rtx (XFmode);
16502  temp = standard_80387_constant_rtx (5); /* fldl2e */
16503  emit_move_insn (operands[3], temp);
16504  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16505})
16506
16507(define_expand "expxf2"
16508  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16509			       (match_dup 2)))
16510   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16511   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16512   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16513   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16514   (parallel [(set (match_operand:XF 0 "register_operand" "")
16515		   (unspec:XF [(match_dup 8) (match_dup 4)]
16516			      UNSPEC_FSCALE_FRACT))
16517	      (set (match_dup 9)
16518		   (unspec:XF [(match_dup 8) (match_dup 4)]
16519			      UNSPEC_FSCALE_EXP))])]
16520  "TARGET_USE_FANCY_MATH_387
16521   && flag_unsafe_math_optimizations"
16522{
16523  rtx temp;
16524  int i;
16525
16526  for (i=2; i<10; i++)
16527    operands[i] = gen_reg_rtx (XFmode);
16528  temp = standard_80387_constant_rtx (5); /* fldl2e */
16529  emit_move_insn (operands[2], temp);
16530  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16531})
16532
16533(define_expand "exp10sf2"
16534  [(set (match_dup 2)
16535	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16536   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16537   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16538   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16539   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16540   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16541   (parallel [(set (match_dup 10)
16542		   (unspec:XF [(match_dup 9) (match_dup 5)]
16543			      UNSPEC_FSCALE_FRACT))
16544	      (set (match_dup 11)
16545		   (unspec:XF [(match_dup 9) (match_dup 5)]
16546			      UNSPEC_FSCALE_EXP))])
16547   (set (match_operand:SF 0 "register_operand" "")
16548	(float_truncate:SF (match_dup 10)))]
16549  "TARGET_USE_FANCY_MATH_387
16550   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16551   && flag_unsafe_math_optimizations"
16552{
16553  rtx temp;
16554  int i;
16555
16556  for (i=2; i<12; i++)
16557    operands[i] = gen_reg_rtx (XFmode);
16558  temp = standard_80387_constant_rtx (6); /* fldl2t */
16559  emit_move_insn (operands[3], temp);
16560  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16561})
16562
16563(define_expand "exp10df2"
16564  [(set (match_dup 2)
16565	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16566   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16567   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16568   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16569   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16570   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16571   (parallel [(set (match_dup 10)
16572		   (unspec:XF [(match_dup 9) (match_dup 5)]
16573			      UNSPEC_FSCALE_FRACT))
16574	      (set (match_dup 11)
16575		   (unspec:XF [(match_dup 9) (match_dup 5)]
16576			      UNSPEC_FSCALE_EXP))])
16577   (set (match_operand:DF 0 "register_operand" "")
16578	(float_truncate:DF (match_dup 10)))]
16579  "TARGET_USE_FANCY_MATH_387
16580   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16581   && flag_unsafe_math_optimizations"
16582{
16583  rtx temp;
16584  int i;
16585
16586  for (i=2; i<12; i++)
16587    operands[i] = gen_reg_rtx (XFmode);
16588  temp = standard_80387_constant_rtx (6); /* fldl2t */
16589  emit_move_insn (operands[3], temp);
16590  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16591})
16592
16593(define_expand "exp10xf2"
16594  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16595			       (match_dup 2)))
16596   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16597   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16598   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16599   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16600   (parallel [(set (match_operand:XF 0 "register_operand" "")
16601		   (unspec:XF [(match_dup 8) (match_dup 4)]
16602			      UNSPEC_FSCALE_FRACT))
16603	      (set (match_dup 9)
16604		   (unspec:XF [(match_dup 8) (match_dup 4)]
16605			      UNSPEC_FSCALE_EXP))])]
16606  "TARGET_USE_FANCY_MATH_387
16607   && flag_unsafe_math_optimizations"
16608{
16609  rtx temp;
16610  int i;
16611
16612  for (i=2; i<10; i++)
16613    operands[i] = gen_reg_rtx (XFmode);
16614  temp = standard_80387_constant_rtx (6); /* fldl2t */
16615  emit_move_insn (operands[2], temp);
16616  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16617})
16618
16619(define_expand "exp2sf2"
16620  [(set (match_dup 2)
16621	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16622   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16623   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16624   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16625   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16626   (parallel [(set (match_dup 8)
16627		   (unspec:XF [(match_dup 7) (match_dup 3)]
16628			      UNSPEC_FSCALE_FRACT))
16629	      (set (match_dup 9)
16630		   (unspec:XF [(match_dup 7) (match_dup 3)]
16631			      UNSPEC_FSCALE_EXP))])
16632   (set (match_operand:SF 0 "register_operand" "")
16633	(float_truncate:SF (match_dup 8)))]
16634  "TARGET_USE_FANCY_MATH_387
16635   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16636   && flag_unsafe_math_optimizations"
16637{
16638  int i;
16639
16640  for (i=2; i<10; i++)
16641    operands[i] = gen_reg_rtx (XFmode);
16642  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16643})
16644
16645(define_expand "exp2df2"
16646  [(set (match_dup 2)
16647	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16648   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16649   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16650   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16651   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16652   (parallel [(set (match_dup 8)
16653		   (unspec:XF [(match_dup 7) (match_dup 3)]
16654			      UNSPEC_FSCALE_FRACT))
16655	      (set (match_dup 9)
16656		   (unspec:XF [(match_dup 7) (match_dup 3)]
16657			      UNSPEC_FSCALE_EXP))])
16658   (set (match_operand:DF 0 "register_operand" "")
16659	(float_truncate:DF (match_dup 8)))]
16660  "TARGET_USE_FANCY_MATH_387
16661   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16662   && flag_unsafe_math_optimizations"
16663{
16664  int i;
16665
16666  for (i=2; i<10; i++)
16667    operands[i] = gen_reg_rtx (XFmode);
16668  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16669})
16670
16671(define_expand "exp2xf2"
16672  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16673   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16674   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16675   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16676   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16677   (parallel [(set (match_operand:XF 0 "register_operand" "")
16678		   (unspec:XF [(match_dup 7) (match_dup 3)]
16679			      UNSPEC_FSCALE_FRACT))
16680	      (set (match_dup 8)
16681		   (unspec:XF [(match_dup 7) (match_dup 3)]
16682			      UNSPEC_FSCALE_EXP))])]
16683  "TARGET_USE_FANCY_MATH_387
16684   && flag_unsafe_math_optimizations"
16685{
16686  int i;
16687
16688  for (i=2; i<9; i++)
16689    operands[i] = gen_reg_rtx (XFmode);
16690  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16691})
16692
16693(define_expand "expm1df2"
16694  [(set (match_dup 2)
16695	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16696   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16697   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16698   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16699   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16700   (parallel [(set (match_dup 8)
16701		   (unspec:XF [(match_dup 7) (match_dup 5)]
16702			      UNSPEC_FSCALE_FRACT))
16703		   (set (match_dup 9)
16704		   (unspec:XF [(match_dup 7) (match_dup 5)]
16705			      UNSPEC_FSCALE_EXP))])
16706   (parallel [(set (match_dup 11)
16707		   (unspec:XF [(match_dup 10) (match_dup 9)]
16708			      UNSPEC_FSCALE_FRACT))
16709	      (set (match_dup 12)
16710		   (unspec:XF [(match_dup 10) (match_dup 9)]
16711			      UNSPEC_FSCALE_EXP))])
16712   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16713   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16714   (set (match_operand:DF 0 "register_operand" "")
16715	(float_truncate:DF (match_dup 14)))]
16716  "TARGET_USE_FANCY_MATH_387
16717   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16718   && flag_unsafe_math_optimizations"
16719{
16720  rtx temp;
16721  int i;
16722
16723  for (i=2; i<15; i++)
16724    operands[i] = gen_reg_rtx (XFmode);
16725  temp = standard_80387_constant_rtx (5); /* fldl2e */
16726  emit_move_insn (operands[3], temp);
16727  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16728})
16729
16730(define_expand "expm1sf2"
16731  [(set (match_dup 2)
16732	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737   (parallel [(set (match_dup 8)
16738		   (unspec:XF [(match_dup 7) (match_dup 5)]
16739			      UNSPEC_FSCALE_FRACT))
16740		   (set (match_dup 9)
16741		   (unspec:XF [(match_dup 7) (match_dup 5)]
16742			      UNSPEC_FSCALE_EXP))])
16743   (parallel [(set (match_dup 11)
16744		   (unspec:XF [(match_dup 10) (match_dup 9)]
16745			      UNSPEC_FSCALE_FRACT))
16746	      (set (match_dup 12)
16747		   (unspec:XF [(match_dup 10) (match_dup 9)]
16748			      UNSPEC_FSCALE_EXP))])
16749   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16750   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16751   (set (match_operand:SF 0 "register_operand" "")
16752	(float_truncate:SF (match_dup 14)))]
16753  "TARGET_USE_FANCY_MATH_387
16754   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16755   && flag_unsafe_math_optimizations"
16756{
16757  rtx temp;
16758  int i;
16759
16760  for (i=2; i<15; i++)
16761    operands[i] = gen_reg_rtx (XFmode);
16762  temp = standard_80387_constant_rtx (5); /* fldl2e */
16763  emit_move_insn (operands[3], temp);
16764  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16765})
16766
16767(define_expand "expm1xf2"
16768  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16769			       (match_dup 2)))
16770   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16771   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16772   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16773   (parallel [(set (match_dup 7)
16774		   (unspec:XF [(match_dup 6) (match_dup 4)]
16775			      UNSPEC_FSCALE_FRACT))
16776		   (set (match_dup 8)
16777		   (unspec:XF [(match_dup 6) (match_dup 4)]
16778			      UNSPEC_FSCALE_EXP))])
16779   (parallel [(set (match_dup 10)
16780		   (unspec:XF [(match_dup 9) (match_dup 8)]
16781			      UNSPEC_FSCALE_FRACT))
16782	      (set (match_dup 11)
16783		   (unspec:XF [(match_dup 9) (match_dup 8)]
16784			      UNSPEC_FSCALE_EXP))])
16785   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16786   (set (match_operand:XF 0 "register_operand" "")
16787	(plus:XF (match_dup 12) (match_dup 7)))]
16788  "TARGET_USE_FANCY_MATH_387
16789   && flag_unsafe_math_optimizations"
16790{
16791  rtx temp;
16792  int i;
16793
16794  for (i=2; i<13; i++)
16795    operands[i] = gen_reg_rtx (XFmode);
16796  temp = standard_80387_constant_rtx (5); /* fldl2e */
16797  emit_move_insn (operands[2], temp);
16798  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16799})
16800
16801(define_expand "ldexpdf3"
16802  [(set (match_dup 3)
16803	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16804   (set (match_dup 4)
16805	(float:XF (match_operand:SI 2 "register_operand" "")))
16806   (parallel [(set (match_dup 5)
16807		   (unspec:XF [(match_dup 3) (match_dup 4)]
16808			      UNSPEC_FSCALE_FRACT))
16809	      (set (match_dup 6)
16810		   (unspec:XF [(match_dup 3) (match_dup 4)]
16811			      UNSPEC_FSCALE_EXP))])
16812   (set (match_operand:DF 0 "register_operand" "")
16813	(float_truncate:DF (match_dup 5)))]
16814  "TARGET_USE_FANCY_MATH_387
16815   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16816   && flag_unsafe_math_optimizations"
16817{
16818  int i;
16819
16820  for (i=3; i<7; i++)
16821    operands[i] = gen_reg_rtx (XFmode);
16822})
16823
16824(define_expand "ldexpsf3"
16825  [(set (match_dup 3)
16826	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16827   (set (match_dup 4)
16828	(float:XF (match_operand:SI 2 "register_operand" "")))
16829   (parallel [(set (match_dup 5)
16830		   (unspec:XF [(match_dup 3) (match_dup 4)]
16831			      UNSPEC_FSCALE_FRACT))
16832	      (set (match_dup 6)
16833		   (unspec:XF [(match_dup 3) (match_dup 4)]
16834			      UNSPEC_FSCALE_EXP))])
16835   (set (match_operand:SF 0 "register_operand" "")
16836	(float_truncate:SF (match_dup 5)))]
16837  "TARGET_USE_FANCY_MATH_387
16838   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16839   && flag_unsafe_math_optimizations"
16840{
16841  int i;
16842
16843  for (i=3; i<7; i++)
16844    operands[i] = gen_reg_rtx (XFmode);
16845})
16846
16847(define_expand "ldexpxf3"
16848  [(set (match_dup 3)
16849	(float:XF (match_operand:SI 2 "register_operand" "")))
16850   (parallel [(set (match_operand:XF 0 " register_operand" "")
16851		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16852			       (match_dup 3)]
16853			      UNSPEC_FSCALE_FRACT))
16854	      (set (match_dup 4)
16855		   (unspec:XF [(match_dup 1) (match_dup 3)]
16856			      UNSPEC_FSCALE_EXP))])]
16857  "TARGET_USE_FANCY_MATH_387
16858   && flag_unsafe_math_optimizations"
16859{
16860  int i;
16861
16862  for (i=3; i<5; i++)
16863    operands[i] = gen_reg_rtx (XFmode);
16864})
16865
16866
16867(define_insn "frndintxf2"
16868  [(set (match_operand:XF 0 "register_operand" "=f")
16869	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16870	 UNSPEC_FRNDINT))]
16871  "TARGET_USE_FANCY_MATH_387
16872   && flag_unsafe_math_optimizations"
16873  "frndint"
16874  [(set_attr "type" "fpspc")
16875   (set_attr "mode" "XF")])
16876
16877(define_expand "rintdf2"
16878  [(use (match_operand:DF 0 "register_operand" ""))
16879   (use (match_operand:DF 1 "register_operand" ""))]
16880  "TARGET_USE_FANCY_MATH_387
16881   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16882   && flag_unsafe_math_optimizations"
16883{
16884  rtx op0 = gen_reg_rtx (XFmode);
16885  rtx op1 = gen_reg_rtx (XFmode);
16886
16887  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16888  emit_insn (gen_frndintxf2 (op0, op1));
16889
16890  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16891  DONE;
16892})
16893
16894(define_expand "rintsf2"
16895  [(use (match_operand:SF 0 "register_operand" ""))
16896   (use (match_operand:SF 1 "register_operand" ""))]
16897  "TARGET_USE_FANCY_MATH_387
16898   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16899   && flag_unsafe_math_optimizations"
16900{
16901  rtx op0 = gen_reg_rtx (XFmode);
16902  rtx op1 = gen_reg_rtx (XFmode);
16903
16904  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16905  emit_insn (gen_frndintxf2 (op0, op1));
16906
16907  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16908  DONE;
16909})
16910
16911(define_expand "rintxf2"
16912  [(use (match_operand:XF 0 "register_operand" ""))
16913   (use (match_operand:XF 1 "register_operand" ""))]
16914  "TARGET_USE_FANCY_MATH_387
16915   && flag_unsafe_math_optimizations"
16916{
16917  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16918  DONE;
16919})
16920
16921(define_insn_and_split "*fistdi2_1"
16922  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16923	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16924	 UNSPEC_FIST))]
16925  "TARGET_USE_FANCY_MATH_387
16926   && flag_unsafe_math_optimizations
16927   && !(reload_completed || reload_in_progress)"
16928  "#"
16929  "&& 1"
16930  [(const_int 0)]
16931{
16932  if (memory_operand (operands[0], VOIDmode))
16933    emit_insn (gen_fistdi2 (operands[0], operands[1]));
16934  else
16935    {
16936      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16937      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16938					 operands[2]));
16939    }
16940  DONE;
16941}
16942  [(set_attr "type" "fpspc")
16943   (set_attr "mode" "DI")])
16944
16945(define_insn "fistdi2"
16946  [(set (match_operand:DI 0 "memory_operand" "=m")
16947	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16948	 UNSPEC_FIST))
16949   (clobber (match_scratch:XF 2 "=&1f"))]
16950  "TARGET_USE_FANCY_MATH_387
16951   && flag_unsafe_math_optimizations"
16952  "* return output_fix_trunc (insn, operands, 0);"
16953  [(set_attr "type" "fpspc")
16954   (set_attr "mode" "DI")])
16955
16956(define_insn "fistdi2_with_temp"
16957  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16958	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16959	 UNSPEC_FIST))
16960   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16961   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16962  "TARGET_USE_FANCY_MATH_387
16963   && flag_unsafe_math_optimizations"
16964  "#"
16965  [(set_attr "type" "fpspc")
16966   (set_attr "mode" "DI")])
16967
16968(define_split 
16969  [(set (match_operand:DI 0 "register_operand" "")
16970	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
16971	 UNSPEC_FIST))
16972   (clobber (match_operand:DI 2 "memory_operand" ""))
16973   (clobber (match_scratch 3 ""))]
16974  "reload_completed"
16975  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16976	      (clobber (match_dup 3))])
16977   (set (match_dup 0) (match_dup 2))]
16978  "")
16979
16980(define_split 
16981  [(set (match_operand:DI 0 "memory_operand" "")
16982	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
16983	 UNSPEC_FIST))
16984   (clobber (match_operand:DI 2 "memory_operand" ""))
16985   (clobber (match_scratch 3 ""))]
16986  "reload_completed"
16987  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16988	      (clobber (match_dup 3))])]
16989  "")
16990
16991(define_insn_and_split "*fist<mode>2_1"
16992  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16993	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16994	 UNSPEC_FIST))]
16995  "TARGET_USE_FANCY_MATH_387
16996   && flag_unsafe_math_optimizations
16997   && !(reload_completed || reload_in_progress)"
16998  "#"
16999  "&& 1"
17000  [(const_int 0)]
17001{
17002  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17003  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17004					operands[2]));
17005  DONE;
17006}
17007  [(set_attr "type" "fpspc")
17008   (set_attr "mode" "<MODE>")])
17009
17010(define_insn "fist<mode>2"
17011  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17012	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17013	 UNSPEC_FIST))]
17014  "TARGET_USE_FANCY_MATH_387
17015   && flag_unsafe_math_optimizations"
17016  "* return output_fix_trunc (insn, operands, 0);"
17017  [(set_attr "type" "fpspc")
17018   (set_attr "mode" "<MODE>")])
17019
17020(define_insn "fist<mode>2_with_temp"
17021  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17022	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17023	 UNSPEC_FIST))
17024   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17025  "TARGET_USE_FANCY_MATH_387
17026   && flag_unsafe_math_optimizations"
17027  "#"
17028  [(set_attr "type" "fpspc")
17029   (set_attr "mode" "<MODE>")])
17030
17031(define_split 
17032  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17033	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17034	 UNSPEC_FIST))
17035   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17036  "reload_completed"
17037  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17038		       UNSPEC_FIST))
17039   (set (match_dup 0) (match_dup 2))]
17040  "")
17041
17042(define_split 
17043  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17044	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17045	 UNSPEC_FIST))
17046   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17047  "reload_completed"
17048  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17049		       UNSPEC_FIST))]
17050  "")
17051
17052(define_expand "lrint<mode>2"
17053  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17054	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17055	 UNSPEC_FIST))]
17056  "TARGET_USE_FANCY_MATH_387
17057   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17058   && flag_unsafe_math_optimizations"
17059  "")
17060
17061;; Rounding mode control word calculation could clobber FLAGS_REG.
17062(define_insn_and_split "frndintxf2_floor"
17063  [(set (match_operand:XF 0 "register_operand" "=f")
17064	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17065	 UNSPEC_FRNDINT_FLOOR))
17066   (clobber (reg:CC FLAGS_REG))]
17067  "TARGET_USE_FANCY_MATH_387
17068   && flag_unsafe_math_optimizations
17069   && !(reload_completed || reload_in_progress)"
17070  "#"
17071  "&& 1"
17072  [(const_int 0)]
17073{
17074  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17075
17076  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17077  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17078
17079  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17080					operands[2], operands[3]));
17081  DONE;
17082}
17083  [(set_attr "type" "frndint")
17084   (set_attr "i387_cw" "floor")
17085   (set_attr "mode" "XF")])
17086
17087(define_insn "frndintxf2_floor_i387"
17088  [(set (match_operand:XF 0 "register_operand" "=f")
17089	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17090	 UNSPEC_FRNDINT_FLOOR))
17091   (use (match_operand:HI 2 "memory_operand" "m"))
17092   (use (match_operand:HI 3 "memory_operand" "m"))]
17093  "TARGET_USE_FANCY_MATH_387
17094   && flag_unsafe_math_optimizations"
17095  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17096  [(set_attr "type" "frndint")
17097   (set_attr "i387_cw" "floor")
17098   (set_attr "mode" "XF")])
17099
17100(define_expand "floorxf2"
17101  [(use (match_operand:XF 0 "register_operand" ""))
17102   (use (match_operand:XF 1 "register_operand" ""))]
17103  "TARGET_USE_FANCY_MATH_387
17104   && flag_unsafe_math_optimizations"
17105{
17106  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17107  DONE;
17108})
17109
17110(define_expand "floordf2"
17111  [(use (match_operand:DF 0 "register_operand" ""))
17112   (use (match_operand:DF 1 "register_operand" ""))]
17113  "TARGET_USE_FANCY_MATH_387
17114   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17115   && flag_unsafe_math_optimizations"
17116{
17117  rtx op0 = gen_reg_rtx (XFmode);
17118  rtx op1 = gen_reg_rtx (XFmode);
17119
17120  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17121  emit_insn (gen_frndintxf2_floor (op0, op1));
17122
17123  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17124  DONE;
17125})
17126
17127(define_expand "floorsf2"
17128  [(use (match_operand:SF 0 "register_operand" ""))
17129   (use (match_operand:SF 1 "register_operand" ""))]
17130  "TARGET_USE_FANCY_MATH_387
17131   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17132   && flag_unsafe_math_optimizations"
17133{
17134  rtx op0 = gen_reg_rtx (XFmode);
17135  rtx op1 = gen_reg_rtx (XFmode);
17136
17137  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17138  emit_insn (gen_frndintxf2_floor (op0, op1));
17139
17140  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17141  DONE;
17142})
17143
17144(define_insn_and_split "*fist<mode>2_floor_1"
17145  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17146	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17147	 UNSPEC_FIST_FLOOR))
17148   (clobber (reg:CC FLAGS_REG))]
17149  "TARGET_USE_FANCY_MATH_387
17150   && flag_unsafe_math_optimizations
17151   && !(reload_completed || reload_in_progress)"
17152  "#"
17153  "&& 1"
17154  [(const_int 0)]
17155{
17156  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17157
17158  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17159  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17160  if (memory_operand (operands[0], VOIDmode))
17161    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17162				      operands[2], operands[3]));
17163  else
17164    {
17165      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17166      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17167						  operands[2], operands[3],
17168						  operands[4]));
17169    }
17170  DONE;
17171}
17172  [(set_attr "type" "fistp")
17173   (set_attr "i387_cw" "floor")
17174   (set_attr "mode" "<MODE>")])
17175
17176(define_insn "fistdi2_floor"
17177  [(set (match_operand:DI 0 "memory_operand" "=m")
17178	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17179	 UNSPEC_FIST_FLOOR))
17180   (use (match_operand:HI 2 "memory_operand" "m"))
17181   (use (match_operand:HI 3 "memory_operand" "m"))
17182   (clobber (match_scratch:XF 4 "=&1f"))]
17183  "TARGET_USE_FANCY_MATH_387
17184   && flag_unsafe_math_optimizations"
17185  "* return output_fix_trunc (insn, operands, 0);"
17186  [(set_attr "type" "fistp")
17187   (set_attr "i387_cw" "floor")
17188   (set_attr "mode" "DI")])
17189
17190(define_insn "fistdi2_floor_with_temp"
17191  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17192	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17193	 UNSPEC_FIST_FLOOR))
17194   (use (match_operand:HI 2 "memory_operand" "m,m"))
17195   (use (match_operand:HI 3 "memory_operand" "m,m"))
17196   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17197   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17198  "TARGET_USE_FANCY_MATH_387
17199   && flag_unsafe_math_optimizations"
17200  "#"
17201  [(set_attr "type" "fistp")
17202   (set_attr "i387_cw" "floor")
17203   (set_attr "mode" "DI")])
17204
17205(define_split 
17206  [(set (match_operand:DI 0 "register_operand" "")
17207	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17208	 UNSPEC_FIST_FLOOR))
17209   (use (match_operand:HI 2 "memory_operand" ""))
17210   (use (match_operand:HI 3 "memory_operand" ""))
17211   (clobber (match_operand:DI 4 "memory_operand" ""))
17212   (clobber (match_scratch 5 ""))]
17213  "reload_completed"
17214  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17215	      (use (match_dup 2))
17216	      (use (match_dup 3))
17217	      (clobber (match_dup 5))])
17218   (set (match_dup 0) (match_dup 4))]
17219  "")
17220
17221(define_split 
17222  [(set (match_operand:DI 0 "memory_operand" "")
17223	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17224	 UNSPEC_FIST_FLOOR))
17225   (use (match_operand:HI 2 "memory_operand" ""))
17226   (use (match_operand:HI 3 "memory_operand" ""))
17227   (clobber (match_operand:DI 4 "memory_operand" ""))
17228   (clobber (match_scratch 5 ""))]
17229  "reload_completed"
17230  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17231	      (use (match_dup 2))
17232	      (use (match_dup 3))
17233	      (clobber (match_dup 5))])]
17234  "")
17235
17236(define_insn "fist<mode>2_floor"
17237  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17238	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17239	 UNSPEC_FIST_FLOOR))
17240   (use (match_operand:HI 2 "memory_operand" "m"))
17241   (use (match_operand:HI 3 "memory_operand" "m"))]
17242  "TARGET_USE_FANCY_MATH_387
17243   && flag_unsafe_math_optimizations"
17244  "* return output_fix_trunc (insn, operands, 0);"
17245  [(set_attr "type" "fistp")
17246   (set_attr "i387_cw" "floor")
17247   (set_attr "mode" "<MODE>")])
17248
17249(define_insn "fist<mode>2_floor_with_temp"
17250  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17251	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17252	 UNSPEC_FIST_FLOOR))
17253   (use (match_operand:HI 2 "memory_operand" "m,m"))
17254   (use (match_operand:HI 3 "memory_operand" "m,m"))
17255   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17256  "TARGET_USE_FANCY_MATH_387
17257   && flag_unsafe_math_optimizations"
17258  "#"
17259  [(set_attr "type" "fistp")
17260   (set_attr "i387_cw" "floor")
17261   (set_attr "mode" "<MODE>")])
17262
17263(define_split 
17264  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17265	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17266	 UNSPEC_FIST_FLOOR))
17267   (use (match_operand:HI 2 "memory_operand" ""))
17268   (use (match_operand:HI 3 "memory_operand" ""))
17269   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17270  "reload_completed"
17271  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17272				  UNSPEC_FIST_FLOOR))
17273	      (use (match_dup 2))
17274	      (use (match_dup 3))])
17275   (set (match_dup 0) (match_dup 4))]
17276  "")
17277
17278(define_split 
17279  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17280	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17281	 UNSPEC_FIST_FLOOR))
17282   (use (match_operand:HI 2 "memory_operand" ""))
17283   (use (match_operand:HI 3 "memory_operand" ""))
17284   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17285  "reload_completed"
17286  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17287				  UNSPEC_FIST_FLOOR))
17288	      (use (match_dup 2))
17289	      (use (match_dup 3))])]
17290  "")
17291
17292(define_expand "lfloor<mode>2"
17293  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17294		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17295		    UNSPEC_FIST_FLOOR))
17296	      (clobber (reg:CC FLAGS_REG))])]
17297  "TARGET_USE_FANCY_MATH_387
17298   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17299   && flag_unsafe_math_optimizations"
17300  "")
17301
17302;; Rounding mode control word calculation could clobber FLAGS_REG.
17303(define_insn_and_split "frndintxf2_ceil"
17304  [(set (match_operand:XF 0 "register_operand" "=f")
17305	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17306	 UNSPEC_FRNDINT_CEIL))
17307   (clobber (reg:CC FLAGS_REG))]
17308  "TARGET_USE_FANCY_MATH_387
17309   && flag_unsafe_math_optimizations
17310   && !(reload_completed || reload_in_progress)"
17311  "#"
17312  "&& 1"
17313  [(const_int 0)]
17314{
17315  ix86_optimize_mode_switching[I387_CEIL] = 1;
17316
17317  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17318  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17319
17320  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17321				       operands[2], operands[3]));
17322  DONE;
17323}
17324  [(set_attr "type" "frndint")
17325   (set_attr "i387_cw" "ceil")
17326   (set_attr "mode" "XF")])
17327
17328(define_insn "frndintxf2_ceil_i387"
17329  [(set (match_operand:XF 0 "register_operand" "=f")
17330	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17331	 UNSPEC_FRNDINT_CEIL))
17332   (use (match_operand:HI 2 "memory_operand" "m"))
17333   (use (match_operand:HI 3 "memory_operand" "m"))]
17334  "TARGET_USE_FANCY_MATH_387
17335   && flag_unsafe_math_optimizations"
17336  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17337  [(set_attr "type" "frndint")
17338   (set_attr "i387_cw" "ceil")
17339   (set_attr "mode" "XF")])
17340
17341(define_expand "ceilxf2"
17342  [(use (match_operand:XF 0 "register_operand" ""))
17343   (use (match_operand:XF 1 "register_operand" ""))]
17344  "TARGET_USE_FANCY_MATH_387
17345   && flag_unsafe_math_optimizations"
17346{
17347  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17348  DONE;
17349})
17350
17351(define_expand "ceildf2"
17352  [(use (match_operand:DF 0 "register_operand" ""))
17353   (use (match_operand:DF 1 "register_operand" ""))]
17354  "TARGET_USE_FANCY_MATH_387
17355   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17356   && flag_unsafe_math_optimizations"
17357{
17358  rtx op0 = gen_reg_rtx (XFmode);
17359  rtx op1 = gen_reg_rtx (XFmode);
17360
17361  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17362  emit_insn (gen_frndintxf2_ceil (op0, op1));
17363
17364  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17365  DONE;
17366})
17367
17368(define_expand "ceilsf2"
17369  [(use (match_operand:SF 0 "register_operand" ""))
17370   (use (match_operand:SF 1 "register_operand" ""))]
17371  "TARGET_USE_FANCY_MATH_387
17372   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17373   && flag_unsafe_math_optimizations"
17374{
17375  rtx op0 = gen_reg_rtx (XFmode);
17376  rtx op1 = gen_reg_rtx (XFmode);
17377
17378  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17379  emit_insn (gen_frndintxf2_ceil (op0, op1));
17380
17381  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17382  DONE;
17383})
17384
17385(define_insn_and_split "*fist<mode>2_ceil_1"
17386  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17387	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17388	 UNSPEC_FIST_CEIL))
17389   (clobber (reg:CC FLAGS_REG))]
17390  "TARGET_USE_FANCY_MATH_387
17391   && flag_unsafe_math_optimizations
17392   && !(reload_completed || reload_in_progress)"
17393  "#"
17394  "&& 1"
17395  [(const_int 0)]
17396{
17397  ix86_optimize_mode_switching[I387_CEIL] = 1;
17398
17399  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17400  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17401  if (memory_operand (operands[0], VOIDmode))
17402    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17403				     operands[2], operands[3]));
17404  else
17405    {
17406      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17407      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17408						 operands[2], operands[3],
17409						 operands[4]));
17410    }
17411  DONE;
17412}
17413  [(set_attr "type" "fistp")
17414   (set_attr "i387_cw" "ceil")
17415   (set_attr "mode" "<MODE>")])
17416
17417(define_insn "fistdi2_ceil"
17418  [(set (match_operand:DI 0 "memory_operand" "=m")
17419	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17420	 UNSPEC_FIST_CEIL))
17421   (use (match_operand:HI 2 "memory_operand" "m"))
17422   (use (match_operand:HI 3 "memory_operand" "m"))
17423   (clobber (match_scratch:XF 4 "=&1f"))]
17424  "TARGET_USE_FANCY_MATH_387
17425   && flag_unsafe_math_optimizations"
17426  "* return output_fix_trunc (insn, operands, 0);"
17427  [(set_attr "type" "fistp")
17428   (set_attr "i387_cw" "ceil")
17429   (set_attr "mode" "DI")])
17430
17431(define_insn "fistdi2_ceil_with_temp"
17432  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17433	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17434	 UNSPEC_FIST_CEIL))
17435   (use (match_operand:HI 2 "memory_operand" "m,m"))
17436   (use (match_operand:HI 3 "memory_operand" "m,m"))
17437   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17438   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17439  "TARGET_USE_FANCY_MATH_387
17440   && flag_unsafe_math_optimizations"
17441  "#"
17442  [(set_attr "type" "fistp")
17443   (set_attr "i387_cw" "ceil")
17444   (set_attr "mode" "DI")])
17445
17446(define_split 
17447  [(set (match_operand:DI 0 "register_operand" "")
17448	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17449	 UNSPEC_FIST_CEIL))
17450   (use (match_operand:HI 2 "memory_operand" ""))
17451   (use (match_operand:HI 3 "memory_operand" ""))
17452   (clobber (match_operand:DI 4 "memory_operand" ""))
17453   (clobber (match_scratch 5 ""))]
17454  "reload_completed"
17455  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17456	      (use (match_dup 2))
17457	      (use (match_dup 3))
17458	      (clobber (match_dup 5))])
17459   (set (match_dup 0) (match_dup 4))]
17460  "")
17461
17462(define_split 
17463  [(set (match_operand:DI 0 "memory_operand" "")
17464	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17465	 UNSPEC_FIST_CEIL))
17466   (use (match_operand:HI 2 "memory_operand" ""))
17467   (use (match_operand:HI 3 "memory_operand" ""))
17468   (clobber (match_operand:DI 4 "memory_operand" ""))
17469   (clobber (match_scratch 5 ""))]
17470  "reload_completed"
17471  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17472	      (use (match_dup 2))
17473	      (use (match_dup 3))
17474	      (clobber (match_dup 5))])]
17475  "")
17476
17477(define_insn "fist<mode>2_ceil"
17478  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17479	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17480	 UNSPEC_FIST_CEIL))
17481   (use (match_operand:HI 2 "memory_operand" "m"))
17482   (use (match_operand:HI 3 "memory_operand" "m"))]
17483  "TARGET_USE_FANCY_MATH_387
17484   && flag_unsafe_math_optimizations"
17485  "* return output_fix_trunc (insn, operands, 0);"
17486  [(set_attr "type" "fistp")
17487   (set_attr "i387_cw" "ceil")
17488   (set_attr "mode" "<MODE>")])
17489
17490(define_insn "fist<mode>2_ceil_with_temp"
17491  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17492	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17493	 UNSPEC_FIST_CEIL))
17494   (use (match_operand:HI 2 "memory_operand" "m,m"))
17495   (use (match_operand:HI 3 "memory_operand" "m,m"))
17496   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17497  "TARGET_USE_FANCY_MATH_387
17498   && flag_unsafe_math_optimizations"
17499  "#"
17500  [(set_attr "type" "fistp")
17501   (set_attr "i387_cw" "ceil")
17502   (set_attr "mode" "<MODE>")])
17503
17504(define_split 
17505  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17506	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17507	 UNSPEC_FIST_CEIL))
17508   (use (match_operand:HI 2 "memory_operand" ""))
17509   (use (match_operand:HI 3 "memory_operand" ""))
17510   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17511  "reload_completed"
17512  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17513				  UNSPEC_FIST_CEIL))
17514	      (use (match_dup 2))
17515	      (use (match_dup 3))])
17516   (set (match_dup 0) (match_dup 4))]
17517  "")
17518
17519(define_split 
17520  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17521	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17522	 UNSPEC_FIST_CEIL))
17523   (use (match_operand:HI 2 "memory_operand" ""))
17524   (use (match_operand:HI 3 "memory_operand" ""))
17525   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17526  "reload_completed"
17527  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17528				  UNSPEC_FIST_CEIL))
17529	      (use (match_dup 2))
17530	      (use (match_dup 3))])]
17531  "")
17532
17533(define_expand "lceil<mode>2"
17534  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17535		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17536		    UNSPEC_FIST_CEIL))
17537	      (clobber (reg:CC FLAGS_REG))])]
17538  "TARGET_USE_FANCY_MATH_387
17539   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17540   && flag_unsafe_math_optimizations"
17541  "")
17542
17543;; Rounding mode control word calculation could clobber FLAGS_REG.
17544(define_insn_and_split "frndintxf2_trunc"
17545  [(set (match_operand:XF 0 "register_operand" "=f")
17546	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17547	 UNSPEC_FRNDINT_TRUNC))
17548   (clobber (reg:CC FLAGS_REG))]
17549  "TARGET_USE_FANCY_MATH_387
17550   && flag_unsafe_math_optimizations
17551   && !(reload_completed || reload_in_progress)"
17552  "#"
17553  "&& 1"
17554  [(const_int 0)]
17555{
17556  ix86_optimize_mode_switching[I387_TRUNC] = 1;
17557
17558  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17559  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17560
17561  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17562					operands[2], operands[3]));
17563  DONE;
17564}
17565  [(set_attr "type" "frndint")
17566   (set_attr "i387_cw" "trunc")
17567   (set_attr "mode" "XF")])
17568
17569(define_insn "frndintxf2_trunc_i387"
17570  [(set (match_operand:XF 0 "register_operand" "=f")
17571	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17572	 UNSPEC_FRNDINT_TRUNC))
17573   (use (match_operand:HI 2 "memory_operand" "m"))
17574   (use (match_operand:HI 3 "memory_operand" "m"))]
17575  "TARGET_USE_FANCY_MATH_387
17576   && flag_unsafe_math_optimizations"
17577  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17578  [(set_attr "type" "frndint")
17579   (set_attr "i387_cw" "trunc")
17580   (set_attr "mode" "XF")])
17581
17582(define_expand "btruncxf2"
17583  [(use (match_operand:XF 0 "register_operand" ""))
17584   (use (match_operand:XF 1 "register_operand" ""))]
17585  "TARGET_USE_FANCY_MATH_387
17586   && flag_unsafe_math_optimizations"
17587{
17588  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17589  DONE;
17590})
17591
17592(define_expand "btruncdf2"
17593  [(use (match_operand:DF 0 "register_operand" ""))
17594   (use (match_operand:DF 1 "register_operand" ""))]
17595  "TARGET_USE_FANCY_MATH_387
17596   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17597   && flag_unsafe_math_optimizations"
17598{
17599  rtx op0 = gen_reg_rtx (XFmode);
17600  rtx op1 = gen_reg_rtx (XFmode);
17601
17602  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17603  emit_insn (gen_frndintxf2_trunc (op0, op1));
17604
17605  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17606  DONE;
17607})
17608
17609(define_expand "btruncsf2"
17610  [(use (match_operand:SF 0 "register_operand" ""))
17611   (use (match_operand:SF 1 "register_operand" ""))]
17612  "TARGET_USE_FANCY_MATH_387
17613   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17614   && flag_unsafe_math_optimizations"
17615{
17616  rtx op0 = gen_reg_rtx (XFmode);
17617  rtx op1 = gen_reg_rtx (XFmode);
17618
17619  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17620  emit_insn (gen_frndintxf2_trunc (op0, op1));
17621
17622  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17623  DONE;
17624})
17625
17626;; Rounding mode control word calculation could clobber FLAGS_REG.
17627(define_insn_and_split "frndintxf2_mask_pm"
17628  [(set (match_operand:XF 0 "register_operand" "=f")
17629	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17630	 UNSPEC_FRNDINT_MASK_PM))
17631   (clobber (reg:CC FLAGS_REG))]
17632  "TARGET_USE_FANCY_MATH_387
17633   && flag_unsafe_math_optimizations
17634   && !(reload_completed || reload_in_progress)"
17635  "#"
17636  "&& 1"
17637  [(const_int 0)]
17638{
17639  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17640
17641  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17642  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17643
17644  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17645					  operands[2], operands[3]));
17646  DONE;
17647}
17648  [(set_attr "type" "frndint")
17649   (set_attr "i387_cw" "mask_pm")
17650   (set_attr "mode" "XF")])
17651
17652(define_insn "frndintxf2_mask_pm_i387"
17653  [(set (match_operand:XF 0 "register_operand" "=f")
17654	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17655	 UNSPEC_FRNDINT_MASK_PM))
17656   (use (match_operand:HI 2 "memory_operand" "m"))
17657   (use (match_operand:HI 3 "memory_operand" "m"))]
17658  "TARGET_USE_FANCY_MATH_387
17659   && flag_unsafe_math_optimizations"
17660  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17661  [(set_attr "type" "frndint")
17662   (set_attr "i387_cw" "mask_pm")
17663   (set_attr "mode" "XF")])
17664
17665(define_expand "nearbyintxf2"
17666  [(use (match_operand:XF 0 "register_operand" ""))
17667   (use (match_operand:XF 1 "register_operand" ""))]
17668  "TARGET_USE_FANCY_MATH_387
17669   && flag_unsafe_math_optimizations"
17670{
17671  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17672
17673  DONE;
17674})
17675
17676(define_expand "nearbyintdf2"
17677  [(use (match_operand:DF 0 "register_operand" ""))
17678   (use (match_operand:DF 1 "register_operand" ""))]
17679  "TARGET_USE_FANCY_MATH_387
17680   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17681   && flag_unsafe_math_optimizations"
17682{
17683  rtx op0 = gen_reg_rtx (XFmode);
17684  rtx op1 = gen_reg_rtx (XFmode);
17685
17686  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17687  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17688
17689  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17690  DONE;
17691})
17692
17693(define_expand "nearbyintsf2"
17694  [(use (match_operand:SF 0 "register_operand" ""))
17695   (use (match_operand:SF 1 "register_operand" ""))]
17696  "TARGET_USE_FANCY_MATH_387
17697   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17698   && flag_unsafe_math_optimizations"
17699{
17700  rtx op0 = gen_reg_rtx (XFmode);
17701  rtx op1 = gen_reg_rtx (XFmode);
17702
17703  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17704  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17705
17706  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17707  DONE;
17708})
17709
17710
17711;; Block operation instructions
17712
17713(define_insn "cld"
17714 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17715 ""
17716 "cld"
17717  [(set_attr "type" "cld")])
17718
17719(define_expand "movmemsi"
17720  [(use (match_operand:BLK 0 "memory_operand" ""))
17721   (use (match_operand:BLK 1 "memory_operand" ""))
17722   (use (match_operand:SI 2 "nonmemory_operand" ""))
17723   (use (match_operand:SI 3 "const_int_operand" ""))]
17724  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17725{
17726 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17727   DONE;
17728 else
17729   FAIL;
17730})
17731
17732(define_expand "movmemdi"
17733  [(use (match_operand:BLK 0 "memory_operand" ""))
17734   (use (match_operand:BLK 1 "memory_operand" ""))
17735   (use (match_operand:DI 2 "nonmemory_operand" ""))
17736   (use (match_operand:DI 3 "const_int_operand" ""))]
17737  "TARGET_64BIT"
17738{
17739 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17740   DONE;
17741 else
17742   FAIL;
17743})
17744
17745;; Most CPUs don't like single string operations
17746;; Handle this case here to simplify previous expander.
17747
17748(define_expand "strmov"
17749  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17750   (set (match_operand 1 "memory_operand" "") (match_dup 4))
17751   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17752	      (clobber (reg:CC FLAGS_REG))])
17753   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17754	      (clobber (reg:CC FLAGS_REG))])]
17755  ""
17756{
17757  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17758
17759  /* If .md ever supports :P for Pmode, these can be directly
17760     in the pattern above.  */
17761  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17762  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17763
17764  if (TARGET_SINGLE_STRINGOP || optimize_size)
17765    {
17766      emit_insn (gen_strmov_singleop (operands[0], operands[1],
17767				      operands[2], operands[3],
17768				      operands[5], operands[6]));
17769      DONE;
17770    }
17771
17772  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17773})
17774
17775(define_expand "strmov_singleop"
17776  [(parallel [(set (match_operand 1 "memory_operand" "")
17777		   (match_operand 3 "memory_operand" ""))
17778	      (set (match_operand 0 "register_operand" "")
17779		   (match_operand 4 "" ""))
17780	      (set (match_operand 2 "register_operand" "")
17781		   (match_operand 5 "" ""))
17782	      (use (reg:SI DIRFLAG_REG))])]
17783  "TARGET_SINGLE_STRINGOP || optimize_size"
17784  "")
17785
17786(define_insn "*strmovdi_rex_1"
17787  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17788	(mem:DI (match_operand:DI 3 "register_operand" "1")))
17789   (set (match_operand:DI 0 "register_operand" "=D")
17790	(plus:DI (match_dup 2)
17791		 (const_int 8)))
17792   (set (match_operand:DI 1 "register_operand" "=S")
17793	(plus:DI (match_dup 3)
17794		 (const_int 8)))
17795   (use (reg:SI DIRFLAG_REG))]
17796  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17797  "movsq"
17798  [(set_attr "type" "str")
17799   (set_attr "mode" "DI")
17800   (set_attr "memory" "both")])
17801
17802(define_insn "*strmovsi_1"
17803  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17804	(mem:SI (match_operand:SI 3 "register_operand" "1")))
17805   (set (match_operand:SI 0 "register_operand" "=D")
17806	(plus:SI (match_dup 2)
17807		 (const_int 4)))
17808   (set (match_operand:SI 1 "register_operand" "=S")
17809	(plus:SI (match_dup 3)
17810		 (const_int 4)))
17811   (use (reg:SI DIRFLAG_REG))]
17812  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17813  "{movsl|movsd}"
17814  [(set_attr "type" "str")
17815   (set_attr "mode" "SI")
17816   (set_attr "memory" "both")])
17817
17818(define_insn "*strmovsi_rex_1"
17819  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17820	(mem:SI (match_operand:DI 3 "register_operand" "1")))
17821   (set (match_operand:DI 0 "register_operand" "=D")
17822	(plus:DI (match_dup 2)
17823		 (const_int 4)))
17824   (set (match_operand:DI 1 "register_operand" "=S")
17825	(plus:DI (match_dup 3)
17826		 (const_int 4)))
17827   (use (reg:SI DIRFLAG_REG))]
17828  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17829  "{movsl|movsd}"
17830  [(set_attr "type" "str")
17831   (set_attr "mode" "SI")
17832   (set_attr "memory" "both")])
17833
17834(define_insn "*strmovhi_1"
17835  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17836	(mem:HI (match_operand:SI 3 "register_operand" "1")))
17837   (set (match_operand:SI 0 "register_operand" "=D")
17838	(plus:SI (match_dup 2)
17839		 (const_int 2)))
17840   (set (match_operand:SI 1 "register_operand" "=S")
17841	(plus:SI (match_dup 3)
17842		 (const_int 2)))
17843   (use (reg:SI DIRFLAG_REG))]
17844  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17845  "movsw"
17846  [(set_attr "type" "str")
17847   (set_attr "memory" "both")
17848   (set_attr "mode" "HI")])
17849
17850(define_insn "*strmovhi_rex_1"
17851  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17852	(mem:HI (match_operand:DI 3 "register_operand" "1")))
17853   (set (match_operand:DI 0 "register_operand" "=D")
17854	(plus:DI (match_dup 2)
17855		 (const_int 2)))
17856   (set (match_operand:DI 1 "register_operand" "=S")
17857	(plus:DI (match_dup 3)
17858		 (const_int 2)))
17859   (use (reg:SI DIRFLAG_REG))]
17860  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17861  "movsw"
17862  [(set_attr "type" "str")
17863   (set_attr "memory" "both")
17864   (set_attr "mode" "HI")])
17865
17866(define_insn "*strmovqi_1"
17867  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17868	(mem:QI (match_operand:SI 3 "register_operand" "1")))
17869   (set (match_operand:SI 0 "register_operand" "=D")
17870	(plus:SI (match_dup 2)
17871		 (const_int 1)))
17872   (set (match_operand:SI 1 "register_operand" "=S")
17873	(plus:SI (match_dup 3)
17874		 (const_int 1)))
17875   (use (reg:SI DIRFLAG_REG))]
17876  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17877  "movsb"
17878  [(set_attr "type" "str")
17879   (set_attr "memory" "both")
17880   (set_attr "mode" "QI")])
17881
17882(define_insn "*strmovqi_rex_1"
17883  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17884	(mem:QI (match_operand:DI 3 "register_operand" "1")))
17885   (set (match_operand:DI 0 "register_operand" "=D")
17886	(plus:DI (match_dup 2)
17887		 (const_int 1)))
17888   (set (match_operand:DI 1 "register_operand" "=S")
17889	(plus:DI (match_dup 3)
17890		 (const_int 1)))
17891   (use (reg:SI DIRFLAG_REG))]
17892  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17893  "movsb"
17894  [(set_attr "type" "str")
17895   (set_attr "memory" "both")
17896   (set_attr "mode" "QI")])
17897
17898(define_expand "rep_mov"
17899  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17900	      (set (match_operand 0 "register_operand" "")
17901		   (match_operand 5 "" ""))
17902	      (set (match_operand 2 "register_operand" "")
17903		   (match_operand 6 "" ""))
17904	      (set (match_operand 1 "memory_operand" "")
17905		   (match_operand 3 "memory_operand" ""))
17906	      (use (match_dup 4))
17907	      (use (reg:SI DIRFLAG_REG))])]
17908  ""
17909  "")
17910
17911(define_insn "*rep_movdi_rex64"
17912  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17913   (set (match_operand:DI 0 "register_operand" "=D") 
17914        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17915			    (const_int 3))
17916		 (match_operand:DI 3 "register_operand" "0")))
17917   (set (match_operand:DI 1 "register_operand" "=S") 
17918        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17919		 (match_operand:DI 4 "register_operand" "1")))
17920   (set (mem:BLK (match_dup 3))
17921	(mem:BLK (match_dup 4)))
17922   (use (match_dup 5))
17923   (use (reg:SI DIRFLAG_REG))]
17924  "TARGET_64BIT"
17925  "{rep\;movsq|rep movsq}"
17926  [(set_attr "type" "str")
17927   (set_attr "prefix_rep" "1")
17928   (set_attr "memory" "both")
17929   (set_attr "mode" "DI")])
17930
17931(define_insn "*rep_movsi"
17932  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17933   (set (match_operand:SI 0 "register_operand" "=D") 
17934        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17935			    (const_int 2))
17936		 (match_operand:SI 3 "register_operand" "0")))
17937   (set (match_operand:SI 1 "register_operand" "=S") 
17938        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17939		 (match_operand:SI 4 "register_operand" "1")))
17940   (set (mem:BLK (match_dup 3))
17941	(mem:BLK (match_dup 4)))
17942   (use (match_dup 5))
17943   (use (reg:SI DIRFLAG_REG))]
17944  "!TARGET_64BIT"
17945  "{rep\;movsl|rep movsd}"
17946  [(set_attr "type" "str")
17947   (set_attr "prefix_rep" "1")
17948   (set_attr "memory" "both")
17949   (set_attr "mode" "SI")])
17950
17951(define_insn "*rep_movsi_rex64"
17952  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17953   (set (match_operand:DI 0 "register_operand" "=D") 
17954        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17955			    (const_int 2))
17956		 (match_operand:DI 3 "register_operand" "0")))
17957   (set (match_operand:DI 1 "register_operand" "=S") 
17958        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17959		 (match_operand:DI 4 "register_operand" "1")))
17960   (set (mem:BLK (match_dup 3))
17961	(mem:BLK (match_dup 4)))
17962   (use (match_dup 5))
17963   (use (reg:SI DIRFLAG_REG))]
17964  "TARGET_64BIT"
17965  "{rep\;movsl|rep movsd}"
17966  [(set_attr "type" "str")
17967   (set_attr "prefix_rep" "1")
17968   (set_attr "memory" "both")
17969   (set_attr "mode" "SI")])
17970
17971(define_insn "*rep_movqi"
17972  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17973   (set (match_operand:SI 0 "register_operand" "=D") 
17974        (plus:SI (match_operand:SI 3 "register_operand" "0")
17975		 (match_operand:SI 5 "register_operand" "2")))
17976   (set (match_operand:SI 1 "register_operand" "=S") 
17977        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17978   (set (mem:BLK (match_dup 3))
17979	(mem:BLK (match_dup 4)))
17980   (use (match_dup 5))
17981   (use (reg:SI DIRFLAG_REG))]
17982  "!TARGET_64BIT"
17983  "{rep\;movsb|rep movsb}"
17984  [(set_attr "type" "str")
17985   (set_attr "prefix_rep" "1")
17986   (set_attr "memory" "both")
17987   (set_attr "mode" "SI")])
17988
17989(define_insn "*rep_movqi_rex64"
17990  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17991   (set (match_operand:DI 0 "register_operand" "=D") 
17992        (plus:DI (match_operand:DI 3 "register_operand" "0")
17993		 (match_operand:DI 5 "register_operand" "2")))
17994   (set (match_operand:DI 1 "register_operand" "=S") 
17995        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17996   (set (mem:BLK (match_dup 3))
17997	(mem:BLK (match_dup 4)))
17998   (use (match_dup 5))
17999   (use (reg:SI DIRFLAG_REG))]
18000  "TARGET_64BIT"
18001  "{rep\;movsb|rep movsb}"
18002  [(set_attr "type" "str")
18003   (set_attr "prefix_rep" "1")
18004   (set_attr "memory" "both")
18005   (set_attr "mode" "SI")])
18006
18007(define_expand "setmemsi"
18008   [(use (match_operand:BLK 0 "memory_operand" ""))
18009    (use (match_operand:SI 1 "nonmemory_operand" ""))
18010    (use (match_operand 2 "const_int_operand" ""))
18011    (use (match_operand 3 "const_int_operand" ""))]
18012  ""
18013{
18014 /* If value to set is not zero, use the library routine.  */
18015 if (operands[2] != const0_rtx)
18016   FAIL;
18017
18018 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18019   DONE;
18020 else
18021   FAIL;
18022})
18023
18024(define_expand "setmemdi"
18025   [(use (match_operand:BLK 0 "memory_operand" ""))
18026    (use (match_operand:DI 1 "nonmemory_operand" ""))
18027    (use (match_operand 2 "const_int_operand" ""))
18028    (use (match_operand 3 "const_int_operand" ""))]
18029  "TARGET_64BIT"
18030{
18031 /* If value to set is not zero, use the library routine.  */
18032 if (operands[2] != const0_rtx)
18033   FAIL;
18034
18035 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18036   DONE;
18037 else
18038   FAIL;
18039})
18040
18041;; Most CPUs don't like single string operations
18042;; Handle this case here to simplify previous expander.
18043
18044(define_expand "strset"
18045  [(set (match_operand 1 "memory_operand" "")
18046	(match_operand 2 "register_operand" ""))
18047   (parallel [(set (match_operand 0 "register_operand" "")
18048		   (match_dup 3))
18049	      (clobber (reg:CC FLAGS_REG))])]
18050  ""
18051{
18052  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18053    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18054
18055  /* If .md ever supports :P for Pmode, this can be directly
18056     in the pattern above.  */
18057  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18058			      GEN_INT (GET_MODE_SIZE (GET_MODE
18059						      (operands[2]))));
18060  if (TARGET_SINGLE_STRINGOP || optimize_size)
18061    {
18062      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18063				      operands[3]));
18064      DONE;
18065    }
18066})
18067
18068(define_expand "strset_singleop"
18069  [(parallel [(set (match_operand 1 "memory_operand" "")
18070		   (match_operand 2 "register_operand" ""))
18071	      (set (match_operand 0 "register_operand" "")
18072		   (match_operand 3 "" ""))
18073	      (use (reg:SI DIRFLAG_REG))])]
18074  "TARGET_SINGLE_STRINGOP || optimize_size"
18075  "")
18076
18077(define_insn "*strsetdi_rex_1"
18078  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18079	(match_operand:DI 2 "register_operand" "a"))
18080   (set (match_operand:DI 0 "register_operand" "=D")
18081	(plus:DI (match_dup 1)
18082		 (const_int 8)))
18083   (use (reg:SI DIRFLAG_REG))]
18084  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18085  "stosq"
18086  [(set_attr "type" "str")
18087   (set_attr "memory" "store")
18088   (set_attr "mode" "DI")])
18089
18090(define_insn "*strsetsi_1"
18091  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18092	(match_operand:SI 2 "register_operand" "a"))
18093   (set (match_operand:SI 0 "register_operand" "=D")
18094	(plus:SI (match_dup 1)
18095		 (const_int 4)))
18096   (use (reg:SI DIRFLAG_REG))]
18097  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18098  "{stosl|stosd}"
18099  [(set_attr "type" "str")
18100   (set_attr "memory" "store")
18101   (set_attr "mode" "SI")])
18102
18103(define_insn "*strsetsi_rex_1"
18104  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18105	(match_operand:SI 2 "register_operand" "a"))
18106   (set (match_operand:DI 0 "register_operand" "=D")
18107	(plus:DI (match_dup 1)
18108		 (const_int 4)))
18109   (use (reg:SI DIRFLAG_REG))]
18110  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18111  "{stosl|stosd}"
18112  [(set_attr "type" "str")
18113   (set_attr "memory" "store")
18114   (set_attr "mode" "SI")])
18115
18116(define_insn "*strsethi_1"
18117  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18118	(match_operand:HI 2 "register_operand" "a"))
18119   (set (match_operand:SI 0 "register_operand" "=D")
18120	(plus:SI (match_dup 1)
18121		 (const_int 2)))
18122   (use (reg:SI DIRFLAG_REG))]
18123  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18124  "stosw"
18125  [(set_attr "type" "str")
18126   (set_attr "memory" "store")
18127   (set_attr "mode" "HI")])
18128
18129(define_insn "*strsethi_rex_1"
18130  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18131	(match_operand:HI 2 "register_operand" "a"))
18132   (set (match_operand:DI 0 "register_operand" "=D")
18133	(plus:DI (match_dup 1)
18134		 (const_int 2)))
18135   (use (reg:SI DIRFLAG_REG))]
18136  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18137  "stosw"
18138  [(set_attr "type" "str")
18139   (set_attr "memory" "store")
18140   (set_attr "mode" "HI")])
18141
18142(define_insn "*strsetqi_1"
18143  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18144	(match_operand:QI 2 "register_operand" "a"))
18145   (set (match_operand:SI 0 "register_operand" "=D")
18146	(plus:SI (match_dup 1)
18147		 (const_int 1)))
18148   (use (reg:SI DIRFLAG_REG))]
18149  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18150  "stosb"
18151  [(set_attr "type" "str")
18152   (set_attr "memory" "store")
18153   (set_attr "mode" "QI")])
18154
18155(define_insn "*strsetqi_rex_1"
18156  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18157	(match_operand:QI 2 "register_operand" "a"))
18158   (set (match_operand:DI 0 "register_operand" "=D")
18159	(plus:DI (match_dup 1)
18160		 (const_int 1)))
18161   (use (reg:SI DIRFLAG_REG))]
18162  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18163  "stosb"
18164  [(set_attr "type" "str")
18165   (set_attr "memory" "store")
18166   (set_attr "mode" "QI")])
18167
18168(define_expand "rep_stos"
18169  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18170	      (set (match_operand 0 "register_operand" "")
18171		   (match_operand 4 "" ""))
18172	      (set (match_operand 2 "memory_operand" "") (const_int 0))
18173	      (use (match_operand 3 "register_operand" ""))
18174	      (use (match_dup 1))
18175	      (use (reg:SI DIRFLAG_REG))])]
18176  ""
18177  "")
18178
18179(define_insn "*rep_stosdi_rex64"
18180  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18181   (set (match_operand:DI 0 "register_operand" "=D") 
18182        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18183			    (const_int 3))
18184		 (match_operand:DI 3 "register_operand" "0")))
18185   (set (mem:BLK (match_dup 3))
18186	(const_int 0))
18187   (use (match_operand:DI 2 "register_operand" "a"))
18188   (use (match_dup 4))
18189   (use (reg:SI DIRFLAG_REG))]
18190  "TARGET_64BIT"
18191  "{rep\;stosq|rep stosq}"
18192  [(set_attr "type" "str")
18193   (set_attr "prefix_rep" "1")
18194   (set_attr "memory" "store")
18195   (set_attr "mode" "DI")])
18196
18197(define_insn "*rep_stossi"
18198  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18199   (set (match_operand:SI 0 "register_operand" "=D") 
18200        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18201			    (const_int 2))
18202		 (match_operand:SI 3 "register_operand" "0")))
18203   (set (mem:BLK (match_dup 3))
18204	(const_int 0))
18205   (use (match_operand:SI 2 "register_operand" "a"))
18206   (use (match_dup 4))
18207   (use (reg:SI DIRFLAG_REG))]
18208  "!TARGET_64BIT"
18209  "{rep\;stosl|rep stosd}"
18210  [(set_attr "type" "str")
18211   (set_attr "prefix_rep" "1")
18212   (set_attr "memory" "store")
18213   (set_attr "mode" "SI")])
18214
18215(define_insn "*rep_stossi_rex64"
18216  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18217   (set (match_operand:DI 0 "register_operand" "=D") 
18218        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18219			    (const_int 2))
18220		 (match_operand:DI 3 "register_operand" "0")))
18221   (set (mem:BLK (match_dup 3))
18222	(const_int 0))
18223   (use (match_operand:SI 2 "register_operand" "a"))
18224   (use (match_dup 4))
18225   (use (reg:SI DIRFLAG_REG))]
18226  "TARGET_64BIT"
18227  "{rep\;stosl|rep stosd}"
18228  [(set_attr "type" "str")
18229   (set_attr "prefix_rep" "1")
18230   (set_attr "memory" "store")
18231   (set_attr "mode" "SI")])
18232
18233(define_insn "*rep_stosqi"
18234  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18235   (set (match_operand:SI 0 "register_operand" "=D") 
18236        (plus:SI (match_operand:SI 3 "register_operand" "0")
18237		 (match_operand:SI 4 "register_operand" "1")))
18238   (set (mem:BLK (match_dup 3))
18239	(const_int 0))
18240   (use (match_operand:QI 2 "register_operand" "a"))
18241   (use (match_dup 4))
18242   (use (reg:SI DIRFLAG_REG))]
18243  "!TARGET_64BIT"
18244  "{rep\;stosb|rep stosb}"
18245  [(set_attr "type" "str")
18246   (set_attr "prefix_rep" "1")
18247   (set_attr "memory" "store")
18248   (set_attr "mode" "QI")])
18249
18250(define_insn "*rep_stosqi_rex64"
18251  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18252   (set (match_operand:DI 0 "register_operand" "=D") 
18253        (plus:DI (match_operand:DI 3 "register_operand" "0")
18254		 (match_operand:DI 4 "register_operand" "1")))
18255   (set (mem:BLK (match_dup 3))
18256	(const_int 0))
18257   (use (match_operand:QI 2 "register_operand" "a"))
18258   (use (match_dup 4))
18259   (use (reg:SI DIRFLAG_REG))]
18260  "TARGET_64BIT"
18261  "{rep\;stosb|rep stosb}"
18262  [(set_attr "type" "str")
18263   (set_attr "prefix_rep" "1")
18264   (set_attr "memory" "store")
18265   (set_attr "mode" "QI")])
18266
18267(define_expand "cmpstrnsi"
18268  [(set (match_operand:SI 0 "register_operand" "")
18269	(compare:SI (match_operand:BLK 1 "general_operand" "")
18270		    (match_operand:BLK 2 "general_operand" "")))
18271   (use (match_operand 3 "general_operand" ""))
18272   (use (match_operand 4 "immediate_operand" ""))]
18273  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18274{
18275  rtx addr1, addr2, out, outlow, count, countreg, align;
18276
18277  /* Can't use this if the user has appropriated esi or edi.  */
18278  if (global_regs[4] || global_regs[5])
18279    FAIL;
18280
18281  out = operands[0];
18282  if (GET_CODE (out) != REG)
18283    out = gen_reg_rtx (SImode);
18284
18285  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18286  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18287  if (addr1 != XEXP (operands[1], 0))
18288    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18289  if (addr2 != XEXP (operands[2], 0))
18290    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18291
18292  count = operands[3];
18293  countreg = ix86_zero_extend_to_Pmode (count);
18294
18295  /* %%% Iff we are testing strict equality, we can use known alignment
18296     to good advantage.  This may be possible with combine, particularly
18297     once cc0 is dead.  */
18298  align = operands[4];
18299
18300  emit_insn (gen_cld ());
18301  if (GET_CODE (count) == CONST_INT)
18302    {
18303      if (INTVAL (count) == 0)
18304	{
18305	  emit_move_insn (operands[0], const0_rtx);
18306	  DONE;
18307	}
18308      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18309				     operands[1], operands[2]));
18310    }
18311  else
18312    {
18313      if (TARGET_64BIT)
18314	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18315      else
18316	emit_insn (gen_cmpsi_1 (countreg, countreg));
18317      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18318				  operands[1], operands[2]));
18319    }
18320
18321  outlow = gen_lowpart (QImode, out);
18322  emit_insn (gen_cmpintqi (outlow));
18323  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18324
18325  if (operands[0] != out)
18326    emit_move_insn (operands[0], out);
18327
18328  DONE;
18329})
18330
18331;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18332
18333(define_expand "cmpintqi"
18334  [(set (match_dup 1)
18335	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18336   (set (match_dup 2)
18337	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18338   (parallel [(set (match_operand:QI 0 "register_operand" "")
18339		   (minus:QI (match_dup 1)
18340			     (match_dup 2)))
18341	      (clobber (reg:CC FLAGS_REG))])]
18342  ""
18343  "operands[1] = gen_reg_rtx (QImode);
18344   operands[2] = gen_reg_rtx (QImode);")
18345
18346;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18347;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18348
18349(define_expand "cmpstrnqi_nz_1"
18350  [(parallel [(set (reg:CC FLAGS_REG)
18351		   (compare:CC (match_operand 4 "memory_operand" "")
18352			       (match_operand 5 "memory_operand" "")))
18353	      (use (match_operand 2 "register_operand" ""))
18354	      (use (match_operand:SI 3 "immediate_operand" ""))
18355	      (use (reg:SI DIRFLAG_REG))
18356	      (clobber (match_operand 0 "register_operand" ""))
18357	      (clobber (match_operand 1 "register_operand" ""))
18358	      (clobber (match_dup 2))])]
18359  ""
18360  "")
18361
18362(define_insn "*cmpstrnqi_nz_1"
18363  [(set (reg:CC FLAGS_REG)
18364	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18365		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18366   (use (match_operand:SI 6 "register_operand" "2"))
18367   (use (match_operand:SI 3 "immediate_operand" "i"))
18368   (use (reg:SI DIRFLAG_REG))
18369   (clobber (match_operand:SI 0 "register_operand" "=S"))
18370   (clobber (match_operand:SI 1 "register_operand" "=D"))
18371   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18372  "!TARGET_64BIT"
18373  "repz{\;| }cmpsb"
18374  [(set_attr "type" "str")
18375   (set_attr "mode" "QI")
18376   (set_attr "prefix_rep" "1")])
18377
18378(define_insn "*cmpstrnqi_nz_rex_1"
18379  [(set (reg:CC FLAGS_REG)
18380	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18381		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18382   (use (match_operand:DI 6 "register_operand" "2"))
18383   (use (match_operand:SI 3 "immediate_operand" "i"))
18384   (use (reg:SI DIRFLAG_REG))
18385   (clobber (match_operand:DI 0 "register_operand" "=S"))
18386   (clobber (match_operand:DI 1 "register_operand" "=D"))
18387   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18388  "TARGET_64BIT"
18389  "repz{\;| }cmpsb"
18390  [(set_attr "type" "str")
18391   (set_attr "mode" "QI")
18392   (set_attr "prefix_rep" "1")])
18393
18394;; The same, but the count is not known to not be zero.
18395
18396(define_expand "cmpstrnqi_1"
18397  [(parallel [(set (reg:CC FLAGS_REG)
18398		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
18399				     (const_int 0))
18400		  (compare:CC (match_operand 4 "memory_operand" "")
18401			      (match_operand 5 "memory_operand" ""))
18402		  (const_int 0)))
18403	      (use (match_operand:SI 3 "immediate_operand" ""))
18404	      (use (reg:CC FLAGS_REG))
18405	      (use (reg:SI DIRFLAG_REG))
18406	      (clobber (match_operand 0 "register_operand" ""))
18407	      (clobber (match_operand 1 "register_operand" ""))
18408	      (clobber (match_dup 2))])]
18409  ""
18410  "")
18411
18412(define_insn "*cmpstrnqi_1"
18413  [(set (reg:CC FLAGS_REG)
18414	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18415			     (const_int 0))
18416	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18417		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18418	  (const_int 0)))
18419   (use (match_operand:SI 3 "immediate_operand" "i"))
18420   (use (reg:CC FLAGS_REG))
18421   (use (reg:SI DIRFLAG_REG))
18422   (clobber (match_operand:SI 0 "register_operand" "=S"))
18423   (clobber (match_operand:SI 1 "register_operand" "=D"))
18424   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18425  "!TARGET_64BIT"
18426  "repz{\;| }cmpsb"
18427  [(set_attr "type" "str")
18428   (set_attr "mode" "QI")
18429   (set_attr "prefix_rep" "1")])
18430
18431(define_insn "*cmpstrnqi_rex_1"
18432  [(set (reg:CC FLAGS_REG)
18433	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18434			     (const_int 0))
18435	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18436		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18437	  (const_int 0)))
18438   (use (match_operand:SI 3 "immediate_operand" "i"))
18439   (use (reg:CC FLAGS_REG))
18440   (use (reg:SI DIRFLAG_REG))
18441   (clobber (match_operand:DI 0 "register_operand" "=S"))
18442   (clobber (match_operand:DI 1 "register_operand" "=D"))
18443   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18444  "TARGET_64BIT"
18445  "repz{\;| }cmpsb"
18446  [(set_attr "type" "str")
18447   (set_attr "mode" "QI")
18448   (set_attr "prefix_rep" "1")])
18449
18450(define_expand "strlensi"
18451  [(set (match_operand:SI 0 "register_operand" "")
18452	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
18453		    (match_operand:QI 2 "immediate_operand" "")
18454		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18455  ""
18456{
18457 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18458   DONE;
18459 else
18460   FAIL;
18461})
18462
18463(define_expand "strlendi"
18464  [(set (match_operand:DI 0 "register_operand" "")
18465	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
18466		    (match_operand:QI 2 "immediate_operand" "")
18467		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18468  ""
18469{
18470 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18471   DONE;
18472 else
18473   FAIL;
18474})
18475
18476(define_expand "strlenqi_1"
18477  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18478	      (use (reg:SI DIRFLAG_REG))
18479	      (clobber (match_operand 1 "register_operand" ""))
18480	      (clobber (reg:CC FLAGS_REG))])]
18481  ""
18482  "")
18483
18484(define_insn "*strlenqi_1"
18485  [(set (match_operand:SI 0 "register_operand" "=&c")
18486	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18487		    (match_operand:QI 2 "register_operand" "a")
18488		    (match_operand:SI 3 "immediate_operand" "i")
18489		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18490   (use (reg:SI DIRFLAG_REG))
18491   (clobber (match_operand:SI 1 "register_operand" "=D"))
18492   (clobber (reg:CC FLAGS_REG))]
18493  "!TARGET_64BIT"
18494  "repnz{\;| }scasb"
18495  [(set_attr "type" "str")
18496   (set_attr "mode" "QI")
18497   (set_attr "prefix_rep" "1")])
18498
18499(define_insn "*strlenqi_rex_1"
18500  [(set (match_operand:DI 0 "register_operand" "=&c")
18501	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18502		    (match_operand:QI 2 "register_operand" "a")
18503		    (match_operand:DI 3 "immediate_operand" "i")
18504		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18505   (use (reg:SI DIRFLAG_REG))
18506   (clobber (match_operand:DI 1 "register_operand" "=D"))
18507   (clobber (reg:CC FLAGS_REG))]
18508  "TARGET_64BIT"
18509  "repnz{\;| }scasb"
18510  [(set_attr "type" "str")
18511   (set_attr "mode" "QI")
18512   (set_attr "prefix_rep" "1")])
18513
18514;; Peephole optimizations to clean up after cmpstrn*.  This should be
18515;; handled in combine, but it is not currently up to the task.
18516;; When used for their truth value, the cmpstrn* expanders generate
18517;; code like this:
18518;;
18519;;   repz cmpsb
18520;;   seta 	%al
18521;;   setb 	%dl
18522;;   cmpb 	%al, %dl
18523;;   jcc	label
18524;;
18525;; The intermediate three instructions are unnecessary.
18526
18527;; This one handles cmpstrn*_nz_1...
18528(define_peephole2
18529  [(parallel[
18530     (set (reg:CC FLAGS_REG)
18531	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18532		      (mem:BLK (match_operand 5 "register_operand" ""))))
18533     (use (match_operand 6 "register_operand" ""))
18534     (use (match_operand:SI 3 "immediate_operand" ""))
18535     (use (reg:SI DIRFLAG_REG))
18536     (clobber (match_operand 0 "register_operand" ""))
18537     (clobber (match_operand 1 "register_operand" ""))
18538     (clobber (match_operand 2 "register_operand" ""))])
18539   (set (match_operand:QI 7 "register_operand" "")
18540	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18541   (set (match_operand:QI 8 "register_operand" "")
18542	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18543   (set (reg FLAGS_REG)
18544	(compare (match_dup 7) (match_dup 8)))
18545  ]
18546  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18547  [(parallel[
18548     (set (reg:CC FLAGS_REG)
18549	  (compare:CC (mem:BLK (match_dup 4))
18550		      (mem:BLK (match_dup 5))))
18551     (use (match_dup 6))
18552     (use (match_dup 3))
18553     (use (reg:SI DIRFLAG_REG))
18554     (clobber (match_dup 0))
18555     (clobber (match_dup 1))
18556     (clobber (match_dup 2))])]
18557  "")
18558
18559;; ...and this one handles cmpstrn*_1.
18560(define_peephole2
18561  [(parallel[
18562     (set (reg:CC FLAGS_REG)
18563	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18564			       (const_int 0))
18565	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18566		        (mem:BLK (match_operand 5 "register_operand" "")))
18567	    (const_int 0)))
18568     (use (match_operand:SI 3 "immediate_operand" ""))
18569     (use (reg:CC FLAGS_REG))
18570     (use (reg:SI DIRFLAG_REG))
18571     (clobber (match_operand 0 "register_operand" ""))
18572     (clobber (match_operand 1 "register_operand" ""))
18573     (clobber (match_operand 2 "register_operand" ""))])
18574   (set (match_operand:QI 7 "register_operand" "")
18575	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18576   (set (match_operand:QI 8 "register_operand" "")
18577	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18578   (set (reg FLAGS_REG)
18579	(compare (match_dup 7) (match_dup 8)))
18580  ]
18581  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18582  [(parallel[
18583     (set (reg:CC FLAGS_REG)
18584	  (if_then_else:CC (ne (match_dup 6)
18585			       (const_int 0))
18586	    (compare:CC (mem:BLK (match_dup 4))
18587			(mem:BLK (match_dup 5)))
18588	    (const_int 0)))
18589     (use (match_dup 3))
18590     (use (reg:CC FLAGS_REG))
18591     (use (reg:SI DIRFLAG_REG))
18592     (clobber (match_dup 0))
18593     (clobber (match_dup 1))
18594     (clobber (match_dup 2))])]
18595  "")
18596
18597
18598
18599;; Conditional move instructions.
18600
18601(define_expand "movdicc"
18602  [(set (match_operand:DI 0 "register_operand" "")
18603	(if_then_else:DI (match_operand 1 "comparison_operator" "")
18604			 (match_operand:DI 2 "general_operand" "")
18605			 (match_operand:DI 3 "general_operand" "")))]
18606  "TARGET_64BIT"
18607  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18608
18609(define_insn "x86_movdicc_0_m1_rex64"
18610  [(set (match_operand:DI 0 "register_operand" "=r")
18611	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18612	  (const_int -1)
18613	  (const_int 0)))
18614   (clobber (reg:CC FLAGS_REG))]
18615  "TARGET_64BIT"
18616  "sbb{q}\t%0, %0"
18617  ; Since we don't have the proper number of operands for an alu insn,
18618  ; fill in all the blanks.
18619  [(set_attr "type" "alu")
18620   (set_attr "pent_pair" "pu")
18621   (set_attr "memory" "none")
18622   (set_attr "imm_disp" "false")
18623   (set_attr "mode" "DI")
18624   (set_attr "length_immediate" "0")])
18625
18626(define_insn "*movdicc_c_rex64"
18627  [(set (match_operand:DI 0 "register_operand" "=r,r")
18628	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18629				[(reg FLAGS_REG) (const_int 0)])
18630		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18631		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18632  "TARGET_64BIT && TARGET_CMOVE
18633   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18634  "@
18635   cmov%O2%C1\t{%2, %0|%0, %2}
18636   cmov%O2%c1\t{%3, %0|%0, %3}"
18637  [(set_attr "type" "icmov")
18638   (set_attr "mode" "DI")])
18639
18640(define_expand "movsicc"
18641  [(set (match_operand:SI 0 "register_operand" "")
18642	(if_then_else:SI (match_operand 1 "comparison_operator" "")
18643			 (match_operand:SI 2 "general_operand" "")
18644			 (match_operand:SI 3 "general_operand" "")))]
18645  ""
18646  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18647
18648;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18649;; the register first winds up with `sbbl $0,reg', which is also weird.
18650;; So just document what we're doing explicitly.
18651
18652(define_insn "x86_movsicc_0_m1"
18653  [(set (match_operand:SI 0 "register_operand" "=r")
18654	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18655	  (const_int -1)
18656	  (const_int 0)))
18657   (clobber (reg:CC FLAGS_REG))]
18658  ""
18659  "sbb{l}\t%0, %0"
18660  ; Since we don't have the proper number of operands for an alu insn,
18661  ; fill in all the blanks.
18662  [(set_attr "type" "alu")
18663   (set_attr "pent_pair" "pu")
18664   (set_attr "memory" "none")
18665   (set_attr "imm_disp" "false")
18666   (set_attr "mode" "SI")
18667   (set_attr "length_immediate" "0")])
18668
18669(define_insn "*movsicc_noc"
18670  [(set (match_operand:SI 0 "register_operand" "=r,r")
18671	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18672				[(reg FLAGS_REG) (const_int 0)])
18673		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18674		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18675  "TARGET_CMOVE
18676   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18677  "@
18678   cmov%O2%C1\t{%2, %0|%0, %2}
18679   cmov%O2%c1\t{%3, %0|%0, %3}"
18680  [(set_attr "type" "icmov")
18681   (set_attr "mode" "SI")])
18682
18683(define_expand "movhicc"
18684  [(set (match_operand:HI 0 "register_operand" "")
18685	(if_then_else:HI (match_operand 1 "comparison_operator" "")
18686			 (match_operand:HI 2 "general_operand" "")
18687			 (match_operand:HI 3 "general_operand" "")))]
18688  "TARGET_HIMODE_MATH"
18689  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18690
18691(define_insn "*movhicc_noc"
18692  [(set (match_operand:HI 0 "register_operand" "=r,r")
18693	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18694				[(reg FLAGS_REG) (const_int 0)])
18695		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18696		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18697  "TARGET_CMOVE
18698   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18699  "@
18700   cmov%O2%C1\t{%2, %0|%0, %2}
18701   cmov%O2%c1\t{%3, %0|%0, %3}"
18702  [(set_attr "type" "icmov")
18703   (set_attr "mode" "HI")])
18704
18705(define_expand "movqicc"
18706  [(set (match_operand:QI 0 "register_operand" "")
18707	(if_then_else:QI (match_operand 1 "comparison_operator" "")
18708			 (match_operand:QI 2 "general_operand" "")
18709			 (match_operand:QI 3 "general_operand" "")))]
18710  "TARGET_QIMODE_MATH"
18711  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18712
18713(define_insn_and_split "*movqicc_noc"
18714  [(set (match_operand:QI 0 "register_operand" "=r,r")
18715	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18716				[(match_operand 4 "flags_reg_operand" "")
18717				 (const_int 0)])
18718		      (match_operand:QI 2 "register_operand" "r,0")
18719		      (match_operand:QI 3 "register_operand" "0,r")))]
18720  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18721  "#"
18722  "&& reload_completed"
18723  [(set (match_dup 0)
18724	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18725		      (match_dup 2)
18726		      (match_dup 3)))]
18727  "operands[0] = gen_lowpart (SImode, operands[0]);
18728   operands[2] = gen_lowpart (SImode, operands[2]);
18729   operands[3] = gen_lowpart (SImode, operands[3]);"
18730  [(set_attr "type" "icmov")
18731   (set_attr "mode" "SI")])
18732
18733(define_expand "movsfcc"
18734  [(set (match_operand:SF 0 "register_operand" "")
18735	(if_then_else:SF (match_operand 1 "comparison_operator" "")
18736			 (match_operand:SF 2 "register_operand" "")
18737			 (match_operand:SF 3 "register_operand" "")))]
18738  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18739  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18740
18741(define_insn "*movsfcc_1_387"
18742  [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18743	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18744				[(reg FLAGS_REG) (const_int 0)])
18745		      (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18746		      (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18747  "TARGET_80387 && TARGET_CMOVE
18748   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18749  "@
18750   fcmov%F1\t{%2, %0|%0, %2}
18751   fcmov%f1\t{%3, %0|%0, %3}
18752   cmov%O2%C1\t{%2, %0|%0, %2}
18753   cmov%O2%c1\t{%3, %0|%0, %3}"
18754  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18755   (set_attr "mode" "SF,SF,SI,SI")])
18756
18757(define_expand "movdfcc"
18758  [(set (match_operand:DF 0 "register_operand" "")
18759	(if_then_else:DF (match_operand 1 "comparison_operator" "")
18760			 (match_operand:DF 2 "register_operand" "")
18761			 (match_operand:DF 3 "register_operand" "")))]
18762  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18763  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18764
18765(define_insn "*movdfcc_1"
18766  [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18767	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18768				[(reg FLAGS_REG) (const_int 0)])
18769		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18770		      (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18771  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18772   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18773  "@
18774   fcmov%F1\t{%2, %0|%0, %2}
18775   fcmov%f1\t{%3, %0|%0, %3}
18776   #
18777   #"
18778  [(set_attr "type" "fcmov,fcmov,multi,multi")
18779   (set_attr "mode" "DF")])
18780
18781(define_insn "*movdfcc_1_rex64"
18782  [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18783	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18784				[(reg FLAGS_REG) (const_int 0)])
18785		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18786		      (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18787  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18788   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18789  "@
18790   fcmov%F1\t{%2, %0|%0, %2}
18791   fcmov%f1\t{%3, %0|%0, %3}
18792   cmov%O2%C1\t{%2, %0|%0, %2}
18793   cmov%O2%c1\t{%3, %0|%0, %3}"
18794  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18795   (set_attr "mode" "DF")])
18796
18797(define_split
18798  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18799	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18800				[(match_operand 4 "flags_reg_operand" "")
18801				 (const_int 0)])
18802		      (match_operand:DF 2 "nonimmediate_operand" "")
18803		      (match_operand:DF 3 "nonimmediate_operand" "")))]
18804  "!TARGET_64BIT && reload_completed"
18805  [(set (match_dup 2)
18806	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18807		      (match_dup 5)
18808		      (match_dup 7)))
18809   (set (match_dup 3)
18810	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18811		      (match_dup 6)
18812		      (match_dup 8)))]
18813  "split_di (operands+2, 1, operands+5, operands+6);
18814   split_di (operands+3, 1, operands+7, operands+8);
18815   split_di (operands, 1, operands+2, operands+3);")
18816
18817(define_expand "movxfcc"
18818  [(set (match_operand:XF 0 "register_operand" "")
18819	(if_then_else:XF (match_operand 1 "comparison_operator" "")
18820			 (match_operand:XF 2 "register_operand" "")
18821			 (match_operand:XF 3 "register_operand" "")))]
18822  "TARGET_80387 && TARGET_CMOVE"
18823  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18824
18825(define_insn "*movxfcc_1"
18826  [(set (match_operand:XF 0 "register_operand" "=f,f")
18827	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18828				[(reg FLAGS_REG) (const_int 0)])
18829		      (match_operand:XF 2 "register_operand" "f,0")
18830		      (match_operand:XF 3 "register_operand" "0,f")))]
18831  "TARGET_80387 && TARGET_CMOVE"
18832  "@
18833   fcmov%F1\t{%2, %0|%0, %2}
18834   fcmov%f1\t{%3, %0|%0, %3}"
18835  [(set_attr "type" "fcmov")
18836   (set_attr "mode" "XF")])
18837
18838;; These versions of the min/max patterns are intentionally ignorant of
18839;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18840;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18841;; are undefined in this condition, we're certain this is correct.
18842
18843(define_insn "sminsf3"
18844  [(set (match_operand:SF 0 "register_operand" "=x")
18845	(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18846		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18847  "TARGET_SSE_MATH"
18848  "minss\t{%2, %0|%0, %2}"
18849  [(set_attr "type" "sseadd")
18850   (set_attr "mode" "SF")])
18851
18852(define_insn "smaxsf3"
18853  [(set (match_operand:SF 0 "register_operand" "=x")
18854	(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18855		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18856  "TARGET_SSE_MATH"
18857  "maxss\t{%2, %0|%0, %2}"
18858  [(set_attr "type" "sseadd")
18859   (set_attr "mode" "SF")])
18860
18861(define_insn "smindf3"
18862  [(set (match_operand:DF 0 "register_operand" "=x")
18863	(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18864		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18865  "TARGET_SSE2 && TARGET_SSE_MATH"
18866  "minsd\t{%2, %0|%0, %2}"
18867  [(set_attr "type" "sseadd")
18868   (set_attr "mode" "DF")])
18869
18870(define_insn "smaxdf3"
18871  [(set (match_operand:DF 0 "register_operand" "=x")
18872	(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18873		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18874  "TARGET_SSE2 && TARGET_SSE_MATH"
18875  "maxsd\t{%2, %0|%0, %2}"
18876  [(set_attr "type" "sseadd")
18877   (set_attr "mode" "DF")])
18878
18879;; These versions of the min/max patterns implement exactly the operations
18880;;   min = (op1 < op2 ? op1 : op2)
18881;;   max = (!(op1 < op2) ? op1 : op2)
18882;; Their operands are not commutative, and thus they may be used in the
18883;; presence of -0.0 and NaN.
18884
18885(define_insn "*ieee_sminsf3"
18886  [(set (match_operand:SF 0 "register_operand" "=x")
18887	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
18888		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
18889		   UNSPEC_IEEE_MIN))]
18890  "TARGET_SSE_MATH"
18891  "minss\t{%2, %0|%0, %2}"
18892  [(set_attr "type" "sseadd")
18893   (set_attr "mode" "SF")])
18894
18895(define_insn "*ieee_smaxsf3"
18896  [(set (match_operand:SF 0 "register_operand" "=x")
18897	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
18898		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
18899		   UNSPEC_IEEE_MAX))]
18900  "TARGET_SSE_MATH"
18901  "maxss\t{%2, %0|%0, %2}"
18902  [(set_attr "type" "sseadd")
18903   (set_attr "mode" "SF")])
18904
18905(define_insn "*ieee_smindf3"
18906  [(set (match_operand:DF 0 "register_operand" "=x")
18907	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
18908		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
18909		   UNSPEC_IEEE_MIN))]
18910  "TARGET_SSE2 && TARGET_SSE_MATH"
18911  "minsd\t{%2, %0|%0, %2}"
18912  [(set_attr "type" "sseadd")
18913   (set_attr "mode" "DF")])
18914
18915(define_insn "*ieee_smaxdf3"
18916  [(set (match_operand:DF 0 "register_operand" "=x")
18917	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
18918		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
18919		   UNSPEC_IEEE_MAX))]
18920  "TARGET_SSE2 && TARGET_SSE_MATH"
18921  "maxsd\t{%2, %0|%0, %2}"
18922  [(set_attr "type" "sseadd")
18923   (set_attr "mode" "DF")])
18924
18925;; Make two stack loads independent:
18926;;   fld aa              fld aa
18927;;   fld %st(0)     ->   fld bb
18928;;   fmul bb             fmul %st(1), %st
18929;;
18930;; Actually we only match the last two instructions for simplicity.
18931(define_peephole2
18932  [(set (match_operand 0 "fp_register_operand" "")
18933	(match_operand 1 "fp_register_operand" ""))
18934   (set (match_dup 0)
18935	(match_operator 2 "binary_fp_operator"
18936	   [(match_dup 0)
18937	    (match_operand 3 "memory_operand" "")]))]
18938  "REGNO (operands[0]) != REGNO (operands[1])"
18939  [(set (match_dup 0) (match_dup 3))
18940   (set (match_dup 0) (match_dup 4))]
18941
18942  ;; The % modifier is not operational anymore in peephole2's, so we have to
18943  ;; swap the operands manually in the case of addition and multiplication.
18944  "if (COMMUTATIVE_ARITH_P (operands[2]))
18945     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18946				 operands[0], operands[1]);
18947   else
18948     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18949				 operands[1], operands[0]);")
18950
18951;; Conditional addition patterns
18952(define_expand "addqicc"
18953  [(match_operand:QI 0 "register_operand" "")
18954   (match_operand 1 "comparison_operator" "")
18955   (match_operand:QI 2 "register_operand" "")
18956   (match_operand:QI 3 "const_int_operand" "")]
18957  ""
18958  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18959
18960(define_expand "addhicc"
18961  [(match_operand:HI 0 "register_operand" "")
18962   (match_operand 1 "comparison_operator" "")
18963   (match_operand:HI 2 "register_operand" "")
18964   (match_operand:HI 3 "const_int_operand" "")]
18965  ""
18966  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18967
18968(define_expand "addsicc"
18969  [(match_operand:SI 0 "register_operand" "")
18970   (match_operand 1 "comparison_operator" "")
18971   (match_operand:SI 2 "register_operand" "")
18972   (match_operand:SI 3 "const_int_operand" "")]
18973  ""
18974  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18975
18976(define_expand "adddicc"
18977  [(match_operand:DI 0 "register_operand" "")
18978   (match_operand 1 "comparison_operator" "")
18979   (match_operand:DI 2 "register_operand" "")
18980   (match_operand:DI 3 "const_int_operand" "")]
18981  "TARGET_64BIT"
18982  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18983
18984
18985;; Misc patterns (?)
18986
18987;; This pattern exists to put a dependency on all ebp-based memory accesses.
18988;; Otherwise there will be nothing to keep
18989;; 
18990;; [(set (reg ebp) (reg esp))]
18991;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18992;;  (clobber (eflags)]
18993;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18994;;
18995;; in proper program order.
18996(define_insn "pro_epilogue_adjust_stack_1"
18997  [(set (match_operand:SI 0 "register_operand" "=r,r")
18998	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
18999	         (match_operand:SI 2 "immediate_operand" "i,i")))
19000   (clobber (reg:CC FLAGS_REG))
19001   (clobber (mem:BLK (scratch)))]
19002  "!TARGET_64BIT"
19003{
19004  switch (get_attr_type (insn))
19005    {
19006    case TYPE_IMOV:
19007      return "mov{l}\t{%1, %0|%0, %1}";
19008
19009    case TYPE_ALU:
19010      if (GET_CODE (operands[2]) == CONST_INT
19011          && (INTVAL (operands[2]) == 128
19012	      || (INTVAL (operands[2]) < 0
19013	          && INTVAL (operands[2]) != -128)))
19014	{
19015	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19016	  return "sub{l}\t{%2, %0|%0, %2}";
19017	}
19018      return "add{l}\t{%2, %0|%0, %2}";
19019
19020    case TYPE_LEA:
19021      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19022      return "lea{l}\t{%a2, %0|%0, %a2}";
19023
19024    default:
19025      gcc_unreachable ();
19026    }
19027}
19028  [(set (attr "type")
19029	(cond [(eq_attr "alternative" "0")
19030		 (const_string "alu")
19031	       (match_operand:SI 2 "const0_operand" "")
19032		 (const_string "imov")
19033	      ]
19034	      (const_string "lea")))
19035   (set_attr "mode" "SI")])
19036
19037(define_insn "pro_epilogue_adjust_stack_rex64"
19038  [(set (match_operand:DI 0 "register_operand" "=r,r")
19039	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19040		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19041   (clobber (reg:CC FLAGS_REG))
19042   (clobber (mem:BLK (scratch)))]
19043  "TARGET_64BIT"
19044{
19045  switch (get_attr_type (insn))
19046    {
19047    case TYPE_IMOV:
19048      return "mov{q}\t{%1, %0|%0, %1}";
19049
19050    case TYPE_ALU:
19051      if (GET_CODE (operands[2]) == CONST_INT
19052	  /* Avoid overflows.  */
19053	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19054          && (INTVAL (operands[2]) == 128
19055	      || (INTVAL (operands[2]) < 0
19056	          && INTVAL (operands[2]) != -128)))
19057	{
19058	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19059	  return "sub{q}\t{%2, %0|%0, %2}";
19060	}
19061      return "add{q}\t{%2, %0|%0, %2}";
19062
19063    case TYPE_LEA:
19064      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19065      return "lea{q}\t{%a2, %0|%0, %a2}";
19066
19067    default:
19068      gcc_unreachable ();
19069    }
19070}
19071  [(set (attr "type")
19072	(cond [(eq_attr "alternative" "0")
19073		 (const_string "alu")
19074	       (match_operand:DI 2 "const0_operand" "")
19075		 (const_string "imov")
19076	      ]
19077	      (const_string "lea")))
19078   (set_attr "mode" "DI")])
19079
19080(define_insn "pro_epilogue_adjust_stack_rex64_2"
19081  [(set (match_operand:DI 0 "register_operand" "=r,r")
19082	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19083		 (match_operand:DI 3 "immediate_operand" "i,i")))
19084   (use (match_operand:DI 2 "register_operand" "r,r"))
19085   (clobber (reg:CC FLAGS_REG))
19086   (clobber (mem:BLK (scratch)))]
19087  "TARGET_64BIT"
19088{
19089  switch (get_attr_type (insn))
19090    {
19091    case TYPE_ALU:
19092      return "add{q}\t{%2, %0|%0, %2}";
19093
19094    case TYPE_LEA:
19095      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19096      return "lea{q}\t{%a2, %0|%0, %a2}";
19097
19098    default:
19099      gcc_unreachable ();
19100    }
19101}
19102  [(set_attr "type" "alu,lea")
19103   (set_attr "mode" "DI")])
19104
19105(define_expand "allocate_stack_worker"
19106  [(match_operand:SI 0 "register_operand" "")]
19107  "TARGET_STACK_PROBE"
19108{
19109  if (reload_completed)
19110    {
19111      if (TARGET_64BIT)
19112	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19113      else
19114	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19115    }
19116  else
19117    {
19118      if (TARGET_64BIT)
19119	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19120      else
19121	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19122    }
19123  DONE;
19124})
19125
19126(define_insn "allocate_stack_worker_1"
19127  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19128    UNSPECV_STACK_PROBE)
19129   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19130   (clobber (match_scratch:SI 1 "=0"))
19131   (clobber (reg:CC FLAGS_REG))]
19132  "!TARGET_64BIT && TARGET_STACK_PROBE"
19133  "call\t__alloca"
19134  [(set_attr "type" "multi")
19135   (set_attr "length" "5")])
19136
19137(define_expand "allocate_stack_worker_postreload"
19138  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19139				    UNSPECV_STACK_PROBE)
19140	      (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19141	      (clobber (match_dup 0))
19142	      (clobber (reg:CC FLAGS_REG))])]
19143  ""
19144  "")
19145
19146(define_insn "allocate_stack_worker_rex64"
19147  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19148    UNSPECV_STACK_PROBE)
19149   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19150   (clobber (match_scratch:DI 1 "=0"))
19151   (clobber (reg:CC FLAGS_REG))]
19152  "TARGET_64BIT && TARGET_STACK_PROBE"
19153  "call\t__alloca"
19154  [(set_attr "type" "multi")
19155   (set_attr "length" "5")])
19156
19157(define_expand "allocate_stack_worker_rex64_postreload"
19158  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19159				    UNSPECV_STACK_PROBE)
19160	      (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19161	      (clobber (match_dup 0))
19162	      (clobber (reg:CC FLAGS_REG))])]
19163  ""
19164  "")
19165
19166(define_expand "allocate_stack"
19167  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19168		   (minus:SI (reg:SI SP_REG)
19169			     (match_operand:SI 1 "general_operand" "")))
19170	      (clobber (reg:CC FLAGS_REG))])
19171   (parallel [(set (reg:SI SP_REG)
19172		   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19173	      (clobber (reg:CC FLAGS_REG))])]
19174  "TARGET_STACK_PROBE"
19175{
19176#ifdef CHECK_STACK_LIMIT
19177  if (GET_CODE (operands[1]) == CONST_INT
19178      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19179    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19180			   operands[1]));
19181  else 
19182#endif
19183    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19184							    operands[1])));
19185
19186  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19187  DONE;
19188})
19189
19190(define_expand "builtin_setjmp_receiver"
19191  [(label_ref (match_operand 0 "" ""))]
19192  "!TARGET_64BIT && flag_pic"
19193{
19194  emit_insn (gen_set_got (pic_offset_table_rtx));
19195  DONE;
19196})
19197
19198;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19199
19200(define_split
19201  [(set (match_operand 0 "register_operand" "")
19202	(match_operator 3 "promotable_binary_operator"
19203	   [(match_operand 1 "register_operand" "")
19204	    (match_operand 2 "aligned_operand" "")]))
19205   (clobber (reg:CC FLAGS_REG))]
19206  "! TARGET_PARTIAL_REG_STALL && reload_completed
19207   && ((GET_MODE (operands[0]) == HImode 
19208	&& ((!optimize_size && !TARGET_FAST_PREFIX)
19209	    || GET_CODE (operands[2]) != CONST_INT
19210	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19211       || (GET_MODE (operands[0]) == QImode 
19212	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19213  [(parallel [(set (match_dup 0)
19214		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19215	      (clobber (reg:CC FLAGS_REG))])]
19216  "operands[0] = gen_lowpart (SImode, operands[0]);
19217   operands[1] = gen_lowpart (SImode, operands[1]);
19218   if (GET_CODE (operands[3]) != ASHIFT)
19219     operands[2] = gen_lowpart (SImode, operands[2]);
19220   PUT_MODE (operands[3], SImode);")
19221
19222; Promote the QImode tests, as i386 has encoding of the AND
19223; instruction with 32-bit sign-extended immediate and thus the
19224; instruction size is unchanged, except in the %eax case for
19225; which it is increased by one byte, hence the ! optimize_size.
19226(define_split
19227  [(set (match_operand 0 "flags_reg_operand" "")
19228	(match_operator 2 "compare_operator"
19229	  [(and (match_operand 3 "aligned_operand" "")
19230		(match_operand 4 "const_int_operand" ""))
19231	   (const_int 0)]))
19232   (set (match_operand 1 "register_operand" "")
19233	(and (match_dup 3) (match_dup 4)))]
19234  "! TARGET_PARTIAL_REG_STALL && reload_completed
19235   /* Ensure that the operand will remain sign-extended immediate.  */
19236   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19237   && ! optimize_size
19238   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19239       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19240  [(parallel [(set (match_dup 0)
19241		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19242			            (const_int 0)]))
19243	      (set (match_dup 1)
19244		   (and:SI (match_dup 3) (match_dup 4)))])]
19245{
19246  operands[4]
19247    = gen_int_mode (INTVAL (operands[4])
19248		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19249  operands[1] = gen_lowpart (SImode, operands[1]);
19250  operands[3] = gen_lowpart (SImode, operands[3]);
19251})
19252
19253; Don't promote the QImode tests, as i386 doesn't have encoding of
19254; the TEST instruction with 32-bit sign-extended immediate and thus
19255; the instruction size would at least double, which is not what we
19256; want even with ! optimize_size.
19257(define_split
19258  [(set (match_operand 0 "flags_reg_operand" "")
19259	(match_operator 1 "compare_operator"
19260	  [(and (match_operand:HI 2 "aligned_operand" "")
19261		(match_operand:HI 3 "const_int_operand" ""))
19262	   (const_int 0)]))]
19263  "! TARGET_PARTIAL_REG_STALL && reload_completed
19264   /* Ensure that the operand will remain sign-extended immediate.  */
19265   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19266   && ! TARGET_FAST_PREFIX
19267   && ! optimize_size"
19268  [(set (match_dup 0)
19269	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19270		         (const_int 0)]))]
19271{
19272  operands[3]
19273    = gen_int_mode (INTVAL (operands[3])
19274		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19275  operands[2] = gen_lowpart (SImode, operands[2]);
19276})
19277
19278(define_split
19279  [(set (match_operand 0 "register_operand" "")
19280	(neg (match_operand 1 "register_operand" "")))
19281   (clobber (reg:CC FLAGS_REG))]
19282  "! TARGET_PARTIAL_REG_STALL && reload_completed
19283   && (GET_MODE (operands[0]) == HImode
19284       || (GET_MODE (operands[0]) == QImode 
19285	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19286  [(parallel [(set (match_dup 0)
19287		   (neg:SI (match_dup 1)))
19288	      (clobber (reg:CC FLAGS_REG))])]
19289  "operands[0] = gen_lowpart (SImode, operands[0]);
19290   operands[1] = gen_lowpart (SImode, operands[1]);")
19291
19292(define_split
19293  [(set (match_operand 0 "register_operand" "")
19294	(not (match_operand 1 "register_operand" "")))]
19295  "! TARGET_PARTIAL_REG_STALL && reload_completed
19296   && (GET_MODE (operands[0]) == HImode
19297       || (GET_MODE (operands[0]) == QImode 
19298	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19299  [(set (match_dup 0)
19300	(not:SI (match_dup 1)))]
19301  "operands[0] = gen_lowpart (SImode, operands[0]);
19302   operands[1] = gen_lowpart (SImode, operands[1]);")
19303
19304(define_split 
19305  [(set (match_operand 0 "register_operand" "")
19306	(if_then_else (match_operator 1 "comparison_operator" 
19307				[(reg FLAGS_REG) (const_int 0)])
19308		      (match_operand 2 "register_operand" "")
19309		      (match_operand 3 "register_operand" "")))]
19310  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19311   && (GET_MODE (operands[0]) == HImode
19312       || (GET_MODE (operands[0]) == QImode 
19313	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19314  [(set (match_dup 0)
19315	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19316  "operands[0] = gen_lowpart (SImode, operands[0]);
19317   operands[2] = gen_lowpart (SImode, operands[2]);
19318   operands[3] = gen_lowpart (SImode, operands[3]);")
19319			
19320
19321;; RTL Peephole optimizations, run before sched2.  These primarily look to
19322;; transform a complex memory operation into two memory to register operations.
19323
19324;; Don't push memory operands
19325(define_peephole2
19326  [(set (match_operand:SI 0 "push_operand" "")
19327	(match_operand:SI 1 "memory_operand" ""))
19328   (match_scratch:SI 2 "r")]
19329  "!optimize_size && !TARGET_PUSH_MEMORY
19330   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19331  [(set (match_dup 2) (match_dup 1))
19332   (set (match_dup 0) (match_dup 2))]
19333  "")
19334
19335(define_peephole2
19336  [(set (match_operand:DI 0 "push_operand" "")
19337	(match_operand:DI 1 "memory_operand" ""))
19338   (match_scratch:DI 2 "r")]
19339  "!optimize_size && !TARGET_PUSH_MEMORY
19340   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19341  [(set (match_dup 2) (match_dup 1))
19342   (set (match_dup 0) (match_dup 2))]
19343  "")
19344
19345;; We need to handle SFmode only, because DFmode and XFmode is split to
19346;; SImode pushes.
19347(define_peephole2
19348  [(set (match_operand:SF 0 "push_operand" "")
19349	(match_operand:SF 1 "memory_operand" ""))
19350   (match_scratch:SF 2 "r")]
19351  "!optimize_size && !TARGET_PUSH_MEMORY
19352   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19353  [(set (match_dup 2) (match_dup 1))
19354   (set (match_dup 0) (match_dup 2))]
19355  "")
19356
19357(define_peephole2
19358  [(set (match_operand:HI 0 "push_operand" "")
19359	(match_operand:HI 1 "memory_operand" ""))
19360   (match_scratch:HI 2 "r")]
19361  "!optimize_size && !TARGET_PUSH_MEMORY
19362   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19363  [(set (match_dup 2) (match_dup 1))
19364   (set (match_dup 0) (match_dup 2))]
19365  "")
19366
19367(define_peephole2
19368  [(set (match_operand:QI 0 "push_operand" "")
19369	(match_operand:QI 1 "memory_operand" ""))
19370   (match_scratch:QI 2 "q")]
19371  "!optimize_size && !TARGET_PUSH_MEMORY
19372   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19373  [(set (match_dup 2) (match_dup 1))
19374   (set (match_dup 0) (match_dup 2))]
19375  "")
19376
19377;; Don't move an immediate directly to memory when the instruction
19378;; gets too big.
19379(define_peephole2
19380  [(match_scratch:SI 1 "r")
19381   (set (match_operand:SI 0 "memory_operand" "")
19382        (const_int 0))]
19383  "! optimize_size
19384   && ! TARGET_USE_MOV0
19385   && TARGET_SPLIT_LONG_MOVES
19386   && get_attr_length (insn) >= ix86_cost->large_insn
19387   && peep2_regno_dead_p (0, FLAGS_REG)"
19388  [(parallel [(set (match_dup 1) (const_int 0))
19389	      (clobber (reg:CC FLAGS_REG))])
19390   (set (match_dup 0) (match_dup 1))]
19391  "")
19392
19393(define_peephole2
19394  [(match_scratch:HI 1 "r")
19395   (set (match_operand:HI 0 "memory_operand" "")
19396        (const_int 0))]
19397  "! optimize_size
19398   && ! TARGET_USE_MOV0
19399   && TARGET_SPLIT_LONG_MOVES
19400   && get_attr_length (insn) >= ix86_cost->large_insn
19401   && peep2_regno_dead_p (0, FLAGS_REG)"
19402  [(parallel [(set (match_dup 2) (const_int 0))
19403	      (clobber (reg:CC FLAGS_REG))])
19404   (set (match_dup 0) (match_dup 1))]
19405  "operands[2] = gen_lowpart (SImode, operands[1]);")
19406
19407(define_peephole2
19408  [(match_scratch:QI 1 "q")
19409   (set (match_operand:QI 0 "memory_operand" "")
19410        (const_int 0))]
19411  "! optimize_size
19412   && ! TARGET_USE_MOV0
19413   && TARGET_SPLIT_LONG_MOVES
19414   && get_attr_length (insn) >= ix86_cost->large_insn
19415   && peep2_regno_dead_p (0, FLAGS_REG)"
19416  [(parallel [(set (match_dup 2) (const_int 0))
19417	      (clobber (reg:CC FLAGS_REG))])
19418   (set (match_dup 0) (match_dup 1))]
19419  "operands[2] = gen_lowpart (SImode, operands[1]);")
19420
19421(define_peephole2
19422  [(match_scratch:SI 2 "r")
19423   (set (match_operand:SI 0 "memory_operand" "")
19424        (match_operand:SI 1 "immediate_operand" ""))]
19425  "! optimize_size
19426   && get_attr_length (insn) >= ix86_cost->large_insn
19427   && TARGET_SPLIT_LONG_MOVES"
19428  [(set (match_dup 2) (match_dup 1))
19429   (set (match_dup 0) (match_dup 2))]
19430  "")
19431
19432(define_peephole2
19433  [(match_scratch:HI 2 "r")
19434   (set (match_operand:HI 0 "memory_operand" "")
19435        (match_operand:HI 1 "immediate_operand" ""))]
19436  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19437  && TARGET_SPLIT_LONG_MOVES"
19438  [(set (match_dup 2) (match_dup 1))
19439   (set (match_dup 0) (match_dup 2))]
19440  "")
19441
19442(define_peephole2
19443  [(match_scratch:QI 2 "q")
19444   (set (match_operand:QI 0 "memory_operand" "")
19445        (match_operand:QI 1 "immediate_operand" ""))]
19446  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19447  && TARGET_SPLIT_LONG_MOVES"
19448  [(set (match_dup 2) (match_dup 1))
19449   (set (match_dup 0) (match_dup 2))]
19450  "")
19451
19452;; Don't compare memory with zero, load and use a test instead.
19453(define_peephole2
19454  [(set (match_operand 0 "flags_reg_operand" "")
19455 	(match_operator 1 "compare_operator"
19456	  [(match_operand:SI 2 "memory_operand" "")
19457	   (const_int 0)]))
19458   (match_scratch:SI 3 "r")]
19459  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19460  [(set (match_dup 3) (match_dup 2))
19461   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19462  "")
19463
19464;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19465;; Don't split NOTs with a displacement operand, because resulting XOR
19466;; will not be pairable anyway.
19467;;
19468;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19469;; represented using a modRM byte.  The XOR replacement is long decoded,
19470;; so this split helps here as well.
19471;;
19472;; Note: Can't do this as a regular split because we can't get proper
19473;; lifetime information then.
19474
19475(define_peephole2
19476  [(set (match_operand:SI 0 "nonimmediate_operand" "")
19477	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19478  "!optimize_size
19479   && peep2_regno_dead_p (0, FLAGS_REG)
19480   && ((TARGET_PENTIUM 
19481        && (GET_CODE (operands[0]) != MEM
19482            || !memory_displacement_operand (operands[0], SImode)))
19483       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19484  [(parallel [(set (match_dup 0)
19485		   (xor:SI (match_dup 1) (const_int -1)))
19486	      (clobber (reg:CC FLAGS_REG))])]
19487  "")
19488
19489(define_peephole2
19490  [(set (match_operand:HI 0 "nonimmediate_operand" "")
19491	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19492  "!optimize_size
19493   && peep2_regno_dead_p (0, FLAGS_REG)
19494   && ((TARGET_PENTIUM 
19495        && (GET_CODE (operands[0]) != MEM
19496            || !memory_displacement_operand (operands[0], HImode)))
19497       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19498  [(parallel [(set (match_dup 0)
19499		   (xor:HI (match_dup 1) (const_int -1)))
19500	      (clobber (reg:CC FLAGS_REG))])]
19501  "")
19502
19503(define_peephole2
19504  [(set (match_operand:QI 0 "nonimmediate_operand" "")
19505	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19506  "!optimize_size
19507   && peep2_regno_dead_p (0, FLAGS_REG)
19508   && ((TARGET_PENTIUM 
19509        && (GET_CODE (operands[0]) != MEM
19510            || !memory_displacement_operand (operands[0], QImode)))
19511       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19512  [(parallel [(set (match_dup 0)
19513		   (xor:QI (match_dup 1) (const_int -1)))
19514	      (clobber (reg:CC FLAGS_REG))])]
19515  "")
19516
19517;; Non pairable "test imm, reg" instructions can be translated to
19518;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19519;; byte opcode instead of two, have a short form for byte operands),
19520;; so do it for other CPUs as well.  Given that the value was dead,
19521;; this should not create any new dependencies.  Pass on the sub-word
19522;; versions if we're concerned about partial register stalls.
19523
19524(define_peephole2
19525  [(set (match_operand 0 "flags_reg_operand" "")
19526	(match_operator 1 "compare_operator"
19527	  [(and:SI (match_operand:SI 2 "register_operand" "")
19528		   (match_operand:SI 3 "immediate_operand" ""))
19529	   (const_int 0)]))]
19530  "ix86_match_ccmode (insn, CCNOmode)
19531   && (true_regnum (operands[2]) != 0
19532       || (GET_CODE (operands[3]) == CONST_INT
19533	   && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19534   && peep2_reg_dead_p (1, operands[2])"
19535  [(parallel
19536     [(set (match_dup 0)
19537	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19538		            (const_int 0)]))
19539      (set (match_dup 2)
19540	   (and:SI (match_dup 2) (match_dup 3)))])]
19541  "")
19542
19543;; We don't need to handle HImode case, because it will be promoted to SImode
19544;; on ! TARGET_PARTIAL_REG_STALL
19545
19546(define_peephole2
19547  [(set (match_operand 0 "flags_reg_operand" "")
19548	(match_operator 1 "compare_operator"
19549	  [(and:QI (match_operand:QI 2 "register_operand" "")
19550		   (match_operand:QI 3 "immediate_operand" ""))
19551	   (const_int 0)]))]
19552  "! TARGET_PARTIAL_REG_STALL
19553   && ix86_match_ccmode (insn, CCNOmode)
19554   && true_regnum (operands[2]) != 0
19555   && peep2_reg_dead_p (1, operands[2])"
19556  [(parallel
19557     [(set (match_dup 0)
19558	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19559		            (const_int 0)]))
19560      (set (match_dup 2)
19561	   (and:QI (match_dup 2) (match_dup 3)))])]
19562  "")
19563
19564(define_peephole2
19565  [(set (match_operand 0 "flags_reg_operand" "")
19566	(match_operator 1 "compare_operator"
19567	  [(and:SI
19568	     (zero_extract:SI
19569	       (match_operand 2 "ext_register_operand" "")
19570	       (const_int 8)
19571	       (const_int 8))
19572	     (match_operand 3 "const_int_operand" ""))
19573	   (const_int 0)]))]
19574  "! TARGET_PARTIAL_REG_STALL
19575   && ix86_match_ccmode (insn, CCNOmode)
19576   && true_regnum (operands[2]) != 0
19577   && peep2_reg_dead_p (1, operands[2])"
19578  [(parallel [(set (match_dup 0)
19579		   (match_op_dup 1
19580		     [(and:SI
19581			(zero_extract:SI
19582			  (match_dup 2)
19583			  (const_int 8)
19584			  (const_int 8))
19585			(match_dup 3))
19586		      (const_int 0)]))
19587	      (set (zero_extract:SI (match_dup 2)
19588				    (const_int 8)
19589				    (const_int 8))
19590		   (and:SI 
19591		     (zero_extract:SI
19592		       (match_dup 2)
19593		       (const_int 8)
19594		       (const_int 8))
19595		     (match_dup 3)))])]
19596  "")
19597
19598;; Don't do logical operations with memory inputs.
19599(define_peephole2
19600  [(match_scratch:SI 2 "r")
19601   (parallel [(set (match_operand:SI 0 "register_operand" "")
19602                   (match_operator:SI 3 "arith_or_logical_operator"
19603                     [(match_dup 0)
19604                      (match_operand:SI 1 "memory_operand" "")]))
19605              (clobber (reg:CC FLAGS_REG))])]
19606  "! optimize_size && ! TARGET_READ_MODIFY"
19607  [(set (match_dup 2) (match_dup 1))
19608   (parallel [(set (match_dup 0)
19609                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19610              (clobber (reg:CC FLAGS_REG))])]
19611  "")
19612
19613(define_peephole2
19614  [(match_scratch:SI 2 "r")
19615   (parallel [(set (match_operand:SI 0 "register_operand" "")
19616                   (match_operator:SI 3 "arith_or_logical_operator"
19617                     [(match_operand:SI 1 "memory_operand" "")
19618                      (match_dup 0)]))
19619              (clobber (reg:CC FLAGS_REG))])]
19620  "! optimize_size && ! TARGET_READ_MODIFY"
19621  [(set (match_dup 2) (match_dup 1))
19622   (parallel [(set (match_dup 0)
19623                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19624              (clobber (reg:CC FLAGS_REG))])]
19625  "")
19626
19627; Don't do logical operations with memory outputs
19628;
19629; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19630; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19631; the same decoder scheduling characteristics as the original.
19632
19633(define_peephole2
19634  [(match_scratch:SI 2 "r")
19635   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19636                   (match_operator:SI 3 "arith_or_logical_operator"
19637                     [(match_dup 0)
19638                      (match_operand:SI 1 "nonmemory_operand" "")]))
19639              (clobber (reg:CC FLAGS_REG))])]
19640  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19641  [(set (match_dup 2) (match_dup 0))
19642   (parallel [(set (match_dup 2)
19643                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19644              (clobber (reg:CC FLAGS_REG))])
19645   (set (match_dup 0) (match_dup 2))]
19646  "")
19647
19648(define_peephole2
19649  [(match_scratch:SI 2 "r")
19650   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19651                   (match_operator:SI 3 "arith_or_logical_operator"
19652                     [(match_operand:SI 1 "nonmemory_operand" "")
19653                      (match_dup 0)]))
19654              (clobber (reg:CC FLAGS_REG))])]
19655  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19656  [(set (match_dup 2) (match_dup 0))
19657   (parallel [(set (match_dup 2)
19658                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19659              (clobber (reg:CC FLAGS_REG))])
19660   (set (match_dup 0) (match_dup 2))]
19661  "")
19662
19663;; Attempt to always use XOR for zeroing registers.
19664(define_peephole2
19665  [(set (match_operand 0 "register_operand" "")
19666	(match_operand 1 "const0_operand" ""))]
19667  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19668   && (! TARGET_USE_MOV0 || optimize_size)
19669   && GENERAL_REG_P (operands[0])
19670   && peep2_regno_dead_p (0, FLAGS_REG)"
19671  [(parallel [(set (match_dup 0) (const_int 0))
19672	      (clobber (reg:CC FLAGS_REG))])]
19673{
19674  operands[0] = gen_lowpart (word_mode, operands[0]);
19675})
19676
19677(define_peephole2
19678  [(set (strict_low_part (match_operand 0 "register_operand" ""))
19679	(const_int 0))]
19680  "(GET_MODE (operands[0]) == QImode
19681    || GET_MODE (operands[0]) == HImode)
19682   && (! TARGET_USE_MOV0 || optimize_size)
19683   && peep2_regno_dead_p (0, FLAGS_REG)"
19684  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19685	      (clobber (reg:CC FLAGS_REG))])])
19686
19687;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19688(define_peephole2
19689  [(set (match_operand 0 "register_operand" "")
19690	(const_int -1))]
19691  "(GET_MODE (operands[0]) == HImode
19692    || GET_MODE (operands[0]) == SImode 
19693    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19694   && (optimize_size || TARGET_PENTIUM)
19695   && peep2_regno_dead_p (0, FLAGS_REG)"
19696  [(parallel [(set (match_dup 0) (const_int -1))
19697	      (clobber (reg:CC FLAGS_REG))])]
19698  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19699			      operands[0]);")
19700
19701;; Attempt to convert simple leas to adds. These can be created by
19702;; move expanders.
19703(define_peephole2
19704  [(set (match_operand:SI 0 "register_operand" "")
19705  	(plus:SI (match_dup 0)
19706		 (match_operand:SI 1 "nonmemory_operand" "")))]
19707  "peep2_regno_dead_p (0, FLAGS_REG)"
19708  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19709	      (clobber (reg:CC FLAGS_REG))])]
19710  "")
19711
19712(define_peephole2
19713  [(set (match_operand:SI 0 "register_operand" "")
19714  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19715			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19716  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19717  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19718	      (clobber (reg:CC FLAGS_REG))])]
19719  "operands[2] = gen_lowpart (SImode, operands[2]);")
19720
19721(define_peephole2
19722  [(set (match_operand:DI 0 "register_operand" "")
19723  	(plus:DI (match_dup 0)
19724		 (match_operand:DI 1 "x86_64_general_operand" "")))]
19725  "peep2_regno_dead_p (0, FLAGS_REG)"
19726  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19727	      (clobber (reg:CC FLAGS_REG))])]
19728  "")
19729
19730(define_peephole2
19731  [(set (match_operand:SI 0 "register_operand" "")
19732  	(mult:SI (match_dup 0)
19733		 (match_operand:SI 1 "const_int_operand" "")))]
19734  "exact_log2 (INTVAL (operands[1])) >= 0
19735   && peep2_regno_dead_p (0, FLAGS_REG)"
19736  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19737	      (clobber (reg:CC FLAGS_REG))])]
19738  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19739
19740(define_peephole2
19741  [(set (match_operand:DI 0 "register_operand" "")
19742  	(mult:DI (match_dup 0)
19743		 (match_operand:DI 1 "const_int_operand" "")))]
19744  "exact_log2 (INTVAL (operands[1])) >= 0
19745   && peep2_regno_dead_p (0, FLAGS_REG)"
19746  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19747	      (clobber (reg:CC FLAGS_REG))])]
19748  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19749
19750(define_peephole2
19751  [(set (match_operand:SI 0 "register_operand" "")
19752  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19753		   (match_operand:DI 2 "const_int_operand" "")) 0))]
19754  "exact_log2 (INTVAL (operands[2])) >= 0
19755   && REGNO (operands[0]) == REGNO (operands[1])
19756   && peep2_regno_dead_p (0, FLAGS_REG)"
19757  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19758	      (clobber (reg:CC FLAGS_REG))])]
19759  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19760
19761;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19762;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19763;; many CPUs it is also faster, since special hardware to avoid esp
19764;; dependencies is present.
19765
19766;; While some of these conversions may be done using splitters, we use peepholes
19767;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19768
19769;; Convert prologue esp subtractions to push.
19770;; We need register to push.  In order to keep verify_flow_info happy we have
19771;; two choices
19772;; - use scratch and clobber it in order to avoid dependencies
19773;; - use already live register
19774;; We can't use the second way right now, since there is no reliable way how to
19775;; verify that given register is live.  First choice will also most likely in
19776;; fewer dependencies.  On the place of esp adjustments it is very likely that
19777;; call clobbered registers are dead.  We may want to use base pointer as an
19778;; alternative when no register is available later.
19779
19780(define_peephole2
19781  [(match_scratch:SI 0 "r")
19782   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19783	      (clobber (reg:CC FLAGS_REG))
19784	      (clobber (mem:BLK (scratch)))])]
19785  "optimize_size || !TARGET_SUB_ESP_4"
19786  [(clobber (match_dup 0))
19787   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19788	      (clobber (mem:BLK (scratch)))])])
19789
19790(define_peephole2
19791  [(match_scratch:SI 0 "r")
19792   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19793	      (clobber (reg:CC FLAGS_REG))
19794	      (clobber (mem:BLK (scratch)))])]
19795  "optimize_size || !TARGET_SUB_ESP_8"
19796  [(clobber (match_dup 0))
19797   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19798   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19799	      (clobber (mem:BLK (scratch)))])])
19800
19801;; Convert esp subtractions to push.
19802(define_peephole2
19803  [(match_scratch:SI 0 "r")
19804   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19805	      (clobber (reg:CC FLAGS_REG))])]
19806  "optimize_size || !TARGET_SUB_ESP_4"
19807  [(clobber (match_dup 0))
19808   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19809
19810(define_peephole2
19811  [(match_scratch:SI 0 "r")
19812   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19813	      (clobber (reg:CC FLAGS_REG))])]
19814  "optimize_size || !TARGET_SUB_ESP_8"
19815  [(clobber (match_dup 0))
19816   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19817   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19818
19819;; Convert epilogue deallocator to pop.
19820(define_peephole2
19821  [(match_scratch:SI 0 "r")
19822   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19823	      (clobber (reg:CC FLAGS_REG))
19824	      (clobber (mem:BLK (scratch)))])]
19825  "optimize_size || !TARGET_ADD_ESP_4"
19826  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19827	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19828	      (clobber (mem:BLK (scratch)))])]
19829  "")
19830
19831;; Two pops case is tricky, since pop causes dependency on destination register.
19832;; We use two registers if available.
19833(define_peephole2
19834  [(match_scratch:SI 0 "r")
19835   (match_scratch:SI 1 "r")
19836   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19837	      (clobber (reg:CC FLAGS_REG))
19838	      (clobber (mem:BLK (scratch)))])]
19839  "optimize_size || !TARGET_ADD_ESP_8"
19840  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19841	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19842	      (clobber (mem:BLK (scratch)))])
19843   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19844	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19845  "")
19846
19847(define_peephole2
19848  [(match_scratch:SI 0 "r")
19849   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19850	      (clobber (reg:CC FLAGS_REG))
19851	      (clobber (mem:BLK (scratch)))])]
19852  "optimize_size"
19853  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19854	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19855	      (clobber (mem:BLK (scratch)))])
19856   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19857	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19858  "")
19859
19860;; Convert esp additions to pop.
19861(define_peephole2
19862  [(match_scratch:SI 0 "r")
19863   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19864	      (clobber (reg:CC FLAGS_REG))])]
19865  ""
19866  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19867	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19868  "")
19869
19870;; Two pops case is tricky, since pop causes dependency on destination register.
19871;; We use two registers if available.
19872(define_peephole2
19873  [(match_scratch:SI 0 "r")
19874   (match_scratch:SI 1 "r")
19875   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19876	      (clobber (reg:CC FLAGS_REG))])]
19877  ""
19878  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19879	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19880   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19881	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19882  "")
19883
19884(define_peephole2
19885  [(match_scratch:SI 0 "r")
19886   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19887	      (clobber (reg:CC FLAGS_REG))])]
19888  "optimize_size"
19889  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19890	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19891   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19892	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19893  "")
19894
19895;; Convert compares with 1 to shorter inc/dec operations when CF is not
19896;; required and register dies.  Similarly for 128 to plus -128.
19897(define_peephole2
19898  [(set (match_operand 0 "flags_reg_operand" "")
19899	(match_operator 1 "compare_operator"
19900	  [(match_operand 2 "register_operand" "")
19901	   (match_operand 3 "const_int_operand" "")]))]
19902  "(INTVAL (operands[3]) == -1
19903    || INTVAL (operands[3]) == 1
19904    || INTVAL (operands[3]) == 128)
19905   && ix86_match_ccmode (insn, CCGCmode)
19906   && peep2_reg_dead_p (1, operands[2])"
19907  [(parallel [(set (match_dup 0)
19908		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19909	      (clobber (match_dup 2))])]
19910  "")
19911
19912(define_peephole2
19913  [(match_scratch:DI 0 "r")
19914   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19915	      (clobber (reg:CC FLAGS_REG))
19916	      (clobber (mem:BLK (scratch)))])]
19917  "optimize_size || !TARGET_SUB_ESP_4"
19918  [(clobber (match_dup 0))
19919   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19920	      (clobber (mem:BLK (scratch)))])])
19921
19922(define_peephole2
19923  [(match_scratch:DI 0 "r")
19924   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19925	      (clobber (reg:CC FLAGS_REG))
19926	      (clobber (mem:BLK (scratch)))])]
19927  "optimize_size || !TARGET_SUB_ESP_8"
19928  [(clobber (match_dup 0))
19929   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19930   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19931	      (clobber (mem:BLK (scratch)))])])
19932
19933;; Convert esp subtractions to push.
19934(define_peephole2
19935  [(match_scratch:DI 0 "r")
19936   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19937	      (clobber (reg:CC FLAGS_REG))])]
19938  "optimize_size || !TARGET_SUB_ESP_4"
19939  [(clobber (match_dup 0))
19940   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19941
19942(define_peephole2
19943  [(match_scratch:DI 0 "r")
19944   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19945	      (clobber (reg:CC FLAGS_REG))])]
19946  "optimize_size || !TARGET_SUB_ESP_8"
19947  [(clobber (match_dup 0))
19948   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19949   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19950
19951;; Convert epilogue deallocator to pop.
19952(define_peephole2
19953  [(match_scratch:DI 0 "r")
19954   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19955	      (clobber (reg:CC FLAGS_REG))
19956	      (clobber (mem:BLK (scratch)))])]
19957  "optimize_size || !TARGET_ADD_ESP_4"
19958  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19959	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19960	      (clobber (mem:BLK (scratch)))])]
19961  "")
19962
19963;; Two pops case is tricky, since pop causes dependency on destination register.
19964;; We use two registers if available.
19965(define_peephole2
19966  [(match_scratch:DI 0 "r")
19967   (match_scratch:DI 1 "r")
19968   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19969	      (clobber (reg:CC FLAGS_REG))
19970	      (clobber (mem:BLK (scratch)))])]
19971  "optimize_size || !TARGET_ADD_ESP_8"
19972  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19973	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19974	      (clobber (mem:BLK (scratch)))])
19975   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19976	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19977  "")
19978
19979(define_peephole2
19980  [(match_scratch:DI 0 "r")
19981   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19982	      (clobber (reg:CC FLAGS_REG))
19983	      (clobber (mem:BLK (scratch)))])]
19984  "optimize_size"
19985  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19986	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19987	      (clobber (mem:BLK (scratch)))])
19988   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19989	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19990  "")
19991
19992;; Convert esp additions to pop.
19993(define_peephole2
19994  [(match_scratch:DI 0 "r")
19995   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19996	      (clobber (reg:CC FLAGS_REG))])]
19997  ""
19998  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19999	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20000  "")
20001
20002;; Two pops case is tricky, since pop causes dependency on destination register.
20003;; We use two registers if available.
20004(define_peephole2
20005  [(match_scratch:DI 0 "r")
20006   (match_scratch:DI 1 "r")
20007   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20008	      (clobber (reg:CC FLAGS_REG))])]
20009  ""
20010  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20011	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20012   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20013	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20014  "")
20015
20016(define_peephole2
20017  [(match_scratch:DI 0 "r")
20018   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20019	      (clobber (reg:CC FLAGS_REG))])]
20020  "optimize_size"
20021  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20022	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20023   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20024	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20025  "")
20026
20027;; Convert imul by three, five and nine into lea
20028(define_peephole2
20029  [(parallel
20030    [(set (match_operand:SI 0 "register_operand" "")
20031	  (mult:SI (match_operand:SI 1 "register_operand" "")
20032		   (match_operand:SI 2 "const_int_operand" "")))
20033     (clobber (reg:CC FLAGS_REG))])]
20034  "INTVAL (operands[2]) == 3
20035   || INTVAL (operands[2]) == 5
20036   || INTVAL (operands[2]) == 9"
20037  [(set (match_dup 0)
20038        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20039                 (match_dup 1)))]
20040  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20041
20042(define_peephole2
20043  [(parallel
20044    [(set (match_operand:SI 0 "register_operand" "")
20045          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20046                   (match_operand:SI 2 "const_int_operand" "")))
20047     (clobber (reg:CC FLAGS_REG))])]
20048  "!optimize_size 
20049   && (INTVAL (operands[2]) == 3
20050       || INTVAL (operands[2]) == 5
20051       || INTVAL (operands[2]) == 9)"
20052  [(set (match_dup 0) (match_dup 1))
20053   (set (match_dup 0)
20054        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20055                 (match_dup 0)))]
20056  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20057
20058(define_peephole2
20059  [(parallel
20060    [(set (match_operand:DI 0 "register_operand" "")
20061	  (mult:DI (match_operand:DI 1 "register_operand" "")
20062		   (match_operand:DI 2 "const_int_operand" "")))
20063     (clobber (reg:CC FLAGS_REG))])]
20064  "TARGET_64BIT
20065   && (INTVAL (operands[2]) == 3
20066       || INTVAL (operands[2]) == 5
20067       || INTVAL (operands[2]) == 9)"
20068  [(set (match_dup 0)
20069        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20070                 (match_dup 1)))]
20071  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20072
20073(define_peephole2
20074  [(parallel
20075    [(set (match_operand:DI 0 "register_operand" "")
20076          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20077                   (match_operand:DI 2 "const_int_operand" "")))
20078     (clobber (reg:CC FLAGS_REG))])]
20079  "TARGET_64BIT
20080   && !optimize_size 
20081   && (INTVAL (operands[2]) == 3
20082       || INTVAL (operands[2]) == 5
20083       || INTVAL (operands[2]) == 9)"
20084  [(set (match_dup 0) (match_dup 1))
20085   (set (match_dup 0)
20086        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20087                 (match_dup 0)))]
20088  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20089
20090;; Imul $32bit_imm, mem, reg is vector decoded, while
20091;; imul $32bit_imm, reg, reg is direct decoded.
20092(define_peephole2
20093  [(match_scratch:DI 3 "r")
20094   (parallel [(set (match_operand:DI 0 "register_operand" "")
20095		   (mult:DI (match_operand:DI 1 "memory_operand" "")
20096			    (match_operand:DI 2 "immediate_operand" "")))
20097	      (clobber (reg:CC FLAGS_REG))])]
20098  "TARGET_K8 && !optimize_size
20099   && (GET_CODE (operands[2]) != CONST_INT
20100       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
20101  [(set (match_dup 3) (match_dup 1))
20102   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20103	      (clobber (reg:CC FLAGS_REG))])]
20104"")
20105
20106(define_peephole2
20107  [(match_scratch:SI 3 "r")
20108   (parallel [(set (match_operand:SI 0 "register_operand" "")
20109		   (mult:SI (match_operand:SI 1 "memory_operand" "")
20110			    (match_operand:SI 2 "immediate_operand" "")))
20111	      (clobber (reg:CC FLAGS_REG))])]
20112  "TARGET_K8 && !optimize_size
20113   && (GET_CODE (operands[2]) != CONST_INT
20114       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
20115  [(set (match_dup 3) (match_dup 1))
20116   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20117	      (clobber (reg:CC FLAGS_REG))])]
20118"")
20119
20120(define_peephole2
20121  [(match_scratch:SI 3 "r")
20122   (parallel [(set (match_operand:DI 0 "register_operand" "")
20123		   (zero_extend:DI
20124		     (mult:SI (match_operand:SI 1 "memory_operand" "")
20125			      (match_operand:SI 2 "immediate_operand" ""))))
20126	      (clobber (reg:CC FLAGS_REG))])]
20127  "TARGET_K8 && !optimize_size
20128   && (GET_CODE (operands[2]) != CONST_INT
20129       || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
20130  [(set (match_dup 3) (match_dup 1))
20131   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20132	      (clobber (reg:CC FLAGS_REG))])]
20133"")
20134
20135;; imul $8/16bit_imm, regmem, reg is vector decoded.
20136;; Convert it into imul reg, reg
20137;; It would be better to force assembler to encode instruction using long
20138;; immediate, but there is apparently no way to do so.
20139(define_peephole2
20140  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20141		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20142			    (match_operand:DI 2 "const_int_operand" "")))
20143	      (clobber (reg:CC FLAGS_REG))])
20144   (match_scratch:DI 3 "r")]
20145  "TARGET_K8 && !optimize_size
20146   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
20147  [(set (match_dup 3) (match_dup 2))
20148   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20149	      (clobber (reg:CC FLAGS_REG))])]
20150{
20151  if (!rtx_equal_p (operands[0], operands[1]))
20152    emit_move_insn (operands[0], operands[1]);
20153})
20154
20155(define_peephole2
20156  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20157		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20158			    (match_operand:SI 2 "const_int_operand" "")))
20159	      (clobber (reg:CC FLAGS_REG))])
20160   (match_scratch:SI 3 "r")]
20161  "TARGET_K8 && !optimize_size
20162   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
20163  [(set (match_dup 3) (match_dup 2))
20164   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20165	      (clobber (reg:CC FLAGS_REG))])]
20166{
20167  if (!rtx_equal_p (operands[0], operands[1]))
20168    emit_move_insn (operands[0], operands[1]);
20169})
20170
20171(define_peephole2
20172  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20173		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20174			    (match_operand:HI 2 "immediate_operand" "")))
20175	      (clobber (reg:CC FLAGS_REG))])
20176   (match_scratch:HI 3 "r")]
20177  "TARGET_K8 && !optimize_size"
20178  [(set (match_dup 3) (match_dup 2))
20179   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20180	      (clobber (reg:CC FLAGS_REG))])]
20181{
20182  if (!rtx_equal_p (operands[0], operands[1]))
20183    emit_move_insn (operands[0], operands[1]);
20184})
20185
20186;; After splitting up read-modify operations, array accesses with memory
20187;; operands might end up in form:
20188;;  sall    $2, %eax
20189;;  movl    4(%esp), %edx
20190;;  addl    %edx, %eax
20191;; instead of pre-splitting:
20192;;  sall    $2, %eax
20193;;  addl    4(%esp), %eax
20194;; Turn it into:
20195;;  movl    4(%esp), %edx
20196;;  leal    (%edx,%eax,4), %eax
20197
20198(define_peephole2
20199  [(parallel [(set (match_operand 0 "register_operand" "")
20200		   (ashift (match_operand 1 "register_operand" "")
20201			   (match_operand 2 "const_int_operand" "")))
20202	       (clobber (reg:CC FLAGS_REG))])
20203   (set (match_operand 3 "register_operand")
20204        (match_operand 4 "x86_64_general_operand" ""))
20205   (parallel [(set (match_operand 5 "register_operand" "")
20206		   (plus (match_operand 6 "register_operand" "")
20207			 (match_operand 7 "register_operand" "")))
20208		   (clobber (reg:CC FLAGS_REG))])]
20209  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20210   /* Validate MODE for lea.  */
20211   && ((!TARGET_PARTIAL_REG_STALL
20212	&& (GET_MODE (operands[0]) == QImode
20213	    || GET_MODE (operands[0]) == HImode))
20214       || GET_MODE (operands[0]) == SImode 
20215       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20216   /* We reorder load and the shift.  */
20217   && !rtx_equal_p (operands[1], operands[3])
20218   && !reg_overlap_mentioned_p (operands[0], operands[4])
20219   /* Last PLUS must consist of operand 0 and 3.  */
20220   && !rtx_equal_p (operands[0], operands[3])
20221   && (rtx_equal_p (operands[3], operands[6])
20222       || rtx_equal_p (operands[3], operands[7]))
20223   && (rtx_equal_p (operands[0], operands[6])
20224       || rtx_equal_p (operands[0], operands[7]))
20225   /* The intermediate operand 0 must die or be same as output.  */
20226   && (rtx_equal_p (operands[0], operands[5])
20227       || peep2_reg_dead_p (3, operands[0]))"
20228  [(set (match_dup 3) (match_dup 4))
20229   (set (match_dup 0) (match_dup 1))]
20230{
20231  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20232  int scale = 1 << INTVAL (operands[2]);
20233  rtx index = gen_lowpart (Pmode, operands[1]);
20234  rtx base = gen_lowpart (Pmode, operands[3]);
20235  rtx dest = gen_lowpart (mode, operands[5]);
20236
20237  operands[1] = gen_rtx_PLUS (Pmode, base,
20238  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20239  if (mode != Pmode)
20240    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20241  operands[0] = dest;
20242})
20243
20244;; Call-value patterns last so that the wildcard operand does not
20245;; disrupt insn-recog's switch tables.
20246
20247(define_insn "*call_value_pop_0"
20248  [(set (match_operand 0 "" "")
20249	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20250	      (match_operand:SI 2 "" "")))
20251   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20252			    (match_operand:SI 3 "immediate_operand" "")))]
20253  "!TARGET_64BIT"
20254{
20255  if (SIBLING_CALL_P (insn))
20256    return "jmp\t%P1";
20257  else
20258    return "call\t%P1";
20259}
20260  [(set_attr "type" "callv")])
20261
20262(define_insn "*call_value_pop_1"
20263  [(set (match_operand 0 "" "")
20264	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20265	      (match_operand:SI 2 "" "")))
20266   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20267			    (match_operand:SI 3 "immediate_operand" "i")))]
20268  "!TARGET_64BIT"
20269{
20270  if (constant_call_address_operand (operands[1], Pmode))
20271    {
20272      if (SIBLING_CALL_P (insn))
20273	return "jmp\t%P1";
20274      else
20275	return "call\t%P1";
20276    }
20277  if (SIBLING_CALL_P (insn))
20278    return "jmp\t%A1";
20279  else
20280    return "call\t%A1";
20281}
20282  [(set_attr "type" "callv")])
20283
20284(define_insn "*call_value_0"
20285  [(set (match_operand 0 "" "")
20286	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20287	      (match_operand:SI 2 "" "")))]
20288  "!TARGET_64BIT"
20289{
20290  if (SIBLING_CALL_P (insn))
20291    return "jmp\t%P1";
20292  else
20293    return "call\t%P1";
20294}
20295  [(set_attr "type" "callv")])
20296
20297(define_insn "*call_value_0_rex64"
20298  [(set (match_operand 0 "" "")
20299	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20300	      (match_operand:DI 2 "const_int_operand" "")))]
20301  "TARGET_64BIT"
20302{
20303  if (SIBLING_CALL_P (insn))
20304    return "jmp\t%P1";
20305  else
20306    return "call\t%P1";
20307}
20308  [(set_attr "type" "callv")])
20309
20310(define_insn "*call_value_1"
20311  [(set (match_operand 0 "" "")
20312	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20313	      (match_operand:SI 2 "" "")))]
20314  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20315{
20316  if (constant_call_address_operand (operands[1], Pmode))
20317    return "call\t%P1";
20318  return "call\t%A1";
20319}
20320  [(set_attr "type" "callv")])
20321
20322(define_insn "*sibcall_value_1"
20323  [(set (match_operand 0 "" "")
20324	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20325	      (match_operand:SI 2 "" "")))]
20326  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20327{
20328  if (constant_call_address_operand (operands[1], Pmode))
20329    return "jmp\t%P1";
20330  return "jmp\t%A1";
20331}
20332  [(set_attr "type" "callv")])
20333
20334(define_insn "*call_value_1_rex64"
20335  [(set (match_operand 0 "" "")
20336	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20337	      (match_operand:DI 2 "" "")))]
20338  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20339{
20340  if (constant_call_address_operand (operands[1], Pmode))
20341    return "call\t%P1";
20342  return "call\t%A1";
20343}
20344  [(set_attr "type" "callv")])
20345
20346(define_insn "*sibcall_value_1_rex64"
20347  [(set (match_operand 0 "" "")
20348	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20349	      (match_operand:DI 2 "" "")))]
20350  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20351  "jmp\t%P1"
20352  [(set_attr "type" "callv")])
20353
20354(define_insn "*sibcall_value_1_rex64_v"
20355  [(set (match_operand 0 "" "")
20356	(call (mem:QI (reg:DI 40))
20357	      (match_operand:DI 1 "" "")))]
20358  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20359  "jmp\t*%%r11"
20360  [(set_attr "type" "callv")])
20361
20362;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20363;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20364;; caught for use by garbage collectors and the like.  Using an insn that
20365;; maps to SIGILL makes it more likely the program will rightfully die.
20366;; Keeping with tradition, "6" is in honor of #UD.
20367(define_insn "trap"
20368  [(trap_if (const_int 1) (const_int 6))]
20369  ""
20370  { return ASM_SHORT "0x0b0f"; }
20371  [(set_attr "length" "2")])
20372
20373(define_expand "sse_prologue_save"
20374  [(parallel [(set (match_operand:BLK 0 "" "")
20375		   (unspec:BLK [(reg:DI 21)
20376				(reg:DI 22)
20377				(reg:DI 23)
20378				(reg:DI 24)
20379				(reg:DI 25)
20380				(reg:DI 26)
20381				(reg:DI 27)
20382				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20383	      (use (match_operand:DI 1 "register_operand" ""))
20384	      (use (match_operand:DI 2 "immediate_operand" ""))
20385	      (use (label_ref:DI (match_operand 3 "" "")))])]
20386  "TARGET_64BIT"
20387  "")
20388
20389(define_insn "*sse_prologue_save_insn"
20390  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20391			  (match_operand:DI 4 "const_int_operand" "n")))
20392	(unspec:BLK [(reg:DI 21)
20393		     (reg:DI 22)
20394		     (reg:DI 23)
20395		     (reg:DI 24)
20396		     (reg:DI 25)
20397		     (reg:DI 26)
20398		     (reg:DI 27)
20399		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20400   (use (match_operand:DI 1 "register_operand" "r"))
20401   (use (match_operand:DI 2 "const_int_operand" "i"))
20402   (use (label_ref:DI (match_operand 3 "" "X")))]
20403  "TARGET_64BIT
20404   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20405   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20406  "*
20407{
20408  int i;
20409  operands[0] = gen_rtx_MEM (Pmode,
20410			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20411  output_asm_insn (\"jmp\\t%A1\", operands);
20412  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20413    {
20414      operands[4] = adjust_address (operands[0], DImode, i*16);
20415      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20416      PUT_MODE (operands[4], TImode);
20417      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20418        output_asm_insn (\"rex\", operands);
20419      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20420    }
20421  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20422			     CODE_LABEL_NUMBER (operands[3]));
20423  RET;
20424}
20425  "
20426  [(set_attr "type" "other")
20427   (set_attr "length_immediate" "0")
20428   (set_attr "length_address" "0")
20429   (set_attr "length" "135")
20430   (set_attr "memory" "store")
20431   (set_attr "modrm" "0")
20432   (set_attr "mode" "DI")])
20433
20434(define_expand "prefetch"
20435  [(prefetch (match_operand 0 "address_operand" "")
20436	     (match_operand:SI 1 "const_int_operand" "")
20437	     (match_operand:SI 2 "const_int_operand" ""))]
20438  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20439{
20440  int rw = INTVAL (operands[1]);
20441  int locality = INTVAL (operands[2]);
20442
20443  gcc_assert (rw == 0 || rw == 1);
20444  gcc_assert (locality >= 0 && locality <= 3);
20445  gcc_assert (GET_MODE (operands[0]) == Pmode
20446	      || GET_MODE (operands[0]) == VOIDmode);
20447
20448  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20449     supported by SSE counterpart or the SSE prefetch is not available
20450     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20451     of locality.  */
20452  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20453    operands[2] = GEN_INT (3);
20454  else
20455    operands[1] = const0_rtx;
20456})
20457
20458(define_insn "*prefetch_sse"
20459  [(prefetch (match_operand:SI 0 "address_operand" "p")
20460	     (const_int 0)
20461	     (match_operand:SI 1 "const_int_operand" ""))]
20462  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20463{
20464  static const char * const patterns[4] = {
20465   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20466  };
20467
20468  int locality = INTVAL (operands[1]);
20469  gcc_assert (locality >= 0 && locality <= 3);
20470
20471  return patterns[locality];  
20472}
20473  [(set_attr "type" "sse")
20474   (set_attr "memory" "none")])
20475
20476(define_insn "*prefetch_sse_rex"
20477  [(prefetch (match_operand:DI 0 "address_operand" "p")
20478	     (const_int 0)
20479	     (match_operand:SI 1 "const_int_operand" ""))]
20480  "TARGET_PREFETCH_SSE && TARGET_64BIT"
20481{
20482  static const char * const patterns[4] = {
20483   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20484  };
20485
20486  int locality = INTVAL (operands[1]);
20487  gcc_assert (locality >= 0 && locality <= 3);
20488
20489  return patterns[locality];  
20490}
20491  [(set_attr "type" "sse")
20492   (set_attr "memory" "none")])
20493
20494(define_insn "*prefetch_3dnow"
20495  [(prefetch (match_operand:SI 0 "address_operand" "p")
20496	     (match_operand:SI 1 "const_int_operand" "n")
20497	     (const_int 3))]
20498  "TARGET_3DNOW && !TARGET_64BIT"
20499{
20500  if (INTVAL (operands[1]) == 0)
20501    return "prefetch\t%a0";
20502  else
20503    return "prefetchw\t%a0";
20504}
20505  [(set_attr "type" "mmx")
20506   (set_attr "memory" "none")])
20507
20508(define_insn "*prefetch_3dnow_rex"
20509  [(prefetch (match_operand:DI 0 "address_operand" "p")
20510	     (match_operand:SI 1 "const_int_operand" "n")
20511	     (const_int 3))]
20512  "TARGET_3DNOW && TARGET_64BIT"
20513{
20514  if (INTVAL (operands[1]) == 0)
20515    return "prefetch\t%a0";
20516  else
20517    return "prefetchw\t%a0";
20518}
20519  [(set_attr "type" "mmx")
20520   (set_attr "memory" "none")])
20521
20522(define_expand "stack_protect_set"
20523  [(match_operand 0 "memory_operand" "")
20524   (match_operand 1 "memory_operand" "")]
20525  ""
20526{
20527#ifdef TARGET_THREAD_SSP_OFFSET
20528  if (TARGET_64BIT)
20529    emit_insn (gen_stack_tls_protect_set_di (operands[0],
20530					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20531  else
20532    emit_insn (gen_stack_tls_protect_set_si (operands[0],
20533					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20534#else
20535  if (TARGET_64BIT)
20536    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20537  else
20538    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20539#endif
20540  DONE;
20541})
20542
20543(define_insn "stack_protect_set_si"
20544  [(set (match_operand:SI 0 "memory_operand" "=m")
20545	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20546   (set (match_scratch:SI 2 "=&r") (const_int 0))
20547   (clobber (reg:CC FLAGS_REG))]
20548  ""
20549  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20550  [(set_attr "type" "multi")])
20551
20552(define_insn "stack_protect_set_di"
20553  [(set (match_operand:DI 0 "memory_operand" "=m")
20554	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20555   (set (match_scratch:DI 2 "=&r") (const_int 0))
20556   (clobber (reg:CC FLAGS_REG))]
20557  "TARGET_64BIT"
20558  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20559  [(set_attr "type" "multi")])
20560
20561(define_insn "stack_tls_protect_set_si"
20562  [(set (match_operand:SI 0 "memory_operand" "=m")
20563	(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20564   (set (match_scratch:SI 2 "=&r") (const_int 0))
20565   (clobber (reg:CC FLAGS_REG))]
20566  ""
20567  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20568  [(set_attr "type" "multi")])
20569
20570(define_insn "stack_tls_protect_set_di"
20571  [(set (match_operand:DI 0 "memory_operand" "=m")
20572	(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20573   (set (match_scratch:DI 2 "=&r") (const_int 0))
20574   (clobber (reg:CC FLAGS_REG))]
20575  "TARGET_64BIT"
20576  "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20577  [(set_attr "type" "multi")])
20578
20579(define_expand "stack_protect_test"
20580  [(match_operand 0 "memory_operand" "")
20581   (match_operand 1 "memory_operand" "")
20582   (match_operand 2 "" "")]
20583  ""
20584{
20585  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20586  ix86_compare_op0 = operands[0];
20587  ix86_compare_op1 = operands[1];
20588  ix86_compare_emitted = flags;
20589
20590#ifdef TARGET_THREAD_SSP_OFFSET
20591  if (TARGET_64BIT)
20592    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20593					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20594  else
20595    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20596					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20597#else
20598  if (TARGET_64BIT)
20599    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20600  else
20601    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20602#endif
20603  emit_jump_insn (gen_beq (operands[2]));
20604  DONE;
20605})
20606
20607(define_insn "stack_protect_test_si"
20608  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20609	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20610		     (match_operand:SI 2 "memory_operand" "m")]
20611		    UNSPEC_SP_TEST))
20612   (clobber (match_scratch:SI 3 "=&r"))]
20613  ""
20614  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20615  [(set_attr "type" "multi")])
20616
20617(define_insn "stack_protect_test_di"
20618  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20619	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20620		     (match_operand:DI 2 "memory_operand" "m")]
20621		    UNSPEC_SP_TEST))
20622   (clobber (match_scratch:DI 3 "=&r"))]
20623  "TARGET_64BIT"
20624  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20625  [(set_attr "type" "multi")])
20626
20627(define_insn "stack_tls_protect_test_si"
20628  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20629	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20630		     (match_operand:SI 2 "const_int_operand" "i")]
20631		    UNSPEC_SP_TLS_TEST))
20632   (clobber (match_scratch:SI 3 "=r"))]
20633  ""
20634  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20635  [(set_attr "type" "multi")])
20636
20637(define_insn "stack_tls_protect_test_di"
20638  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20639	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20640		     (match_operand:DI 2 "const_int_operand" "i")]
20641		    UNSPEC_SP_TLS_TEST))
20642   (clobber (match_scratch:DI 3 "=r"))]
20643  "TARGET_64BIT"
20644  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20645  [(set_attr "type" "multi")])
20646
20647(include "sse.md")
20648(include "mmx.md")
20649(include "sync.md")
20650