i386.md revision 236962
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, 2006
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   (UNSPEC_TLSDESC		19)
77
78   ; Other random patterns
79   (UNSPEC_SCAS			20)
80   (UNSPEC_FNSTSW		21)
81   (UNSPEC_SAHF			22)
82   (UNSPEC_FSTCW		23)
83   (UNSPEC_ADD_CARRY		24)
84   (UNSPEC_FLDCW		25)
85   (UNSPEC_REP			26)
86   (UNSPEC_EH_RETURN		27)
87   (UNSPEC_LD_MPIC		28)	; load_macho_picbase
88
89   ; For SSE/MMX support:
90   (UNSPEC_FIX_NOTRUNC		30)
91   (UNSPEC_MASKMOV		31)
92   (UNSPEC_MOVMSK		32)
93   (UNSPEC_MOVNT		33)
94   (UNSPEC_MOVU			34)
95   (UNSPEC_RCP			35)
96   (UNSPEC_RSQRT		36)
97   (UNSPEC_SFENCE		37)
98   (UNSPEC_NOP			38)	; prevents combiner cleverness
99   (UNSPEC_PFRCP		39)
100   (UNSPEC_PFRCPIT1		40)
101   (UNSPEC_PFRCPIT2		41)
102   (UNSPEC_PFRSQRT		42)
103   (UNSPEC_PFRSQIT1		43)
104   (UNSPEC_MFENCE		44)
105   (UNSPEC_LFENCE		45)
106   (UNSPEC_PSADBW		46)
107   (UNSPEC_LDDQU		47)
108
109   ; Generic math support
110   (UNSPEC_COPYSIGN		50)
111   (UNSPEC_IEEE_MIN		51)	; not commutative
112   (UNSPEC_IEEE_MAX		52)	; not commutative
113
114   ; x87 Floating point
115   (UNSPEC_SIN			60)
116   (UNSPEC_COS			61)
117   (UNSPEC_FPATAN		62)
118   (UNSPEC_FYL2X		63)
119   (UNSPEC_FYL2XP1		64)
120   (UNSPEC_FRNDINT		65)
121   (UNSPEC_FIST			66)
122   (UNSPEC_F2XM1		67)
123
124   ; x87 Rounding
125   (UNSPEC_FRNDINT_FLOOR	70)
126   (UNSPEC_FRNDINT_CEIL 	71)
127   (UNSPEC_FRNDINT_TRUNC	72)
128   (UNSPEC_FRNDINT_MASK_PM	73)
129   (UNSPEC_FIST_FLOOR		74)
130   (UNSPEC_FIST_CEIL 		75)
131
132   ; x87 Double output FP
133   (UNSPEC_SINCOS_COS		80)
134   (UNSPEC_SINCOS_SIN		81)
135   (UNSPEC_TAN_ONE		82)
136   (UNSPEC_TAN_TAN		83)
137   (UNSPEC_XTRACT_FRACT		84)
138   (UNSPEC_XTRACT_EXP		85)
139   (UNSPEC_FSCALE_FRACT		86)
140   (UNSPEC_FSCALE_EXP		87)
141   (UNSPEC_FPREM_F		88)
142   (UNSPEC_FPREM_U		89)
143   (UNSPEC_FPREM1_F		90)
144   (UNSPEC_FPREM1_U		91)
145
146   ; SSP patterns
147   (UNSPEC_SP_SET		100)
148   (UNSPEC_SP_TEST		101)
149   (UNSPEC_SP_TLS_SET		102)
150   (UNSPEC_SP_TLS_TEST		103)
151
152   ; SSSE3
153   (UNSPEC_PSHUFB		120)
154   (UNSPEC_PSIGN		121)
155   (UNSPEC_PALIGNR		122)
156
157   ; For SSE4A support
158   (UNSPEC_EXTRQI               130)
159   (UNSPEC_EXTRQ                131)   
160   (UNSPEC_INSERTQI             132)
161   (UNSPEC_INSERTQ              133)
162  ])
163
164(define_constants
165  [(UNSPECV_BLOCKAGE		0)
166   (UNSPECV_STACK_PROBE		1)
167   (UNSPECV_EMMS		2)
168   (UNSPECV_LDMXCSR		3)
169   (UNSPECV_STMXCSR		4)
170   (UNSPECV_FEMMS		5)
171   (UNSPECV_CLFLUSH		6)
172   (UNSPECV_ALIGN		7)
173   (UNSPECV_MONITOR		8)
174   (UNSPECV_MWAIT		9)
175   (UNSPECV_CMPXCHG_1		10)
176   (UNSPECV_CMPXCHG_2		11)
177   (UNSPECV_XCHG		12)
178   (UNSPECV_LOCK		13)
179  ])
180
181;; Registers by name.
182(define_constants
183  [(BP_REG			 6)
184   (SP_REG			 7)
185   (FLAGS_REG			17)
186   (FPSR_REG			18)
187   (FPCR_REG			19)
188   (DIRFLAG_REG			20)
189   (R11_REG			41)
190  ])
191
192;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
193;; from i386.c.
194
195;; In C guard expressions, put expressions which may be compile-time
196;; constants first.  This allows for better optimization.  For
197;; example, write "TARGET_64BIT && reload_completed", not
198;; "reload_completed && TARGET_64BIT".
199
200
201;; Processor type.  This attribute must exactly match the processor_type
202;; enumeration in i386.h.
203(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
204                    nocona,core2,generic32,generic64,amdfam10"
205  (const (symbol_ref "ix86_tune")))
206
207;; A basic instruction type.  Refinements due to arguments to be
208;; provided in other attributes.
209(define_attr "type"
210  "other,multi,
211   alu,alu1,negnot,imov,imovx,lea,
212   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
213   icmp,test,ibr,setcc,icmov,
214   push,pop,call,callv,leave,
215   str,,bitmanip,cld,
216   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
217   sselog,sselog1,sseiadd,sseishft,sseimul,
218   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
219   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
220  (const_string "other"))
221
222;; Main data type used by the insn
223(define_attr "mode"
224  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
225  (const_string "unknown"))
226
227;; The CPU unit operations uses.
228(define_attr "unit" "integer,i387,sse,mmx,unknown"
229  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
230	   (const_string "i387")
231	 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
232			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
233	   (const_string "sse")
234	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
235	   (const_string "mmx")
236	 (eq_attr "type" "other")
237	   (const_string "unknown")]
238	 (const_string "integer")))
239
240;; The (bounding maximum) length of an instruction immediate.
241(define_attr "length_immediate" ""
242  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave,
243                          bitmanip")
244	   (const_int 0)
245	 (eq_attr "unit" "i387,sse,mmx")
246	   (const_int 0)
247	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
248			  imul,icmp,push,pop")
249	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
250	 (eq_attr "type" "imov,test")
251	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
252	 (eq_attr "type" "call")
253	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
254	     (const_int 4)
255	     (const_int 0))
256	 (eq_attr "type" "callv")
257	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
258	     (const_int 4)
259	     (const_int 0))
260	 ;; We don't know the size before shorten_branches.  Expect
261	 ;; the instruction to fit for better scheduling.
262	 (eq_attr "type" "ibr")
263	   (const_int 1)
264	 ]
265	 (symbol_ref "/* Update immediate_length and other attributes! */
266		      gcc_unreachable (),1")))
267
268;; The (bounding maximum) length of an instruction address.
269(define_attr "length_address" ""
270  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
271	   (const_int 0)
272	 (and (eq_attr "type" "call")
273	      (match_operand 0 "constant_call_address_operand" ""))
274	     (const_int 0)
275	 (and (eq_attr "type" "callv")
276	      (match_operand 1 "constant_call_address_operand" ""))
277	     (const_int 0)
278	 ]
279	 (symbol_ref "ix86_attr_length_address_default (insn)")))
280
281;; Set when length prefix is used.
282(define_attr "prefix_data16" ""
283  (if_then_else (ior (eq_attr "mode" "HI")
284		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
285    (const_int 1)
286    (const_int 0)))
287
288;; Set when string REP prefix is used.
289(define_attr "prefix_rep" "" 
290  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
291    (const_int 1)
292    (const_int 0)))
293
294;; Set when 0f opcode prefix is used.
295(define_attr "prefix_0f" ""
296  (if_then_else 
297    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
298	 (eq_attr "unit" "sse,mmx"))
299    (const_int 1)
300    (const_int 0)))
301
302;; Set when REX opcode prefix is used.
303(define_attr "prefix_rex" ""
304  (cond [(and (eq_attr "mode" "DI")
305  	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
306	   (const_int 1)
307	 (and (eq_attr "mode" "QI")
308	      (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
309		  (const_int 0)))
310	   (const_int 1)
311	 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
312	     (const_int 0))
313	   (const_int 1)
314	]
315	(const_int 0)))
316
317;; Set when modrm byte is used.
318(define_attr "modrm" ""
319  (cond [(eq_attr "type" "str,cld,leave")
320	   (const_int 0)
321	 (eq_attr "unit" "i387")
322	   (const_int 0)
323         (and (eq_attr "type" "incdec")
324	      (ior (match_operand:SI 1 "register_operand" "")
325		   (match_operand:HI 1 "register_operand" "")))
326	   (const_int 0)
327	 (and (eq_attr "type" "push")
328	      (not (match_operand 1 "memory_operand" "")))
329	   (const_int 0)
330	 (and (eq_attr "type" "pop")
331	      (not (match_operand 0 "memory_operand" "")))
332	   (const_int 0)
333	 (and (eq_attr "type" "imov")
334	      (ior (and (match_operand 0 "register_operand" "")
335			(match_operand 1 "immediate_operand" ""))
336		   (ior (and (match_operand 0 "ax_reg_operand" "")
337			     (match_operand 1 "memory_displacement_only_operand" ""))
338			(and (match_operand 0 "memory_displacement_only_operand" "")
339			     (match_operand 1 "ax_reg_operand" "")))))
340	   (const_int 0)
341	 (and (eq_attr "type" "call")
342	      (match_operand 0 "constant_call_address_operand" ""))
343	     (const_int 0)
344	 (and (eq_attr "type" "callv")
345	      (match_operand 1 "constant_call_address_operand" ""))
346	     (const_int 0)
347	 ]
348	 (const_int 1)))
349
350;; The (bounding maximum) length of an instruction in bytes.
351;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
352;; Later we may want to split them and compute proper length as for
353;; other insns.
354(define_attr "length" ""
355  (cond [(eq_attr "type" "other,multi,fistp,frndint")
356	   (const_int 16)
357	 (eq_attr "type" "fcmp")
358	   (const_int 4)
359	 (eq_attr "unit" "i387")
360	   (plus (const_int 2)
361		 (plus (attr "prefix_data16")
362		       (attr "length_address")))]
363	 (plus (plus (attr "modrm")
364		     (plus (attr "prefix_0f")
365			   (plus (attr "prefix_rex")
366				 (const_int 1))))
367	       (plus (attr "prefix_rep")
368		     (plus (attr "prefix_data16")
369			   (plus (attr "length_immediate")
370				 (attr "length_address")))))))
371
372;; The `memory' attribute is `none' if no memory is referenced, `load' or
373;; `store' if there is a simple memory reference therein, or `unknown'
374;; if the instruction is complex.
375
376(define_attr "memory" "none,load,store,both,unknown"
377  (cond [(eq_attr "type" "other,multi,str")
378	   (const_string "unknown")
379	 (eq_attr "type" "lea,fcmov,fpspc,cld")
380	   (const_string "none")
381	 (eq_attr "type" "fistp,leave")
382	   (const_string "both")
383	 (eq_attr "type" "frndint")
384	   (const_string "load")
385	 (eq_attr "type" "push")
386	   (if_then_else (match_operand 1 "memory_operand" "")
387	     (const_string "both")
388	     (const_string "store"))
389	 (eq_attr "type" "pop")
390	   (if_then_else (match_operand 0 "memory_operand" "")
391	     (const_string "both")
392	     (const_string "load"))
393	 (eq_attr "type" "setcc")
394	   (if_then_else (match_operand 0 "memory_operand" "")
395	     (const_string "store")
396	     (const_string "none"))
397	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
398	   (if_then_else (ior (match_operand 0 "memory_operand" "")
399			      (match_operand 1 "memory_operand" ""))
400	     (const_string "load")
401	     (const_string "none"))
402	 (eq_attr "type" "ibr")
403	   (if_then_else (match_operand 0 "memory_operand" "")
404	     (const_string "load")
405	     (const_string "none"))
406	 (eq_attr "type" "call")
407	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
408	     (const_string "none")
409	     (const_string "load"))
410	 (eq_attr "type" "callv")
411	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
412	     (const_string "none")
413	     (const_string "load"))
414	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
415	      (match_operand 1 "memory_operand" ""))
416	   (const_string "both")
417	 (and (match_operand 0 "memory_operand" "")
418	      (match_operand 1 "memory_operand" ""))
419	   (const_string "both")
420	 (match_operand 0 "memory_operand" "")
421	   (const_string "store")
422	 (match_operand 1 "memory_operand" "")
423	   (const_string "load")
424	 (and (eq_attr "type"
425		 "!alu1,negnot,ishift1,
426		   imov,imovx,icmp,test,bitmanip,
427		   fmov,fcmp,fsgn,
428		   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
429		   mmx,mmxmov,mmxcmp,mmxcvt")
430	      (match_operand 2 "memory_operand" ""))
431	   (const_string "load")
432	 (and (eq_attr "type" "icmov")
433	      (match_operand 3 "memory_operand" ""))
434	   (const_string "load")
435	]
436	(const_string "none")))
437
438;; Indicates if an instruction has both an immediate and a displacement.
439
440(define_attr "imm_disp" "false,true,unknown"
441  (cond [(eq_attr "type" "other,multi")
442	   (const_string "unknown")
443	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
444	      (and (match_operand 0 "memory_displacement_operand" "")
445		   (match_operand 1 "immediate_operand" "")))
446	   (const_string "true")
447	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
448	      (and (match_operand 0 "memory_displacement_operand" "")
449		   (match_operand 2 "immediate_operand" "")))
450	   (const_string "true")
451	]
452	(const_string "false")))
453
454;; Indicates if an FP operation has an integer source.
455
456(define_attr "fp_int_src" "false,true"
457  (const_string "false"))
458
459;; Defines rounding mode of an FP operation.
460
461(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
462  (const_string "any"))
463
464;; Describe a user's asm statement.
465(define_asm_attributes
466  [(set_attr "length" "128")
467   (set_attr "type" "multi")])
468
469;; All x87 floating point modes
470(define_mode_macro X87MODEF [SF DF XF])
471 
472;; All integer modes handled by x87 fisttp operator.
473(define_mode_macro X87MODEI [HI SI DI])
474
475;; All integer modes handled by integer x87 operators.
476(define_mode_macro X87MODEI12 [HI SI])
477
478;; All SSE floating point modes
479(define_mode_macro SSEMODEF [SF DF])
480 
481;; All integer modes handled by SSE cvtts?2si* operators.
482(define_mode_macro SSEMODEI24 [SI DI])
483
484
485;; Scheduling descriptions
486
487(include "pentium.md")
488(include "ppro.md")
489(include "k6.md")
490(include "athlon.md")
491(include "geode.md")
492
493
494;; Operand and operator predicates and constraints
495
496(include "predicates.md")
497(include "constraints.md")
498
499
500;; Compare instructions.
501
502;; All compare insns have expanders that save the operands away without
503;; actually generating RTL.  The bCOND or sCOND (emitted immediately
504;; after the cmp) will actually emit the cmpM.
505
506(define_expand "cmpti"
507  [(set (reg:CC FLAGS_REG)
508	(compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
509		    (match_operand:TI 1 "x86_64_general_operand" "")))]
510  "TARGET_64BIT"
511{
512  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
513    operands[0] = force_reg (TImode, operands[0]);
514  ix86_compare_op0 = operands[0];
515  ix86_compare_op1 = operands[1];
516  DONE;
517})
518
519(define_expand "cmpdi"
520  [(set (reg:CC FLAGS_REG)
521	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
522		    (match_operand:DI 1 "x86_64_general_operand" "")))]
523  ""
524{
525  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
526    operands[0] = force_reg (DImode, operands[0]);
527  ix86_compare_op0 = operands[0];
528  ix86_compare_op1 = operands[1];
529  DONE;
530})
531
532(define_expand "cmpsi"
533  [(set (reg:CC FLAGS_REG)
534	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
535		    (match_operand:SI 1 "general_operand" "")))]
536  ""
537{
538  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
539    operands[0] = force_reg (SImode, operands[0]);
540  ix86_compare_op0 = operands[0];
541  ix86_compare_op1 = operands[1];
542  DONE;
543})
544
545(define_expand "cmphi"
546  [(set (reg:CC FLAGS_REG)
547	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
548		    (match_operand:HI 1 "general_operand" "")))]
549  ""
550{
551  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
552    operands[0] = force_reg (HImode, operands[0]);
553  ix86_compare_op0 = operands[0];
554  ix86_compare_op1 = operands[1];
555  DONE;
556})
557
558(define_expand "cmpqi"
559  [(set (reg:CC FLAGS_REG)
560	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
561		    (match_operand:QI 1 "general_operand" "")))]
562  "TARGET_QIMODE_MATH"
563{
564  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
565    operands[0] = force_reg (QImode, operands[0]);
566  ix86_compare_op0 = operands[0];
567  ix86_compare_op1 = operands[1];
568  DONE;
569})
570
571(define_insn "cmpdi_ccno_1_rex64"
572  [(set (reg FLAGS_REG)
573	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
574		 (match_operand:DI 1 "const0_operand" "n,n")))]
575  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
576  "@
577   test{q}\t{%0, %0|%0, %0}
578   cmp{q}\t{%1, %0|%0, %1}"
579  [(set_attr "type" "test,icmp")
580   (set_attr "length_immediate" "0,1")
581   (set_attr "mode" "DI")])
582
583(define_insn "*cmpdi_minus_1_rex64"
584  [(set (reg FLAGS_REG)
585	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
586			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
587		 (const_int 0)))]
588  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
589  "cmp{q}\t{%1, %0|%0, %1}"
590  [(set_attr "type" "icmp")
591   (set_attr "mode" "DI")])
592
593(define_expand "cmpdi_1_rex64"
594  [(set (reg:CC FLAGS_REG)
595	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
596		    (match_operand:DI 1 "general_operand" "")))]
597  "TARGET_64BIT"
598  "")
599
600(define_insn "cmpdi_1_insn_rex64"
601  [(set (reg FLAGS_REG)
602	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
603		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
604  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
605  "cmp{q}\t{%1, %0|%0, %1}"
606  [(set_attr "type" "icmp")
607   (set_attr "mode" "DI")])
608
609
610(define_insn "*cmpsi_ccno_1"
611  [(set (reg FLAGS_REG)
612	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
613		 (match_operand:SI 1 "const0_operand" "n,n")))]
614  "ix86_match_ccmode (insn, CCNOmode)"
615  "@
616   test{l}\t{%0, %0|%0, %0}
617   cmp{l}\t{%1, %0|%0, %1}"
618  [(set_attr "type" "test,icmp")
619   (set_attr "length_immediate" "0,1")
620   (set_attr "mode" "SI")])
621
622(define_insn "*cmpsi_minus_1"
623  [(set (reg FLAGS_REG)
624	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625			   (match_operand:SI 1 "general_operand" "ri,mr"))
626		 (const_int 0)))]
627  "ix86_match_ccmode (insn, CCGOCmode)"
628  "cmp{l}\t{%1, %0|%0, %1}"
629  [(set_attr "type" "icmp")
630   (set_attr "mode" "SI")])
631
632(define_expand "cmpsi_1"
633  [(set (reg:CC FLAGS_REG)
634	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
635		    (match_operand:SI 1 "general_operand" "ri,mr")))]
636  ""
637  "")
638
639(define_insn "*cmpsi_1_insn"
640  [(set (reg FLAGS_REG)
641	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642		 (match_operand:SI 1 "general_operand" "ri,mr")))]
643  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
644    && ix86_match_ccmode (insn, CCmode)"
645  "cmp{l}\t{%1, %0|%0, %1}"
646  [(set_attr "type" "icmp")
647   (set_attr "mode" "SI")])
648
649(define_insn "*cmphi_ccno_1"
650  [(set (reg FLAGS_REG)
651	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
652		 (match_operand:HI 1 "const0_operand" "n,n")))]
653  "ix86_match_ccmode (insn, CCNOmode)"
654  "@
655   test{w}\t{%0, %0|%0, %0}
656   cmp{w}\t{%1, %0|%0, %1}"
657  [(set_attr "type" "test,icmp")
658   (set_attr "length_immediate" "0,1")
659   (set_attr "mode" "HI")])
660
661(define_insn "*cmphi_minus_1"
662  [(set (reg FLAGS_REG)
663	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
664			   (match_operand:HI 1 "general_operand" "ri,mr"))
665		 (const_int 0)))]
666  "ix86_match_ccmode (insn, CCGOCmode)"
667  "cmp{w}\t{%1, %0|%0, %1}"
668  [(set_attr "type" "icmp")
669   (set_attr "mode" "HI")])
670
671(define_insn "*cmphi_1"
672  [(set (reg FLAGS_REG)
673	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
674		 (match_operand:HI 1 "general_operand" "ri,mr")))]
675  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
676   && ix86_match_ccmode (insn, CCmode)"
677  "cmp{w}\t{%1, %0|%0, %1}"
678  [(set_attr "type" "icmp")
679   (set_attr "mode" "HI")])
680
681(define_insn "*cmpqi_ccno_1"
682  [(set (reg FLAGS_REG)
683	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
684		 (match_operand:QI 1 "const0_operand" "n,n")))]
685  "ix86_match_ccmode (insn, CCNOmode)"
686  "@
687   test{b}\t{%0, %0|%0, %0}
688   cmp{b}\t{$0, %0|%0, 0}"
689  [(set_attr "type" "test,icmp")
690   (set_attr "length_immediate" "0,1")
691   (set_attr "mode" "QI")])
692
693(define_insn "*cmpqi_1"
694  [(set (reg FLAGS_REG)
695	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
696		 (match_operand:QI 1 "general_operand" "qi,mq")))]
697  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
698    && ix86_match_ccmode (insn, CCmode)"
699  "cmp{b}\t{%1, %0|%0, %1}"
700  [(set_attr "type" "icmp")
701   (set_attr "mode" "QI")])
702
703(define_insn "*cmpqi_minus_1"
704  [(set (reg FLAGS_REG)
705	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
706			   (match_operand:QI 1 "general_operand" "qi,mq"))
707		 (const_int 0)))]
708  "ix86_match_ccmode (insn, CCGOCmode)"
709  "cmp{b}\t{%1, %0|%0, %1}"
710  [(set_attr "type" "icmp")
711   (set_attr "mode" "QI")])
712
713(define_insn "*cmpqi_ext_1"
714  [(set (reg FLAGS_REG)
715	(compare
716	  (match_operand:QI 0 "general_operand" "Qm")
717	  (subreg:QI
718	    (zero_extract:SI
719	      (match_operand 1 "ext_register_operand" "Q")
720	      (const_int 8)
721	      (const_int 8)) 0)))]
722  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
723  "cmp{b}\t{%h1, %0|%0, %h1}"
724  [(set_attr "type" "icmp")
725   (set_attr "mode" "QI")])
726
727(define_insn "*cmpqi_ext_1_rex64"
728  [(set (reg FLAGS_REG)
729	(compare
730	  (match_operand:QI 0 "register_operand" "Q")
731	  (subreg:QI
732	    (zero_extract:SI
733	      (match_operand 1 "ext_register_operand" "Q")
734	      (const_int 8)
735	      (const_int 8)) 0)))]
736  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
737  "cmp{b}\t{%h1, %0|%0, %h1}"
738  [(set_attr "type" "icmp")
739   (set_attr "mode" "QI")])
740
741(define_insn "*cmpqi_ext_2"
742  [(set (reg FLAGS_REG)
743	(compare
744	  (subreg:QI
745	    (zero_extract:SI
746	      (match_operand 0 "ext_register_operand" "Q")
747	      (const_int 8)
748	      (const_int 8)) 0)
749	  (match_operand:QI 1 "const0_operand" "n")))]
750  "ix86_match_ccmode (insn, CCNOmode)"
751  "test{b}\t%h0, %h0"
752  [(set_attr "type" "test")
753   (set_attr "length_immediate" "0")
754   (set_attr "mode" "QI")])
755
756(define_expand "cmpqi_ext_3"
757  [(set (reg:CC FLAGS_REG)
758	(compare:CC
759	  (subreg:QI
760	    (zero_extract:SI
761	      (match_operand 0 "ext_register_operand" "")
762	      (const_int 8)
763	      (const_int 8)) 0)
764	  (match_operand:QI 1 "general_operand" "")))]
765  ""
766  "")
767
768(define_insn "cmpqi_ext_3_insn"
769  [(set (reg FLAGS_REG)
770	(compare
771	  (subreg:QI
772	    (zero_extract:SI
773	      (match_operand 0 "ext_register_operand" "Q")
774	      (const_int 8)
775	      (const_int 8)) 0)
776	  (match_operand:QI 1 "general_operand" "Qmn")))]
777  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
778  "cmp{b}\t{%1, %h0|%h0, %1}"
779  [(set_attr "type" "icmp")
780   (set_attr "mode" "QI")])
781
782(define_insn "cmpqi_ext_3_insn_rex64"
783  [(set (reg FLAGS_REG)
784	(compare
785	  (subreg:QI
786	    (zero_extract:SI
787	      (match_operand 0 "ext_register_operand" "Q")
788	      (const_int 8)
789	      (const_int 8)) 0)
790	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
791  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
792  "cmp{b}\t{%1, %h0|%h0, %1}"
793  [(set_attr "type" "icmp")
794   (set_attr "mode" "QI")])
795
796(define_insn "*cmpqi_ext_4"
797  [(set (reg FLAGS_REG)
798	(compare
799	  (subreg:QI
800	    (zero_extract:SI
801	      (match_operand 0 "ext_register_operand" "Q")
802	      (const_int 8)
803	      (const_int 8)) 0)
804	  (subreg:QI
805	    (zero_extract:SI
806	      (match_operand 1 "ext_register_operand" "Q")
807	      (const_int 8)
808	      (const_int 8)) 0)))]
809  "ix86_match_ccmode (insn, CCmode)"
810  "cmp{b}\t{%h1, %h0|%h0, %h1}"
811  [(set_attr "type" "icmp")
812   (set_attr "mode" "QI")])
813
814;; These implement float point compares.
815;; %%% See if we can get away with VOIDmode operands on the actual insns,
816;; which would allow mix and match FP modes on the compares.  Which is what
817;; the old patterns did, but with many more of them.
818
819(define_expand "cmpxf"
820  [(set (reg:CC FLAGS_REG)
821	(compare:CC (match_operand:XF 0 "nonmemory_operand" "")
822		    (match_operand:XF 1 "nonmemory_operand" "")))]
823  "TARGET_80387"
824{
825  ix86_compare_op0 = operands[0];
826  ix86_compare_op1 = operands[1];
827  DONE;
828})
829
830(define_expand "cmpdf"
831  [(set (reg:CC FLAGS_REG)
832	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
833		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
834  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
835{
836  ix86_compare_op0 = operands[0];
837  ix86_compare_op1 = operands[1];
838  DONE;
839})
840
841(define_expand "cmpsf"
842  [(set (reg:CC FLAGS_REG)
843	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
844		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
845  "TARGET_80387 || TARGET_SSE_MATH"
846{
847  ix86_compare_op0 = operands[0];
848  ix86_compare_op1 = operands[1];
849  DONE;
850})
851
852;; FP compares, step 1:
853;; Set the FP condition codes.
854;;
855;; CCFPmode	compare with exceptions
856;; CCFPUmode	compare with no exceptions
857
858;; We may not use "#" to split and emit these, since the REG_DEAD notes
859;; used to manage the reg stack popping would not be preserved.
860
861(define_insn "*cmpfp_0"
862  [(set (match_operand:HI 0 "register_operand" "=a")
863	(unspec:HI
864	  [(compare:CCFP
865	     (match_operand 1 "register_operand" "f")
866	     (match_operand 2 "const0_operand" "X"))]
867	UNSPEC_FNSTSW))]
868  "TARGET_80387
869   && FLOAT_MODE_P (GET_MODE (operands[1]))
870   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
871  "* return output_fp_compare (insn, operands, 0, 0);"
872  [(set_attr "type" "multi")
873   (set_attr "unit" "i387")
874   (set (attr "mode")
875     (cond [(match_operand:SF 1 "" "")
876	      (const_string "SF")
877	    (match_operand:DF 1 "" "")
878	      (const_string "DF")
879	   ]
880	   (const_string "XF")))])
881
882(define_insn "*cmpfp_sf"
883  [(set (match_operand:HI 0 "register_operand" "=a")
884	(unspec:HI
885	  [(compare:CCFP
886	     (match_operand:SF 1 "register_operand" "f")
887	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
888	  UNSPEC_FNSTSW))]
889  "TARGET_80387"
890  "* return output_fp_compare (insn, operands, 0, 0);"
891  [(set_attr "type" "multi")
892   (set_attr "unit" "i387")
893   (set_attr "mode" "SF")])
894
895(define_insn "*cmpfp_df"
896  [(set (match_operand:HI 0 "register_operand" "=a")
897	(unspec:HI
898	  [(compare:CCFP
899	     (match_operand:DF 1 "register_operand" "f")
900	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
901	  UNSPEC_FNSTSW))]
902  "TARGET_80387"
903  "* return output_fp_compare (insn, operands, 0, 0);"
904  [(set_attr "type" "multi")
905   (set_attr "unit" "i387")
906   (set_attr "mode" "DF")])
907
908(define_insn "*cmpfp_xf"
909  [(set (match_operand:HI 0 "register_operand" "=a")
910	(unspec:HI
911	  [(compare:CCFP
912	     (match_operand:XF 1 "register_operand" "f")
913	     (match_operand:XF 2 "register_operand" "f"))]
914	  UNSPEC_FNSTSW))]
915  "TARGET_80387"
916  "* return output_fp_compare (insn, operands, 0, 0);"
917  [(set_attr "type" "multi")
918   (set_attr "unit" "i387")
919   (set_attr "mode" "XF")])
920
921(define_insn "*cmpfp_u"
922  [(set (match_operand:HI 0 "register_operand" "=a")
923	(unspec:HI
924	  [(compare:CCFPU
925	     (match_operand 1 "register_operand" "f")
926	     (match_operand 2 "register_operand" "f"))]
927	  UNSPEC_FNSTSW))]
928  "TARGET_80387
929   && FLOAT_MODE_P (GET_MODE (operands[1]))
930   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
931  "* return output_fp_compare (insn, operands, 0, 1);"
932  [(set_attr "type" "multi")
933   (set_attr "unit" "i387")
934   (set (attr "mode")
935     (cond [(match_operand:SF 1 "" "")
936	      (const_string "SF")
937	    (match_operand:DF 1 "" "")
938	      (const_string "DF")
939	   ]
940	   (const_string "XF")))])
941
942(define_insn "*cmpfp_<mode>"
943  [(set (match_operand:HI 0 "register_operand" "=a")
944	(unspec:HI
945	  [(compare:CCFP
946	     (match_operand 1 "register_operand" "f")
947	     (match_operator 3 "float_operator"
948	       [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
949	  UNSPEC_FNSTSW))]
950  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
951   && FLOAT_MODE_P (GET_MODE (operands[1]))
952   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
953  "* return output_fp_compare (insn, operands, 0, 0);"
954  [(set_attr "type" "multi")
955   (set_attr "unit" "i387")
956   (set_attr "fp_int_src" "true")
957   (set_attr "mode" "<MODE>")])
958
959;; FP compares, step 2
960;; Move the fpsw to ax.
961
962(define_insn "x86_fnstsw_1"
963  [(set (match_operand:HI 0 "register_operand" "=a")
964	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
965  "TARGET_80387"
966  "fnstsw\t%0"
967  [(set_attr "length" "2")
968   (set_attr "mode" "SI")
969   (set_attr "unit" "i387")])
970
971;; FP compares, step 3
972;; Get ax into flags, general case.
973
974(define_insn "x86_sahf_1"
975  [(set (reg:CC FLAGS_REG)
976	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
977  "!TARGET_64BIT"
978  "sahf"
979  [(set_attr "length" "1")
980   (set_attr "athlon_decode" "vector")
981   (set_attr "amdfam10_decode" "direct")
982   (set_attr "mode" "SI")])
983
984;; Pentium Pro can do steps 1 through 3 in one go.
985;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
986(define_insn "*cmpfp_i_mixed"
987  [(set (reg:CCFP FLAGS_REG)
988	(compare:CCFP (match_operand 0 "register_operand" "f,x")
989		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
990  "TARGET_MIX_SSE_I387
991   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
992   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993  "* return output_fp_compare (insn, operands, 1, 0);"
994  [(set_attr "type" "fcmp,ssecomi")
995   (set (attr "mode")
996     (if_then_else (match_operand:SF 1 "" "")
997        (const_string "SF")
998        (const_string "DF")))
999   (set_attr "athlon_decode" "vector")
1000   (set_attr "amdfam10_decode" "direct")])
1001
1002(define_insn "*cmpfp_i_sse"
1003  [(set (reg:CCFP FLAGS_REG)
1004	(compare:CCFP (match_operand 0 "register_operand" "x")
1005		      (match_operand 1 "nonimmediate_operand" "xm")))]
1006  "TARGET_SSE_MATH
1007   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1008   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1009  "* return output_fp_compare (insn, operands, 1, 0);"
1010  [(set_attr "type" "ssecomi")
1011   (set (attr "mode")
1012     (if_then_else (match_operand:SF 1 "" "")
1013        (const_string "SF")
1014        (const_string "DF")))
1015   (set_attr "athlon_decode" "vector")
1016   (set_attr "amdfam10_decode" "direct")])
1017
1018(define_insn "*cmpfp_i_i387"
1019  [(set (reg:CCFP FLAGS_REG)
1020	(compare:CCFP (match_operand 0 "register_operand" "f")
1021		      (match_operand 1 "register_operand" "f")))]
1022  "TARGET_80387 && TARGET_CMOVE
1023   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1024   && FLOAT_MODE_P (GET_MODE (operands[0]))
1025   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1026  "* return output_fp_compare (insn, operands, 1, 0);"
1027  [(set_attr "type" "fcmp")
1028   (set (attr "mode")
1029     (cond [(match_operand:SF 1 "" "")
1030	      (const_string "SF")
1031	    (match_operand:DF 1 "" "")
1032	      (const_string "DF")
1033	   ]
1034	   (const_string "XF")))
1035   (set_attr "athlon_decode" "vector")
1036   (set_attr "amdfam10_decode" "direct")])
1037
1038(define_insn "*cmpfp_iu_mixed"
1039  [(set (reg:CCFPU FLAGS_REG)
1040	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
1041		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1042  "TARGET_MIX_SSE_I387
1043   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1044   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1045  "* return output_fp_compare (insn, operands, 1, 1);"
1046  [(set_attr "type" "fcmp,ssecomi")
1047   (set (attr "mode")
1048     (if_then_else (match_operand:SF 1 "" "")
1049        (const_string "SF")
1050        (const_string "DF")))
1051   (set_attr "athlon_decode" "vector")
1052   (set_attr "amdfam10_decode" "direct")])
1053
1054(define_insn "*cmpfp_iu_sse"
1055  [(set (reg:CCFPU FLAGS_REG)
1056	(compare:CCFPU (match_operand 0 "register_operand" "x")
1057		       (match_operand 1 "nonimmediate_operand" "xm")))]
1058  "TARGET_SSE_MATH
1059   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1060   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1061  "* return output_fp_compare (insn, operands, 1, 1);"
1062  [(set_attr "type" "ssecomi")
1063   (set (attr "mode")
1064     (if_then_else (match_operand:SF 1 "" "")
1065        (const_string "SF")
1066        (const_string "DF")))
1067   (set_attr "athlon_decode" "vector")
1068   (set_attr "amdfam10_decode" "direct")])
1069
1070(define_insn "*cmpfp_iu_387"
1071  [(set (reg:CCFPU FLAGS_REG)
1072	(compare:CCFPU (match_operand 0 "register_operand" "f")
1073		       (match_operand 1 "register_operand" "f")))]
1074  "TARGET_80387 && TARGET_CMOVE
1075   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1076   && FLOAT_MODE_P (GET_MODE (operands[0]))
1077   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1078  "* return output_fp_compare (insn, operands, 1, 1);"
1079  [(set_attr "type" "fcmp")
1080   (set (attr "mode")
1081     (cond [(match_operand:SF 1 "" "")
1082	      (const_string "SF")
1083	    (match_operand:DF 1 "" "")
1084	      (const_string "DF")
1085	   ]
1086	   (const_string "XF")))
1087   (set_attr "athlon_decode" "vector")
1088   (set_attr "amdfam10_decode" "direct")])
1089
1090;; Move instructions.
1091
1092;; General case of fullword move.
1093
1094(define_expand "movsi"
1095  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1096	(match_operand:SI 1 "general_operand" ""))]
1097  ""
1098  "ix86_expand_move (SImode, operands); DONE;")
1099
1100;; Push/pop instructions.  They are separate since autoinc/dec is not a
1101;; general_operand.
1102;;
1103;; %%% We don't use a post-inc memory reference because x86 is not a 
1104;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1105;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1106;; targets without our curiosities, and it is just as easy to represent
1107;; this differently.
1108
1109(define_insn "*pushsi2"
1110  [(set (match_operand:SI 0 "push_operand" "=<")
1111	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1112  "!TARGET_64BIT"
1113  "push{l}\t%1"
1114  [(set_attr "type" "push")
1115   (set_attr "mode" "SI")])
1116
1117;; For 64BIT abi we always round up to 8 bytes.
1118(define_insn "*pushsi2_rex64"
1119  [(set (match_operand:SI 0 "push_operand" "=X")
1120	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1121  "TARGET_64BIT"
1122  "push{q}\t%q1"
1123  [(set_attr "type" "push")
1124   (set_attr "mode" "SI")])
1125
1126(define_insn "*pushsi2_prologue"
1127  [(set (match_operand:SI 0 "push_operand" "=<")
1128	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1129   (clobber (mem:BLK (scratch)))]
1130  "!TARGET_64BIT"
1131  "push{l}\t%1"
1132  [(set_attr "type" "push")
1133   (set_attr "mode" "SI")])
1134
1135(define_insn "*popsi1_epilogue"
1136  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1137	(mem:SI (reg:SI SP_REG)))
1138   (set (reg:SI SP_REG)
1139	(plus:SI (reg:SI SP_REG) (const_int 4)))
1140   (clobber (mem:BLK (scratch)))]
1141  "!TARGET_64BIT"
1142  "pop{l}\t%0"
1143  [(set_attr "type" "pop")
1144   (set_attr "mode" "SI")])
1145
1146(define_insn "popsi1"
1147  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1148	(mem:SI (reg:SI SP_REG)))
1149   (set (reg:SI SP_REG)
1150	(plus:SI (reg:SI SP_REG) (const_int 4)))]
1151  "!TARGET_64BIT"
1152  "pop{l}\t%0"
1153  [(set_attr "type" "pop")
1154   (set_attr "mode" "SI")])
1155
1156(define_insn "*movsi_xor"
1157  [(set (match_operand:SI 0 "register_operand" "=r")
1158	(match_operand:SI 1 "const0_operand" "i"))
1159   (clobber (reg:CC FLAGS_REG))]
1160  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1161  "xor{l}\t{%0, %0|%0, %0}"
1162  [(set_attr "type" "alu1")
1163   (set_attr "mode" "SI")
1164   (set_attr "length_immediate" "0")])
1165 
1166(define_insn "*movsi_or"
1167  [(set (match_operand:SI 0 "register_operand" "=r")
1168	(match_operand:SI 1 "immediate_operand" "i"))
1169   (clobber (reg:CC FLAGS_REG))]
1170  "reload_completed
1171   && operands[1] == constm1_rtx
1172   && (TARGET_PENTIUM || optimize_size)"
1173{
1174  operands[1] = constm1_rtx;
1175  return "or{l}\t{%1, %0|%0, %1}";
1176}
1177  [(set_attr "type" "alu1")
1178   (set_attr "mode" "SI")
1179   (set_attr "length_immediate" "1")])
1180
1181(define_insn "*movsi_1"
1182  [(set (match_operand:SI 0 "nonimmediate_operand"
1183			"=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1184	(match_operand:SI 1 "general_operand"
1185			"rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1186  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1187{
1188  switch (get_attr_type (insn))
1189    {
1190    case TYPE_SSELOG1:
1191      if (get_attr_mode (insn) == MODE_TI)
1192        return "pxor\t%0, %0";
1193      return "xorps\t%0, %0";
1194
1195    case TYPE_SSEMOV:
1196      switch (get_attr_mode (insn))
1197	{
1198	case MODE_TI:
1199	  return "movdqa\t{%1, %0|%0, %1}";
1200	case MODE_V4SF:
1201	  return "movaps\t{%1, %0|%0, %1}";
1202	case MODE_SI:
1203          return "movd\t{%1, %0|%0, %1}";
1204	case MODE_SF:
1205          return "movss\t{%1, %0|%0, %1}";
1206	default:
1207	  gcc_unreachable ();
1208	}
1209
1210    case TYPE_MMXADD:
1211      return "pxor\t%0, %0";
1212
1213    case TYPE_MMXMOV:
1214      if (get_attr_mode (insn) == MODE_DI)
1215	return "movq\t{%1, %0|%0, %1}";
1216      return "movd\t{%1, %0|%0, %1}";
1217
1218    case TYPE_LEA:
1219      return "lea{l}\t{%1, %0|%0, %1}";
1220
1221    default:
1222      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1223      return "mov{l}\t{%1, %0|%0, %1}";
1224    }
1225}
1226  [(set (attr "type")
1227     (cond [(eq_attr "alternative" "2")
1228	      (const_string "mmxadd")
1229	    (eq_attr "alternative" "3,4,5")
1230	      (const_string "mmxmov")
1231	    (eq_attr "alternative" "6")
1232	      (const_string "sselog1")
1233	    (eq_attr "alternative" "7,8,9,10,11")
1234	      (const_string "ssemov")
1235 	    (match_operand:DI 1 "pic_32bit_operand" "")
1236	      (const_string "lea")
1237	   ]
1238	   (const_string "imov")))
1239   (set (attr "mode")
1240     (cond [(eq_attr "alternative" "2,3")
1241	      (const_string "DI")
1242	    (eq_attr "alternative" "6,7")
1243	      (if_then_else
1244	        (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1245	        (const_string "V4SF")
1246	        (const_string "TI"))
1247	    (and (eq_attr "alternative" "8,9,10,11")
1248	         (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1249	      (const_string "SF")
1250	   ]
1251	   (const_string "SI")))])
1252
1253;; Stores and loads of ax to arbitrary constant address.
1254;; We fake an second form of instruction to force reload to load address
1255;; into register when rax is not available
1256(define_insn "*movabssi_1_rex64"
1257  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1258	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1259  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1260  "@
1261   movabs{l}\t{%1, %P0|%P0, %1}
1262   mov{l}\t{%1, %a0|%a0, %1}"
1263  [(set_attr "type" "imov")
1264   (set_attr "modrm" "0,*")
1265   (set_attr "length_address" "8,0")
1266   (set_attr "length_immediate" "0,*")
1267   (set_attr "memory" "store")
1268   (set_attr "mode" "SI")])
1269
1270(define_insn "*movabssi_2_rex64"
1271  [(set (match_operand:SI 0 "register_operand" "=a,r")
1272        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1273  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1274  "@
1275   movabs{l}\t{%P1, %0|%0, %P1}
1276   mov{l}\t{%a1, %0|%0, %a1}"
1277  [(set_attr "type" "imov")
1278   (set_attr "modrm" "0,*")
1279   (set_attr "length_address" "8,0")
1280   (set_attr "length_immediate" "0")
1281   (set_attr "memory" "load")
1282   (set_attr "mode" "SI")])
1283
1284(define_insn "*swapsi"
1285  [(set (match_operand:SI 0 "register_operand" "+r")
1286	(match_operand:SI 1 "register_operand" "+r"))
1287   (set (match_dup 1)
1288	(match_dup 0))]
1289  ""
1290  "xchg{l}\t%1, %0"
1291  [(set_attr "type" "imov")
1292   (set_attr "mode" "SI")
1293   (set_attr "pent_pair" "np")
1294   (set_attr "athlon_decode" "vector")
1295   (set_attr "amdfam10_decode" "double")])   
1296
1297(define_expand "movhi"
1298  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1299        (match_operand:HI 1 "general_operand" ""))]
1300  ""
1301  "ix86_expand_move (HImode, operands); DONE;")
1302
1303(define_insn "*pushhi2"
1304  [(set (match_operand:HI 0 "push_operand" "=X")
1305	(match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1306  "!TARGET_64BIT"
1307  "push{l}\t%k1"
1308  [(set_attr "type" "push")
1309   (set_attr "mode" "SI")])
1310
1311;; For 64BIT abi we always round up to 8 bytes.
1312(define_insn "*pushhi2_rex64"
1313  [(set (match_operand:HI 0 "push_operand" "=X")
1314	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1315  "TARGET_64BIT"
1316  "push{q}\t%q1"
1317  [(set_attr "type" "push")
1318   (set_attr "mode" "DI")])
1319
1320(define_insn "*movhi_1"
1321  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1322	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1323  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1324{
1325  switch (get_attr_type (insn))
1326    {
1327    case TYPE_IMOVX:
1328      /* movzwl is faster than movw on p2 due to partial word stalls,
1329	 though not as fast as an aligned movl.  */
1330      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1331    default:
1332      if (get_attr_mode (insn) == MODE_SI)
1333        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1334      else
1335        return "mov{w}\t{%1, %0|%0, %1}";
1336    }
1337}
1338  [(set (attr "type")
1339     (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1340	      (const_string "imov")
1341	    (and (eq_attr "alternative" "0")
1342		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1343			  (const_int 0))
1344		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1345			  (const_int 0))))
1346	      (const_string "imov")
1347	    (and (eq_attr "alternative" "1,2")
1348		 (match_operand:HI 1 "aligned_operand" ""))
1349	      (const_string "imov")
1350	    (and (ne (symbol_ref "TARGET_MOVX")
1351		     (const_int 0))
1352		 (eq_attr "alternative" "0,2"))
1353	      (const_string "imovx")
1354	   ]
1355	   (const_string "imov")))
1356    (set (attr "mode")
1357      (cond [(eq_attr "type" "imovx")
1358	       (const_string "SI")
1359	     (and (eq_attr "alternative" "1,2")
1360		  (match_operand:HI 1 "aligned_operand" ""))
1361	       (const_string "SI")
1362	     (and (eq_attr "alternative" "0")
1363		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1364			   (const_int 0))
1365		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1366			   (const_int 0))))
1367	       (const_string "SI")
1368	    ]
1369	    (const_string "HI")))])
1370
1371;; Stores and loads of ax to arbitrary constant address.
1372;; We fake an second form of instruction to force reload to load address
1373;; into register when rax is not available
1374(define_insn "*movabshi_1_rex64"
1375  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1376	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1377  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1378  "@
1379   movabs{w}\t{%1, %P0|%P0, %1}
1380   mov{w}\t{%1, %a0|%a0, %1}"
1381  [(set_attr "type" "imov")
1382   (set_attr "modrm" "0,*")
1383   (set_attr "length_address" "8,0")
1384   (set_attr "length_immediate" "0,*")
1385   (set_attr "memory" "store")
1386   (set_attr "mode" "HI")])
1387
1388(define_insn "*movabshi_2_rex64"
1389  [(set (match_operand:HI 0 "register_operand" "=a,r")
1390        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1391  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1392  "@
1393   movabs{w}\t{%P1, %0|%0, %P1}
1394   mov{w}\t{%a1, %0|%0, %a1}"
1395  [(set_attr "type" "imov")
1396   (set_attr "modrm" "0,*")
1397   (set_attr "length_address" "8,0")
1398   (set_attr "length_immediate" "0")
1399   (set_attr "memory" "load")
1400   (set_attr "mode" "HI")])
1401
1402(define_insn "*swaphi_1"
1403  [(set (match_operand:HI 0 "register_operand" "+r")
1404	(match_operand:HI 1 "register_operand" "+r"))
1405   (set (match_dup 1)
1406	(match_dup 0))]
1407  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1408  "xchg{l}\t%k1, %k0"
1409  [(set_attr "type" "imov")
1410   (set_attr "mode" "SI")
1411   (set_attr "pent_pair" "np")
1412   (set_attr "athlon_decode" "vector")
1413   (set_attr "amdfam10_decode" "double")])   
1414
1415;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1416(define_insn "*swaphi_2"
1417  [(set (match_operand:HI 0 "register_operand" "+r")
1418	(match_operand:HI 1 "register_operand" "+r"))
1419   (set (match_dup 1)
1420	(match_dup 0))]
1421  "TARGET_PARTIAL_REG_STALL"
1422  "xchg{w}\t%1, %0"
1423  [(set_attr "type" "imov")
1424   (set_attr "mode" "HI")
1425   (set_attr "pent_pair" "np")
1426   (set_attr "athlon_decode" "vector")])
1427
1428(define_expand "movstricthi"
1429  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1430	(match_operand:HI 1 "general_operand" ""))]
1431  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1432{
1433  /* Don't generate memory->memory moves, go through a register */
1434  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1435    operands[1] = force_reg (HImode, operands[1]);
1436})
1437
1438(define_insn "*movstricthi_1"
1439  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1440	(match_operand:HI 1 "general_operand" "rn,m"))]
1441  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1442   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1443  "mov{w}\t{%1, %0|%0, %1}"
1444  [(set_attr "type" "imov")
1445   (set_attr "mode" "HI")])
1446
1447(define_insn "*movstricthi_xor"
1448  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1449	(match_operand:HI 1 "const0_operand" "i"))
1450   (clobber (reg:CC FLAGS_REG))]
1451  "reload_completed
1452   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1453  "xor{w}\t{%0, %0|%0, %0}"
1454  [(set_attr "type" "alu1")
1455   (set_attr "mode" "HI")
1456   (set_attr "length_immediate" "0")])
1457
1458(define_expand "movqi"
1459  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1460	(match_operand:QI 1 "general_operand" ""))]
1461  ""
1462  "ix86_expand_move (QImode, operands); DONE;")
1463
1464;; emit_push_insn when it calls move_by_pieces requires an insn to
1465;; "push a byte".  But actually we use pushl, which has the effect
1466;; of rounding the amount pushed up to a word.
1467
1468(define_insn "*pushqi2"
1469  [(set (match_operand:QI 0 "push_operand" "=X")
1470	(match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1471  "!TARGET_64BIT"
1472  "push{l}\t%k1"
1473  [(set_attr "type" "push")
1474   (set_attr "mode" "SI")])
1475
1476;; For 64BIT abi we always round up to 8 bytes.
1477(define_insn "*pushqi2_rex64"
1478  [(set (match_operand:QI 0 "push_operand" "=X")
1479	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1480  "TARGET_64BIT"
1481  "push{q}\t%q1"
1482  [(set_attr "type" "push")
1483   (set_attr "mode" "DI")])
1484
1485;; Situation is quite tricky about when to choose full sized (SImode) move
1486;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1487;; partial register dependency machines (such as AMD Athlon), where QImode
1488;; moves issue extra dependency and for partial register stalls machines
1489;; that don't use QImode patterns (and QImode move cause stall on the next
1490;; instruction).
1491;;
1492;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1493;; register stall machines with, where we use QImode instructions, since
1494;; partial register stall can be caused there.  Then we use movzx.
1495(define_insn "*movqi_1"
1496  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1497	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1498  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1499{
1500  switch (get_attr_type (insn))
1501    {
1502    case TYPE_IMOVX:
1503      gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1504      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1505    default:
1506      if (get_attr_mode (insn) == MODE_SI)
1507        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1508      else
1509        return "mov{b}\t{%1, %0|%0, %1}";
1510    }
1511}
1512  [(set (attr "type")
1513     (cond [(and (eq_attr "alternative" "5")
1514		 (not (match_operand:QI 1 "aligned_operand" "")))
1515	      (const_string "imovx")
1516	    (ne (symbol_ref "optimize_size") (const_int 0))
1517	      (const_string "imov")
1518	    (and (eq_attr "alternative" "3")
1519		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520			  (const_int 0))
1521		      (eq (symbol_ref "TARGET_QIMODE_MATH")
1522			  (const_int 0))))
1523	      (const_string "imov")
1524	    (eq_attr "alternative" "3,5")
1525	      (const_string "imovx")
1526	    (and (ne (symbol_ref "TARGET_MOVX")
1527		     (const_int 0))
1528		 (eq_attr "alternative" "2"))
1529	      (const_string "imovx")
1530	   ]
1531	   (const_string "imov")))
1532   (set (attr "mode")
1533      (cond [(eq_attr "alternative" "3,4,5")
1534	       (const_string "SI")
1535	     (eq_attr "alternative" "6")
1536	       (const_string "QI")
1537	     (eq_attr "type" "imovx")
1538	       (const_string "SI")
1539	     (and (eq_attr "type" "imov")
1540		  (and (eq_attr "alternative" "0,1")
1541		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1542				(const_int 0))
1543			    (and (eq (symbol_ref "optimize_size")
1544				     (const_int 0))
1545			    	 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1546				     (const_int 0))))))
1547	       (const_string "SI")
1548	     ;; Avoid partial register stalls when not using QImode arithmetic
1549	     (and (eq_attr "type" "imov")
1550		  (and (eq_attr "alternative" "0,1")
1551		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1552				(const_int 0))
1553			    (eq (symbol_ref "TARGET_QIMODE_MATH")
1554				(const_int 0)))))
1555	       (const_string "SI")
1556	   ]
1557	   (const_string "QI")))])
1558
1559(define_expand "reload_outqi"
1560  [(parallel [(match_operand:QI 0 "" "=m")
1561              (match_operand:QI 1 "register_operand" "r")
1562              (match_operand:QI 2 "register_operand" "=&q")])]
1563  ""
1564{
1565  rtx op0, op1, op2;
1566  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1567
1568  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1569  if (! q_regs_operand (op1, QImode))
1570    {
1571      emit_insn (gen_movqi (op2, op1));
1572      op1 = op2;
1573    }
1574  emit_insn (gen_movqi (op0, op1));
1575  DONE;
1576})
1577
1578(define_insn "*swapqi_1"
1579  [(set (match_operand:QI 0 "register_operand" "+r")
1580	(match_operand:QI 1 "register_operand" "+r"))
1581   (set (match_dup 1)
1582	(match_dup 0))]
1583  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1584  "xchg{l}\t%k1, %k0"
1585  [(set_attr "type" "imov")
1586   (set_attr "mode" "SI")
1587   (set_attr "pent_pair" "np")
1588   (set_attr "athlon_decode" "vector")
1589   (set_attr "amdfam10_decode" "vector")])   
1590
1591;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1592(define_insn "*swapqi_2"
1593  [(set (match_operand:QI 0 "register_operand" "+q")
1594	(match_operand:QI 1 "register_operand" "+q"))
1595   (set (match_dup 1)
1596	(match_dup 0))]
1597  "TARGET_PARTIAL_REG_STALL"
1598  "xchg{b}\t%1, %0"
1599  [(set_attr "type" "imov")
1600   (set_attr "mode" "QI")
1601   (set_attr "pent_pair" "np")
1602   (set_attr "athlon_decode" "vector")])
1603
1604(define_expand "movstrictqi"
1605  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1606	(match_operand:QI 1 "general_operand" ""))]
1607  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1608{
1609  /* Don't generate memory->memory moves, go through a register.  */
1610  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1611    operands[1] = force_reg (QImode, operands[1]);
1612})
1613
1614(define_insn "*movstrictqi_1"
1615  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1616	(match_operand:QI 1 "general_operand" "*qn,m"))]
1617  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1618   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1619  "mov{b}\t{%1, %0|%0, %1}"
1620  [(set_attr "type" "imov")
1621   (set_attr "mode" "QI")])
1622
1623(define_insn "*movstrictqi_xor"
1624  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1625	(match_operand:QI 1 "const0_operand" "i"))
1626   (clobber (reg:CC FLAGS_REG))]
1627  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1628  "xor{b}\t{%0, %0|%0, %0}"
1629  [(set_attr "type" "alu1")
1630   (set_attr "mode" "QI")
1631   (set_attr "length_immediate" "0")])
1632
1633(define_insn "*movsi_extv_1"
1634  [(set (match_operand:SI 0 "register_operand" "=R")
1635	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1636			 (const_int 8)
1637			 (const_int 8)))]
1638  ""
1639  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1640  [(set_attr "type" "imovx")
1641   (set_attr "mode" "SI")])
1642
1643(define_insn "*movhi_extv_1"
1644  [(set (match_operand:HI 0 "register_operand" "=R")
1645	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1646			 (const_int 8)
1647			 (const_int 8)))]
1648  ""
1649  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1650  [(set_attr "type" "imovx")
1651   (set_attr "mode" "SI")])
1652
1653(define_insn "*movqi_extv_1"
1654  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1655        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1656                         (const_int 8)
1657                         (const_int 8)))]
1658  "!TARGET_64BIT"
1659{
1660  switch (get_attr_type (insn))
1661    {
1662    case TYPE_IMOVX:
1663      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1664    default:
1665      return "mov{b}\t{%h1, %0|%0, %h1}";
1666    }
1667}
1668  [(set (attr "type")
1669     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1670			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1671			     (ne (symbol_ref "TARGET_MOVX")
1672				 (const_int 0))))
1673	(const_string "imovx")
1674	(const_string "imov")))
1675   (set (attr "mode")
1676     (if_then_else (eq_attr "type" "imovx")
1677	(const_string "SI")
1678	(const_string "QI")))])
1679
1680(define_insn "*movqi_extv_1_rex64"
1681  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1682        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1683                         (const_int 8)
1684                         (const_int 8)))]
1685  "TARGET_64BIT"
1686{
1687  switch (get_attr_type (insn))
1688    {
1689    case TYPE_IMOVX:
1690      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1691    default:
1692      return "mov{b}\t{%h1, %0|%0, %h1}";
1693    }
1694}
1695  [(set (attr "type")
1696     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698			     (ne (symbol_ref "TARGET_MOVX")
1699				 (const_int 0))))
1700	(const_string "imovx")
1701	(const_string "imov")))
1702   (set (attr "mode")
1703     (if_then_else (eq_attr "type" "imovx")
1704	(const_string "SI")
1705	(const_string "QI")))])
1706
1707;; Stores and loads of ax to arbitrary constant address.
1708;; We fake an second form of instruction to force reload to load address
1709;; into register when rax is not available
1710(define_insn "*movabsqi_1_rex64"
1711  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1712	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1713  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1714  "@
1715   movabs{b}\t{%1, %P0|%P0, %1}
1716   mov{b}\t{%1, %a0|%a0, %1}"
1717  [(set_attr "type" "imov")
1718   (set_attr "modrm" "0,*")
1719   (set_attr "length_address" "8,0")
1720   (set_attr "length_immediate" "0,*")
1721   (set_attr "memory" "store")
1722   (set_attr "mode" "QI")])
1723
1724(define_insn "*movabsqi_2_rex64"
1725  [(set (match_operand:QI 0 "register_operand" "=a,r")
1726        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1727  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1728  "@
1729   movabs{b}\t{%P1, %0|%0, %P1}
1730   mov{b}\t{%a1, %0|%0, %a1}"
1731  [(set_attr "type" "imov")
1732   (set_attr "modrm" "0,*")
1733   (set_attr "length_address" "8,0")
1734   (set_attr "length_immediate" "0")
1735   (set_attr "memory" "load")
1736   (set_attr "mode" "QI")])
1737
1738(define_insn "*movdi_extzv_1"
1739  [(set (match_operand:DI 0 "register_operand" "=R")
1740	(zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1741			 (const_int 8)
1742			 (const_int 8)))]
1743  "TARGET_64BIT"
1744  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1745  [(set_attr "type" "imovx")
1746   (set_attr "mode" "DI")])
1747
1748(define_insn "*movsi_extzv_1"
1749  [(set (match_operand:SI 0 "register_operand" "=R")
1750	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1751			 (const_int 8)
1752			 (const_int 8)))]
1753  ""
1754  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1755  [(set_attr "type" "imovx")
1756   (set_attr "mode" "SI")])
1757
1758(define_insn "*movqi_extzv_2"
1759  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1760        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1761				    (const_int 8)
1762				    (const_int 8)) 0))]
1763  "!TARGET_64BIT"
1764{
1765  switch (get_attr_type (insn))
1766    {
1767    case TYPE_IMOVX:
1768      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1769    default:
1770      return "mov{b}\t{%h1, %0|%0, %h1}";
1771    }
1772}
1773  [(set (attr "type")
1774     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1775			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1776			     (ne (symbol_ref "TARGET_MOVX")
1777				 (const_int 0))))
1778	(const_string "imovx")
1779	(const_string "imov")))
1780   (set (attr "mode")
1781     (if_then_else (eq_attr "type" "imovx")
1782	(const_string "SI")
1783	(const_string "QI")))])
1784
1785(define_insn "*movqi_extzv_2_rex64"
1786  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1787        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1788				    (const_int 8)
1789				    (const_int 8)) 0))]
1790  "TARGET_64BIT"
1791{
1792  switch (get_attr_type (insn))
1793    {
1794    case TYPE_IMOVX:
1795      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1796    default:
1797      return "mov{b}\t{%h1, %0|%0, %h1}";
1798    }
1799}
1800  [(set (attr "type")
1801     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1802			(ne (symbol_ref "TARGET_MOVX")
1803			    (const_int 0)))
1804	(const_string "imovx")
1805	(const_string "imov")))
1806   (set (attr "mode")
1807     (if_then_else (eq_attr "type" "imovx")
1808	(const_string "SI")
1809	(const_string "QI")))])
1810
1811(define_insn "movsi_insv_1"
1812  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1813			 (const_int 8)
1814			 (const_int 8))
1815	(match_operand:SI 1 "general_operand" "Qmn"))]
1816  "!TARGET_64BIT"
1817  "mov{b}\t{%b1, %h0|%h0, %b1}"
1818  [(set_attr "type" "imov")
1819   (set_attr "mode" "QI")])
1820
1821(define_insn "movdi_insv_1_rex64"
1822  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1823			 (const_int 8)
1824			 (const_int 8))
1825	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
1826  "TARGET_64BIT"
1827  "mov{b}\t{%b1, %h0|%h0, %b1}"
1828  [(set_attr "type" "imov")
1829   (set_attr "mode" "QI")])
1830
1831(define_insn "*movqi_insv_2"
1832  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1833			 (const_int 8)
1834			 (const_int 8))
1835	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1836		     (const_int 8)))]
1837  ""
1838  "mov{b}\t{%h1, %h0|%h0, %h1}"
1839  [(set_attr "type" "imov")
1840   (set_attr "mode" "QI")])
1841
1842(define_expand "movdi"
1843  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1844	(match_operand:DI 1 "general_operand" ""))]
1845  ""
1846  "ix86_expand_move (DImode, operands); DONE;")
1847
1848(define_insn "*pushdi"
1849  [(set (match_operand:DI 0 "push_operand" "=<")
1850	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1851  "!TARGET_64BIT"
1852  "#")
1853
1854(define_insn "*pushdi2_rex64"
1855  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1856	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1857  "TARGET_64BIT"
1858  "@
1859   push{q}\t%1
1860   #"
1861  [(set_attr "type" "push,multi")
1862   (set_attr "mode" "DI")])
1863
1864;; Convert impossible pushes of immediate to existing instructions.
1865;; First try to get scratch register and go through it.  In case this
1866;; fails, push sign extended lower part first and then overwrite
1867;; upper part by 32bit move.
1868(define_peephole2
1869  [(match_scratch:DI 2 "r")
1870   (set (match_operand:DI 0 "push_operand" "")
1871        (match_operand:DI 1 "immediate_operand" ""))]
1872  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1873   && !x86_64_immediate_operand (operands[1], DImode)"
1874  [(set (match_dup 2) (match_dup 1))
1875   (set (match_dup 0) (match_dup 2))]
1876  "")
1877
1878;; We need to define this as both peepholer and splitter for case
1879;; peephole2 pass is not run.
1880;; "&& 1" is needed to keep it from matching the previous pattern.
1881(define_peephole2
1882  [(set (match_operand:DI 0 "push_operand" "")
1883        (match_operand:DI 1 "immediate_operand" ""))]
1884  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1885   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1886  [(set (match_dup 0) (match_dup 1))
1887   (set (match_dup 2) (match_dup 3))]
1888  "split_di (operands + 1, 1, operands + 2, operands + 3);
1889   operands[1] = gen_lowpart (DImode, operands[2]);
1890   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1891						    GEN_INT (4)));
1892  ")
1893
1894(define_split
1895  [(set (match_operand:DI 0 "push_operand" "")
1896        (match_operand:DI 1 "immediate_operand" ""))]
1897  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1898		    ? flow2_completed : reload_completed)
1899   && !symbolic_operand (operands[1], DImode)
1900   && !x86_64_immediate_operand (operands[1], DImode)"
1901  [(set (match_dup 0) (match_dup 1))
1902   (set (match_dup 2) (match_dup 3))]
1903  "split_di (operands + 1, 1, operands + 2, operands + 3);
1904   operands[1] = gen_lowpart (DImode, operands[2]);
1905   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1906						    GEN_INT (4)));
1907  ")
1908
1909(define_insn "*pushdi2_prologue_rex64"
1910  [(set (match_operand:DI 0 "push_operand" "=<")
1911	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
1912   (clobber (mem:BLK (scratch)))]
1913  "TARGET_64BIT"
1914  "push{q}\t%1"
1915  [(set_attr "type" "push")
1916   (set_attr "mode" "DI")])
1917
1918(define_insn "*popdi1_epilogue_rex64"
1919  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1920	(mem:DI (reg:DI SP_REG)))
1921   (set (reg:DI SP_REG)
1922	(plus:DI (reg:DI SP_REG) (const_int 8)))
1923   (clobber (mem:BLK (scratch)))]
1924  "TARGET_64BIT"
1925  "pop{q}\t%0"
1926  [(set_attr "type" "pop")
1927   (set_attr "mode" "DI")])
1928
1929(define_insn "popdi1"
1930  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1931	(mem:DI (reg:DI SP_REG)))
1932   (set (reg:DI SP_REG)
1933	(plus:DI (reg:DI SP_REG) (const_int 8)))]
1934  "TARGET_64BIT"
1935  "pop{q}\t%0"
1936  [(set_attr "type" "pop")
1937   (set_attr "mode" "DI")])
1938
1939(define_insn "*movdi_xor_rex64"
1940  [(set (match_operand:DI 0 "register_operand" "=r")
1941	(match_operand:DI 1 "const0_operand" "i"))
1942   (clobber (reg:CC FLAGS_REG))]
1943  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1944   && reload_completed"
1945  "xor{l}\t{%k0, %k0|%k0, %k0}"
1946  [(set_attr "type" "alu1")
1947   (set_attr "mode" "SI")
1948   (set_attr "length_immediate" "0")])
1949
1950(define_insn "*movdi_or_rex64"
1951  [(set (match_operand:DI 0 "register_operand" "=r")
1952	(match_operand:DI 1 "const_int_operand" "i"))
1953   (clobber (reg:CC FLAGS_REG))]
1954  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1955   && reload_completed
1956   && operands[1] == constm1_rtx"
1957{
1958  operands[1] = constm1_rtx;
1959  return "or{q}\t{%1, %0|%0, %1}";
1960}
1961  [(set_attr "type" "alu1")
1962   (set_attr "mode" "DI")
1963   (set_attr "length_immediate" "1")])
1964
1965(define_insn "*movdi_2"
1966  [(set (match_operand:DI 0 "nonimmediate_operand"
1967				"=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1968	(match_operand:DI 1 "general_operand"
1969				"riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1970  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971  "@
1972   #
1973   #
1974   pxor\t%0, %0
1975   movq\t{%1, %0|%0, %1}
1976   movq\t{%1, %0|%0, %1}
1977   pxor\t%0, %0
1978   movq\t{%1, %0|%0, %1}
1979   movdqa\t{%1, %0|%0, %1}
1980   movq\t{%1, %0|%0, %1}
1981   xorps\t%0, %0
1982   movlps\t{%1, %0|%0, %1}
1983   movaps\t{%1, %0|%0, %1}
1984   movlps\t{%1, %0|%0, %1}"
1985  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1986   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1987
1988(define_split
1989  [(set (match_operand:DI 0 "push_operand" "")
1990        (match_operand:DI 1 "general_operand" ""))]
1991  "!TARGET_64BIT && reload_completed
1992   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1993  [(const_int 0)]
1994  "ix86_split_long_move (operands); DONE;")
1995
1996;; %%% This multiword shite has got to go.
1997(define_split
1998  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1999        (match_operand:DI 1 "general_operand" ""))]
2000  "!TARGET_64BIT && reload_completed
2001   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2002   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2003  [(const_int 0)]
2004  "ix86_split_long_move (operands); DONE;")
2005
2006(define_insn "*movdi_1_rex64"
2007  [(set (match_operand:DI 0 "nonimmediate_operand"
2008		"=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2009	(match_operand:DI 1 "general_operand"
2010		"Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2011  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2012{
2013  switch (get_attr_type (insn))
2014    {
2015    case TYPE_SSECVT:
2016      if (which_alternative == 13)
2017	return "movq2dq\t{%1, %0|%0, %1}";
2018      else
2019	return "movdq2q\t{%1, %0|%0, %1}";
2020    case TYPE_SSEMOV:
2021      if (get_attr_mode (insn) == MODE_TI)
2022	  return "movdqa\t{%1, %0|%0, %1}";
2023      /* FALLTHRU */
2024    case TYPE_MMXMOV:
2025      /* Moves from and into integer register is done using movd opcode with
2026 	 REX prefix.  */
2027      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2028	  return "movd\t{%1, %0|%0, %1}";
2029      return "movq\t{%1, %0|%0, %1}";
2030    case TYPE_SSELOG1:
2031    case TYPE_MMXADD:
2032      return "pxor\t%0, %0";
2033    case TYPE_MULTI:
2034      return "#";
2035    case TYPE_LEA:
2036      return "lea{q}\t{%a1, %0|%0, %a1}";
2037    default:
2038      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2039      if (get_attr_mode (insn) == MODE_SI)
2040	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2041      else if (which_alternative == 2)
2042	return "movabs{q}\t{%1, %0|%0, %1}";
2043      else
2044	return "mov{q}\t{%1, %0|%0, %1}";
2045    }
2046}
2047  [(set (attr "type")
2048     (cond [(eq_attr "alternative" "5")
2049	      (const_string "mmxadd")
2050	    (eq_attr "alternative" "6,7,8")
2051	      (const_string "mmxmov")
2052	    (eq_attr "alternative" "9")
2053	      (const_string "sselog1")
2054	    (eq_attr "alternative" "10,11,12")
2055	      (const_string "ssemov")
2056	    (eq_attr "alternative" "13,14")
2057	      (const_string "ssecvt")
2058	    (eq_attr "alternative" "4")
2059	      (const_string "multi")
2060 	    (match_operand:DI 1 "pic_32bit_operand" "")
2061	      (const_string "lea")
2062	   ]
2063	   (const_string "imov")))
2064   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2065   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2066   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2067
2068;; Stores and loads of ax to arbitrary constant address.
2069;; We fake an second form of instruction to force reload to load address
2070;; into register when rax is not available
2071(define_insn "*movabsdi_1_rex64"
2072  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2073	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2074  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2075  "@
2076   movabs{q}\t{%1, %P0|%P0, %1}
2077   mov{q}\t{%1, %a0|%a0, %1}"
2078  [(set_attr "type" "imov")
2079   (set_attr "modrm" "0,*")
2080   (set_attr "length_address" "8,0")
2081   (set_attr "length_immediate" "0,*")
2082   (set_attr "memory" "store")
2083   (set_attr "mode" "DI")])
2084
2085(define_insn "*movabsdi_2_rex64"
2086  [(set (match_operand:DI 0 "register_operand" "=a,r")
2087        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2088  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2089  "@
2090   movabs{q}\t{%P1, %0|%0, %P1}
2091   mov{q}\t{%a1, %0|%0, %a1}"
2092  [(set_attr "type" "imov")
2093   (set_attr "modrm" "0,*")
2094   (set_attr "length_address" "8,0")
2095   (set_attr "length_immediate" "0")
2096   (set_attr "memory" "load")
2097   (set_attr "mode" "DI")])
2098
2099;; Convert impossible stores of immediate to existing instructions.
2100;; First try to get scratch register and go through it.  In case this
2101;; fails, move by 32bit parts.
2102(define_peephole2
2103  [(match_scratch:DI 2 "r")
2104   (set (match_operand:DI 0 "memory_operand" "")
2105        (match_operand:DI 1 "immediate_operand" ""))]
2106  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2107   && !x86_64_immediate_operand (operands[1], DImode)"
2108  [(set (match_dup 2) (match_dup 1))
2109   (set (match_dup 0) (match_dup 2))]
2110  "")
2111
2112;; We need to define this as both peepholer and splitter for case
2113;; peephole2 pass is not run.
2114;; "&& 1" is needed to keep it from matching the previous pattern.
2115(define_peephole2
2116  [(set (match_operand:DI 0 "memory_operand" "")
2117        (match_operand:DI 1 "immediate_operand" ""))]
2118  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2120  [(set (match_dup 2) (match_dup 3))
2121   (set (match_dup 4) (match_dup 5))]
2122  "split_di (operands, 2, operands + 2, operands + 4);")
2123
2124(define_split
2125  [(set (match_operand:DI 0 "memory_operand" "")
2126        (match_operand:DI 1 "immediate_operand" ""))]
2127  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2128		    ? flow2_completed : reload_completed)
2129   && !symbolic_operand (operands[1], DImode)
2130   && !x86_64_immediate_operand (operands[1], DImode)"
2131  [(set (match_dup 2) (match_dup 3))
2132   (set (match_dup 4) (match_dup 5))]
2133  "split_di (operands, 2, operands + 2, operands + 4);")
2134
2135(define_insn "*swapdi_rex64"
2136  [(set (match_operand:DI 0 "register_operand" "+r")
2137	(match_operand:DI 1 "register_operand" "+r"))
2138   (set (match_dup 1)
2139	(match_dup 0))]
2140  "TARGET_64BIT"
2141  "xchg{q}\t%1, %0"
2142  [(set_attr "type" "imov")
2143   (set_attr "mode" "DI")
2144   (set_attr "pent_pair" "np")
2145   (set_attr "athlon_decode" "vector")
2146   (set_attr "amdfam10_decode" "double")])   
2147
2148(define_expand "movti"
2149  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2150	(match_operand:TI 1 "nonimmediate_operand" ""))]
2151  "TARGET_SSE || TARGET_64BIT"
2152{
2153  if (TARGET_64BIT)
2154    ix86_expand_move (TImode, operands);
2155  else
2156    ix86_expand_vector_move (TImode, operands);
2157  DONE;
2158})
2159
2160(define_insn "*movti_internal"
2161  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2162	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2163  "TARGET_SSE && !TARGET_64BIT
2164   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2165{
2166  switch (which_alternative)
2167    {
2168    case 0:
2169      if (get_attr_mode (insn) == MODE_V4SF)
2170	return "xorps\t%0, %0";
2171      else
2172	return "pxor\t%0, %0";
2173    case 1:
2174    case 2:
2175      if (get_attr_mode (insn) == MODE_V4SF)
2176	return "movaps\t{%1, %0|%0, %1}";
2177      else
2178	return "movdqa\t{%1, %0|%0, %1}";
2179    default:
2180      gcc_unreachable ();
2181    }
2182}
2183  [(set_attr "type" "sselog1,ssemov,ssemov")
2184   (set (attr "mode")
2185	(cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2186		    (ne (symbol_ref "optimize_size") (const_int 0)))
2187		 (const_string "V4SF")
2188	       (and (eq_attr "alternative" "2")
2189		    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2190			(const_int 0)))
2191		 (const_string "V4SF")]
2192	      (const_string "TI")))])
2193
2194(define_insn "*movti_rex64"
2195  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2196	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2197  "TARGET_64BIT
2198   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2199{
2200  switch (which_alternative)
2201    {
2202    case 0:
2203    case 1:
2204      return "#";
2205    case 2:
2206      if (get_attr_mode (insn) == MODE_V4SF)
2207	return "xorps\t%0, %0";
2208      else
2209	return "pxor\t%0, %0";
2210    case 3:
2211    case 4:
2212      if (get_attr_mode (insn) == MODE_V4SF)
2213	return "movaps\t{%1, %0|%0, %1}";
2214      else
2215	return "movdqa\t{%1, %0|%0, %1}";
2216    default:
2217      gcc_unreachable ();
2218    }
2219}
2220  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2221   (set (attr "mode")
2222        (cond [(eq_attr "alternative" "2,3")
2223		 (if_then_else
2224		   (ne (symbol_ref "optimize_size")
2225		       (const_int 0))
2226		   (const_string "V4SF")
2227		   (const_string "TI"))
2228	       (eq_attr "alternative" "4")
2229		 (if_then_else
2230		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2231			    (const_int 0))
2232			(ne (symbol_ref "optimize_size")
2233			    (const_int 0)))
2234		   (const_string "V4SF")
2235		   (const_string "TI"))]
2236	       (const_string "DI")))])
2237
2238(define_split
2239  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2240        (match_operand:TI 1 "general_operand" ""))]
2241  "reload_completed && !SSE_REG_P (operands[0])
2242   && !SSE_REG_P (operands[1])"
2243  [(const_int 0)]
2244  "ix86_split_long_move (operands); DONE;")
2245
2246(define_expand "movsf"
2247  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2248	(match_operand:SF 1 "general_operand" ""))]
2249  ""
2250  "ix86_expand_move (SFmode, operands); DONE;")
2251
2252(define_insn "*pushsf"
2253  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2254	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2255  "!TARGET_64BIT"
2256{
2257  /* Anything else should be already split before reg-stack.  */
2258  gcc_assert (which_alternative == 1);
2259  return "push{l}\t%1";
2260}
2261  [(set_attr "type" "multi,push,multi")
2262   (set_attr "unit" "i387,*,*")
2263   (set_attr "mode" "SF,SI,SF")])
2264
2265(define_insn "*pushsf_rex64"
2266  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2267	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2268  "TARGET_64BIT"
2269{
2270  /* Anything else should be already split before reg-stack.  */
2271  gcc_assert (which_alternative == 1);
2272  return "push{q}\t%q1";
2273}
2274  [(set_attr "type" "multi,push,multi")
2275   (set_attr "unit" "i387,*,*")
2276   (set_attr "mode" "SF,DI,SF")])
2277
2278(define_split
2279  [(set (match_operand:SF 0 "push_operand" "")
2280	(match_operand:SF 1 "memory_operand" ""))]
2281  "reload_completed
2282   && GET_CODE (operands[1]) == MEM
2283   && constant_pool_reference_p (operands[1])"
2284  [(set (match_dup 0)
2285	(match_dup 1))]
2286  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2287
2288
2289;; %%% Kill this when call knows how to work this out.
2290(define_split
2291  [(set (match_operand:SF 0 "push_operand" "")
2292	(match_operand:SF 1 "any_fp_register_operand" ""))]
2293  "!TARGET_64BIT"
2294  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2295   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2296
2297(define_split
2298  [(set (match_operand:SF 0 "push_operand" "")
2299	(match_operand:SF 1 "any_fp_register_operand" ""))]
2300  "TARGET_64BIT"
2301  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2302   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2303
2304(define_insn "*movsf_1"
2305  [(set (match_operand:SF 0 "nonimmediate_operand"
2306	  "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2307	(match_operand:SF 1 "general_operand"
2308	  "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2309  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2310   && (reload_in_progress || reload_completed
2311       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2312       || GET_CODE (operands[1]) != CONST_DOUBLE
2313       || memory_operand (operands[0], SFmode))" 
2314{
2315  switch (which_alternative)
2316    {
2317    case 0:
2318      return output_387_reg_move (insn, operands);
2319
2320    case 1:
2321      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2322        return "fstp%z0\t%y0";
2323      else
2324        return "fst%z0\t%y0";
2325
2326    case 2:
2327      return standard_80387_constant_opcode (operands[1]);
2328
2329    case 3:
2330    case 4:
2331      return "mov{l}\t{%1, %0|%0, %1}";
2332    case 5:
2333      if (get_attr_mode (insn) == MODE_TI)
2334	return "pxor\t%0, %0";
2335      else
2336	return "xorps\t%0, %0";
2337    case 6:
2338      if (get_attr_mode (insn) == MODE_V4SF)
2339	return "movaps\t{%1, %0|%0, %1}";
2340      else
2341	return "movss\t{%1, %0|%0, %1}";
2342    case 7:
2343    case 8:
2344      return "movss\t{%1, %0|%0, %1}";
2345
2346    case 9:
2347    case 10:
2348      return "movd\t{%1, %0|%0, %1}";
2349
2350    case 11:
2351      return "movq\t{%1, %0|%0, %1}";
2352
2353    default:
2354      gcc_unreachable ();
2355    }
2356}
2357  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2358   (set (attr "mode")
2359        (cond [(eq_attr "alternative" "3,4,9,10")
2360		 (const_string "SI")
2361	       (eq_attr "alternative" "5")
2362		 (if_then_else
2363		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2364			    	 (const_int 0))
2365			     (ne (symbol_ref "TARGET_SSE2")
2366				 (const_int 0)))
2367			(eq (symbol_ref "optimize_size")
2368			    (const_int 0)))
2369		   (const_string "TI")
2370		   (const_string "V4SF"))
2371	       /* For architectures resolving dependencies on
2372		  whole SSE registers use APS move to break dependency
2373		  chains, otherwise use short move to avoid extra work. 
2374
2375		  Do the same for architectures resolving dependencies on
2376		  the parts.  While in DF mode it is better to always handle
2377		  just register parts, the SF mode is different due to lack
2378		  of instructions to load just part of the register.  It is
2379		  better to maintain the whole registers in single format
2380		  to avoid problems on using packed logical operations.  */
2381	       (eq_attr "alternative" "6")
2382		 (if_then_else
2383		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2384			    (const_int 0))
2385			(ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2386			    (const_int 0)))
2387		   (const_string "V4SF")
2388		   (const_string "SF"))
2389	       (eq_attr "alternative" "11")
2390		 (const_string "DI")]
2391	       (const_string "SF")))])
2392
2393(define_insn "*swapsf"
2394  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2395	(match_operand:SF 1 "fp_register_operand" "+f"))
2396   (set (match_dup 1)
2397	(match_dup 0))]
2398  "reload_completed || TARGET_80387"
2399{
2400  if (STACK_TOP_P (operands[0]))
2401    return "fxch\t%1";
2402  else
2403    return "fxch\t%0";
2404}
2405  [(set_attr "type" "fxch")
2406   (set_attr "mode" "SF")])
2407
2408(define_expand "movdf"
2409  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2410	(match_operand:DF 1 "general_operand" ""))]
2411  ""
2412  "ix86_expand_move (DFmode, operands); DONE;")
2413
2414;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2415;; Size of pushdf using integer instructions is 2+2*memory operand size
2416;; On the average, pushdf using integers can be still shorter.  Allow this
2417;; pattern for optimize_size too.
2418
2419(define_insn "*pushdf_nointeger"
2420  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2421	(match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2422  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2423{
2424  /* This insn should be already split before reg-stack.  */
2425  gcc_unreachable ();
2426}
2427  [(set_attr "type" "multi")
2428   (set_attr "unit" "i387,*,*,*")
2429   (set_attr "mode" "DF,SI,SI,DF")])
2430
2431(define_insn "*pushdf_integer"
2432  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2433	(match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2434  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2435{
2436  /* This insn should be already split before reg-stack.  */
2437  gcc_unreachable ();
2438}
2439  [(set_attr "type" "multi")
2440   (set_attr "unit" "i387,*,*")
2441   (set_attr "mode" "DF,SI,DF")])
2442
2443;; %%% Kill this when call knows how to work this out.
2444(define_split
2445  [(set (match_operand:DF 0 "push_operand" "")
2446	(match_operand:DF 1 "any_fp_register_operand" ""))]
2447  "!TARGET_64BIT && reload_completed"
2448  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2449   (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2450  "")
2451
2452(define_split
2453  [(set (match_operand:DF 0 "push_operand" "")
2454	(match_operand:DF 1 "any_fp_register_operand" ""))]
2455  "TARGET_64BIT && reload_completed"
2456  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2457   (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2458  "")
2459
2460(define_split
2461  [(set (match_operand:DF 0 "push_operand" "")
2462	(match_operand:DF 1 "general_operand" ""))]
2463  "reload_completed"
2464  [(const_int 0)]
2465  "ix86_split_long_move (operands); DONE;")
2466
2467;; Moving is usually shorter when only FP registers are used. This separate
2468;; movdf pattern avoids the use of integer registers for FP operations
2469;; when optimizing for size.
2470
2471(define_insn "*movdf_nointeger"
2472  [(set (match_operand:DF 0 "nonimmediate_operand"
2473			"=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2474	(match_operand:DF 1 "general_operand"
2475			"fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2476  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2477   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2478   && (reload_in_progress || reload_completed
2479       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2480       || GET_CODE (operands[1]) != CONST_DOUBLE
2481       || memory_operand (operands[0], DFmode))" 
2482{
2483  switch (which_alternative)
2484    {
2485    case 0:
2486      return output_387_reg_move (insn, operands);
2487
2488    case 1:
2489      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2490        return "fstp%z0\t%y0";
2491      else
2492        return "fst%z0\t%y0";
2493
2494    case 2:
2495      return standard_80387_constant_opcode (operands[1]);
2496
2497    case 3:
2498    case 4:
2499      return "#";
2500    case 5:
2501      switch (get_attr_mode (insn))
2502	{
2503	case MODE_V4SF:
2504	  return "xorps\t%0, %0";
2505	case MODE_V2DF:
2506	  return "xorpd\t%0, %0";
2507	case MODE_TI:
2508	  return "pxor\t%0, %0";
2509	default:
2510	  gcc_unreachable ();
2511	}
2512    case 6:
2513    case 7:
2514    case 8:
2515      switch (get_attr_mode (insn))
2516	{
2517	case MODE_V4SF:
2518	  return "movaps\t{%1, %0|%0, %1}";
2519	case MODE_V2DF:
2520	  return "movapd\t{%1, %0|%0, %1}";
2521	case MODE_TI:
2522	  return "movdqa\t{%1, %0|%0, %1}";
2523	case MODE_DI:
2524	  return "movq\t{%1, %0|%0, %1}";
2525	case MODE_DF:
2526	  return "movsd\t{%1, %0|%0, %1}";
2527	case MODE_V1DF:
2528	  return "movlpd\t{%1, %0|%0, %1}";
2529	case MODE_V2SF:
2530	  return "movlps\t{%1, %0|%0, %1}";
2531	default:
2532	  gcc_unreachable ();
2533	}
2534
2535    default:
2536      gcc_unreachable ();
2537    }
2538}
2539  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2540   (set (attr "mode")
2541        (cond [(eq_attr "alternative" "0,1,2")
2542		 (const_string "DF")
2543	       (eq_attr "alternative" "3,4")
2544		 (const_string "SI")
2545
2546	       /* For SSE1, we have many fewer alternatives.  */
2547	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2548		 (cond [(eq_attr "alternative" "5,6")
2549			  (const_string "V4SF")
2550		       ]
2551		   (const_string "V2SF"))
2552
2553	       /* xorps is one byte shorter.  */
2554	       (eq_attr "alternative" "5")
2555		 (cond [(ne (symbol_ref "optimize_size")
2556			    (const_int 0))
2557			  (const_string "V4SF")
2558			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2559			    (const_int 0))
2560			  (const_string "TI")
2561		       ]
2562		       (const_string "V2DF"))
2563
2564	       /* For architectures resolving dependencies on
2565		  whole SSE registers use APD move to break dependency
2566		  chains, otherwise use short move to avoid extra work.
2567
2568		  movaps encodes one byte shorter.  */
2569	       (eq_attr "alternative" "6")
2570		 (cond
2571		   [(ne (symbol_ref "optimize_size")
2572		        (const_int 0))
2573		      (const_string "V4SF")
2574		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2575		        (const_int 0))
2576		      (const_string "V2DF")
2577		   ]
2578		   (const_string "DF"))
2579	       /* For architectures resolving dependencies on register
2580		  parts we may avoid extra work to zero out upper part
2581		  of register.  */
2582	       (eq_attr "alternative" "7")
2583		 (if_then_else
2584		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2585		       (const_int 0))
2586		   (const_string "V1DF")
2587		   (const_string "DF"))
2588	      ]
2589	      (const_string "DF")))])
2590
2591(define_insn "*movdf_integer"
2592  [(set (match_operand:DF 0 "nonimmediate_operand"
2593		"=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2594	(match_operand:DF 1 "general_operand"
2595		"fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2596  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2597   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2598   && (reload_in_progress || reload_completed
2599       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2600       || GET_CODE (operands[1]) != CONST_DOUBLE
2601       || memory_operand (operands[0], DFmode))" 
2602{
2603  switch (which_alternative)
2604    {
2605    case 0:
2606      return output_387_reg_move (insn, operands);
2607
2608    case 1:
2609      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2610        return "fstp%z0\t%y0";
2611      else
2612        return "fst%z0\t%y0";
2613
2614    case 2:
2615      return standard_80387_constant_opcode (operands[1]);
2616
2617    case 3:
2618    case 4:
2619      return "#";
2620
2621    case 5:
2622      switch (get_attr_mode (insn))
2623	{
2624	case MODE_V4SF:
2625	  return "xorps\t%0, %0";
2626	case MODE_V2DF:
2627	  return "xorpd\t%0, %0";
2628	case MODE_TI:
2629	  return "pxor\t%0, %0";
2630	default:
2631	  gcc_unreachable ();
2632	}
2633    case 6:
2634    case 7:
2635    case 8:
2636      switch (get_attr_mode (insn))
2637	{
2638	case MODE_V4SF:
2639	  return "movaps\t{%1, %0|%0, %1}";
2640	case MODE_V2DF:
2641	  return "movapd\t{%1, %0|%0, %1}";
2642	case MODE_TI:
2643	  return "movdqa\t{%1, %0|%0, %1}";
2644	case MODE_DI:
2645	  return "movq\t{%1, %0|%0, %1}";
2646	case MODE_DF:
2647	  return "movsd\t{%1, %0|%0, %1}";
2648	case MODE_V1DF:
2649	  return "movlpd\t{%1, %0|%0, %1}";
2650	case MODE_V2SF:
2651	  return "movlps\t{%1, %0|%0, %1}";
2652	default:
2653	  gcc_unreachable ();
2654	}
2655
2656    default:
2657      gcc_unreachable();
2658    }
2659}
2660  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2661   (set (attr "mode")
2662        (cond [(eq_attr "alternative" "0,1,2")
2663		 (const_string "DF")
2664	       (eq_attr "alternative" "3,4")
2665		 (const_string "SI")
2666
2667	       /* For SSE1, we have many fewer alternatives.  */
2668	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2669		 (cond [(eq_attr "alternative" "5,6")
2670			  (const_string "V4SF")
2671		       ]
2672		   (const_string "V2SF"))
2673
2674	       /* xorps is one byte shorter.  */
2675	       (eq_attr "alternative" "5")
2676		 (cond [(ne (symbol_ref "optimize_size")
2677			    (const_int 0))
2678			  (const_string "V4SF")
2679			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2680			    (const_int 0))
2681			  (const_string "TI")
2682		       ]
2683		       (const_string "V2DF"))
2684
2685	       /* For architectures resolving dependencies on
2686		  whole SSE registers use APD move to break dependency
2687		  chains, otherwise use short move to avoid extra work.
2688
2689		  movaps encodes one byte shorter.  */
2690	       (eq_attr "alternative" "6")
2691		 (cond
2692		   [(ne (symbol_ref "optimize_size")
2693		        (const_int 0))
2694		      (const_string "V4SF")
2695		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2696		        (const_int 0))
2697		      (const_string "V2DF")
2698		   ]
2699		   (const_string "DF"))
2700	       /* For architectures resolving dependencies on register
2701		  parts we may avoid extra work to zero out upper part
2702		  of register.  */
2703	       (eq_attr "alternative" "7")
2704		 (if_then_else
2705		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2706		       (const_int 0))
2707		   (const_string "V1DF")
2708		   (const_string "DF"))
2709	      ]
2710	      (const_string "DF")))])
2711
2712(define_split
2713  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2714	(match_operand:DF 1 "general_operand" ""))]
2715  "reload_completed
2716   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2717   && ! (ANY_FP_REG_P (operands[0]) || 
2718	 (GET_CODE (operands[0]) == SUBREG
2719	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2720   && ! (ANY_FP_REG_P (operands[1]) || 
2721	 (GET_CODE (operands[1]) == SUBREG
2722	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2723  [(const_int 0)]
2724  "ix86_split_long_move (operands); DONE;")
2725
2726(define_insn "*swapdf"
2727  [(set (match_operand:DF 0 "fp_register_operand" "+f")
2728	(match_operand:DF 1 "fp_register_operand" "+f"))
2729   (set (match_dup 1)
2730	(match_dup 0))]
2731  "reload_completed || TARGET_80387"
2732{
2733  if (STACK_TOP_P (operands[0]))
2734    return "fxch\t%1";
2735  else
2736    return "fxch\t%0";
2737}
2738  [(set_attr "type" "fxch")
2739   (set_attr "mode" "DF")])
2740
2741(define_expand "movxf"
2742  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2743	(match_operand:XF 1 "general_operand" ""))]
2744  ""
2745  "ix86_expand_move (XFmode, operands); DONE;")
2746
2747;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2748;; Size of pushdf using integer instructions is 3+3*memory operand size
2749;; Pushing using integer instructions is longer except for constants
2750;; and direct memory references.
2751;; (assuming that any given constant is pushed only once, but this ought to be
2752;;  handled elsewhere).
2753
2754(define_insn "*pushxf_nointeger"
2755  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2756	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2757  "optimize_size"
2758{
2759  /* This insn should be already split before reg-stack.  */
2760  gcc_unreachable ();
2761}
2762  [(set_attr "type" "multi")
2763   (set_attr "unit" "i387,*,*")
2764   (set_attr "mode" "XF,SI,SI")])
2765
2766(define_insn "*pushxf_integer"
2767  [(set (match_operand:XF 0 "push_operand" "=<,<")
2768	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2769  "!optimize_size"
2770{
2771  /* This insn should be already split before reg-stack.  */
2772  gcc_unreachable ();
2773}
2774  [(set_attr "type" "multi")
2775   (set_attr "unit" "i387,*")
2776   (set_attr "mode" "XF,SI")])
2777
2778(define_split
2779  [(set (match_operand 0 "push_operand" "")
2780	(match_operand 1 "general_operand" ""))]
2781  "reload_completed
2782   && (GET_MODE (operands[0]) == XFmode
2783       || GET_MODE (operands[0]) == DFmode)
2784   && !ANY_FP_REG_P (operands[1])"
2785  [(const_int 0)]
2786  "ix86_split_long_move (operands); DONE;")
2787
2788(define_split
2789  [(set (match_operand:XF 0 "push_operand" "")
2790	(match_operand:XF 1 "any_fp_register_operand" ""))]
2791  "!TARGET_64BIT"
2792  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2793   (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2794  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2795
2796(define_split
2797  [(set (match_operand:XF 0 "push_operand" "")
2798	(match_operand:XF 1 "any_fp_register_operand" ""))]
2799  "TARGET_64BIT"
2800  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2801   (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2802  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2803
2804;; Do not use integer registers when optimizing for size
2805(define_insn "*movxf_nointeger"
2806  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2807	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2808  "optimize_size
2809   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2810   && (reload_in_progress || reload_completed
2811       || GET_CODE (operands[1]) != CONST_DOUBLE
2812       || memory_operand (operands[0], XFmode))" 
2813{
2814  switch (which_alternative)
2815    {
2816    case 0:
2817      return output_387_reg_move (insn, operands);
2818
2819    case 1:
2820      /* There is no non-popping store to memory for XFmode.  So if
2821	 we need one, follow the store with a load.  */
2822      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2823        return "fstp%z0\t%y0\;fld%z0\t%y0";
2824      else
2825        return "fstp%z0\t%y0";
2826
2827    case 2:
2828      return standard_80387_constant_opcode (operands[1]);
2829
2830    case 3: case 4:
2831      return "#";
2832    default:
2833      gcc_unreachable ();
2834    }
2835}
2836  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2837   (set_attr "mode" "XF,XF,XF,SI,SI")])
2838
2839(define_insn "*movxf_integer"
2840  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2841	(match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2842  "!optimize_size
2843   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2844   && (reload_in_progress || reload_completed
2845       || GET_CODE (operands[1]) != CONST_DOUBLE
2846       || memory_operand (operands[0], XFmode))" 
2847{
2848  switch (which_alternative)
2849    {
2850    case 0:
2851      return output_387_reg_move (insn, operands);
2852
2853    case 1:
2854      /* There is no non-popping store to memory for XFmode.  So if
2855	 we need one, follow the store with a load.  */
2856      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2857        return "fstp%z0\t%y0\;fld%z0\t%y0";
2858      else
2859        return "fstp%z0\t%y0";
2860
2861    case 2:
2862      return standard_80387_constant_opcode (operands[1]);
2863
2864    case 3: case 4:
2865      return "#";
2866
2867    default:
2868      gcc_unreachable ();
2869    }
2870}
2871  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2872   (set_attr "mode" "XF,XF,XF,SI,SI")])
2873
2874(define_split
2875  [(set (match_operand 0 "nonimmediate_operand" "")
2876	(match_operand 1 "general_operand" ""))]
2877  "reload_completed
2878   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2879   && GET_MODE (operands[0]) == XFmode
2880   && ! (ANY_FP_REG_P (operands[0]) || 
2881	 (GET_CODE (operands[0]) == SUBREG
2882	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2883   && ! (ANY_FP_REG_P (operands[1]) || 
2884	 (GET_CODE (operands[1]) == SUBREG
2885	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2886  [(const_int 0)]
2887  "ix86_split_long_move (operands); DONE;")
2888
2889(define_split
2890  [(set (match_operand 0 "register_operand" "")
2891	(match_operand 1 "memory_operand" ""))]
2892  "reload_completed
2893   && GET_CODE (operands[1]) == MEM
2894   && (GET_MODE (operands[0]) == XFmode
2895       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2896   && constant_pool_reference_p (operands[1])"
2897  [(set (match_dup 0) (match_dup 1))]
2898{
2899  rtx c = avoid_constant_pool_reference (operands[1]);
2900  rtx r = operands[0];
2901
2902  if (GET_CODE (r) == SUBREG)
2903    r = SUBREG_REG (r);
2904
2905  if (SSE_REG_P (r))
2906    {
2907      if (!standard_sse_constant_p (c))
2908	FAIL;
2909    }
2910  else if (FP_REG_P (r))
2911    {
2912      if (!standard_80387_constant_p (c))
2913	FAIL;
2914    }
2915  else if (MMX_REG_P (r))
2916    FAIL;
2917
2918  operands[1] = c;
2919})
2920
2921(define_insn "swapxf"
2922  [(set (match_operand:XF 0 "register_operand" "+f")
2923	(match_operand:XF 1 "register_operand" "+f"))
2924   (set (match_dup 1)
2925	(match_dup 0))]
2926  "TARGET_80387"
2927{
2928  if (STACK_TOP_P (operands[0]))
2929    return "fxch\t%1";
2930  else
2931    return "fxch\t%0";
2932}
2933  [(set_attr "type" "fxch")
2934   (set_attr "mode" "XF")])
2935
2936(define_expand "movtf"
2937  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2938	(match_operand:TF 1 "nonimmediate_operand" ""))]
2939  "TARGET_64BIT"
2940{
2941  ix86_expand_move (TFmode, operands);
2942  DONE;
2943})
2944
2945(define_insn "*movtf_internal"
2946  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2947	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2948  "TARGET_64BIT
2949   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2950{
2951  switch (which_alternative)
2952    {
2953    case 0:
2954    case 1:
2955      return "#";
2956    case 2:
2957      if (get_attr_mode (insn) == MODE_V4SF)
2958	return "xorps\t%0, %0";
2959      else
2960	return "pxor\t%0, %0";
2961    case 3:
2962    case 4:
2963      if (get_attr_mode (insn) == MODE_V4SF)
2964	return "movaps\t{%1, %0|%0, %1}";
2965      else
2966	return "movdqa\t{%1, %0|%0, %1}";
2967    default:
2968      gcc_unreachable ();
2969    }
2970}
2971  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2972   (set (attr "mode")
2973        (cond [(eq_attr "alternative" "2,3")
2974		 (if_then_else
2975		   (ne (symbol_ref "optimize_size")
2976		       (const_int 0))
2977		   (const_string "V4SF")
2978		   (const_string "TI"))
2979	       (eq_attr "alternative" "4")
2980		 (if_then_else
2981		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2982			    (const_int 0))
2983			(ne (symbol_ref "optimize_size")
2984			    (const_int 0)))
2985		   (const_string "V4SF")
2986		   (const_string "TI"))]
2987	       (const_string "DI")))])
2988
2989(define_split
2990  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2991        (match_operand:TF 1 "general_operand" ""))]
2992  "reload_completed && !SSE_REG_P (operands[0])
2993   && !SSE_REG_P (operands[1])"
2994  [(const_int 0)]
2995  "ix86_split_long_move (operands); DONE;")
2996
2997;; Zero extension instructions
2998
2999(define_expand "zero_extendhisi2"
3000  [(set (match_operand:SI 0 "register_operand" "")
3001     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3002  ""
3003{
3004  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3005    {
3006      operands[1] = force_reg (HImode, operands[1]);
3007      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3008      DONE;
3009    }
3010})
3011
3012(define_insn "zero_extendhisi2_and"
3013  [(set (match_operand:SI 0 "register_operand" "=r")
3014     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3015   (clobber (reg:CC FLAGS_REG))]
3016  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3017  "#"
3018  [(set_attr "type" "alu1")
3019   (set_attr "mode" "SI")])
3020
3021(define_split
3022  [(set (match_operand:SI 0 "register_operand" "")
3023	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3024   (clobber (reg:CC FLAGS_REG))]
3025  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3026  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3027	      (clobber (reg:CC FLAGS_REG))])]
3028  "")
3029
3030(define_insn "*zero_extendhisi2_movzwl"
3031  [(set (match_operand:SI 0 "register_operand" "=r")
3032     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3033  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3034  "movz{wl|x}\t{%1, %0|%0, %1}"
3035  [(set_attr "type" "imovx")
3036   (set_attr "mode" "SI")])
3037
3038(define_expand "zero_extendqihi2"
3039  [(parallel
3040    [(set (match_operand:HI 0 "register_operand" "")
3041       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3042     (clobber (reg:CC FLAGS_REG))])]
3043  ""
3044  "")
3045
3046(define_insn "*zero_extendqihi2_and"
3047  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3048     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3049   (clobber (reg:CC FLAGS_REG))]
3050  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3051  "#"
3052  [(set_attr "type" "alu1")
3053   (set_attr "mode" "HI")])
3054
3055(define_insn "*zero_extendqihi2_movzbw_and"
3056  [(set (match_operand:HI 0 "register_operand" "=r,r")
3057     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3058   (clobber (reg:CC FLAGS_REG))]
3059  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3060  "#"
3061  [(set_attr "type" "imovx,alu1")
3062   (set_attr "mode" "HI")])
3063
3064; zero extend to SImode here to avoid partial register stalls
3065(define_insn "*zero_extendqihi2_movzbl"
3066  [(set (match_operand:HI 0 "register_operand" "=r")
3067     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3068  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3069  "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3070  [(set_attr "type" "imovx")
3071   (set_attr "mode" "SI")])
3072
3073;; For the movzbw case strip only the clobber
3074(define_split
3075  [(set (match_operand:HI 0 "register_operand" "")
3076	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3077   (clobber (reg:CC FLAGS_REG))]
3078  "reload_completed 
3079   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3080   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3081  [(set (match_operand:HI 0 "register_operand" "")
3082	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3083
3084;; When source and destination does not overlap, clear destination
3085;; first and then do the movb
3086(define_split
3087  [(set (match_operand:HI 0 "register_operand" "")
3088	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3089   (clobber (reg:CC FLAGS_REG))]
3090  "reload_completed
3091   && ANY_QI_REG_P (operands[0])
3092   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3093   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3094  [(set (match_dup 0) (const_int 0))
3095   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3096  "operands[2] = gen_lowpart (QImode, operands[0]);")
3097
3098;; Rest is handled by single and.
3099(define_split
3100  [(set (match_operand:HI 0 "register_operand" "")
3101	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3102   (clobber (reg:CC FLAGS_REG))]
3103  "reload_completed
3104   && true_regnum (operands[0]) == true_regnum (operands[1])"
3105  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3106	      (clobber (reg:CC FLAGS_REG))])]
3107  "")
3108
3109(define_expand "zero_extendqisi2"
3110  [(parallel
3111    [(set (match_operand:SI 0 "register_operand" "")
3112       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3113     (clobber (reg:CC FLAGS_REG))])]
3114  ""
3115  "")
3116
3117(define_insn "*zero_extendqisi2_and"
3118  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3119     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3120   (clobber (reg:CC FLAGS_REG))]
3121  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3122  "#"
3123  [(set_attr "type" "alu1")
3124   (set_attr "mode" "SI")])
3125
3126(define_insn "*zero_extendqisi2_movzbw_and"
3127  [(set (match_operand:SI 0 "register_operand" "=r,r")
3128     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3129   (clobber (reg:CC FLAGS_REG))]
3130  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3131  "#"
3132  [(set_attr "type" "imovx,alu1")
3133   (set_attr "mode" "SI")])
3134
3135(define_insn "*zero_extendqisi2_movzbw"
3136  [(set (match_operand:SI 0 "register_operand" "=r")
3137     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3138  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3139  "movz{bl|x}\t{%1, %0|%0, %1}"
3140  [(set_attr "type" "imovx")
3141   (set_attr "mode" "SI")])
3142
3143;; For the movzbl case strip only the clobber
3144(define_split
3145  [(set (match_operand:SI 0 "register_operand" "")
3146	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3147   (clobber (reg:CC FLAGS_REG))]
3148  "reload_completed 
3149   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3150   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3151  [(set (match_dup 0)
3152	(zero_extend:SI (match_dup 1)))])
3153
3154;; When source and destination does not overlap, clear destination
3155;; first and then do the movb
3156(define_split
3157  [(set (match_operand:SI 0 "register_operand" "")
3158	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3159   (clobber (reg:CC FLAGS_REG))]
3160  "reload_completed
3161   && ANY_QI_REG_P (operands[0])
3162   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3163   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3164   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3165  [(set (match_dup 0) (const_int 0))
3166   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3167  "operands[2] = gen_lowpart (QImode, operands[0]);")
3168
3169;; Rest is handled by single and.
3170(define_split
3171  [(set (match_operand:SI 0 "register_operand" "")
3172	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3173   (clobber (reg:CC FLAGS_REG))]
3174  "reload_completed
3175   && true_regnum (operands[0]) == true_regnum (operands[1])"
3176  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3177	      (clobber (reg:CC FLAGS_REG))])]
3178  "")
3179
3180;; %%% Kill me once multi-word ops are sane.
3181(define_expand "zero_extendsidi2"
3182  [(set (match_operand:DI 0 "register_operand" "=r")
3183     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3184  ""
3185  "if (!TARGET_64BIT)
3186     {
3187       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3188       DONE;
3189     }
3190  ")
3191
3192(define_insn "zero_extendsidi2_32"
3193  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3194	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3195   (clobber (reg:CC FLAGS_REG))]
3196  "!TARGET_64BIT"
3197  "@
3198   #
3199   #
3200   #
3201   movd\t{%1, %0|%0, %1}
3202   movd\t{%1, %0|%0, %1}"
3203  [(set_attr "mode" "SI,SI,SI,DI,TI")
3204   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3205
3206(define_insn "zero_extendsidi2_rex64"
3207  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3208     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3209  "TARGET_64BIT"
3210  "@
3211   mov\t{%k1, %k0|%k0, %k1}
3212   #
3213   movd\t{%1, %0|%0, %1}
3214   movd\t{%1, %0|%0, %1}"
3215  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3216   (set_attr "mode" "SI,DI,SI,SI")])
3217
3218(define_split
3219  [(set (match_operand:DI 0 "memory_operand" "")
3220     (zero_extend:DI (match_dup 0)))]
3221  "TARGET_64BIT"
3222  [(set (match_dup 4) (const_int 0))]
3223  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3224
3225(define_split 
3226  [(set (match_operand:DI 0 "register_operand" "")
3227	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3228   (clobber (reg:CC FLAGS_REG))]
3229  "!TARGET_64BIT && reload_completed
3230   && true_regnum (operands[0]) == true_regnum (operands[1])"
3231  [(set (match_dup 4) (const_int 0))]
3232  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3233
3234(define_split 
3235  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3236	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3237   (clobber (reg:CC FLAGS_REG))]
3238  "!TARGET_64BIT && reload_completed
3239   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3240  [(set (match_dup 3) (match_dup 1))
3241   (set (match_dup 4) (const_int 0))]
3242  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3243
3244(define_insn "zero_extendhidi2"
3245  [(set (match_operand:DI 0 "register_operand" "=r")
3246     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3247  "TARGET_64BIT"
3248  "movz{wl|x}\t{%1, %k0|%k0, %1}"
3249  [(set_attr "type" "imovx")
3250   (set_attr "mode" "DI")])
3251
3252(define_insn "zero_extendqidi2"
3253  [(set (match_operand:DI 0 "register_operand" "=r")
3254     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3255  "TARGET_64BIT"
3256  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3257  [(set_attr "type" "imovx")
3258   (set_attr "mode" "DI")])
3259
3260;; Sign extension instructions
3261
3262(define_expand "extendsidi2"
3263  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3264		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3265	      (clobber (reg:CC FLAGS_REG))
3266	      (clobber (match_scratch:SI 2 ""))])]
3267  ""
3268{
3269  if (TARGET_64BIT)
3270    {
3271      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3272      DONE;
3273    }
3274})
3275
3276(define_insn "*extendsidi2_1"
3277  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3278	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3279   (clobber (reg:CC FLAGS_REG))
3280   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3281  "!TARGET_64BIT"
3282  "#")
3283
3284(define_insn "extendsidi2_rex64"
3285  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3286	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3287  "TARGET_64BIT"
3288  "@
3289   {cltq|cdqe}
3290   movs{lq|x}\t{%1,%0|%0, %1}"
3291  [(set_attr "type" "imovx")
3292   (set_attr "mode" "DI")
3293   (set_attr "prefix_0f" "0")
3294   (set_attr "modrm" "0,1")])
3295
3296(define_insn "extendhidi2"
3297  [(set (match_operand:DI 0 "register_operand" "=r")
3298	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3299  "TARGET_64BIT"
3300  "movs{wq|x}\t{%1,%0|%0, %1}"
3301  [(set_attr "type" "imovx")
3302   (set_attr "mode" "DI")])
3303
3304(define_insn "extendqidi2"
3305  [(set (match_operand:DI 0 "register_operand" "=r")
3306	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3307  "TARGET_64BIT"
3308  "movs{bq|x}\t{%1,%0|%0, %1}"
3309   [(set_attr "type" "imovx")
3310    (set_attr "mode" "DI")])
3311
3312;; Extend to memory case when source register does die.
3313(define_split 
3314  [(set (match_operand:DI 0 "memory_operand" "")
3315	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3316   (clobber (reg:CC FLAGS_REG))
3317   (clobber (match_operand:SI 2 "register_operand" ""))]
3318  "(reload_completed
3319    && dead_or_set_p (insn, operands[1])
3320    && !reg_mentioned_p (operands[1], operands[0]))"
3321  [(set (match_dup 3) (match_dup 1))
3322   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3323	      (clobber (reg:CC FLAGS_REG))])
3324   (set (match_dup 4) (match_dup 1))]
3325  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3326
3327;; Extend to memory case when source register does not die.
3328(define_split 
3329  [(set (match_operand:DI 0 "memory_operand" "")
3330	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331   (clobber (reg:CC FLAGS_REG))
3332   (clobber (match_operand:SI 2 "register_operand" ""))]
3333  "reload_completed"
3334  [(const_int 0)]
3335{
3336  split_di (&operands[0], 1, &operands[3], &operands[4]);
3337
3338  emit_move_insn (operands[3], operands[1]);
3339
3340  /* Generate a cltd if possible and doing so it profitable.  */
3341  if (true_regnum (operands[1]) == 0
3342      && true_regnum (operands[2]) == 1
3343      && (optimize_size || TARGET_USE_CLTD))
3344    {
3345      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3346    }
3347  else
3348    {
3349      emit_move_insn (operands[2], operands[1]);
3350      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3351    }
3352  emit_move_insn (operands[4], operands[2]);
3353  DONE;
3354})
3355
3356;; Extend to register case.  Optimize case where source and destination
3357;; registers match and cases where we can use cltd.
3358(define_split 
3359  [(set (match_operand:DI 0 "register_operand" "")
3360	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3361   (clobber (reg:CC FLAGS_REG))
3362   (clobber (match_scratch:SI 2 ""))]
3363  "reload_completed"
3364  [(const_int 0)]
3365{
3366  split_di (&operands[0], 1, &operands[3], &operands[4]);
3367
3368  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3369    emit_move_insn (operands[3], operands[1]);
3370
3371  /* Generate a cltd if possible and doing so it profitable.  */
3372  if (true_regnum (operands[3]) == 0
3373      && (optimize_size || TARGET_USE_CLTD))
3374    {
3375      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3376      DONE;
3377    }
3378
3379  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3380    emit_move_insn (operands[4], operands[1]);
3381
3382  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3383  DONE;
3384})
3385
3386(define_insn "extendhisi2"
3387  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3388	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3389  ""
3390{
3391  switch (get_attr_prefix_0f (insn))
3392    {
3393    case 0:
3394      return "{cwtl|cwde}";
3395    default:
3396      return "movs{wl|x}\t{%1,%0|%0, %1}";
3397    }
3398}
3399  [(set_attr "type" "imovx")
3400   (set_attr "mode" "SI")
3401   (set (attr "prefix_0f")
3402     ;; movsx is short decodable while cwtl is vector decoded.
3403     (if_then_else (and (eq_attr "cpu" "!k6")
3404			(eq_attr "alternative" "0"))
3405	(const_string "0")
3406	(const_string "1")))
3407   (set (attr "modrm")
3408     (if_then_else (eq_attr "prefix_0f" "0")
3409	(const_string "0")
3410	(const_string "1")))])
3411
3412(define_insn "*extendhisi2_zext"
3413  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3414	(zero_extend:DI
3415	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3416  "TARGET_64BIT"
3417{
3418  switch (get_attr_prefix_0f (insn))
3419    {
3420    case 0:
3421      return "{cwtl|cwde}";
3422    default:
3423      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3424    }
3425}
3426  [(set_attr "type" "imovx")
3427   (set_attr "mode" "SI")
3428   (set (attr "prefix_0f")
3429     ;; movsx is short decodable while cwtl is vector decoded.
3430     (if_then_else (and (eq_attr "cpu" "!k6")
3431			(eq_attr "alternative" "0"))
3432	(const_string "0")
3433	(const_string "1")))
3434   (set (attr "modrm")
3435     (if_then_else (eq_attr "prefix_0f" "0")
3436	(const_string "0")
3437	(const_string "1")))])
3438
3439(define_insn "extendqihi2"
3440  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3441	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3442  ""
3443{
3444  switch (get_attr_prefix_0f (insn))
3445    {
3446    case 0:
3447      return "{cbtw|cbw}";
3448    default:
3449      return "movs{bw|x}\t{%1,%0|%0, %1}";
3450    }
3451}
3452  [(set_attr "type" "imovx")
3453   (set_attr "mode" "HI")
3454   (set (attr "prefix_0f")
3455     ;; movsx is short decodable while cwtl is vector decoded.
3456     (if_then_else (and (eq_attr "cpu" "!k6")
3457			(eq_attr "alternative" "0"))
3458	(const_string "0")
3459	(const_string "1")))
3460   (set (attr "modrm")
3461     (if_then_else (eq_attr "prefix_0f" "0")
3462	(const_string "0")
3463	(const_string "1")))])
3464
3465(define_insn "extendqisi2"
3466  [(set (match_operand:SI 0 "register_operand" "=r")
3467	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3468  ""
3469  "movs{bl|x}\t{%1,%0|%0, %1}"
3470   [(set_attr "type" "imovx")
3471    (set_attr "mode" "SI")])
3472
3473(define_insn "*extendqisi2_zext"
3474  [(set (match_operand:DI 0 "register_operand" "=r")
3475	(zero_extend:DI
3476	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3477  "TARGET_64BIT"
3478  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3479   [(set_attr "type" "imovx")
3480    (set_attr "mode" "SI")])
3481
3482;; Conversions between float and double.
3483
3484;; These are all no-ops in the model used for the 80387.  So just
3485;; emit moves.
3486
3487;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3488(define_insn "*dummy_extendsfdf2"
3489  [(set (match_operand:DF 0 "push_operand" "=<")
3490	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3491  "0"
3492  "#")
3493
3494(define_split
3495  [(set (match_operand:DF 0 "push_operand" "")
3496	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3497  "!TARGET_64BIT"
3498  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3499   (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3500
3501(define_split
3502  [(set (match_operand:DF 0 "push_operand" "")
3503	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3504  "TARGET_64BIT"
3505  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3506   (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3507
3508(define_insn "*dummy_extendsfxf2"
3509  [(set (match_operand:XF 0 "push_operand" "=<")
3510	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3511  "0"
3512  "#")
3513
3514(define_split
3515  [(set (match_operand:XF 0 "push_operand" "")
3516	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3517  ""
3518  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3519   (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3520  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521
3522(define_split
3523  [(set (match_operand:XF 0 "push_operand" "")
3524	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3525  "TARGET_64BIT"
3526  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3527   (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3528  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3529
3530(define_split
3531  [(set (match_operand:XF 0 "push_operand" "")
3532	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3533  ""
3534  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3535   (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3536  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3537
3538(define_split
3539  [(set (match_operand:XF 0 "push_operand" "")
3540	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3541  "TARGET_64BIT"
3542  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3543   (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3544  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3545
3546(define_expand "extendsfdf2"
3547  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3548        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3549  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3550{
3551  /* ??? Needed for compress_float_constant since all fp constants
3552     are LEGITIMATE_CONSTANT_P.  */
3553  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3554    {
3555      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3556	  && standard_80387_constant_p (operands[1]) > 0)
3557	{
3558	  operands[1] = simplify_const_unary_operation
3559	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3560	  emit_move_insn_1 (operands[0], operands[1]);
3561	  DONE;
3562	}
3563      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564    }
3565  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3566    operands[1] = force_reg (SFmode, operands[1]);
3567})
3568
3569(define_insn "*extendsfdf2_mixed"
3570  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3571        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3572  "TARGET_SSE2 && TARGET_MIX_SSE_I387
3573   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3574{
3575  switch (which_alternative)
3576    {
3577    case 0:
3578      return output_387_reg_move (insn, operands);
3579
3580    case 1:
3581      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3582        return "fstp%z0\t%y0";
3583      else
3584        return "fst%z0\t%y0";
3585
3586    case 2:
3587      return "cvtss2sd\t{%1, %0|%0, %1}";
3588
3589    default:
3590      gcc_unreachable ();
3591    }
3592}
3593  [(set_attr "type" "fmov,fmov,ssecvt")
3594   (set_attr "mode" "SF,XF,DF")])
3595
3596(define_insn "*extendsfdf2_sse"
3597  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3598        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3599  "TARGET_SSE2 && TARGET_SSE_MATH
3600   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3601  "cvtss2sd\t{%1, %0|%0, %1}"
3602  [(set_attr "type" "ssecvt")
3603   (set_attr "mode" "DF")])
3604
3605(define_insn "*extendsfdf2_i387"
3606  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3607        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3608  "TARGET_80387
3609   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3610{
3611  switch (which_alternative)
3612    {
3613    case 0:
3614      return output_387_reg_move (insn, operands);
3615
3616    case 1:
3617      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3618        return "fstp%z0\t%y0";
3619      else
3620        return "fst%z0\t%y0";
3621
3622    default:
3623      gcc_unreachable ();
3624    }
3625}
3626  [(set_attr "type" "fmov")
3627   (set_attr "mode" "SF,XF")])
3628
3629(define_expand "extendsfxf2"
3630  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3631        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3632  "TARGET_80387"
3633{
3634  /* ??? Needed for compress_float_constant since all fp constants
3635     are LEGITIMATE_CONSTANT_P.  */
3636  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3637    {
3638      if (standard_80387_constant_p (operands[1]) > 0)
3639	{
3640	  operands[1] = simplify_const_unary_operation
3641	    (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3642	  emit_move_insn_1 (operands[0], operands[1]);
3643	  DONE;
3644	}
3645      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3646    }
3647  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3648    operands[1] = force_reg (SFmode, operands[1]);
3649})
3650
3651(define_insn "*extendsfxf2_i387"
3652  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3653        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3654  "TARGET_80387
3655   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3656{
3657  switch (which_alternative)
3658    {
3659    case 0:
3660      return output_387_reg_move (insn, operands);
3661
3662    case 1:
3663      /* There is no non-popping store to memory for XFmode.  So if
3664	 we need one, follow the store with a load.  */
3665      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3666        return "fstp%z0\t%y0";
3667      else
3668        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3669
3670    default:
3671      gcc_unreachable ();
3672    }
3673}
3674  [(set_attr "type" "fmov")
3675   (set_attr "mode" "SF,XF")])
3676
3677(define_expand "extenddfxf2"
3678  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3679        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3680  "TARGET_80387"
3681{
3682  /* ??? Needed for compress_float_constant since all fp constants
3683     are LEGITIMATE_CONSTANT_P.  */
3684  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3685    {
3686      if (standard_80387_constant_p (operands[1]) > 0)
3687	{
3688	  operands[1] = simplify_const_unary_operation
3689	    (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3690	  emit_move_insn_1 (operands[0], operands[1]);
3691	  DONE;
3692	}
3693      operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3694    }
3695  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3696    operands[1] = force_reg (DFmode, operands[1]);
3697})
3698
3699(define_insn "*extenddfxf2_i387"
3700  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3701        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3702  "TARGET_80387
3703   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3704{
3705  switch (which_alternative)
3706    {
3707    case 0:
3708      return output_387_reg_move (insn, operands);
3709
3710    case 1:
3711      /* There is no non-popping store to memory for XFmode.  So if
3712	 we need one, follow the store with a load.  */
3713      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3715      else
3716        return "fstp%z0\t%y0";
3717
3718    default:
3719      gcc_unreachable ();
3720    }
3721}
3722  [(set_attr "type" "fmov")
3723   (set_attr "mode" "DF,XF")])
3724
3725;; %%% This seems bad bad news.
3726;; This cannot output into an f-reg because there is no way to be sure
3727;; of truncating in that case.  Otherwise this is just like a simple move
3728;; insn.  So we pretend we can output to a reg in order to get better
3729;; register preferencing, but we really use a stack slot.
3730
3731;; Conversion from DFmode to SFmode.
3732
3733(define_expand "truncdfsf2"
3734  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3735	(float_truncate:SF
3736	  (match_operand:DF 1 "nonimmediate_operand" "")))]
3737  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3738{
3739  if (MEM_P (operands[0]) && MEM_P (operands[1]))
3740    operands[1] = force_reg (DFmode, operands[1]);
3741
3742  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3743    ;
3744  else if (flag_unsafe_math_optimizations)
3745    ;
3746  else
3747    {
3748      rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3749      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3750      DONE;
3751    }
3752})
3753
3754(define_expand "truncdfsf2_with_temp"
3755  [(parallel [(set (match_operand:SF 0 "" "")
3756		   (float_truncate:SF (match_operand:DF 1 "" "")))
3757	      (clobber (match_operand:SF 2 "" ""))])]
3758  "")
3759
3760(define_insn "*truncdfsf_fast_mixed"
3761  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3762        (float_truncate:SF
3763          (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3764  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3765{
3766  switch (which_alternative)
3767    {
3768    case 0:
3769      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3770	return "fstp%z0\t%y0";
3771      else
3772	return "fst%z0\t%y0";
3773    case 1:
3774      return output_387_reg_move (insn, operands);
3775    case 2:
3776      return "cvtsd2ss\t{%1, %0|%0, %1}";
3777    default:
3778      gcc_unreachable ();
3779    }
3780}
3781  [(set_attr "type" "fmov,fmov,ssecvt")
3782   (set_attr "mode" "SF")])
3783
3784;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3785;; because nothing we do here is unsafe.
3786(define_insn "*truncdfsf_fast_sse"
3787  [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3788        (float_truncate:SF
3789          (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3790  "TARGET_SSE2 && TARGET_SSE_MATH"
3791  "cvtsd2ss\t{%1, %0|%0, %1}"
3792  [(set_attr "type" "ssecvt")
3793   (set_attr "mode" "SF")])
3794
3795(define_insn "*truncdfsf_fast_i387"
3796  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3797        (float_truncate:SF
3798          (match_operand:DF 1 "nonimmediate_operand" "f")))]
3799  "TARGET_80387 && flag_unsafe_math_optimizations"
3800  "* return output_387_reg_move (insn, operands);"
3801  [(set_attr "type" "fmov")
3802   (set_attr "mode" "SF")])
3803
3804(define_insn "*truncdfsf_mixed"
3805  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3806	(float_truncate:SF
3807	  (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3808   (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3809  "TARGET_MIX_SSE_I387"
3810{
3811  switch (which_alternative)
3812    {
3813    case 0:
3814      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3815	return "fstp%z0\t%y0";
3816      else
3817	return "fst%z0\t%y0";
3818    case 1:
3819      return "#";
3820    case 2:
3821      return "cvtsd2ss\t{%1, %0|%0, %1}";
3822    default:
3823      gcc_unreachable ();
3824    }
3825}
3826  [(set_attr "type" "fmov,multi,ssecvt")
3827   (set_attr "unit" "*,i387,*")
3828   (set_attr "mode" "SF")])
3829
3830(define_insn "*truncdfsf_i387"
3831  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3832	(float_truncate:SF
3833	  (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3834   (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3835  "TARGET_80387"
3836{
3837  switch (which_alternative)
3838    {
3839    case 0:
3840      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3841	return "fstp%z0\t%y0";
3842      else
3843	return "fst%z0\t%y0";
3844    case 1:
3845      return "#";
3846    default:
3847      gcc_unreachable ();
3848    }
3849}
3850  [(set_attr "type" "fmov,multi")
3851   (set_attr "unit" "*,i387")
3852   (set_attr "mode" "SF")])
3853
3854(define_insn "*truncdfsf2_i387_1"
3855  [(set (match_operand:SF 0 "memory_operand" "=m")
3856	(float_truncate:SF
3857	  (match_operand:DF 1 "register_operand" "f")))]
3858  "TARGET_80387
3859   && !(TARGET_SSE2 && TARGET_SSE_MATH)
3860   && !TARGET_MIX_SSE_I387"
3861{
3862  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3863    return "fstp%z0\t%y0";
3864  else
3865    return "fst%z0\t%y0";
3866}
3867  [(set_attr "type" "fmov")
3868   (set_attr "mode" "SF")])
3869
3870(define_split
3871  [(set (match_operand:SF 0 "register_operand" "")
3872	(float_truncate:SF
3873	 (match_operand:DF 1 "fp_register_operand" "")))
3874   (clobber (match_operand 2 "" ""))]
3875  "reload_completed"
3876  [(set (match_dup 2) (match_dup 1))
3877   (set (match_dup 0) (match_dup 2))]
3878{
3879  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3880})
3881
3882;; Conversion from XFmode to SFmode.
3883
3884(define_expand "truncxfsf2"
3885  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3886		   (float_truncate:SF
3887		    (match_operand:XF 1 "register_operand" "")))
3888	      (clobber (match_dup 2))])]
3889  "TARGET_80387"
3890{
3891  if (flag_unsafe_math_optimizations)
3892    {
3893      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3894      emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3895      if (reg != operands[0])
3896	emit_move_insn (operands[0], reg);
3897      DONE;
3898    }
3899  else
3900    operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3901})
3902
3903(define_insn "*truncxfsf2_mixed"
3904  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3905	(float_truncate:SF
3906	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3907   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3908  "TARGET_MIX_SSE_I387"
3909{
3910  gcc_assert (!which_alternative);
3911  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3912    return "fstp%z0\t%y0";
3913  else
3914    return "fst%z0\t%y0";
3915}
3916  [(set_attr "type" "fmov,multi,multi,multi")
3917   (set_attr "unit" "*,i387,i387,i387")
3918   (set_attr "mode" "SF")])
3919
3920(define_insn "truncxfsf2_i387_noop"
3921  [(set (match_operand:SF 0 "register_operand" "=f")
3922	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3923  "TARGET_80387 && flag_unsafe_math_optimizations"
3924{
3925  return output_387_reg_move (insn, operands);
3926}
3927  [(set_attr "type" "fmov")
3928   (set_attr "mode" "SF")])
3929
3930(define_insn "*truncxfsf2_i387"
3931  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3932	(float_truncate:SF
3933	 (match_operand:XF 1 "register_operand" "f,f,f")))
3934   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3935  "TARGET_80387"
3936{
3937  gcc_assert (!which_alternative);
3938  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939    return "fstp%z0\t%y0";
3940   else
3941     return "fst%z0\t%y0";
3942}
3943  [(set_attr "type" "fmov,multi,multi")
3944   (set_attr "unit" "*,i387,i387")
3945   (set_attr "mode" "SF")])
3946
3947(define_insn "*truncxfsf2_i387_1"
3948  [(set (match_operand:SF 0 "memory_operand" "=m")
3949	(float_truncate:SF
3950	 (match_operand:XF 1 "register_operand" "f")))]
3951  "TARGET_80387"
3952{
3953  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954    return "fstp%z0\t%y0";
3955  else
3956    return "fst%z0\t%y0";
3957}
3958  [(set_attr "type" "fmov")
3959   (set_attr "mode" "SF")])
3960
3961(define_split
3962  [(set (match_operand:SF 0 "register_operand" "")
3963	(float_truncate:SF
3964	 (match_operand:XF 1 "register_operand" "")))
3965   (clobber (match_operand:SF 2 "memory_operand" ""))]
3966  "TARGET_80387 && reload_completed"
3967  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3968   (set (match_dup 0) (match_dup 2))]
3969  "")
3970
3971(define_split
3972  [(set (match_operand:SF 0 "memory_operand" "")
3973	(float_truncate:SF
3974	 (match_operand:XF 1 "register_operand" "")))
3975   (clobber (match_operand:SF 2 "memory_operand" ""))]
3976  "TARGET_80387"
3977  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3978  "")
3979
3980;; Conversion from XFmode to DFmode.
3981
3982(define_expand "truncxfdf2"
3983  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3984		   (float_truncate:DF
3985		    (match_operand:XF 1 "register_operand" "")))
3986	      (clobber (match_dup 2))])]
3987  "TARGET_80387"
3988{
3989  if (flag_unsafe_math_optimizations)
3990    {
3991      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3992      emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3993      if (reg != operands[0])
3994	emit_move_insn (operands[0], reg);
3995      DONE;
3996    }
3997  else
3998    operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3999})
4000
4001(define_insn "*truncxfdf2_mixed"
4002  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4003	(float_truncate:DF
4004	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4005   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4006  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4007{
4008  gcc_assert (!which_alternative);
4009  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4010    return "fstp%z0\t%y0";
4011  else
4012    return "fst%z0\t%y0";
4013}
4014  [(set_attr "type" "fmov,multi,multi,multi")
4015   (set_attr "unit" "*,i387,i387,i387")
4016   (set_attr "mode" "DF")])
4017
4018(define_insn "truncxfdf2_i387_noop"
4019  [(set (match_operand:DF 0 "register_operand" "=f")
4020	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4021  "TARGET_80387 && flag_unsafe_math_optimizations"
4022{
4023  return output_387_reg_move (insn, operands);
4024}
4025  [(set_attr "type" "fmov")
4026   (set_attr "mode" "DF")])
4027
4028(define_insn "*truncxfdf2_i387"
4029  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4030	(float_truncate:DF
4031	 (match_operand:XF 1 "register_operand" "f,f,f")))
4032   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4033  "TARGET_80387"
4034{
4035  gcc_assert (!which_alternative);
4036  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4037    return "fstp%z0\t%y0";
4038  else
4039    return "fst%z0\t%y0";
4040}
4041  [(set_attr "type" "fmov,multi,multi")
4042   (set_attr "unit" "*,i387,i387")
4043   (set_attr "mode" "DF")])
4044
4045(define_insn "*truncxfdf2_i387_1"
4046  [(set (match_operand:DF 0 "memory_operand" "=m")
4047	(float_truncate:DF
4048	  (match_operand:XF 1 "register_operand" "f")))]
4049  "TARGET_80387"
4050{
4051  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4052    return "fstp%z0\t%y0";
4053  else
4054    return "fst%z0\t%y0";
4055}
4056  [(set_attr "type" "fmov")
4057   (set_attr "mode" "DF")])
4058
4059(define_split
4060  [(set (match_operand:DF 0 "register_operand" "")
4061	(float_truncate:DF
4062	 (match_operand:XF 1 "register_operand" "")))
4063   (clobber (match_operand:DF 2 "memory_operand" ""))]
4064  "TARGET_80387 && reload_completed"
4065  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4066   (set (match_dup 0) (match_dup 2))]
4067  "")
4068
4069(define_split
4070  [(set (match_operand:DF 0 "memory_operand" "")
4071	(float_truncate:DF
4072	 (match_operand:XF 1 "register_operand" "")))
4073   (clobber (match_operand:DF 2 "memory_operand" ""))]
4074  "TARGET_80387"
4075  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4076  "")
4077
4078;; Signed conversion to DImode.
4079
4080(define_expand "fix_truncxfdi2"
4081  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4082                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4083	      (clobber (reg:CC FLAGS_REG))])]
4084  "TARGET_80387"
4085{
4086  if (TARGET_FISTTP)
4087   {
4088     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4089     DONE;
4090   }
4091})
4092
4093(define_expand "fix_trunc<mode>di2"
4094  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4095                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4096              (clobber (reg:CC FLAGS_REG))])]
4097  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4098{
4099  if (TARGET_FISTTP
4100      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4101   {
4102     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4103     DONE;
4104   }
4105  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4106   {
4107     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4108     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4109     if (out != operands[0])
4110	emit_move_insn (operands[0], out);
4111     DONE;
4112   }
4113})
4114
4115;; Signed conversion to SImode.
4116
4117(define_expand "fix_truncxfsi2"
4118  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4119                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4120	      (clobber (reg:CC FLAGS_REG))])]
4121  "TARGET_80387"
4122{
4123  if (TARGET_FISTTP)
4124   {
4125     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4126     DONE;
4127   }
4128})
4129
4130(define_expand "fix_trunc<mode>si2"
4131  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4132	           (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4133	      (clobber (reg:CC FLAGS_REG))])]
4134  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4135{
4136  if (TARGET_FISTTP
4137      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4138   {
4139     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4140     DONE;
4141   }
4142  if (SSE_FLOAT_MODE_P (<MODE>mode))
4143   {
4144     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4145     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4146     if (out != operands[0])
4147	emit_move_insn (operands[0], out);
4148     DONE;
4149   }
4150})
4151
4152;; Signed conversion to HImode.
4153
4154(define_expand "fix_trunc<mode>hi2"
4155  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4156	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4157              (clobber (reg:CC FLAGS_REG))])]
4158  "TARGET_80387
4159   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4160{
4161  if (TARGET_FISTTP)
4162   {
4163     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4164     DONE;
4165   }
4166})
4167
4168;; When SSE is available, it is always faster to use it!
4169(define_insn "fix_truncsfdi_sse"
4170  [(set (match_operand:DI 0 "register_operand" "=r,r")
4171	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4172  "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4173  "cvttss2si{q}\t{%1, %0|%0, %1}"
4174  [(set_attr "type" "sseicvt")
4175   (set_attr "mode" "SF")
4176   (set_attr "athlon_decode" "double,vector")
4177   (set_attr "amdfam10_decode" "double,double")])
4178
4179(define_insn "fix_truncdfdi_sse"
4180  [(set (match_operand:DI 0 "register_operand" "=r,r")
4181	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4182  "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4183  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4184  [(set_attr "type" "sseicvt")
4185   (set_attr "mode" "DF")
4186   (set_attr "athlon_decode" "double,vector")
4187   (set_attr "amdfam10_decode" "double,double")])
4188
4189(define_insn "fix_truncsfsi_sse"
4190  [(set (match_operand:SI 0 "register_operand" "=r,r")
4191	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4192  "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4193  "cvttss2si\t{%1, %0|%0, %1}"
4194  [(set_attr "type" "sseicvt")
4195   (set_attr "mode" "DF")
4196   (set_attr "athlon_decode" "double,vector")
4197   (set_attr "amdfam10_decode" "double,double")])
4198
4199(define_insn "fix_truncdfsi_sse"
4200  [(set (match_operand:SI 0 "register_operand" "=r,r")
4201	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4202  "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4203  "cvttsd2si\t{%1, %0|%0, %1}"
4204  [(set_attr "type" "sseicvt")
4205   (set_attr "mode" "DF")
4206   (set_attr "athlon_decode" "double,vector")
4207   (set_attr "amdfam10_decode" "double,double")])
4208
4209;; Avoid vector decoded forms of the instruction.
4210(define_peephole2
4211  [(match_scratch:DF 2 "Y")
4212   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4213	(fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4214  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4215  [(set (match_dup 2) (match_dup 1))
4216   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4217  "")
4218
4219(define_peephole2
4220  [(match_scratch:SF 2 "x")
4221   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4222	(fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4223  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4224  [(set (match_dup 2) (match_dup 1))
4225   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4226  "")
4227
4228(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4229  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4230	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4231  "TARGET_FISTTP
4232   && FLOAT_MODE_P (GET_MODE (operands[1]))
4233   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4234	 && (TARGET_64BIT || <MODE>mode != DImode))
4235	&& TARGET_SSE_MATH)
4236   && !(reload_completed || reload_in_progress)"
4237  "#"
4238  "&& 1"
4239  [(const_int 0)]
4240{
4241  if (memory_operand (operands[0], VOIDmode))
4242    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4243  else
4244    {
4245      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4246      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4247							    operands[1],
4248							    operands[2]));
4249    }
4250  DONE;
4251}
4252  [(set_attr "type" "fisttp")
4253   (set_attr "mode" "<MODE>")])
4254
4255(define_insn "fix_trunc<mode>_i387_fisttp"
4256  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4257	(fix:X87MODEI (match_operand 1 "register_operand" "f")))
4258   (clobber (match_scratch:XF 2 "=&1f"))]
4259  "TARGET_FISTTP
4260   && FLOAT_MODE_P (GET_MODE (operands[1]))
4261   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4262	 && (TARGET_64BIT || <MODE>mode != DImode))
4263	&& TARGET_SSE_MATH)"
4264  "* return output_fix_trunc (insn, operands, 1);"
4265  [(set_attr "type" "fisttp")
4266   (set_attr "mode" "<MODE>")])
4267
4268(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4269  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4270	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4271   (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4272   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4273  "TARGET_FISTTP
4274   && FLOAT_MODE_P (GET_MODE (operands[1]))
4275   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4276	&& (TARGET_64BIT || <MODE>mode != DImode))
4277	&& TARGET_SSE_MATH)"
4278  "#"
4279  [(set_attr "type" "fisttp")
4280   (set_attr "mode" "<MODE>")])
4281
4282(define_split
4283  [(set (match_operand:X87MODEI 0 "register_operand" "")
4284	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4285   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4286   (clobber (match_scratch 3 ""))]
4287  "reload_completed"
4288  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4289	      (clobber (match_dup 3))])
4290   (set (match_dup 0) (match_dup 2))]
4291  "")
4292
4293(define_split
4294  [(set (match_operand:X87MODEI 0 "memory_operand" "")
4295	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4296   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4297   (clobber (match_scratch 3 ""))]
4298  "reload_completed"
4299  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4300	      (clobber (match_dup 3))])]
4301  "")
4302
4303;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4304;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4305;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4306;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4307;; function in i386.c.
4308(define_insn_and_split "*fix_trunc<mode>_i387_1"
4309  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4310	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4311   (clobber (reg:CC FLAGS_REG))]
4312  "TARGET_80387 && !TARGET_FISTTP
4313   && FLOAT_MODE_P (GET_MODE (operands[1]))
4314   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4315	 && (TARGET_64BIT || <MODE>mode != DImode))
4316   && !(reload_completed || reload_in_progress)"
4317  "#"
4318  "&& 1"
4319  [(const_int 0)]
4320{
4321  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4322
4323  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4324  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4325  if (memory_operand (operands[0], VOIDmode))
4326    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4327					 operands[2], operands[3]));
4328  else
4329    {
4330      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4331      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4332						     operands[2], operands[3],
4333						     operands[4]));
4334    }
4335  DONE;
4336}
4337  [(set_attr "type" "fistp")
4338   (set_attr "i387_cw" "trunc")
4339   (set_attr "mode" "<MODE>")])
4340
4341(define_insn "fix_truncdi_i387"
4342  [(set (match_operand:DI 0 "memory_operand" "=m")
4343	(fix:DI (match_operand 1 "register_operand" "f")))
4344   (use (match_operand:HI 2 "memory_operand" "m"))
4345   (use (match_operand:HI 3 "memory_operand" "m"))
4346   (clobber (match_scratch:XF 4 "=&1f"))]
4347  "TARGET_80387 && !TARGET_FISTTP
4348   && FLOAT_MODE_P (GET_MODE (operands[1]))
4349   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4350  "* return output_fix_trunc (insn, operands, 0);"
4351  [(set_attr "type" "fistp")
4352   (set_attr "i387_cw" "trunc")
4353   (set_attr "mode" "DI")])
4354
4355(define_insn "fix_truncdi_i387_with_temp"
4356  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4357	(fix:DI (match_operand 1 "register_operand" "f,f")))
4358   (use (match_operand:HI 2 "memory_operand" "m,m"))
4359   (use (match_operand:HI 3 "memory_operand" "m,m"))
4360   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4361   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4362  "TARGET_80387 && !TARGET_FISTTP
4363   && FLOAT_MODE_P (GET_MODE (operands[1]))
4364   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4365  "#"
4366  [(set_attr "type" "fistp")
4367   (set_attr "i387_cw" "trunc")
4368   (set_attr "mode" "DI")])
4369
4370(define_split 
4371  [(set (match_operand:DI 0 "register_operand" "")
4372	(fix:DI (match_operand 1 "register_operand" "")))
4373   (use (match_operand:HI 2 "memory_operand" ""))
4374   (use (match_operand:HI 3 "memory_operand" ""))
4375   (clobber (match_operand:DI 4 "memory_operand" ""))
4376   (clobber (match_scratch 5 ""))]
4377  "reload_completed"
4378  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4379	      (use (match_dup 2))
4380	      (use (match_dup 3))
4381	      (clobber (match_dup 5))])
4382   (set (match_dup 0) (match_dup 4))]
4383  "")
4384
4385(define_split 
4386  [(set (match_operand:DI 0 "memory_operand" "")
4387	(fix:DI (match_operand 1 "register_operand" "")))
4388   (use (match_operand:HI 2 "memory_operand" ""))
4389   (use (match_operand:HI 3 "memory_operand" ""))
4390   (clobber (match_operand:DI 4 "memory_operand" ""))
4391   (clobber (match_scratch 5 ""))]
4392  "reload_completed"
4393  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4394	      (use (match_dup 2))
4395	      (use (match_dup 3))
4396	      (clobber (match_dup 5))])]
4397  "")
4398
4399(define_insn "fix_trunc<mode>_i387"
4400  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4401	(fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4402   (use (match_operand:HI 2 "memory_operand" "m"))
4403   (use (match_operand:HI 3 "memory_operand" "m"))]
4404  "TARGET_80387 && !TARGET_FISTTP
4405   && FLOAT_MODE_P (GET_MODE (operands[1]))
4406   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4407  "* return output_fix_trunc (insn, operands, 0);"
4408  [(set_attr "type" "fistp")
4409   (set_attr "i387_cw" "trunc")
4410   (set_attr "mode" "<MODE>")])
4411
4412(define_insn "fix_trunc<mode>_i387_with_temp"
4413  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4414	(fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4415   (use (match_operand:HI 2 "memory_operand" "m,m"))
4416   (use (match_operand:HI 3 "memory_operand" "m,m"))
4417   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4418  "TARGET_80387 && !TARGET_FISTTP
4419   && FLOAT_MODE_P (GET_MODE (operands[1]))
4420   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4421  "#"
4422  [(set_attr "type" "fistp")
4423   (set_attr "i387_cw" "trunc")
4424   (set_attr "mode" "<MODE>")])
4425
4426(define_split 
4427  [(set (match_operand:X87MODEI12 0 "register_operand" "")
4428	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4429   (use (match_operand:HI 2 "memory_operand" ""))
4430   (use (match_operand:HI 3 "memory_operand" ""))
4431   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4432  "reload_completed"
4433  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4434	      (use (match_dup 2))
4435	      (use (match_dup 3))])
4436   (set (match_dup 0) (match_dup 4))]
4437  "")
4438
4439(define_split 
4440  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4441	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4442   (use (match_operand:HI 2 "memory_operand" ""))
4443   (use (match_operand:HI 3 "memory_operand" ""))
4444   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4445  "reload_completed"
4446  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4447	      (use (match_dup 2))
4448	      (use (match_dup 3))])]
4449  "")
4450
4451(define_insn "x86_fnstcw_1"
4452  [(set (match_operand:HI 0 "memory_operand" "=m")
4453	(unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4454  "TARGET_80387"
4455  "fnstcw\t%0"
4456  [(set_attr "length" "2")
4457   (set_attr "mode" "HI")
4458   (set_attr "unit" "i387")])
4459
4460(define_insn "x86_fldcw_1"
4461  [(set (reg:HI FPCR_REG)
4462	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4463  "TARGET_80387"
4464  "fldcw\t%0"
4465  [(set_attr "length" "2")
4466   (set_attr "mode" "HI")
4467   (set_attr "unit" "i387")
4468   (set_attr "athlon_decode" "vector")
4469   (set_attr "amdfam10_decode" "vector")])   
4470
4471;; Conversion between fixed point and floating point.
4472
4473;; Even though we only accept memory inputs, the backend _really_
4474;; wants to be able to do this between registers.
4475
4476(define_expand "floathisf2"
4477  [(set (match_operand:SF 0 "register_operand" "")
4478	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4479  "TARGET_80387 || TARGET_SSE_MATH"
4480{
4481  if (TARGET_SSE_MATH)
4482    {
4483      emit_insn (gen_floatsisf2 (operands[0],
4484				 convert_to_mode (SImode, operands[1], 0)));
4485      DONE;
4486    }
4487})
4488
4489(define_insn "*floathisf2_i387"
4490  [(set (match_operand:SF 0 "register_operand" "=f,f")
4491	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4492  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4493  "@
4494   fild%z1\t%1
4495   #"
4496  [(set_attr "type" "fmov,multi")
4497   (set_attr "mode" "SF")
4498   (set_attr "unit" "*,i387")
4499   (set_attr "fp_int_src" "true")])
4500
4501(define_expand "floatsisf2"
4502  [(set (match_operand:SF 0 "register_operand" "")
4503	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4504  "TARGET_80387 || TARGET_SSE_MATH"
4505  "")
4506
4507(define_insn "*floatsisf2_mixed"
4508  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4509	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4510  "TARGET_MIX_SSE_I387"
4511  "@
4512   fild%z1\t%1
4513   #
4514   cvtsi2ss\t{%1, %0|%0, %1}
4515   cvtsi2ss\t{%1, %0|%0, %1}"
4516  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4517   (set_attr "mode" "SF")
4518   (set_attr "unit" "*,i387,*,*")
4519   (set_attr "athlon_decode" "*,*,vector,double")
4520   (set_attr "amdfam10_decode" "*,*,vector,double")
4521   (set_attr "fp_int_src" "true")])
4522
4523(define_insn "*floatsisf2_sse"
4524  [(set (match_operand:SF 0 "register_operand" "=x,x")
4525	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4526  "TARGET_SSE_MATH"
4527  "cvtsi2ss\t{%1, %0|%0, %1}"
4528  [(set_attr "type" "sseicvt")
4529   (set_attr "mode" "SF")
4530   (set_attr "athlon_decode" "vector,double")
4531   (set_attr "amdfam10_decode" "vector,double")
4532   (set_attr "fp_int_src" "true")])
4533
4534(define_insn "*floatsisf2_i387"
4535  [(set (match_operand:SF 0 "register_operand" "=f,f")
4536	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4537  "TARGET_80387"
4538  "@
4539   fild%z1\t%1
4540   #"
4541  [(set_attr "type" "fmov,multi")
4542   (set_attr "mode" "SF")
4543   (set_attr "unit" "*,i387")
4544   (set_attr "fp_int_src" "true")])
4545
4546(define_expand "floatdisf2"
4547  [(set (match_operand:SF 0 "register_operand" "")
4548	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4549  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4550  "")
4551
4552(define_insn "*floatdisf2_mixed"
4553  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4554	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4555  "TARGET_64BIT && TARGET_MIX_SSE_I387"
4556  "@
4557   fild%z1\t%1
4558   #
4559   cvtsi2ss{q}\t{%1, %0|%0, %1}
4560   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4561  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4562   (set_attr "mode" "SF")
4563   (set_attr "unit" "*,i387,*,*")
4564   (set_attr "athlon_decode" "*,*,vector,double")
4565   (set_attr "amdfam10_decode" "*,*,vector,double")
4566   (set_attr "fp_int_src" "true")])
4567
4568(define_insn "*floatdisf2_sse"
4569  [(set (match_operand:SF 0 "register_operand" "=x,x")
4570	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4571  "TARGET_64BIT && TARGET_SSE_MATH"
4572  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4573  [(set_attr "type" "sseicvt")
4574   (set_attr "mode" "SF")
4575   (set_attr "athlon_decode" "vector,double")
4576   (set_attr "amdfam10_decode" "vector,double")
4577   (set_attr "fp_int_src" "true")])
4578
4579(define_insn "*floatdisf2_i387"
4580  [(set (match_operand:SF 0 "register_operand" "=f,f")
4581	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4582  "TARGET_80387"
4583  "@
4584   fild%z1\t%1
4585   #"
4586  [(set_attr "type" "fmov,multi")
4587   (set_attr "mode" "SF")
4588   (set_attr "unit" "*,i387")
4589   (set_attr "fp_int_src" "true")])
4590
4591(define_expand "floathidf2"
4592  [(set (match_operand:DF 0 "register_operand" "")
4593	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4594  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4595{
4596  if (TARGET_SSE2 && TARGET_SSE_MATH)
4597    {
4598      emit_insn (gen_floatsidf2 (operands[0],
4599				 convert_to_mode (SImode, operands[1], 0)));
4600      DONE;
4601    }
4602})
4603
4604(define_insn "*floathidf2_i387"
4605  [(set (match_operand:DF 0 "register_operand" "=f,f")
4606	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4607  "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4608  "@
4609   fild%z1\t%1
4610   #"
4611  [(set_attr "type" "fmov,multi")
4612   (set_attr "mode" "DF")
4613   (set_attr "unit" "*,i387")
4614   (set_attr "fp_int_src" "true")])
4615
4616(define_expand "floatsidf2"
4617  [(set (match_operand:DF 0 "register_operand" "")
4618	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4619  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4620  "")
4621
4622(define_insn "*floatsidf2_mixed"
4623  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4624	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4625  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4626  "@
4627   fild%z1\t%1
4628   #
4629   cvtsi2sd\t{%1, %0|%0, %1}
4630   cvtsi2sd\t{%1, %0|%0, %1}"
4631  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4632   (set_attr "mode" "DF")
4633   (set_attr "unit" "*,i387,*,*")
4634   (set_attr "athlon_decode" "*,*,double,direct")
4635   (set_attr "amdfam10_decode" "*,*,vector,double")
4636   (set_attr "fp_int_src" "true")])
4637
4638(define_insn "*floatsidf2_sse"
4639  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4640	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4641  "TARGET_SSE2 && TARGET_SSE_MATH"
4642  "cvtsi2sd\t{%1, %0|%0, %1}"
4643  [(set_attr "type" "sseicvt")
4644   (set_attr "mode" "DF")
4645   (set_attr "athlon_decode" "double,direct")
4646   (set_attr "amdfam10_decode" "vector,double")
4647   (set_attr "fp_int_src" "true")])
4648
4649(define_insn "*floatsidf2_i387"
4650  [(set (match_operand:DF 0 "register_operand" "=f,f")
4651	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4652  "TARGET_80387"
4653  "@
4654   fild%z1\t%1
4655   #"
4656  [(set_attr "type" "fmov,multi")
4657   (set_attr "mode" "DF")
4658   (set_attr "unit" "*,i387")
4659   (set_attr "fp_int_src" "true")])
4660
4661(define_expand "floatdidf2"
4662  [(set (match_operand:DF 0 "register_operand" "")
4663	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4664  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4665  "")
4666
4667(define_insn "*floatdidf2_mixed"
4668  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4669	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4670  "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4671  "@
4672   fild%z1\t%1
4673   #
4674   cvtsi2sd{q}\t{%1, %0|%0, %1}
4675   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4676  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4677   (set_attr "mode" "DF")
4678   (set_attr "unit" "*,i387,*,*")
4679   (set_attr "athlon_decode" "*,*,double,direct")
4680   (set_attr "amdfam10_decode" "*,*,vector,double")
4681   (set_attr "fp_int_src" "true")])
4682
4683(define_insn "*floatdidf2_sse"
4684  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4685	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4686  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4687  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4688  [(set_attr "type" "sseicvt")
4689   (set_attr "mode" "DF")
4690   (set_attr "athlon_decode" "double,direct")
4691   (set_attr "amdfam10_decode" "vector,double")
4692   (set_attr "fp_int_src" "true")])
4693
4694(define_insn "*floatdidf2_i387"
4695  [(set (match_operand:DF 0 "register_operand" "=f,f")
4696	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4697  "TARGET_80387"
4698  "@
4699   fild%z1\t%1
4700   #"
4701  [(set_attr "type" "fmov,multi")
4702   (set_attr "mode" "DF")
4703   (set_attr "unit" "*,i387")
4704   (set_attr "fp_int_src" "true")])
4705
4706(define_insn "floathixf2"
4707  [(set (match_operand:XF 0 "register_operand" "=f,f")
4708	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4709  "TARGET_80387"
4710  "@
4711   fild%z1\t%1
4712   #"
4713  [(set_attr "type" "fmov,multi")
4714   (set_attr "mode" "XF")
4715   (set_attr "unit" "*,i387")
4716   (set_attr "fp_int_src" "true")])
4717
4718(define_insn "floatsixf2"
4719  [(set (match_operand:XF 0 "register_operand" "=f,f")
4720	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4721  "TARGET_80387"
4722  "@
4723   fild%z1\t%1
4724   #"
4725  [(set_attr "type" "fmov,multi")
4726   (set_attr "mode" "XF")
4727   (set_attr "unit" "*,i387")
4728   (set_attr "fp_int_src" "true")])
4729
4730(define_insn "floatdixf2"
4731  [(set (match_operand:XF 0 "register_operand" "=f,f")
4732	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4733  "TARGET_80387"
4734  "@
4735   fild%z1\t%1
4736   #"
4737  [(set_attr "type" "fmov,multi")
4738   (set_attr "mode" "XF")
4739   (set_attr "unit" "*,i387")
4740   (set_attr "fp_int_src" "true")])
4741
4742;; %%% Kill these when reload knows how to do it.
4743(define_split
4744  [(set (match_operand 0 "fp_register_operand" "")
4745	(float (match_operand 1 "register_operand" "")))]
4746  "reload_completed
4747   && TARGET_80387
4748   && FLOAT_MODE_P (GET_MODE (operands[0]))"
4749  [(const_int 0)]
4750{
4751  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4752  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4753  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4754  ix86_free_from_memory (GET_MODE (operands[1]));
4755  DONE;
4756})
4757
4758(define_expand "floatunssisf2"
4759  [(use (match_operand:SF 0 "register_operand" ""))
4760   (use (match_operand:SI 1 "register_operand" ""))]
4761  "!TARGET_64BIT && TARGET_SSE_MATH"
4762  "x86_emit_floatuns (operands); DONE;")
4763
4764(define_expand "floatunsdisf2"
4765  [(use (match_operand:SF 0 "register_operand" ""))
4766   (use (match_operand:DI 1 "register_operand" ""))]
4767  "TARGET_64BIT && TARGET_SSE_MATH"
4768  "x86_emit_floatuns (operands); DONE;")
4769
4770(define_expand "floatunsdidf2"
4771  [(use (match_operand:DF 0 "register_operand" ""))
4772   (use (match_operand:DI 1 "register_operand" ""))]
4773  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4774  "x86_emit_floatuns (operands); DONE;")
4775
4776;; SSE extract/set expanders
4777
4778
4779;; Add instructions
4780
4781;; %%% splits for addditi3
4782
4783(define_expand "addti3"
4784  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4785	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4786		 (match_operand:TI 2 "x86_64_general_operand" "")))
4787   (clobber (reg:CC FLAGS_REG))]
4788  "TARGET_64BIT"
4789  "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4790
4791(define_insn "*addti3_1"
4792  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4793	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4794		 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4795   (clobber (reg:CC FLAGS_REG))]
4796  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4797  "#")
4798
4799(define_split
4800  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4801	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4802		 (match_operand:TI 2 "x86_64_general_operand" "")))
4803   (clobber (reg:CC FLAGS_REG))]
4804  "TARGET_64BIT && reload_completed"
4805  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4806					  UNSPEC_ADD_CARRY))
4807	      (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4808   (parallel [(set (match_dup 3)
4809		   (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4810				     (match_dup 4))
4811			    (match_dup 5)))
4812	      (clobber (reg:CC FLAGS_REG))])]
4813  "split_ti (operands+0, 1, operands+0, operands+3);
4814   split_ti (operands+1, 1, operands+1, operands+4);
4815   split_ti (operands+2, 1, operands+2, operands+5);")
4816
4817;; %%% splits for addsidi3
4818;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4819;	(plus:DI (match_operand:DI 1 "general_operand" "")
4820;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4821
4822(define_expand "adddi3"
4823  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4824	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4825		 (match_operand:DI 2 "x86_64_general_operand" "")))
4826   (clobber (reg:CC FLAGS_REG))]
4827  ""
4828  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4829
4830(define_insn "*adddi3_1"
4831  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4832	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4833		 (match_operand:DI 2 "general_operand" "roiF,riF")))
4834   (clobber (reg:CC FLAGS_REG))]
4835  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4836  "#")
4837
4838(define_split
4839  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4840	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4841		 (match_operand:DI 2 "general_operand" "")))
4842   (clobber (reg:CC FLAGS_REG))]
4843  "!TARGET_64BIT && reload_completed"
4844  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4845					  UNSPEC_ADD_CARRY))
4846	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4847   (parallel [(set (match_dup 3)
4848		   (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4849				     (match_dup 4))
4850			    (match_dup 5)))
4851	      (clobber (reg:CC FLAGS_REG))])]
4852  "split_di (operands+0, 1, operands+0, operands+3);
4853   split_di (operands+1, 1, operands+1, operands+4);
4854   split_di (operands+2, 1, operands+2, operands+5);")
4855
4856(define_insn "adddi3_carry_rex64"
4857  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4858	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4859			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4860		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4861   (clobber (reg:CC FLAGS_REG))]
4862  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4863  "adc{q}\t{%2, %0|%0, %2}"
4864  [(set_attr "type" "alu")
4865   (set_attr "pent_pair" "pu")
4866   (set_attr "mode" "DI")])
4867
4868(define_insn "*adddi3_cc_rex64"
4869  [(set (reg:CC FLAGS_REG)
4870	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4871		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4872		   UNSPEC_ADD_CARRY))
4873   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4874	(plus:DI (match_dup 1) (match_dup 2)))]
4875  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4876  "add{q}\t{%2, %0|%0, %2}"
4877  [(set_attr "type" "alu")
4878   (set_attr "mode" "DI")])
4879
4880(define_insn "addqi3_carry"
4881  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4882	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4883			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4884		   (match_operand:QI 2 "general_operand" "qi,qm")))
4885   (clobber (reg:CC FLAGS_REG))]
4886  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4887  "adc{b}\t{%2, %0|%0, %2}"
4888  [(set_attr "type" "alu")
4889   (set_attr "pent_pair" "pu")
4890   (set_attr "mode" "QI")])
4891
4892(define_insn "addhi3_carry"
4893  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4894	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4895			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4896		   (match_operand:HI 2 "general_operand" "ri,rm")))
4897   (clobber (reg:CC FLAGS_REG))]
4898  "ix86_binary_operator_ok (PLUS, HImode, operands)"
4899  "adc{w}\t{%2, %0|%0, %2}"
4900  [(set_attr "type" "alu")
4901   (set_attr "pent_pair" "pu")
4902   (set_attr "mode" "HI")])
4903
4904(define_insn "addsi3_carry"
4905  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4906	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4907			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4908		   (match_operand:SI 2 "general_operand" "ri,rm")))
4909   (clobber (reg:CC FLAGS_REG))]
4910  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4911  "adc{l}\t{%2, %0|%0, %2}"
4912  [(set_attr "type" "alu")
4913   (set_attr "pent_pair" "pu")
4914   (set_attr "mode" "SI")])
4915
4916(define_insn "*addsi3_carry_zext"
4917  [(set (match_operand:DI 0 "register_operand" "=r")
4918	  (zero_extend:DI 
4919	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4920			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
4921		     (match_operand:SI 2 "general_operand" "rim"))))
4922   (clobber (reg:CC FLAGS_REG))]
4923  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4924  "adc{l}\t{%2, %k0|%k0, %2}"
4925  [(set_attr "type" "alu")
4926   (set_attr "pent_pair" "pu")
4927   (set_attr "mode" "SI")])
4928
4929(define_insn "*addsi3_cc"
4930  [(set (reg:CC FLAGS_REG)
4931	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4932		    (match_operand:SI 2 "general_operand" "ri,rm")]
4933		   UNSPEC_ADD_CARRY))
4934   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4935	(plus:SI (match_dup 1) (match_dup 2)))]
4936  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4937  "add{l}\t{%2, %0|%0, %2}"
4938  [(set_attr "type" "alu")
4939   (set_attr "mode" "SI")])
4940
4941(define_insn "addqi3_cc"
4942  [(set (reg:CC FLAGS_REG)
4943	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4944		    (match_operand:QI 2 "general_operand" "qi,qm")]
4945		   UNSPEC_ADD_CARRY))
4946   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4947	(plus:QI (match_dup 1) (match_dup 2)))]
4948  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4949  "add{b}\t{%2, %0|%0, %2}"
4950  [(set_attr "type" "alu")
4951   (set_attr "mode" "QI")])
4952
4953(define_expand "addsi3"
4954  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4955		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4956			    (match_operand:SI 2 "general_operand" "")))
4957	      (clobber (reg:CC FLAGS_REG))])]
4958  ""
4959  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4960
4961(define_insn "*lea_1"
4962  [(set (match_operand:SI 0 "register_operand" "=r")
4963	(match_operand:SI 1 "no_seg_address_operand" "p"))]
4964  "!TARGET_64BIT"
4965  "lea{l}\t{%a1, %0|%0, %a1}"
4966  [(set_attr "type" "lea")
4967   (set_attr "mode" "SI")])
4968
4969(define_insn "*lea_1_rex64"
4970  [(set (match_operand:SI 0 "register_operand" "=r")
4971	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4972  "TARGET_64BIT"
4973  "lea{l}\t{%a1, %0|%0, %a1}"
4974  [(set_attr "type" "lea")
4975   (set_attr "mode" "SI")])
4976
4977(define_insn "*lea_1_zext"
4978  [(set (match_operand:DI 0 "register_operand" "=r")
4979	(zero_extend:DI
4980	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4981  "TARGET_64BIT"
4982  "lea{l}\t{%a1, %k0|%k0, %a1}"
4983  [(set_attr "type" "lea")
4984   (set_attr "mode" "SI")])
4985
4986(define_insn "*lea_2_rex64"
4987  [(set (match_operand:DI 0 "register_operand" "=r")
4988	(match_operand:DI 1 "no_seg_address_operand" "p"))]
4989  "TARGET_64BIT"
4990  "lea{q}\t{%a1, %0|%0, %a1}"
4991  [(set_attr "type" "lea")
4992   (set_attr "mode" "DI")])
4993
4994;; The lea patterns for non-Pmodes needs to be matched by several
4995;; insns converted to real lea by splitters.
4996
4997(define_insn_and_split "*lea_general_1"
4998  [(set (match_operand 0 "register_operand" "=r")
4999	(plus (plus (match_operand 1 "index_register_operand" "l")
5000		    (match_operand 2 "register_operand" "r"))
5001	      (match_operand 3 "immediate_operand" "i")))]
5002  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5003    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5004   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5005   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5006   && GET_MODE (operands[0]) == GET_MODE (operands[2])
5007   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5008       || GET_MODE (operands[3]) == VOIDmode)"
5009  "#"
5010  "&& reload_completed"
5011  [(const_int 0)]
5012{
5013  rtx pat;
5014  operands[0] = gen_lowpart (SImode, operands[0]);
5015  operands[1] = gen_lowpart (Pmode, operands[1]);
5016  operands[2] = gen_lowpart (Pmode, operands[2]);
5017  operands[3] = gen_lowpart (Pmode, operands[3]);
5018  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5019  		      operands[3]);
5020  if (Pmode != SImode)
5021    pat = gen_rtx_SUBREG (SImode, pat, 0);
5022  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5023  DONE;
5024}
5025  [(set_attr "type" "lea")
5026   (set_attr "mode" "SI")])
5027
5028(define_insn_and_split "*lea_general_1_zext"
5029  [(set (match_operand:DI 0 "register_operand" "=r")
5030	(zero_extend:DI
5031	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5032			    (match_operand:SI 2 "register_operand" "r"))
5033		   (match_operand:SI 3 "immediate_operand" "i"))))]
5034  "TARGET_64BIT"
5035  "#"
5036  "&& reload_completed"
5037  [(set (match_dup 0)
5038	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5039						     (match_dup 2))
5040					    (match_dup 3)) 0)))]
5041{
5042  operands[1] = gen_lowpart (Pmode, operands[1]);
5043  operands[2] = gen_lowpart (Pmode, operands[2]);
5044  operands[3] = gen_lowpart (Pmode, operands[3]);
5045}
5046  [(set_attr "type" "lea")
5047   (set_attr "mode" "SI")])
5048
5049(define_insn_and_split "*lea_general_2"
5050  [(set (match_operand 0 "register_operand" "=r")
5051	(plus (mult (match_operand 1 "index_register_operand" "l")
5052		    (match_operand 2 "const248_operand" "i"))
5053	      (match_operand 3 "nonmemory_operand" "ri")))]
5054  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5055    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5056   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5057   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5058   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5059       || GET_MODE (operands[3]) == VOIDmode)"
5060  "#"
5061  "&& reload_completed"
5062  [(const_int 0)]
5063{
5064  rtx pat;
5065  operands[0] = gen_lowpart (SImode, operands[0]);
5066  operands[1] = gen_lowpart (Pmode, operands[1]);
5067  operands[3] = gen_lowpart (Pmode, operands[3]);
5068  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5069  		      operands[3]);
5070  if (Pmode != SImode)
5071    pat = gen_rtx_SUBREG (SImode, pat, 0);
5072  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5073  DONE;
5074}
5075  [(set_attr "type" "lea")
5076   (set_attr "mode" "SI")])
5077
5078(define_insn_and_split "*lea_general_2_zext"
5079  [(set (match_operand:DI 0 "register_operand" "=r")
5080	(zero_extend:DI
5081	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5082			    (match_operand:SI 2 "const248_operand" "n"))
5083		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5084  "TARGET_64BIT"
5085  "#"
5086  "&& reload_completed"
5087  [(set (match_dup 0)
5088	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5089						     (match_dup 2))
5090					    (match_dup 3)) 0)))]
5091{
5092  operands[1] = gen_lowpart (Pmode, operands[1]);
5093  operands[3] = gen_lowpart (Pmode, operands[3]);
5094}
5095  [(set_attr "type" "lea")
5096   (set_attr "mode" "SI")])
5097
5098(define_insn_and_split "*lea_general_3"
5099  [(set (match_operand 0 "register_operand" "=r")
5100	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
5101			  (match_operand 2 "const248_operand" "i"))
5102		    (match_operand 3 "register_operand" "r"))
5103	      (match_operand 4 "immediate_operand" "i")))]
5104  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5105    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5106   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5107   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5108   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5109  "#"
5110  "&& reload_completed"
5111  [(const_int 0)]
5112{
5113  rtx pat;
5114  operands[0] = gen_lowpart (SImode, operands[0]);
5115  operands[1] = gen_lowpart (Pmode, operands[1]);
5116  operands[3] = gen_lowpart (Pmode, operands[3]);
5117  operands[4] = gen_lowpart (Pmode, operands[4]);
5118  pat = gen_rtx_PLUS (Pmode,
5119  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5120		      					 operands[2]),
5121				    operands[3]),
5122  		      operands[4]);
5123  if (Pmode != SImode)
5124    pat = gen_rtx_SUBREG (SImode, pat, 0);
5125  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5126  DONE;
5127}
5128  [(set_attr "type" "lea")
5129   (set_attr "mode" "SI")])
5130
5131(define_insn_and_split "*lea_general_3_zext"
5132  [(set (match_operand:DI 0 "register_operand" "=r")
5133	(zero_extend:DI
5134	  (plus:SI (plus:SI (mult:SI
5135			      (match_operand:SI 1 "index_register_operand" "l")
5136			      (match_operand:SI 2 "const248_operand" "n"))
5137			    (match_operand:SI 3 "register_operand" "r"))
5138		   (match_operand:SI 4 "immediate_operand" "i"))))]
5139  "TARGET_64BIT"
5140  "#"
5141  "&& reload_completed"
5142  [(set (match_dup 0)
5143	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5144							      (match_dup 2))
5145						     (match_dup 3))
5146					    (match_dup 4)) 0)))]
5147{
5148  operands[1] = gen_lowpart (Pmode, operands[1]);
5149  operands[3] = gen_lowpart (Pmode, operands[3]);
5150  operands[4] = gen_lowpart (Pmode, operands[4]);
5151}
5152  [(set_attr "type" "lea")
5153   (set_attr "mode" "SI")])
5154
5155(define_insn "*adddi_1_rex64"
5156  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5157	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5158		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5159   (clobber (reg:CC FLAGS_REG))]
5160  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5161{
5162  switch (get_attr_type (insn))
5163    {
5164    case TYPE_LEA:
5165      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5166      return "lea{q}\t{%a2, %0|%0, %a2}";
5167
5168    case TYPE_INCDEC:
5169      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5170      if (operands[2] == const1_rtx)
5171        return "inc{q}\t%0";
5172      else
5173        {
5174	  gcc_assert (operands[2] == constm1_rtx);
5175          return "dec{q}\t%0";
5176	}
5177
5178    default:
5179      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5180
5181      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5183      if (GET_CODE (operands[2]) == CONST_INT
5184	  /* Avoid overflows.  */
5185	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186          && (INTVAL (operands[2]) == 128
5187	      || (INTVAL (operands[2]) < 0
5188		  && INTVAL (operands[2]) != -128)))
5189        {
5190          operands[2] = GEN_INT (-INTVAL (operands[2]));
5191          return "sub{q}\t{%2, %0|%0, %2}";
5192        }
5193      return "add{q}\t{%2, %0|%0, %2}";
5194    }
5195}
5196  [(set (attr "type")
5197     (cond [(eq_attr "alternative" "2")
5198	      (const_string "lea")
5199	    ; Current assemblers are broken and do not allow @GOTOFF in
5200	    ; ought but a memory context.
5201	    (match_operand:DI 2 "pic_symbolic_operand" "")
5202	      (const_string "lea")
5203	    (match_operand:DI 2 "incdec_operand" "")
5204	      (const_string "incdec")
5205	   ]
5206	   (const_string "alu")))
5207   (set_attr "mode" "DI")])
5208
5209;; Convert lea to the lea pattern to avoid flags dependency.
5210(define_split
5211  [(set (match_operand:DI 0 "register_operand" "")
5212	(plus:DI (match_operand:DI 1 "register_operand" "")
5213		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5214   (clobber (reg:CC FLAGS_REG))]
5215  "TARGET_64BIT && reload_completed
5216   && true_regnum (operands[0]) != true_regnum (operands[1])"
5217  [(set (match_dup 0)
5218	(plus:DI (match_dup 1)
5219		 (match_dup 2)))]
5220  "")
5221
5222(define_insn "*adddi_2_rex64"
5223  [(set (reg FLAGS_REG)
5224	(compare
5225	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5226		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5227	  (const_int 0)))			
5228   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5229	(plus:DI (match_dup 1) (match_dup 2)))]
5230  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5231   && ix86_binary_operator_ok (PLUS, DImode, operands)
5232   /* Current assemblers are broken and do not allow @GOTOFF in
5233      ought but a memory context.  */
5234   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5235{
5236  switch (get_attr_type (insn))
5237    {
5238    case TYPE_INCDEC:
5239      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5240      if (operands[2] == const1_rtx)
5241        return "inc{q}\t%0";
5242      else
5243        {
5244	  gcc_assert (operands[2] == constm1_rtx);
5245          return "dec{q}\t%0";
5246	}
5247
5248    default:
5249      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5250      /* ???? We ought to handle there the 32bit case too
5251	 - do we need new constraint?  */
5252      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5253	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5254      if (GET_CODE (operands[2]) == CONST_INT
5255	  /* Avoid overflows.  */
5256	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5257          && (INTVAL (operands[2]) == 128
5258	      || (INTVAL (operands[2]) < 0
5259		  && INTVAL (operands[2]) != -128)))
5260        {
5261          operands[2] = GEN_INT (-INTVAL (operands[2]));
5262          return "sub{q}\t{%2, %0|%0, %2}";
5263        }
5264      return "add{q}\t{%2, %0|%0, %2}";
5265    }
5266}
5267  [(set (attr "type")
5268     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5269	(const_string "incdec")
5270	(const_string "alu")))
5271   (set_attr "mode" "DI")])
5272
5273(define_insn "*adddi_3_rex64"
5274  [(set (reg FLAGS_REG)
5275	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5276		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5277   (clobber (match_scratch:DI 0 "=r"))]
5278  "TARGET_64BIT
5279   && ix86_match_ccmode (insn, CCZmode)
5280   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5281   /* Current assemblers are broken and do not allow @GOTOFF in
5282      ought but a memory context.  */
5283   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5284{
5285  switch (get_attr_type (insn))
5286    {
5287    case TYPE_INCDEC:
5288      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5289      if (operands[2] == const1_rtx)
5290        return "inc{q}\t%0";
5291      else
5292        {
5293	  gcc_assert (operands[2] == constm1_rtx);
5294          return "dec{q}\t%0";
5295	}
5296
5297    default:
5298      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5299      /* ???? We ought to handle there the 32bit case too
5300	 - do we need new constraint?  */
5301      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5302	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5303      if (GET_CODE (operands[2]) == CONST_INT
5304	  /* Avoid overflows.  */
5305	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5306          && (INTVAL (operands[2]) == 128
5307	      || (INTVAL (operands[2]) < 0
5308		  && INTVAL (operands[2]) != -128)))
5309        {
5310          operands[2] = GEN_INT (-INTVAL (operands[2]));
5311          return "sub{q}\t{%2, %0|%0, %2}";
5312        }
5313      return "add{q}\t{%2, %0|%0, %2}";
5314    }
5315}
5316  [(set (attr "type")
5317     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5318	(const_string "incdec")
5319	(const_string "alu")))
5320   (set_attr "mode" "DI")])
5321
5322; For comparisons against 1, -1 and 128, we may generate better code
5323; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5324; is matched then.  We can't accept general immediate, because for
5325; case of overflows,  the result is messed up.
5326; This pattern also don't hold of 0x8000000000000000, since the value overflows
5327; when negated.
5328; Also carry flag is reversed compared to cmp, so this conversion is valid
5329; only for comparisons not depending on it.
5330(define_insn "*adddi_4_rex64"
5331  [(set (reg FLAGS_REG)
5332	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5333		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5334   (clobber (match_scratch:DI 0 "=rm"))]
5335  "TARGET_64BIT
5336   &&  ix86_match_ccmode (insn, CCGCmode)"
5337{
5338  switch (get_attr_type (insn))
5339    {
5340    case TYPE_INCDEC:
5341      if (operands[2] == constm1_rtx)
5342        return "inc{q}\t%0";
5343      else
5344        {
5345	  gcc_assert (operands[2] == const1_rtx);
5346          return "dec{q}\t%0";
5347	}
5348
5349    default:
5350      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5351      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5352	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5353      if ((INTVAL (operands[2]) == -128
5354	   || (INTVAL (operands[2]) > 0
5355	       && INTVAL (operands[2]) != 128))
5356	  /* Avoid overflows.  */
5357	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5358	return "sub{q}\t{%2, %0|%0, %2}";
5359      operands[2] = GEN_INT (-INTVAL (operands[2]));
5360      return "add{q}\t{%2, %0|%0, %2}";
5361    }
5362}
5363  [(set (attr "type")
5364     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5365	(const_string "incdec")
5366	(const_string "alu")))
5367   (set_attr "mode" "DI")])
5368
5369(define_insn "*adddi_5_rex64"
5370  [(set (reg FLAGS_REG)
5371	(compare
5372	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5373		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5374	  (const_int 0)))			
5375   (clobber (match_scratch:DI 0 "=r"))]
5376  "TARGET_64BIT
5377   && ix86_match_ccmode (insn, CCGOCmode)
5378   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5379   /* Current assemblers are broken and do not allow @GOTOFF in
5380      ought but a memory context.  */
5381   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5382{
5383  switch (get_attr_type (insn))
5384    {
5385    case TYPE_INCDEC:
5386      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5387      if (operands[2] == const1_rtx)
5388        return "inc{q}\t%0";
5389      else
5390        {
5391          gcc_assert (operands[2] == constm1_rtx);
5392          return "dec{q}\t%0";
5393	}
5394
5395    default:
5396      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5397      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5398	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5399      if (GET_CODE (operands[2]) == CONST_INT
5400	  /* Avoid overflows.  */
5401	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5402          && (INTVAL (operands[2]) == 128
5403	      || (INTVAL (operands[2]) < 0
5404		  && INTVAL (operands[2]) != -128)))
5405        {
5406          operands[2] = GEN_INT (-INTVAL (operands[2]));
5407          return "sub{q}\t{%2, %0|%0, %2}";
5408        }
5409      return "add{q}\t{%2, %0|%0, %2}";
5410    }
5411}
5412  [(set (attr "type")
5413     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5414	(const_string "incdec")
5415	(const_string "alu")))
5416   (set_attr "mode" "DI")])
5417
5418
5419(define_insn "*addsi_1"
5420  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5421	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5422		 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5423   (clobber (reg:CC FLAGS_REG))]
5424  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5425{
5426  switch (get_attr_type (insn))
5427    {
5428    case TYPE_LEA:
5429      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5430      return "lea{l}\t{%a2, %0|%0, %a2}";
5431
5432    case TYPE_INCDEC:
5433      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5434      if (operands[2] == const1_rtx)
5435        return "inc{l}\t%0";
5436      else
5437	{
5438  	  gcc_assert (operands[2] == constm1_rtx);
5439          return "dec{l}\t%0";
5440	}
5441
5442    default:
5443      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5444
5445      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5446	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5447      if (GET_CODE (operands[2]) == CONST_INT
5448          && (INTVAL (operands[2]) == 128
5449	      || (INTVAL (operands[2]) < 0
5450		  && INTVAL (operands[2]) != -128)))
5451        {
5452          operands[2] = GEN_INT (-INTVAL (operands[2]));
5453          return "sub{l}\t{%2, %0|%0, %2}";
5454        }
5455      return "add{l}\t{%2, %0|%0, %2}";
5456    }
5457}
5458  [(set (attr "type")
5459     (cond [(eq_attr "alternative" "2")
5460	      (const_string "lea")
5461	    ; Current assemblers are broken and do not allow @GOTOFF in
5462	    ; ought but a memory context.
5463	    (match_operand:SI 2 "pic_symbolic_operand" "")
5464	      (const_string "lea")
5465	    (match_operand:SI 2 "incdec_operand" "")
5466	      (const_string "incdec")
5467	   ]
5468	   (const_string "alu")))
5469   (set_attr "mode" "SI")])
5470
5471;; Convert lea to the lea pattern to avoid flags dependency.
5472(define_split
5473  [(set (match_operand 0 "register_operand" "")
5474	(plus (match_operand 1 "register_operand" "")
5475              (match_operand 2 "nonmemory_operand" "")))
5476   (clobber (reg:CC FLAGS_REG))]
5477  "reload_completed
5478   && true_regnum (operands[0]) != true_regnum (operands[1])"
5479  [(const_int 0)]
5480{
5481  rtx pat;
5482  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5483     may confuse gen_lowpart.  */
5484  if (GET_MODE (operands[0]) != Pmode)
5485    {
5486      operands[1] = gen_lowpart (Pmode, operands[1]);
5487      operands[2] = gen_lowpart (Pmode, operands[2]);
5488    }
5489  operands[0] = gen_lowpart (SImode, operands[0]);
5490  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5491  if (Pmode != SImode)
5492    pat = gen_rtx_SUBREG (SImode, pat, 0);
5493  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5494  DONE;
5495})
5496
5497;; It may seem that nonimmediate operand is proper one for operand 1.
5498;; The addsi_1 pattern allows nonimmediate operand at that place and
5499;; we take care in ix86_binary_operator_ok to not allow two memory
5500;; operands so proper swapping will be done in reload.  This allow
5501;; patterns constructed from addsi_1 to match.
5502(define_insn "addsi_1_zext"
5503  [(set (match_operand:DI 0 "register_operand" "=r,r")
5504	(zero_extend:DI
5505	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5506		   (match_operand:SI 2 "general_operand" "rmni,lni"))))
5507   (clobber (reg:CC FLAGS_REG))]
5508  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5509{
5510  switch (get_attr_type (insn))
5511    {
5512    case TYPE_LEA:
5513      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5514      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5515
5516    case TYPE_INCDEC:
5517      if (operands[2] == const1_rtx)
5518        return "inc{l}\t%k0";
5519      else
5520        {
5521	  gcc_assert (operands[2] == constm1_rtx);
5522          return "dec{l}\t%k0";
5523	}
5524
5525    default:
5526      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5527	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5528      if (GET_CODE (operands[2]) == CONST_INT
5529          && (INTVAL (operands[2]) == 128
5530	      || (INTVAL (operands[2]) < 0
5531		  && INTVAL (operands[2]) != -128)))
5532        {
5533          operands[2] = GEN_INT (-INTVAL (operands[2]));
5534          return "sub{l}\t{%2, %k0|%k0, %2}";
5535        }
5536      return "add{l}\t{%2, %k0|%k0, %2}";
5537    }
5538}
5539  [(set (attr "type")
5540     (cond [(eq_attr "alternative" "1")
5541	      (const_string "lea")
5542	    ; Current assemblers are broken and do not allow @GOTOFF in
5543	    ; ought but a memory context.
5544	    (match_operand:SI 2 "pic_symbolic_operand" "")
5545	      (const_string "lea")
5546	    (match_operand:SI 2 "incdec_operand" "")
5547	      (const_string "incdec")
5548	   ]
5549	   (const_string "alu")))
5550   (set_attr "mode" "SI")])
5551
5552;; Convert lea to the lea pattern to avoid flags dependency.
5553(define_split
5554  [(set (match_operand:DI 0 "register_operand" "")
5555	(zero_extend:DI
5556	  (plus:SI (match_operand:SI 1 "register_operand" "")
5557		   (match_operand:SI 2 "nonmemory_operand" ""))))
5558   (clobber (reg:CC FLAGS_REG))]
5559  "TARGET_64BIT && reload_completed
5560   && true_regnum (operands[0]) != true_regnum (operands[1])"
5561  [(set (match_dup 0)
5562	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5563{
5564  operands[1] = gen_lowpart (Pmode, operands[1]);
5565  operands[2] = gen_lowpart (Pmode, operands[2]);
5566})
5567
5568(define_insn "*addsi_2"
5569  [(set (reg FLAGS_REG)
5570	(compare
5571	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5572		   (match_operand:SI 2 "general_operand" "rmni,rni"))
5573	  (const_int 0)))			
5574   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5575	(plus:SI (match_dup 1) (match_dup 2)))]
5576  "ix86_match_ccmode (insn, CCGOCmode)
5577   && ix86_binary_operator_ok (PLUS, SImode, operands)
5578   /* Current assemblers are broken and do not allow @GOTOFF in
5579      ought but a memory context.  */
5580   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5581{
5582  switch (get_attr_type (insn))
5583    {
5584    case TYPE_INCDEC:
5585      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5586      if (operands[2] == const1_rtx)
5587        return "inc{l}\t%0";
5588      else
5589        {
5590	  gcc_assert (operands[2] == constm1_rtx);
5591          return "dec{l}\t%0";
5592	}
5593
5594    default:
5595      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5596      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5597	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5598      if (GET_CODE (operands[2]) == CONST_INT
5599          && (INTVAL (operands[2]) == 128
5600	      || (INTVAL (operands[2]) < 0
5601		  && INTVAL (operands[2]) != -128)))
5602        {
5603          operands[2] = GEN_INT (-INTVAL (operands[2]));
5604          return "sub{l}\t{%2, %0|%0, %2}";
5605        }
5606      return "add{l}\t{%2, %0|%0, %2}";
5607    }
5608}
5609  [(set (attr "type")
5610     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5611	(const_string "incdec")
5612	(const_string "alu")))
5613   (set_attr "mode" "SI")])
5614
5615;; See comment for addsi_1_zext why we do use nonimmediate_operand
5616(define_insn "*addsi_2_zext"
5617  [(set (reg FLAGS_REG)
5618	(compare
5619	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5620		   (match_operand:SI 2 "general_operand" "rmni"))
5621	  (const_int 0)))			
5622   (set (match_operand:DI 0 "register_operand" "=r")
5623	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5624  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5625   && ix86_binary_operator_ok (PLUS, SImode, operands)
5626   /* Current assemblers are broken and do not allow @GOTOFF in
5627      ought but a memory context.  */
5628   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629{
5630  switch (get_attr_type (insn))
5631    {
5632    case TYPE_INCDEC:
5633      if (operands[2] == const1_rtx)
5634        return "inc{l}\t%k0";
5635      else
5636	{
5637	  gcc_assert (operands[2] == constm1_rtx);
5638          return "dec{l}\t%k0";
5639	}
5640
5641    default:
5642      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5643	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5644      if (GET_CODE (operands[2]) == CONST_INT
5645          && (INTVAL (operands[2]) == 128
5646	      || (INTVAL (operands[2]) < 0
5647		  && INTVAL (operands[2]) != -128)))
5648        {
5649          operands[2] = GEN_INT (-INTVAL (operands[2]));
5650          return "sub{l}\t{%2, %k0|%k0, %2}";
5651        }
5652      return "add{l}\t{%2, %k0|%k0, %2}";
5653    }
5654}
5655  [(set (attr "type")
5656     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5657	(const_string "incdec")
5658	(const_string "alu")))
5659   (set_attr "mode" "SI")])
5660
5661(define_insn "*addsi_3"
5662  [(set (reg FLAGS_REG)
5663	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5664		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5665   (clobber (match_scratch:SI 0 "=r"))]
5666  "ix86_match_ccmode (insn, CCZmode)
5667   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5668   /* Current assemblers are broken and do not allow @GOTOFF in
5669      ought but a memory context.  */
5670   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5671{
5672  switch (get_attr_type (insn))
5673    {
5674    case TYPE_INCDEC:
5675      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5676      if (operands[2] == const1_rtx)
5677        return "inc{l}\t%0";
5678      else
5679        {
5680	  gcc_assert (operands[2] == constm1_rtx);
5681          return "dec{l}\t%0";
5682	}
5683
5684    default:
5685      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5686      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5687	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5688      if (GET_CODE (operands[2]) == CONST_INT
5689          && (INTVAL (operands[2]) == 128
5690	      || (INTVAL (operands[2]) < 0
5691		  && INTVAL (operands[2]) != -128)))
5692        {
5693          operands[2] = GEN_INT (-INTVAL (operands[2]));
5694          return "sub{l}\t{%2, %0|%0, %2}";
5695        }
5696      return "add{l}\t{%2, %0|%0, %2}";
5697    }
5698}
5699  [(set (attr "type")
5700     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5701	(const_string "incdec")
5702	(const_string "alu")))
5703   (set_attr "mode" "SI")])
5704
5705;; See comment for addsi_1_zext why we do use nonimmediate_operand
5706(define_insn "*addsi_3_zext"
5707  [(set (reg FLAGS_REG)
5708	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5709		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5710   (set (match_operand:DI 0 "register_operand" "=r")
5711	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5712  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5713   && ix86_binary_operator_ok (PLUS, SImode, operands)
5714   /* Current assemblers are broken and do not allow @GOTOFF in
5715      ought but a memory context.  */
5716   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5717{
5718  switch (get_attr_type (insn))
5719    {
5720    case TYPE_INCDEC:
5721      if (operands[2] == const1_rtx)
5722        return "inc{l}\t%k0";
5723      else
5724        {
5725	  gcc_assert (operands[2] == constm1_rtx);
5726          return "dec{l}\t%k0";
5727	}
5728
5729    default:
5730      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5731	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5732      if (GET_CODE (operands[2]) == CONST_INT
5733          && (INTVAL (operands[2]) == 128
5734	      || (INTVAL (operands[2]) < 0
5735		  && INTVAL (operands[2]) != -128)))
5736        {
5737          operands[2] = GEN_INT (-INTVAL (operands[2]));
5738          return "sub{l}\t{%2, %k0|%k0, %2}";
5739        }
5740      return "add{l}\t{%2, %k0|%k0, %2}";
5741    }
5742}
5743  [(set (attr "type")
5744     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5745	(const_string "incdec")
5746	(const_string "alu")))
5747   (set_attr "mode" "SI")])
5748
5749; For comparisons against 1, -1 and 128, we may generate better code
5750; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5751; is matched then.  We can't accept general immediate, because for
5752; case of overflows,  the result is messed up.
5753; This pattern also don't hold of 0x80000000, since the value overflows
5754; when negated.
5755; Also carry flag is reversed compared to cmp, so this conversion is valid
5756; only for comparisons not depending on it.
5757(define_insn "*addsi_4"
5758  [(set (reg FLAGS_REG)
5759	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
5760		 (match_operand:SI 2 "const_int_operand" "n")))
5761   (clobber (match_scratch:SI 0 "=rm"))]
5762  "ix86_match_ccmode (insn, CCGCmode)
5763   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5764{
5765  switch (get_attr_type (insn))
5766    {
5767    case TYPE_INCDEC:
5768      if (operands[2] == constm1_rtx)
5769        return "inc{l}\t%0";
5770      else
5771        {
5772	  gcc_assert (operands[2] == const1_rtx);
5773          return "dec{l}\t%0";
5774	}
5775
5776    default:
5777      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5779	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5780      if ((INTVAL (operands[2]) == -128
5781	   || (INTVAL (operands[2]) > 0
5782	       && INTVAL (operands[2]) != 128)))
5783	return "sub{l}\t{%2, %0|%0, %2}";
5784      operands[2] = GEN_INT (-INTVAL (operands[2]));
5785      return "add{l}\t{%2, %0|%0, %2}";
5786    }
5787}
5788  [(set (attr "type")
5789     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5790	(const_string "incdec")
5791	(const_string "alu")))
5792   (set_attr "mode" "SI")])
5793
5794(define_insn "*addsi_5"
5795  [(set (reg FLAGS_REG)
5796	(compare
5797	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5798		   (match_operand:SI 2 "general_operand" "rmni"))
5799	  (const_int 0)))			
5800   (clobber (match_scratch:SI 0 "=r"))]
5801  "ix86_match_ccmode (insn, CCGOCmode)
5802   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5803   /* Current assemblers are broken and do not allow @GOTOFF in
5804      ought but a memory context.  */
5805   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5806{
5807  switch (get_attr_type (insn))
5808    {
5809    case TYPE_INCDEC:
5810      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5811      if (operands[2] == const1_rtx)
5812        return "inc{l}\t%0";
5813      else
5814        {
5815	  gcc_assert (operands[2] == constm1_rtx);
5816          return "dec{l}\t%0";
5817	}
5818
5819    default:
5820      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5821      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5822	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5823      if (GET_CODE (operands[2]) == CONST_INT
5824          && (INTVAL (operands[2]) == 128
5825	      || (INTVAL (operands[2]) < 0
5826		  && INTVAL (operands[2]) != -128)))
5827        {
5828          operands[2] = GEN_INT (-INTVAL (operands[2]));
5829          return "sub{l}\t{%2, %0|%0, %2}";
5830        }
5831      return "add{l}\t{%2, %0|%0, %2}";
5832    }
5833}
5834  [(set (attr "type")
5835     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5836	(const_string "incdec")
5837	(const_string "alu")))
5838   (set_attr "mode" "SI")])
5839
5840(define_expand "addhi3"
5841  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5842		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5843			    (match_operand:HI 2 "general_operand" "")))
5844	      (clobber (reg:CC FLAGS_REG))])]
5845  "TARGET_HIMODE_MATH"
5846  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5847
5848;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5849;; type optimizations enabled by define-splits.  This is not important
5850;; for PII, and in fact harmful because of partial register stalls.
5851
5852(define_insn "*addhi_1_lea"
5853  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5854	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5855		 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5856   (clobber (reg:CC FLAGS_REG))]
5857  "!TARGET_PARTIAL_REG_STALL
5858   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5859{
5860  switch (get_attr_type (insn))
5861    {
5862    case TYPE_LEA:
5863      return "#";
5864    case TYPE_INCDEC:
5865      if (operands[2] == const1_rtx)
5866	return "inc{w}\t%0";
5867      else
5868	{
5869	  gcc_assert (operands[2] == constm1_rtx);
5870	  return "dec{w}\t%0";
5871	}
5872
5873    default:
5874      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5875	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5876      if (GET_CODE (operands[2]) == CONST_INT
5877          && (INTVAL (operands[2]) == 128
5878	      || (INTVAL (operands[2]) < 0
5879		  && INTVAL (operands[2]) != -128)))
5880	{
5881	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5882	  return "sub{w}\t{%2, %0|%0, %2}";
5883	}
5884      return "add{w}\t{%2, %0|%0, %2}";
5885    }
5886}
5887  [(set (attr "type")
5888     (if_then_else (eq_attr "alternative" "2")
5889	(const_string "lea")
5890	(if_then_else (match_operand:HI 2 "incdec_operand" "")
5891	   (const_string "incdec")
5892	   (const_string "alu"))))
5893   (set_attr "mode" "HI,HI,SI")])
5894
5895(define_insn "*addhi_1"
5896  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5897	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5898		 (match_operand:HI 2 "general_operand" "ri,rm")))
5899   (clobber (reg:CC FLAGS_REG))]
5900  "TARGET_PARTIAL_REG_STALL
5901   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5902{
5903  switch (get_attr_type (insn))
5904    {
5905    case TYPE_INCDEC:
5906      if (operands[2] == const1_rtx)
5907	return "inc{w}\t%0";
5908      else
5909        {
5910	  gcc_assert (operands[2] == constm1_rtx);
5911	  return "dec{w}\t%0";
5912	}
5913
5914    default:
5915      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5917      if (GET_CODE (operands[2]) == CONST_INT
5918          && (INTVAL (operands[2]) == 128
5919	      || (INTVAL (operands[2]) < 0
5920		  && INTVAL (operands[2]) != -128)))
5921	{
5922	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5923	  return "sub{w}\t{%2, %0|%0, %2}";
5924	}
5925      return "add{w}\t{%2, %0|%0, %2}";
5926    }
5927}
5928  [(set (attr "type")
5929     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930	(const_string "incdec")
5931	(const_string "alu")))
5932   (set_attr "mode" "HI")])
5933
5934(define_insn "*addhi_2"
5935  [(set (reg FLAGS_REG)
5936	(compare
5937	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5938		   (match_operand:HI 2 "general_operand" "rmni,rni"))
5939	  (const_int 0)))			
5940   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5941	(plus:HI (match_dup 1) (match_dup 2)))]
5942  "ix86_match_ccmode (insn, CCGOCmode)
5943   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5944{
5945  switch (get_attr_type (insn))
5946    {
5947    case TYPE_INCDEC:
5948      if (operands[2] == const1_rtx)
5949	return "inc{w}\t%0";
5950      else
5951        {
5952	  gcc_assert (operands[2] == constm1_rtx);
5953	  return "dec{w}\t%0";
5954	}
5955
5956    default:
5957      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5958	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5959      if (GET_CODE (operands[2]) == CONST_INT
5960          && (INTVAL (operands[2]) == 128
5961	      || (INTVAL (operands[2]) < 0
5962		  && INTVAL (operands[2]) != -128)))
5963	{
5964	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5965	  return "sub{w}\t{%2, %0|%0, %2}";
5966	}
5967      return "add{w}\t{%2, %0|%0, %2}";
5968    }
5969}
5970  [(set (attr "type")
5971     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5972	(const_string "incdec")
5973	(const_string "alu")))
5974   (set_attr "mode" "HI")])
5975
5976(define_insn "*addhi_3"
5977  [(set (reg FLAGS_REG)
5978	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5979		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5980   (clobber (match_scratch:HI 0 "=r"))]
5981  "ix86_match_ccmode (insn, CCZmode)
5982   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5983{
5984  switch (get_attr_type (insn))
5985    {
5986    case TYPE_INCDEC:
5987      if (operands[2] == const1_rtx)
5988	return "inc{w}\t%0";
5989      else
5990        {
5991	  gcc_assert (operands[2] == constm1_rtx);
5992	  return "dec{w}\t%0";
5993	}
5994
5995    default:
5996      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5997	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5998      if (GET_CODE (operands[2]) == CONST_INT
5999          && (INTVAL (operands[2]) == 128
6000	      || (INTVAL (operands[2]) < 0
6001		  && INTVAL (operands[2]) != -128)))
6002	{
6003	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6004	  return "sub{w}\t{%2, %0|%0, %2}";
6005	}
6006      return "add{w}\t{%2, %0|%0, %2}";
6007    }
6008}
6009  [(set (attr "type")
6010     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6011	(const_string "incdec")
6012	(const_string "alu")))
6013   (set_attr "mode" "HI")])
6014
6015; See comments above addsi_4 for details.
6016(define_insn "*addhi_4"
6017  [(set (reg FLAGS_REG)
6018	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
6019		 (match_operand:HI 2 "const_int_operand" "n")))
6020   (clobber (match_scratch:HI 0 "=rm"))]
6021  "ix86_match_ccmode (insn, CCGCmode)
6022   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6023{
6024  switch (get_attr_type (insn))
6025    {
6026    case TYPE_INCDEC:
6027      if (operands[2] == constm1_rtx)
6028        return "inc{w}\t%0";
6029      else
6030	{
6031	  gcc_assert (operands[2] == const1_rtx);
6032          return "dec{w}\t%0";
6033	}
6034
6035    default:
6036      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6037      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6038	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6039      if ((INTVAL (operands[2]) == -128
6040	   || (INTVAL (operands[2]) > 0
6041	       && INTVAL (operands[2]) != 128)))
6042	return "sub{w}\t{%2, %0|%0, %2}";
6043      operands[2] = GEN_INT (-INTVAL (operands[2]));
6044      return "add{w}\t{%2, %0|%0, %2}";
6045    }
6046}
6047  [(set (attr "type")
6048     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049	(const_string "incdec")
6050	(const_string "alu")))
6051   (set_attr "mode" "SI")])
6052
6053
6054(define_insn "*addhi_5"
6055  [(set (reg FLAGS_REG)
6056	(compare
6057	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6058		   (match_operand:HI 2 "general_operand" "rmni"))
6059	  (const_int 0)))			
6060   (clobber (match_scratch:HI 0 "=r"))]
6061  "ix86_match_ccmode (insn, CCGOCmode)
6062   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6063{
6064  switch (get_attr_type (insn))
6065    {
6066    case TYPE_INCDEC:
6067      if (operands[2] == const1_rtx)
6068	return "inc{w}\t%0";
6069      else
6070	{
6071	  gcc_assert (operands[2] == constm1_rtx);
6072	  return "dec{w}\t%0";
6073	}
6074
6075    default:
6076      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6077	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6078      if (GET_CODE (operands[2]) == CONST_INT
6079          && (INTVAL (operands[2]) == 128
6080	      || (INTVAL (operands[2]) < 0
6081		  && INTVAL (operands[2]) != -128)))
6082	{
6083	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6084	  return "sub{w}\t{%2, %0|%0, %2}";
6085	}
6086      return "add{w}\t{%2, %0|%0, %2}";
6087    }
6088}
6089  [(set (attr "type")
6090     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6091	(const_string "incdec")
6092	(const_string "alu")))
6093   (set_attr "mode" "HI")])
6094
6095(define_expand "addqi3"
6096  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6097		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6098			    (match_operand:QI 2 "general_operand" "")))
6099	      (clobber (reg:CC FLAGS_REG))])]
6100  "TARGET_QIMODE_MATH"
6101  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6102
6103;; %%% Potential partial reg stall on alternative 2.  What to do?
6104(define_insn "*addqi_1_lea"
6105  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6106	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6107		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6108   (clobber (reg:CC FLAGS_REG))]
6109  "!TARGET_PARTIAL_REG_STALL
6110   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6111{
6112  int widen = (which_alternative == 2);
6113  switch (get_attr_type (insn))
6114    {
6115    case TYPE_LEA:
6116      return "#";
6117    case TYPE_INCDEC:
6118      if (operands[2] == const1_rtx)
6119	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6120      else
6121	{
6122	  gcc_assert (operands[2] == constm1_rtx);
6123	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6124	}
6125
6126    default:
6127      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6128	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6129      if (GET_CODE (operands[2]) == CONST_INT
6130          && (INTVAL (operands[2]) == 128
6131	      || (INTVAL (operands[2]) < 0
6132		  && INTVAL (operands[2]) != -128)))
6133	{
6134	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6135	  if (widen)
6136	    return "sub{l}\t{%2, %k0|%k0, %2}";
6137	  else
6138	    return "sub{b}\t{%2, %0|%0, %2}";
6139	}
6140      if (widen)
6141        return "add{l}\t{%k2, %k0|%k0, %k2}";
6142      else
6143        return "add{b}\t{%2, %0|%0, %2}";
6144    }
6145}
6146  [(set (attr "type")
6147     (if_then_else (eq_attr "alternative" "3")
6148	(const_string "lea")
6149	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6150	   (const_string "incdec")
6151	   (const_string "alu"))))
6152   (set_attr "mode" "QI,QI,SI,SI")])
6153
6154(define_insn "*addqi_1"
6155  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6156	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6157		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6158   (clobber (reg:CC FLAGS_REG))]
6159  "TARGET_PARTIAL_REG_STALL
6160   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6161{
6162  int widen = (which_alternative == 2);
6163  switch (get_attr_type (insn))
6164    {
6165    case TYPE_INCDEC:
6166      if (operands[2] == const1_rtx)
6167	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6168      else
6169	{
6170	  gcc_assert (operands[2] == constm1_rtx);
6171	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6172	}
6173
6174    default:
6175      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6176	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6177      if (GET_CODE (operands[2]) == CONST_INT
6178          && (INTVAL (operands[2]) == 128
6179	      || (INTVAL (operands[2]) < 0
6180		  && INTVAL (operands[2]) != -128)))
6181	{
6182	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6183	  if (widen)
6184	    return "sub{l}\t{%2, %k0|%k0, %2}";
6185	  else
6186	    return "sub{b}\t{%2, %0|%0, %2}";
6187	}
6188      if (widen)
6189        return "add{l}\t{%k2, %k0|%k0, %k2}";
6190      else
6191        return "add{b}\t{%2, %0|%0, %2}";
6192    }
6193}
6194  [(set (attr "type")
6195     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6196	(const_string "incdec")
6197	(const_string "alu")))
6198   (set_attr "mode" "QI,QI,SI")])
6199
6200(define_insn "*addqi_1_slp"
6201  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6202	(plus:QI (match_dup 0)
6203		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6204   (clobber (reg:CC FLAGS_REG))]
6205  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6206   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6207{
6208  switch (get_attr_type (insn))
6209    {
6210    case TYPE_INCDEC:
6211      if (operands[1] == const1_rtx)
6212	return "inc{b}\t%0";
6213      else
6214	{
6215	  gcc_assert (operands[1] == constm1_rtx);
6216	  return "dec{b}\t%0";
6217	}
6218
6219    default:
6220      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6221      if (GET_CODE (operands[1]) == CONST_INT
6222	  && INTVAL (operands[1]) < 0)
6223	{
6224	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6225	  return "sub{b}\t{%1, %0|%0, %1}";
6226	}
6227      return "add{b}\t{%1, %0|%0, %1}";
6228    }
6229}
6230  [(set (attr "type")
6231     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6232	(const_string "incdec")
6233	(const_string "alu1")))
6234   (set (attr "memory")
6235     (if_then_else (match_operand 1 "memory_operand" "")
6236        (const_string "load")
6237        (const_string "none")))
6238   (set_attr "mode" "QI")])
6239
6240(define_insn "*addqi_2"
6241  [(set (reg FLAGS_REG)
6242	(compare
6243	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6244		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6245	  (const_int 0)))
6246   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6247	(plus:QI (match_dup 1) (match_dup 2)))]
6248  "ix86_match_ccmode (insn, CCGOCmode)
6249   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6250{
6251  switch (get_attr_type (insn))
6252    {
6253    case TYPE_INCDEC:
6254      if (operands[2] == const1_rtx)
6255	return "inc{b}\t%0";
6256      else
6257        {
6258	  gcc_assert (operands[2] == constm1_rtx
6259		      || (GET_CODE (operands[2]) == CONST_INT
6260		          && INTVAL (operands[2]) == 255));
6261	  return "dec{b}\t%0";
6262	}
6263
6264    default:
6265      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6266      if (GET_CODE (operands[2]) == CONST_INT
6267          && INTVAL (operands[2]) < 0)
6268	{
6269	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6270	  return "sub{b}\t{%2, %0|%0, %2}";
6271	}
6272      return "add{b}\t{%2, %0|%0, %2}";
6273    }
6274}
6275  [(set (attr "type")
6276     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6277	(const_string "incdec")
6278	(const_string "alu")))
6279   (set_attr "mode" "QI")])
6280
6281(define_insn "*addqi_3"
6282  [(set (reg FLAGS_REG)
6283	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6284		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6285   (clobber (match_scratch:QI 0 "=q"))]
6286  "ix86_match_ccmode (insn, CCZmode)
6287   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6288{
6289  switch (get_attr_type (insn))
6290    {
6291    case TYPE_INCDEC:
6292      if (operands[2] == const1_rtx)
6293	return "inc{b}\t%0";
6294      else
6295        {
6296	  gcc_assert (operands[2] == constm1_rtx
6297		      || (GET_CODE (operands[2]) == CONST_INT
6298			  && INTVAL (operands[2]) == 255));
6299	  return "dec{b}\t%0";
6300	}
6301
6302    default:
6303      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6304      if (GET_CODE (operands[2]) == CONST_INT
6305          && INTVAL (operands[2]) < 0)
6306	{
6307	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6308	  return "sub{b}\t{%2, %0|%0, %2}";
6309	}
6310      return "add{b}\t{%2, %0|%0, %2}";
6311    }
6312}
6313  [(set (attr "type")
6314     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6315	(const_string "incdec")
6316	(const_string "alu")))
6317   (set_attr "mode" "QI")])
6318
6319; See comments above addsi_4 for details.
6320(define_insn "*addqi_4"
6321  [(set (reg FLAGS_REG)
6322	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6323		 (match_operand:QI 2 "const_int_operand" "n")))
6324   (clobber (match_scratch:QI 0 "=qm"))]
6325  "ix86_match_ccmode (insn, CCGCmode)
6326   && (INTVAL (operands[2]) & 0xff) != 0x80"
6327{
6328  switch (get_attr_type (insn))
6329    {
6330    case TYPE_INCDEC:
6331      if (operands[2] == constm1_rtx
6332	  || (GET_CODE (operands[2]) == CONST_INT
6333	      && INTVAL (operands[2]) == 255))
6334        return "inc{b}\t%0";
6335      else
6336	{
6337	  gcc_assert (operands[2] == const1_rtx);
6338          return "dec{b}\t%0";
6339	}
6340
6341    default:
6342      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6343      if (INTVAL (operands[2]) < 0)
6344        {
6345          operands[2] = GEN_INT (-INTVAL (operands[2]));
6346          return "add{b}\t{%2, %0|%0, %2}";
6347        }
6348      return "sub{b}\t{%2, %0|%0, %2}";
6349    }
6350}
6351  [(set (attr "type")
6352     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6353	(const_string "incdec")
6354	(const_string "alu")))
6355   (set_attr "mode" "QI")])
6356
6357
6358(define_insn "*addqi_5"
6359  [(set (reg FLAGS_REG)
6360	(compare
6361	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6362		   (match_operand:QI 2 "general_operand" "qmni"))
6363	  (const_int 0)))
6364   (clobber (match_scratch:QI 0 "=q"))]
6365  "ix86_match_ccmode (insn, CCGOCmode)
6366   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6367{
6368  switch (get_attr_type (insn))
6369    {
6370    case TYPE_INCDEC:
6371      if (operands[2] == const1_rtx)
6372	return "inc{b}\t%0";
6373      else
6374        {
6375	  gcc_assert (operands[2] == constm1_rtx
6376		      || (GET_CODE (operands[2]) == CONST_INT
6377			  && INTVAL (operands[2]) == 255));
6378	  return "dec{b}\t%0";
6379	}
6380
6381    default:
6382      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6383      if (GET_CODE (operands[2]) == CONST_INT
6384          && INTVAL (operands[2]) < 0)
6385	{
6386	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6387	  return "sub{b}\t{%2, %0|%0, %2}";
6388	}
6389      return "add{b}\t{%2, %0|%0, %2}";
6390    }
6391}
6392  [(set (attr "type")
6393     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394	(const_string "incdec")
6395	(const_string "alu")))
6396   (set_attr "mode" "QI")])
6397
6398
6399(define_insn "addqi_ext_1"
6400  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6401			 (const_int 8)
6402			 (const_int 8))
6403	(plus:SI
6404	  (zero_extract:SI
6405	    (match_operand 1 "ext_register_operand" "0")
6406	    (const_int 8)
6407	    (const_int 8))
6408	  (match_operand:QI 2 "general_operand" "Qmn")))
6409   (clobber (reg:CC FLAGS_REG))]
6410  "!TARGET_64BIT"
6411{
6412  switch (get_attr_type (insn))
6413    {
6414    case TYPE_INCDEC:
6415      if (operands[2] == const1_rtx)
6416	return "inc{b}\t%h0";
6417      else
6418        {
6419	  gcc_assert (operands[2] == constm1_rtx
6420		      || (GET_CODE (operands[2]) == CONST_INT
6421			  && INTVAL (operands[2]) == 255));
6422          return "dec{b}\t%h0";
6423	}
6424
6425    default:
6426      return "add{b}\t{%2, %h0|%h0, %2}";
6427    }
6428}
6429  [(set (attr "type")
6430     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6431	(const_string "incdec")
6432	(const_string "alu")))
6433   (set_attr "mode" "QI")])
6434
6435(define_insn "*addqi_ext_1_rex64"
6436  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6437			 (const_int 8)
6438			 (const_int 8))
6439	(plus:SI
6440	  (zero_extract:SI
6441	    (match_operand 1 "ext_register_operand" "0")
6442	    (const_int 8)
6443	    (const_int 8))
6444	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6445   (clobber (reg:CC FLAGS_REG))]
6446  "TARGET_64BIT"
6447{
6448  switch (get_attr_type (insn))
6449    {
6450    case TYPE_INCDEC:
6451      if (operands[2] == const1_rtx)
6452	return "inc{b}\t%h0";
6453      else
6454        {
6455	  gcc_assert (operands[2] == constm1_rtx
6456		      || (GET_CODE (operands[2]) == CONST_INT
6457			  && INTVAL (operands[2]) == 255));
6458          return "dec{b}\t%h0";
6459        }
6460
6461    default:
6462      return "add{b}\t{%2, %h0|%h0, %2}";
6463    }
6464}
6465  [(set (attr "type")
6466     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6467	(const_string "incdec")
6468	(const_string "alu")))
6469   (set_attr "mode" "QI")])
6470
6471(define_insn "*addqi_ext_2"
6472  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6473			 (const_int 8)
6474			 (const_int 8))
6475	(plus:SI
6476	  (zero_extract:SI
6477	    (match_operand 1 "ext_register_operand" "%0")
6478	    (const_int 8)
6479	    (const_int 8))
6480	  (zero_extract:SI
6481	    (match_operand 2 "ext_register_operand" "Q")
6482	    (const_int 8)
6483	    (const_int 8))))
6484   (clobber (reg:CC FLAGS_REG))]
6485  ""
6486  "add{b}\t{%h2, %h0|%h0, %h2}"
6487  [(set_attr "type" "alu")
6488   (set_attr "mode" "QI")])
6489
6490;; The patterns that match these are at the end of this file.
6491
6492(define_expand "addxf3"
6493  [(set (match_operand:XF 0 "register_operand" "")
6494	(plus:XF (match_operand:XF 1 "register_operand" "")
6495		 (match_operand:XF 2 "register_operand" "")))]
6496  "TARGET_80387"
6497  "")
6498
6499(define_expand "adddf3"
6500  [(set (match_operand:DF 0 "register_operand" "")
6501	(plus:DF (match_operand:DF 1 "register_operand" "")
6502		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6503  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6504  "")
6505
6506(define_expand "addsf3"
6507  [(set (match_operand:SF 0 "register_operand" "")
6508	(plus:SF (match_operand:SF 1 "register_operand" "")
6509		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6510  "TARGET_80387 || TARGET_SSE_MATH"
6511  "")
6512
6513;; Subtract instructions
6514
6515;; %%% splits for subditi3
6516
6517(define_expand "subti3"
6518  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6519		   (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6520			     (match_operand:TI 2 "x86_64_general_operand" "")))
6521	      (clobber (reg:CC FLAGS_REG))])]
6522  "TARGET_64BIT"
6523  "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6524
6525(define_insn "*subti3_1"
6526  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6527	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6528		  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6529   (clobber (reg:CC FLAGS_REG))]
6530  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6531  "#")
6532
6533(define_split
6534  [(set (match_operand:TI 0 "nonimmediate_operand" "")
6535	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6536		  (match_operand:TI 2 "x86_64_general_operand" "")))
6537   (clobber (reg:CC FLAGS_REG))]
6538  "TARGET_64BIT && reload_completed"
6539  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6540	      (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6541   (parallel [(set (match_dup 3)
6542		   (minus:DI (match_dup 4)
6543			     (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6544				      (match_dup 5))))
6545	      (clobber (reg:CC FLAGS_REG))])]
6546  "split_ti (operands+0, 1, operands+0, operands+3);
6547   split_ti (operands+1, 1, operands+1, operands+4);
6548   split_ti (operands+2, 1, operands+2, operands+5);")
6549
6550;; %%% splits for subsidi3
6551
6552(define_expand "subdi3"
6553  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6554		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6555			     (match_operand:DI 2 "x86_64_general_operand" "")))
6556	      (clobber (reg:CC FLAGS_REG))])]
6557  ""
6558  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6559
6560(define_insn "*subdi3_1"
6561  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6562	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6563		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6564   (clobber (reg:CC FLAGS_REG))]
6565  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6566  "#")
6567
6568(define_split
6569  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6570	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6571		  (match_operand:DI 2 "general_operand" "")))
6572   (clobber (reg:CC FLAGS_REG))]
6573  "!TARGET_64BIT && reload_completed"
6574  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6575	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6576   (parallel [(set (match_dup 3)
6577		   (minus:SI (match_dup 4)
6578			     (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6579				      (match_dup 5))))
6580	      (clobber (reg:CC FLAGS_REG))])]
6581  "split_di (operands+0, 1, operands+0, operands+3);
6582   split_di (operands+1, 1, operands+1, operands+4);
6583   split_di (operands+2, 1, operands+2, operands+5);")
6584
6585(define_insn "subdi3_carry_rex64"
6586  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6587	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6589	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6590   (clobber (reg:CC FLAGS_REG))]
6591  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6592  "sbb{q}\t{%2, %0|%0, %2}"
6593  [(set_attr "type" "alu")
6594   (set_attr "pent_pair" "pu")
6595   (set_attr "mode" "DI")])
6596
6597(define_insn "*subdi_1_rex64"
6598  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6599	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6600		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6601   (clobber (reg:CC FLAGS_REG))]
6602  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6603  "sub{q}\t{%2, %0|%0, %2}"
6604  [(set_attr "type" "alu")
6605   (set_attr "mode" "DI")])
6606
6607(define_insn "*subdi_2_rex64"
6608  [(set (reg FLAGS_REG)
6609	(compare
6610	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6611		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6612	  (const_int 0)))
6613   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6614	(minus:DI (match_dup 1) (match_dup 2)))]
6615  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6616   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6617  "sub{q}\t{%2, %0|%0, %2}"
6618  [(set_attr "type" "alu")
6619   (set_attr "mode" "DI")])
6620
6621(define_insn "*subdi_3_rex63"
6622  [(set (reg FLAGS_REG)
6623	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6624		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6625   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6626	(minus:DI (match_dup 1) (match_dup 2)))]
6627  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6628   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6629  "sub{q}\t{%2, %0|%0, %2}"
6630  [(set_attr "type" "alu")
6631   (set_attr "mode" "DI")])
6632
6633(define_insn "subqi3_carry"
6634  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6635	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6636	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6637	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6638   (clobber (reg:CC FLAGS_REG))]
6639  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6640  "sbb{b}\t{%2, %0|%0, %2}"
6641  [(set_attr "type" "alu")
6642   (set_attr "pent_pair" "pu")
6643   (set_attr "mode" "QI")])
6644
6645(define_insn "subhi3_carry"
6646  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6647	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6648	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6649	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6650   (clobber (reg:CC FLAGS_REG))]
6651  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6652  "sbb{w}\t{%2, %0|%0, %2}"
6653  [(set_attr "type" "alu")
6654   (set_attr "pent_pair" "pu")
6655   (set_attr "mode" "HI")])
6656
6657(define_insn "subsi3_carry"
6658  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6659	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6660	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6661	       (match_operand:SI 2 "general_operand" "ri,rm"))))
6662   (clobber (reg:CC FLAGS_REG))]
6663  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6664  "sbb{l}\t{%2, %0|%0, %2}"
6665  [(set_attr "type" "alu")
6666   (set_attr "pent_pair" "pu")
6667   (set_attr "mode" "SI")])
6668
6669(define_insn "subsi3_carry_zext"
6670  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6671	  (zero_extend:DI
6672	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6673	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6674		 (match_operand:SI 2 "general_operand" "ri,rm")))))
6675   (clobber (reg:CC FLAGS_REG))]
6676  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6677  "sbb{l}\t{%2, %k0|%k0, %2}"
6678  [(set_attr "type" "alu")
6679   (set_attr "pent_pair" "pu")
6680   (set_attr "mode" "SI")])
6681
6682(define_expand "subsi3"
6683  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6684		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6685			     (match_operand:SI 2 "general_operand" "")))
6686	      (clobber (reg:CC FLAGS_REG))])]
6687  ""
6688  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6689
6690(define_insn "*subsi_1"
6691  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6692	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6693		  (match_operand:SI 2 "general_operand" "ri,rm")))
6694   (clobber (reg:CC FLAGS_REG))]
6695  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6696  "sub{l}\t{%2, %0|%0, %2}"
6697  [(set_attr "type" "alu")
6698   (set_attr "mode" "SI")])
6699
6700(define_insn "*subsi_1_zext"
6701  [(set (match_operand:DI 0 "register_operand" "=r")
6702	(zero_extend:DI
6703	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6704		    (match_operand:SI 2 "general_operand" "rim"))))
6705   (clobber (reg:CC FLAGS_REG))]
6706  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707  "sub{l}\t{%2, %k0|%k0, %2}"
6708  [(set_attr "type" "alu")
6709   (set_attr "mode" "SI")])
6710
6711(define_insn "*subsi_2"
6712  [(set (reg FLAGS_REG)
6713	(compare
6714	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6715		    (match_operand:SI 2 "general_operand" "ri,rm"))
6716	  (const_int 0)))
6717   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6718	(minus:SI (match_dup 1) (match_dup 2)))]
6719  "ix86_match_ccmode (insn, CCGOCmode)
6720   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721  "sub{l}\t{%2, %0|%0, %2}"
6722  [(set_attr "type" "alu")
6723   (set_attr "mode" "SI")])
6724
6725(define_insn "*subsi_2_zext"
6726  [(set (reg FLAGS_REG)
6727	(compare
6728	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6729		    (match_operand:SI 2 "general_operand" "rim"))
6730	  (const_int 0)))
6731   (set (match_operand:DI 0 "register_operand" "=r")
6732	(zero_extend:DI
6733	  (minus:SI (match_dup 1)
6734		    (match_dup 2))))]
6735  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6736   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6737  "sub{l}\t{%2, %k0|%k0, %2}"
6738  [(set_attr "type" "alu")
6739   (set_attr "mode" "SI")])
6740
6741(define_insn "*subsi_3"
6742  [(set (reg FLAGS_REG)
6743	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6744		 (match_operand:SI 2 "general_operand" "ri,rm")))
6745   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6746	(minus:SI (match_dup 1) (match_dup 2)))]
6747  "ix86_match_ccmode (insn, CCmode)
6748   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6749  "sub{l}\t{%2, %0|%0, %2}"
6750  [(set_attr "type" "alu")
6751   (set_attr "mode" "SI")])
6752
6753(define_insn "*subsi_3_zext"
6754  [(set (reg FLAGS_REG)
6755	(compare (match_operand:SI 1 "register_operand" "0")
6756		 (match_operand:SI 2 "general_operand" "rim")))
6757   (set (match_operand:DI 0 "register_operand" "=r")
6758	(zero_extend:DI
6759	  (minus:SI (match_dup 1)
6760		    (match_dup 2))))]
6761  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6762   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763  "sub{l}\t{%2, %1|%1, %2}"
6764  [(set_attr "type" "alu")
6765   (set_attr "mode" "DI")])
6766
6767(define_expand "subhi3"
6768  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6769		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6770			     (match_operand:HI 2 "general_operand" "")))
6771	      (clobber (reg:CC FLAGS_REG))])]
6772  "TARGET_HIMODE_MATH"
6773  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6774
6775(define_insn "*subhi_1"
6776  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6777	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6778		  (match_operand:HI 2 "general_operand" "ri,rm")))
6779   (clobber (reg:CC FLAGS_REG))]
6780  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6781  "sub{w}\t{%2, %0|%0, %2}"
6782  [(set_attr "type" "alu")
6783   (set_attr "mode" "HI")])
6784
6785(define_insn "*subhi_2"
6786  [(set (reg FLAGS_REG)
6787	(compare
6788	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6789		    (match_operand:HI 2 "general_operand" "ri,rm"))
6790	  (const_int 0)))
6791   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6792	(minus:HI (match_dup 1) (match_dup 2)))]
6793  "ix86_match_ccmode (insn, CCGOCmode)
6794   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6795  "sub{w}\t{%2, %0|%0, %2}"
6796  [(set_attr "type" "alu")
6797   (set_attr "mode" "HI")])
6798
6799(define_insn "*subhi_3"
6800  [(set (reg FLAGS_REG)
6801	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6802		 (match_operand:HI 2 "general_operand" "ri,rm")))
6803   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6804	(minus:HI (match_dup 1) (match_dup 2)))]
6805  "ix86_match_ccmode (insn, CCmode)
6806   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6807  "sub{w}\t{%2, %0|%0, %2}"
6808  [(set_attr "type" "alu")
6809   (set_attr "mode" "HI")])
6810
6811(define_expand "subqi3"
6812  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6813		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6814			     (match_operand:QI 2 "general_operand" "")))
6815	      (clobber (reg:CC FLAGS_REG))])]
6816  "TARGET_QIMODE_MATH"
6817  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6818
6819(define_insn "*subqi_1"
6820  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6821	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6822		  (match_operand:QI 2 "general_operand" "qn,qmn")))
6823   (clobber (reg:CC FLAGS_REG))]
6824  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6825  "sub{b}\t{%2, %0|%0, %2}"
6826  [(set_attr "type" "alu")
6827   (set_attr "mode" "QI")])
6828
6829(define_insn "*subqi_1_slp"
6830  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6831	(minus:QI (match_dup 0)
6832		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6833   (clobber (reg:CC FLAGS_REG))]
6834  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6835   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6836  "sub{b}\t{%1, %0|%0, %1}"
6837  [(set_attr "type" "alu1")
6838   (set_attr "mode" "QI")])
6839
6840(define_insn "*subqi_2"
6841  [(set (reg FLAGS_REG)
6842	(compare
6843	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6844		    (match_operand:QI 2 "general_operand" "qi,qm"))
6845	  (const_int 0)))
6846   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6847	(minus:HI (match_dup 1) (match_dup 2)))]
6848  "ix86_match_ccmode (insn, CCGOCmode)
6849   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6850  "sub{b}\t{%2, %0|%0, %2}"
6851  [(set_attr "type" "alu")
6852   (set_attr "mode" "QI")])
6853
6854(define_insn "*subqi_3"
6855  [(set (reg FLAGS_REG)
6856	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857		 (match_operand:QI 2 "general_operand" "qi,qm")))
6858   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6859	(minus:HI (match_dup 1) (match_dup 2)))]
6860  "ix86_match_ccmode (insn, CCmode)
6861   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6862  "sub{b}\t{%2, %0|%0, %2}"
6863  [(set_attr "type" "alu")
6864   (set_attr "mode" "QI")])
6865
6866;; The patterns that match these are at the end of this file.
6867
6868(define_expand "subxf3"
6869  [(set (match_operand:XF 0 "register_operand" "")
6870	(minus:XF (match_operand:XF 1 "register_operand" "")
6871		  (match_operand:XF 2 "register_operand" "")))]
6872  "TARGET_80387"
6873  "")
6874
6875(define_expand "subdf3"
6876  [(set (match_operand:DF 0 "register_operand" "")
6877	(minus:DF (match_operand:DF 1 "register_operand" "")
6878		  (match_operand:DF 2 "nonimmediate_operand" "")))]
6879  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6880  "")
6881
6882(define_expand "subsf3"
6883  [(set (match_operand:SF 0 "register_operand" "")
6884	(minus:SF (match_operand:SF 1 "register_operand" "")
6885		  (match_operand:SF 2 "nonimmediate_operand" "")))]
6886  "TARGET_80387 || TARGET_SSE_MATH"
6887  "")
6888
6889;; Multiply instructions
6890
6891(define_expand "muldi3"
6892  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6893		   (mult:DI (match_operand:DI 1 "register_operand" "")
6894			    (match_operand:DI 2 "x86_64_general_operand" "")))
6895	      (clobber (reg:CC FLAGS_REG))])]
6896  "TARGET_64BIT"
6897  "")
6898
6899;; On AMDFAM10 
6900;; IMUL reg64, reg64, imm8 	Direct
6901;; IMUL reg64, mem64, imm8 	VectorPath
6902;; IMUL reg64, reg64, imm32 	Direct
6903;; IMUL reg64, mem64, imm32 	VectorPath 
6904;; IMUL reg64, reg64 		Direct
6905;; IMUL reg64, mem64 		Direct
6906
6907(define_insn "*muldi3_1_rex64"
6908  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6909	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6910		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6911   (clobber (reg:CC FLAGS_REG))]
6912  "TARGET_64BIT
6913   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6914  "@
6915   imul{q}\t{%2, %1, %0|%0, %1, %2}
6916   imul{q}\t{%2, %1, %0|%0, %1, %2}
6917   imul{q}\t{%2, %0|%0, %2}"
6918  [(set_attr "type" "imul")
6919   (set_attr "prefix_0f" "0,0,1")
6920   (set (attr "athlon_decode")
6921	(cond [(eq_attr "cpu" "athlon")
6922		  (const_string "vector")
6923	       (eq_attr "alternative" "1")
6924		  (const_string "vector")
6925	       (and (eq_attr "alternative" "2")
6926		    (match_operand 1 "memory_operand" ""))
6927		  (const_string "vector")]
6928	      (const_string "direct")))
6929   (set (attr "amdfam10_decode")
6930	(cond [(and (eq_attr "alternative" "0,1")
6931		    (match_operand 1 "memory_operand" ""))
6932		  (const_string "vector")]
6933	      (const_string "direct")))	      
6934   (set_attr "mode" "DI")])
6935
6936(define_expand "mulsi3"
6937  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6938		   (mult:SI (match_operand:SI 1 "register_operand" "")
6939			    (match_operand:SI 2 "general_operand" "")))
6940	      (clobber (reg:CC FLAGS_REG))])]
6941  ""
6942  "")
6943
6944;; On AMDFAM10 
6945;; IMUL reg32, reg32, imm8 	Direct
6946;; IMUL reg32, mem32, imm8 	VectorPath
6947;; IMUL reg32, reg32, imm32 	Direct
6948;; IMUL reg32, mem32, imm32 	VectorPath
6949;; IMUL reg32, reg32 		Direct
6950;; IMUL reg32, mem32 		Direct
6951
6952(define_insn "*mulsi3_1"
6953  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6954	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6955		 (match_operand:SI 2 "general_operand" "K,i,mr")))
6956   (clobber (reg:CC FLAGS_REG))]
6957  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958  "@
6959   imul{l}\t{%2, %1, %0|%0, %1, %2}
6960   imul{l}\t{%2, %1, %0|%0, %1, %2}
6961   imul{l}\t{%2, %0|%0, %2}"
6962  [(set_attr "type" "imul")
6963   (set_attr "prefix_0f" "0,0,1")
6964   (set (attr "athlon_decode")
6965	(cond [(eq_attr "cpu" "athlon")
6966		  (const_string "vector")
6967	       (eq_attr "alternative" "1")
6968		  (const_string "vector")
6969	       (and (eq_attr "alternative" "2")
6970		    (match_operand 1 "memory_operand" ""))
6971		  (const_string "vector")]
6972	      (const_string "direct")))
6973   (set (attr "amdfam10_decode")
6974	(cond [(and (eq_attr "alternative" "0,1")
6975		    (match_operand 1 "memory_operand" ""))
6976		  (const_string "vector")]
6977	      (const_string "direct")))	      
6978   (set_attr "mode" "SI")])
6979
6980(define_insn "*mulsi3_1_zext"
6981  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6982	(zero_extend:DI
6983	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6984		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
6985   (clobber (reg:CC FLAGS_REG))]
6986  "TARGET_64BIT
6987   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6988  "@
6989   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6990   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6991   imul{l}\t{%2, %k0|%k0, %2}"
6992  [(set_attr "type" "imul")
6993   (set_attr "prefix_0f" "0,0,1")
6994   (set (attr "athlon_decode")
6995	(cond [(eq_attr "cpu" "athlon")
6996		  (const_string "vector")
6997	       (eq_attr "alternative" "1")
6998		  (const_string "vector")
6999	       (and (eq_attr "alternative" "2")
7000		    (match_operand 1 "memory_operand" ""))
7001		  (const_string "vector")]
7002	      (const_string "direct")))
7003   (set (attr "amdfam10_decode")
7004	(cond [(and (eq_attr "alternative" "0,1")
7005		    (match_operand 1 "memory_operand" ""))
7006		  (const_string "vector")]
7007	      (const_string "direct")))	      
7008   (set_attr "mode" "SI")])
7009
7010(define_expand "mulhi3"
7011  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7012		   (mult:HI (match_operand:HI 1 "register_operand" "")
7013			    (match_operand:HI 2 "general_operand" "")))
7014	      (clobber (reg:CC FLAGS_REG))])]
7015  "TARGET_HIMODE_MATH"
7016  "")
7017
7018;; On AMDFAM10
7019;; IMUL reg16, reg16, imm8 	VectorPath
7020;; IMUL reg16, mem16, imm8 	VectorPath
7021;; IMUL reg16, reg16, imm16 	VectorPath
7022;; IMUL reg16, mem16, imm16 	VectorPath
7023;; IMUL reg16, reg16 		Direct
7024;; IMUL reg16, mem16 		Direct
7025(define_insn "*mulhi3_1"
7026  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7027	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7028		 (match_operand:HI 2 "general_operand" "K,i,mr")))
7029   (clobber (reg:CC FLAGS_REG))]
7030  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7031  "@
7032   imul{w}\t{%2, %1, %0|%0, %1, %2}
7033   imul{w}\t{%2, %1, %0|%0, %1, %2}
7034   imul{w}\t{%2, %0|%0, %2}"
7035  [(set_attr "type" "imul")
7036   (set_attr "prefix_0f" "0,0,1")
7037   (set (attr "athlon_decode")
7038	(cond [(eq_attr "cpu" "athlon")
7039		  (const_string "vector")
7040	       (eq_attr "alternative" "1,2")
7041		  (const_string "vector")]
7042	      (const_string "direct")))
7043   (set (attr "amdfam10_decode")
7044	(cond [(eq_attr "alternative" "0,1")
7045		  (const_string "vector")]
7046	      (const_string "direct")))
7047   (set_attr "mode" "HI")])
7048
7049(define_expand "mulqi3"
7050  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7051		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7052			    (match_operand:QI 2 "register_operand" "")))
7053	      (clobber (reg:CC FLAGS_REG))])]
7054  "TARGET_QIMODE_MATH"
7055  "")
7056
7057;;On AMDFAM10
7058;; MUL reg8 	Direct
7059;; MUL mem8 	Direct
7060
7061(define_insn "*mulqi3_1"
7062  [(set (match_operand:QI 0 "register_operand" "=a")
7063	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7064		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7065   (clobber (reg:CC FLAGS_REG))]
7066  "TARGET_QIMODE_MATH
7067   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7068  "mul{b}\t%2"
7069  [(set_attr "type" "imul")
7070   (set_attr "length_immediate" "0")
7071   (set (attr "athlon_decode")
7072     (if_then_else (eq_attr "cpu" "athlon")
7073        (const_string "vector")
7074        (const_string "direct")))
7075   (set_attr "amdfam10_decode" "direct")        
7076   (set_attr "mode" "QI")])
7077
7078(define_expand "umulqihi3"
7079  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080		   (mult:HI (zero_extend:HI
7081			      (match_operand:QI 1 "nonimmediate_operand" ""))
7082			    (zero_extend:HI
7083			      (match_operand:QI 2 "register_operand" ""))))
7084	      (clobber (reg:CC FLAGS_REG))])]
7085  "TARGET_QIMODE_MATH"
7086  "")
7087
7088(define_insn "*umulqihi3_1"
7089  [(set (match_operand:HI 0 "register_operand" "=a")
7090	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7091		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7092   (clobber (reg:CC FLAGS_REG))]
7093  "TARGET_QIMODE_MATH
7094   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7095  "mul{b}\t%2"
7096  [(set_attr "type" "imul")
7097   (set_attr "length_immediate" "0")
7098   (set (attr "athlon_decode")
7099     (if_then_else (eq_attr "cpu" "athlon")
7100        (const_string "vector")
7101        (const_string "direct")))
7102   (set_attr "amdfam10_decode" "direct")        
7103   (set_attr "mode" "QI")])
7104
7105(define_expand "mulqihi3"
7106  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7107		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7108			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7109	      (clobber (reg:CC FLAGS_REG))])]
7110  "TARGET_QIMODE_MATH"
7111  "")
7112
7113(define_insn "*mulqihi3_insn"
7114  [(set (match_operand:HI 0 "register_operand" "=a")
7115	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7116		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7117   (clobber (reg:CC FLAGS_REG))]
7118  "TARGET_QIMODE_MATH
7119   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7120  "imul{b}\t%2"
7121  [(set_attr "type" "imul")
7122   (set_attr "length_immediate" "0")
7123   (set (attr "athlon_decode")
7124     (if_then_else (eq_attr "cpu" "athlon")
7125        (const_string "vector")
7126        (const_string "direct")))
7127   (set_attr "amdfam10_decode" "direct")        
7128   (set_attr "mode" "QI")])
7129
7130(define_expand "umulditi3"
7131  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7132		   (mult:TI (zero_extend:TI
7133			      (match_operand:DI 1 "nonimmediate_operand" ""))
7134			    (zero_extend:TI
7135			      (match_operand:DI 2 "register_operand" ""))))
7136	      (clobber (reg:CC FLAGS_REG))])]
7137  "TARGET_64BIT"
7138  "")
7139
7140(define_insn "*umulditi3_insn"
7141  [(set (match_operand:TI 0 "register_operand" "=A")
7142	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7143		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7144   (clobber (reg:CC FLAGS_REG))]
7145  "TARGET_64BIT
7146   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7147  "mul{q}\t%2"
7148  [(set_attr "type" "imul")
7149   (set_attr "length_immediate" "0")
7150   (set (attr "athlon_decode")
7151     (if_then_else (eq_attr "cpu" "athlon")
7152        (const_string "vector")
7153        (const_string "double")))
7154   (set_attr "amdfam10_decode" "double")        
7155   (set_attr "mode" "DI")])
7156
7157;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7158(define_expand "umulsidi3"
7159  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7160		   (mult:DI (zero_extend:DI
7161			      (match_operand:SI 1 "nonimmediate_operand" ""))
7162			    (zero_extend:DI
7163			      (match_operand:SI 2 "register_operand" ""))))
7164	      (clobber (reg:CC FLAGS_REG))])]
7165  "!TARGET_64BIT"
7166  "")
7167
7168(define_insn "*umulsidi3_insn"
7169  [(set (match_operand:DI 0 "register_operand" "=A")
7170	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7171		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7172   (clobber (reg:CC FLAGS_REG))]
7173  "!TARGET_64BIT
7174   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7175  "mul{l}\t%2"
7176  [(set_attr "type" "imul")
7177   (set_attr "length_immediate" "0")
7178   (set (attr "athlon_decode")
7179     (if_then_else (eq_attr "cpu" "athlon")
7180        (const_string "vector")
7181        (const_string "double")))
7182   (set_attr "amdfam10_decode" "double")        
7183   (set_attr "mode" "SI")])
7184
7185(define_expand "mulditi3"
7186  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7187		   (mult:TI (sign_extend:TI
7188			      (match_operand:DI 1 "nonimmediate_operand" ""))
7189			    (sign_extend:TI
7190			      (match_operand:DI 2 "register_operand" ""))))
7191	      (clobber (reg:CC FLAGS_REG))])]
7192  "TARGET_64BIT"
7193  "")
7194
7195(define_insn "*mulditi3_insn"
7196  [(set (match_operand:TI 0 "register_operand" "=A")
7197	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7198		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7199   (clobber (reg:CC FLAGS_REG))]
7200  "TARGET_64BIT
7201   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7202  "imul{q}\t%2"
7203  [(set_attr "type" "imul")
7204   (set_attr "length_immediate" "0")
7205   (set (attr "athlon_decode")
7206     (if_then_else (eq_attr "cpu" "athlon")
7207        (const_string "vector")
7208        (const_string "double")))
7209   (set_attr "amdfam10_decode" "double")
7210   (set_attr "mode" "DI")])
7211
7212(define_expand "mulsidi3"
7213  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7214		   (mult:DI (sign_extend:DI
7215			      (match_operand:SI 1 "nonimmediate_operand" ""))
7216			    (sign_extend:DI
7217			      (match_operand:SI 2 "register_operand" ""))))
7218	      (clobber (reg:CC FLAGS_REG))])]
7219  "!TARGET_64BIT"
7220  "")
7221
7222(define_insn "*mulsidi3_insn"
7223  [(set (match_operand:DI 0 "register_operand" "=A")
7224	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7225		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7226   (clobber (reg:CC FLAGS_REG))]
7227  "!TARGET_64BIT
7228   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7229  "imul{l}\t%2"
7230  [(set_attr "type" "imul")
7231   (set_attr "length_immediate" "0")
7232   (set (attr "athlon_decode")
7233     (if_then_else (eq_attr "cpu" "athlon")
7234        (const_string "vector")
7235        (const_string "double")))
7236   (set_attr "amdfam10_decode" "double")        
7237   (set_attr "mode" "SI")])
7238
7239(define_expand "umuldi3_highpart"
7240  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7241		   (truncate:DI
7242		     (lshiftrt:TI
7243		       (mult:TI (zero_extend:TI
7244				  (match_operand:DI 1 "nonimmediate_operand" ""))
7245				(zero_extend:TI
7246				  (match_operand:DI 2 "register_operand" "")))
7247		       (const_int 64))))
7248	      (clobber (match_scratch:DI 3 ""))
7249	      (clobber (reg:CC FLAGS_REG))])]
7250  "TARGET_64BIT"
7251  "")
7252
7253(define_insn "*umuldi3_highpart_rex64"
7254  [(set (match_operand:DI 0 "register_operand" "=d")
7255	(truncate:DI
7256	  (lshiftrt:TI
7257	    (mult:TI (zero_extend:TI
7258		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7259		     (zero_extend:TI
7260		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7261	    (const_int 64))))
7262   (clobber (match_scratch:DI 3 "=1"))
7263   (clobber (reg:CC FLAGS_REG))]
7264  "TARGET_64BIT
7265   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7266  "mul{q}\t%2"
7267  [(set_attr "type" "imul")
7268   (set_attr "length_immediate" "0")
7269   (set (attr "athlon_decode")
7270     (if_then_else (eq_attr "cpu" "athlon")
7271        (const_string "vector")
7272        (const_string "double")))
7273   (set_attr "amdfam10_decode" "double")        
7274   (set_attr "mode" "DI")])
7275
7276(define_expand "umulsi3_highpart"
7277  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7278		   (truncate:SI
7279		     (lshiftrt:DI
7280		       (mult:DI (zero_extend:DI
7281				  (match_operand:SI 1 "nonimmediate_operand" ""))
7282				(zero_extend:DI
7283				  (match_operand:SI 2 "register_operand" "")))
7284		       (const_int 32))))
7285	      (clobber (match_scratch:SI 3 ""))
7286	      (clobber (reg:CC FLAGS_REG))])]
7287  ""
7288  "")
7289
7290(define_insn "*umulsi3_highpart_insn"
7291  [(set (match_operand:SI 0 "register_operand" "=d")
7292	(truncate:SI
7293	  (lshiftrt:DI
7294	    (mult:DI (zero_extend:DI
7295		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7296		     (zero_extend:DI
7297		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7298	    (const_int 32))))
7299   (clobber (match_scratch:SI 3 "=1"))
7300   (clobber (reg:CC FLAGS_REG))]
7301  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7302  "mul{l}\t%2"
7303  [(set_attr "type" "imul")
7304   (set_attr "length_immediate" "0")
7305   (set (attr "athlon_decode")
7306     (if_then_else (eq_attr "cpu" "athlon")
7307        (const_string "vector")
7308        (const_string "double")))
7309   (set_attr "amdfam10_decode" "double")
7310   (set_attr "mode" "SI")])
7311
7312(define_insn "*umulsi3_highpart_zext"
7313  [(set (match_operand:DI 0 "register_operand" "=d")
7314	(zero_extend:DI (truncate:SI
7315	  (lshiftrt:DI
7316	    (mult:DI (zero_extend:DI
7317		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7318		     (zero_extend:DI
7319		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7320	    (const_int 32)))))
7321   (clobber (match_scratch:SI 3 "=1"))
7322   (clobber (reg:CC FLAGS_REG))]
7323  "TARGET_64BIT
7324   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7325  "mul{l}\t%2"
7326  [(set_attr "type" "imul")
7327   (set_attr "length_immediate" "0")
7328   (set (attr "athlon_decode")
7329     (if_then_else (eq_attr "cpu" "athlon")
7330        (const_string "vector")
7331        (const_string "double")))
7332   (set_attr "amdfam10_decode" "double")
7333   (set_attr "mode" "SI")])
7334
7335(define_expand "smuldi3_highpart"
7336  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7337		   (truncate:DI
7338		     (lshiftrt:TI
7339		       (mult:TI (sign_extend:TI
7340				  (match_operand:DI 1 "nonimmediate_operand" ""))
7341				(sign_extend:TI
7342				  (match_operand:DI 2 "register_operand" "")))
7343		       (const_int 64))))
7344	      (clobber (match_scratch:DI 3 ""))
7345	      (clobber (reg:CC FLAGS_REG))])]
7346  "TARGET_64BIT"
7347  "")
7348
7349(define_insn "*smuldi3_highpart_rex64"
7350  [(set (match_operand:DI 0 "register_operand" "=d")
7351	(truncate:DI
7352	  (lshiftrt:TI
7353	    (mult:TI (sign_extend:TI
7354		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7355		     (sign_extend:TI
7356		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7357	    (const_int 64))))
7358   (clobber (match_scratch:DI 3 "=1"))
7359   (clobber (reg:CC FLAGS_REG))]
7360  "TARGET_64BIT
7361   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7362  "imul{q}\t%2"
7363  [(set_attr "type" "imul")
7364   (set (attr "athlon_decode")
7365     (if_then_else (eq_attr "cpu" "athlon")
7366        (const_string "vector")
7367        (const_string "double")))
7368   (set_attr "amdfam10_decode" "double")
7369   (set_attr "mode" "DI")])
7370
7371(define_expand "smulsi3_highpart"
7372  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7373		   (truncate:SI
7374		     (lshiftrt:DI
7375		       (mult:DI (sign_extend:DI
7376				  (match_operand:SI 1 "nonimmediate_operand" ""))
7377				(sign_extend:DI
7378				  (match_operand:SI 2 "register_operand" "")))
7379		       (const_int 32))))
7380	      (clobber (match_scratch:SI 3 ""))
7381	      (clobber (reg:CC FLAGS_REG))])]
7382  ""
7383  "")
7384
7385(define_insn "*smulsi3_highpart_insn"
7386  [(set (match_operand:SI 0 "register_operand" "=d")
7387	(truncate:SI
7388	  (lshiftrt:DI
7389	    (mult:DI (sign_extend:DI
7390		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7391		     (sign_extend:DI
7392		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7393	    (const_int 32))))
7394   (clobber (match_scratch:SI 3 "=1"))
7395   (clobber (reg:CC FLAGS_REG))]
7396  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7397  "imul{l}\t%2"
7398  [(set_attr "type" "imul")
7399   (set (attr "athlon_decode")
7400     (if_then_else (eq_attr "cpu" "athlon")
7401        (const_string "vector")
7402        (const_string "double")))
7403   (set_attr "amdfam10_decode" "double")
7404   (set_attr "mode" "SI")])
7405
7406(define_insn "*smulsi3_highpart_zext"
7407  [(set (match_operand:DI 0 "register_operand" "=d")
7408	(zero_extend:DI (truncate:SI
7409	  (lshiftrt:DI
7410	    (mult:DI (sign_extend:DI
7411		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7412		     (sign_extend:DI
7413		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7414	    (const_int 32)))))
7415   (clobber (match_scratch:SI 3 "=1"))
7416   (clobber (reg:CC FLAGS_REG))]
7417  "TARGET_64BIT
7418   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7419  "imul{l}\t%2"
7420  [(set_attr "type" "imul")
7421   (set (attr "athlon_decode")
7422     (if_then_else (eq_attr "cpu" "athlon")
7423        (const_string "vector")
7424        (const_string "double")))
7425   (set_attr "amdfam10_decode" "double")
7426   (set_attr "mode" "SI")])
7427
7428;; The patterns that match these are at the end of this file.
7429
7430(define_expand "mulxf3"
7431  [(set (match_operand:XF 0 "register_operand" "")
7432	(mult:XF (match_operand:XF 1 "register_operand" "")
7433		 (match_operand:XF 2 "register_operand" "")))]
7434  "TARGET_80387"
7435  "")
7436
7437(define_expand "muldf3"
7438  [(set (match_operand:DF 0 "register_operand" "")
7439	(mult:DF (match_operand:DF 1 "register_operand" "")
7440		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7441  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7442  "")
7443
7444(define_expand "mulsf3"
7445  [(set (match_operand:SF 0 "register_operand" "")
7446	(mult:SF (match_operand:SF 1 "register_operand" "")
7447		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7448  "TARGET_80387 || TARGET_SSE_MATH"
7449  "")
7450
7451;; Divide instructions
7452
7453(define_insn "divqi3"
7454  [(set (match_operand:QI 0 "register_operand" "=a")
7455	(div:QI (match_operand:HI 1 "register_operand" "0")
7456		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7457   (clobber (reg:CC FLAGS_REG))]
7458  "TARGET_QIMODE_MATH"
7459  "idiv{b}\t%2"
7460  [(set_attr "type" "idiv")
7461   (set_attr "mode" "QI")])
7462
7463(define_insn "udivqi3"
7464  [(set (match_operand:QI 0 "register_operand" "=a")
7465	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7466		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7467   (clobber (reg:CC FLAGS_REG))]
7468  "TARGET_QIMODE_MATH"
7469  "div{b}\t%2"
7470  [(set_attr "type" "idiv")
7471   (set_attr "mode" "QI")])
7472
7473;; The patterns that match these are at the end of this file.
7474
7475(define_expand "divxf3"
7476  [(set (match_operand:XF 0 "register_operand" "")
7477	(div:XF (match_operand:XF 1 "register_operand" "")
7478		(match_operand:XF 2 "register_operand" "")))]
7479  "TARGET_80387"
7480  "")
7481
7482(define_expand "divdf3"
7483  [(set (match_operand:DF 0 "register_operand" "")
7484 	(div:DF (match_operand:DF 1 "register_operand" "")
7485 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7486   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7487   "")
7488 
7489(define_expand "divsf3"
7490  [(set (match_operand:SF 0 "register_operand" "")
7491	(div:SF (match_operand:SF 1 "register_operand" "")
7492		(match_operand:SF 2 "nonimmediate_operand" "")))]
7493  "TARGET_80387 || TARGET_SSE_MATH"
7494  "")
7495
7496;; Remainder instructions.
7497
7498(define_expand "divmoddi4"
7499  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7500		   (div:DI (match_operand:DI 1 "register_operand" "")
7501			   (match_operand:DI 2 "nonimmediate_operand" "")))
7502	      (set (match_operand:DI 3 "register_operand" "")
7503		   (mod:DI (match_dup 1) (match_dup 2)))
7504	      (clobber (reg:CC FLAGS_REG))])]
7505  "TARGET_64BIT"
7506  "")
7507
7508;; Allow to come the parameter in eax or edx to avoid extra moves.
7509;; Penalize eax case slightly because it results in worse scheduling
7510;; of code.
7511(define_insn "*divmoddi4_nocltd_rex64"
7512  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7513	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7514		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7515   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7516	(mod:DI (match_dup 2) (match_dup 3)))
7517   (clobber (reg:CC FLAGS_REG))]
7518  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7519  "#"
7520  [(set_attr "type" "multi")])
7521
7522(define_insn "*divmoddi4_cltd_rex64"
7523  [(set (match_operand:DI 0 "register_operand" "=a")
7524	(div:DI (match_operand:DI 2 "register_operand" "a")
7525		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7526   (set (match_operand:DI 1 "register_operand" "=&d")
7527	(mod:DI (match_dup 2) (match_dup 3)))
7528   (clobber (reg:CC FLAGS_REG))]
7529  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7530  "#"
7531  [(set_attr "type" "multi")])
7532
7533(define_insn "*divmoddi_noext_rex64"
7534  [(set (match_operand:DI 0 "register_operand" "=a")
7535	(div:DI (match_operand:DI 1 "register_operand" "0")
7536		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7537   (set (match_operand:DI 3 "register_operand" "=d")
7538	(mod:DI (match_dup 1) (match_dup 2)))
7539   (use (match_operand:DI 4 "register_operand" "3"))
7540   (clobber (reg:CC FLAGS_REG))]
7541  "TARGET_64BIT"
7542  "idiv{q}\t%2"
7543  [(set_attr "type" "idiv")
7544   (set_attr "mode" "DI")])
7545
7546(define_split
7547  [(set (match_operand:DI 0 "register_operand" "")
7548	(div:DI (match_operand:DI 1 "register_operand" "")
7549		(match_operand:DI 2 "nonimmediate_operand" "")))
7550   (set (match_operand:DI 3 "register_operand" "")
7551	(mod:DI (match_dup 1) (match_dup 2)))
7552   (clobber (reg:CC FLAGS_REG))]
7553  "TARGET_64BIT && reload_completed"
7554  [(parallel [(set (match_dup 3)
7555		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7556	      (clobber (reg:CC FLAGS_REG))])
7557   (parallel [(set (match_dup 0)
7558	           (div:DI (reg:DI 0) (match_dup 2)))
7559	      (set (match_dup 3)
7560		   (mod:DI (reg:DI 0) (match_dup 2)))
7561	      (use (match_dup 3))
7562	      (clobber (reg:CC FLAGS_REG))])]
7563{
7564  /* Avoid use of cltd in favor of a mov+shift.  */
7565  if (!TARGET_USE_CLTD && !optimize_size)
7566    {
7567      if (true_regnum (operands[1]))
7568        emit_move_insn (operands[0], operands[1]);
7569      else
7570	emit_move_insn (operands[3], operands[1]);
7571      operands[4] = operands[3];
7572    }
7573  else
7574    {
7575      gcc_assert (!true_regnum (operands[1]));
7576      operands[4] = operands[1];
7577    }
7578})
7579
7580
7581(define_expand "divmodsi4"
7582  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7583		   (div:SI (match_operand:SI 1 "register_operand" "")
7584			   (match_operand:SI 2 "nonimmediate_operand" "")))
7585	      (set (match_operand:SI 3 "register_operand" "")
7586		   (mod:SI (match_dup 1) (match_dup 2)))
7587	      (clobber (reg:CC FLAGS_REG))])]
7588  ""
7589  "")
7590
7591;; Allow to come the parameter in eax or edx to avoid extra moves.
7592;; Penalize eax case slightly because it results in worse scheduling
7593;; of code.
7594(define_insn "*divmodsi4_nocltd"
7595  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7596	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7597		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7598   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7599	(mod:SI (match_dup 2) (match_dup 3)))
7600   (clobber (reg:CC FLAGS_REG))]
7601  "!optimize_size && !TARGET_USE_CLTD"
7602  "#"
7603  [(set_attr "type" "multi")])
7604
7605(define_insn "*divmodsi4_cltd"
7606  [(set (match_operand:SI 0 "register_operand" "=a")
7607	(div:SI (match_operand:SI 2 "register_operand" "a")
7608		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7609   (set (match_operand:SI 1 "register_operand" "=&d")
7610	(mod:SI (match_dup 2) (match_dup 3)))
7611   (clobber (reg:CC FLAGS_REG))]
7612  "optimize_size || TARGET_USE_CLTD"
7613  "#"
7614  [(set_attr "type" "multi")])
7615
7616(define_insn "*divmodsi_noext"
7617  [(set (match_operand:SI 0 "register_operand" "=a")
7618	(div:SI (match_operand:SI 1 "register_operand" "0")
7619		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7620   (set (match_operand:SI 3 "register_operand" "=d")
7621	(mod:SI (match_dup 1) (match_dup 2)))
7622   (use (match_operand:SI 4 "register_operand" "3"))
7623   (clobber (reg:CC FLAGS_REG))]
7624  ""
7625  "idiv{l}\t%2"
7626  [(set_attr "type" "idiv")
7627   (set_attr "mode" "SI")])
7628
7629(define_split
7630  [(set (match_operand:SI 0 "register_operand" "")
7631	(div:SI (match_operand:SI 1 "register_operand" "")
7632		(match_operand:SI 2 "nonimmediate_operand" "")))
7633   (set (match_operand:SI 3 "register_operand" "")
7634	(mod:SI (match_dup 1) (match_dup 2)))
7635   (clobber (reg:CC FLAGS_REG))]
7636  "reload_completed"
7637  [(parallel [(set (match_dup 3)
7638		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7639	      (clobber (reg:CC FLAGS_REG))])
7640   (parallel [(set (match_dup 0)
7641	           (div:SI (reg:SI 0) (match_dup 2)))
7642	      (set (match_dup 3)
7643		   (mod:SI (reg:SI 0) (match_dup 2)))
7644	      (use (match_dup 3))
7645	      (clobber (reg:CC FLAGS_REG))])]
7646{
7647  /* Avoid use of cltd in favor of a mov+shift.  */
7648  if (!TARGET_USE_CLTD && !optimize_size)
7649    {
7650      if (true_regnum (operands[1]))
7651        emit_move_insn (operands[0], operands[1]);
7652      else
7653	emit_move_insn (operands[3], operands[1]);
7654      operands[4] = operands[3];
7655    }
7656  else
7657    {
7658      gcc_assert (!true_regnum (operands[1]));
7659      operands[4] = operands[1];
7660    }
7661})
7662;; %%% Split me.
7663(define_insn "divmodhi4"
7664  [(set (match_operand:HI 0 "register_operand" "=a")
7665	(div:HI (match_operand:HI 1 "register_operand" "0")
7666		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7667   (set (match_operand:HI 3 "register_operand" "=&d")
7668	(mod:HI (match_dup 1) (match_dup 2)))
7669   (clobber (reg:CC FLAGS_REG))]
7670  "TARGET_HIMODE_MATH"
7671  "cwtd\;idiv{w}\t%2"
7672  [(set_attr "type" "multi")
7673   (set_attr "length_immediate" "0")
7674   (set_attr "mode" "SI")])
7675
7676(define_insn "udivmoddi4"
7677  [(set (match_operand:DI 0 "register_operand" "=a")
7678	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7679		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7680   (set (match_operand:DI 3 "register_operand" "=&d")
7681	(umod:DI (match_dup 1) (match_dup 2)))
7682   (clobber (reg:CC FLAGS_REG))]
7683  "TARGET_64BIT"
7684  "xor{q}\t%3, %3\;div{q}\t%2"
7685  [(set_attr "type" "multi")
7686   (set_attr "length_immediate" "0")
7687   (set_attr "mode" "DI")])
7688
7689(define_insn "*udivmoddi4_noext"
7690  [(set (match_operand:DI 0 "register_operand" "=a")
7691	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7692		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7693   (set (match_operand:DI 3 "register_operand" "=d")
7694	(umod:DI (match_dup 1) (match_dup 2)))
7695   (use (match_dup 3))
7696   (clobber (reg:CC FLAGS_REG))]
7697  "TARGET_64BIT"
7698  "div{q}\t%2"
7699  [(set_attr "type" "idiv")
7700   (set_attr "mode" "DI")])
7701
7702(define_split
7703  [(set (match_operand:DI 0 "register_operand" "")
7704	(udiv:DI (match_operand:DI 1 "register_operand" "")
7705		 (match_operand:DI 2 "nonimmediate_operand" "")))
7706   (set (match_operand:DI 3 "register_operand" "")
7707	(umod:DI (match_dup 1) (match_dup 2)))
7708   (clobber (reg:CC FLAGS_REG))]
7709  "TARGET_64BIT && reload_completed"
7710  [(set (match_dup 3) (const_int 0))
7711   (parallel [(set (match_dup 0)
7712		   (udiv:DI (match_dup 1) (match_dup 2)))
7713	      (set (match_dup 3)
7714		   (umod:DI (match_dup 1) (match_dup 2)))
7715	      (use (match_dup 3))
7716	      (clobber (reg:CC FLAGS_REG))])]
7717  "")
7718
7719(define_insn "udivmodsi4"
7720  [(set (match_operand:SI 0 "register_operand" "=a")
7721	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7722		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7723   (set (match_operand:SI 3 "register_operand" "=&d")
7724	(umod:SI (match_dup 1) (match_dup 2)))
7725   (clobber (reg:CC FLAGS_REG))]
7726  ""
7727  "xor{l}\t%3, %3\;div{l}\t%2"
7728  [(set_attr "type" "multi")
7729   (set_attr "length_immediate" "0")
7730   (set_attr "mode" "SI")])
7731
7732(define_insn "*udivmodsi4_noext"
7733  [(set (match_operand:SI 0 "register_operand" "=a")
7734	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7735		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7736   (set (match_operand:SI 3 "register_operand" "=d")
7737	(umod:SI (match_dup 1) (match_dup 2)))
7738   (use (match_dup 3))
7739   (clobber (reg:CC FLAGS_REG))]
7740  ""
7741  "div{l}\t%2"
7742  [(set_attr "type" "idiv")
7743   (set_attr "mode" "SI")])
7744
7745(define_split
7746  [(set (match_operand:SI 0 "register_operand" "")
7747	(udiv:SI (match_operand:SI 1 "register_operand" "")
7748		 (match_operand:SI 2 "nonimmediate_operand" "")))
7749   (set (match_operand:SI 3 "register_operand" "")
7750	(umod:SI (match_dup 1) (match_dup 2)))
7751   (clobber (reg:CC FLAGS_REG))]
7752  "reload_completed"
7753  [(set (match_dup 3) (const_int 0))
7754   (parallel [(set (match_dup 0)
7755		   (udiv:SI (match_dup 1) (match_dup 2)))
7756	      (set (match_dup 3)
7757		   (umod:SI (match_dup 1) (match_dup 2)))
7758	      (use (match_dup 3))
7759	      (clobber (reg:CC FLAGS_REG))])]
7760  "")
7761
7762(define_expand "udivmodhi4"
7763  [(set (match_dup 4) (const_int 0))
7764   (parallel [(set (match_operand:HI 0 "register_operand" "")
7765		   (udiv:HI (match_operand:HI 1 "register_operand" "")
7766		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
7767	      (set (match_operand:HI 3 "register_operand" "")
7768	   	   (umod:HI (match_dup 1) (match_dup 2)))
7769	      (use (match_dup 4))
7770	      (clobber (reg:CC FLAGS_REG))])]
7771  "TARGET_HIMODE_MATH"
7772  "operands[4] = gen_reg_rtx (HImode);")
7773
7774(define_insn "*udivmodhi_noext"
7775  [(set (match_operand:HI 0 "register_operand" "=a")
7776	(udiv:HI (match_operand:HI 1 "register_operand" "0")
7777		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7778   (set (match_operand:HI 3 "register_operand" "=d")
7779	(umod:HI (match_dup 1) (match_dup 2)))
7780   (use (match_operand:HI 4 "register_operand" "3"))
7781   (clobber (reg:CC FLAGS_REG))]
7782  ""
7783  "div{w}\t%2"
7784  [(set_attr "type" "idiv")
7785   (set_attr "mode" "HI")])
7786
7787;; We cannot use div/idiv for double division, because it causes
7788;; "division by zero" on the overflow and that's not what we expect
7789;; from truncate.  Because true (non truncating) double division is
7790;; never generated, we can't create this insn anyway.
7791;
7792;(define_insn ""
7793;  [(set (match_operand:SI 0 "register_operand" "=a")
7794;	(truncate:SI
7795;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7796;		   (zero_extend:DI
7797;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7798;   (set (match_operand:SI 3 "register_operand" "=d")
7799;	(truncate:SI
7800;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7801;   (clobber (reg:CC FLAGS_REG))]
7802;  ""
7803;  "div{l}\t{%2, %0|%0, %2}"
7804;  [(set_attr "type" "idiv")])
7805
7806;;- Logical AND instructions
7807
7808;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7809;; Note that this excludes ah.
7810
7811(define_insn "*testdi_1_rex64"
7812  [(set (reg FLAGS_REG)
7813	(compare
7814	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7815		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7816	  (const_int 0)))]
7817  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7818   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7819  "@
7820   test{l}\t{%k1, %k0|%k0, %k1}
7821   test{l}\t{%k1, %k0|%k0, %k1}
7822   test{q}\t{%1, %0|%0, %1}
7823   test{q}\t{%1, %0|%0, %1}
7824   test{q}\t{%1, %0|%0, %1}"
7825  [(set_attr "type" "test")
7826   (set_attr "modrm" "0,1,0,1,1")
7827   (set_attr "mode" "SI,SI,DI,DI,DI")
7828   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7829
7830(define_insn "testsi_1"
7831  [(set (reg FLAGS_REG)
7832	(compare
7833	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7834		  (match_operand:SI 1 "general_operand" "in,in,rin"))
7835	  (const_int 0)))]
7836  "ix86_match_ccmode (insn, CCNOmode)
7837   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7838  "test{l}\t{%1, %0|%0, %1}"
7839  [(set_attr "type" "test")
7840   (set_attr "modrm" "0,1,1")
7841   (set_attr "mode" "SI")
7842   (set_attr "pent_pair" "uv,np,uv")])
7843
7844(define_expand "testsi_ccno_1"
7845  [(set (reg:CCNO FLAGS_REG)
7846	(compare:CCNO
7847	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7848		  (match_operand:SI 1 "nonmemory_operand" ""))
7849	  (const_int 0)))]
7850  ""
7851  "")
7852
7853(define_insn "*testhi_1"
7854  [(set (reg FLAGS_REG)
7855        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7856			 (match_operand:HI 1 "general_operand" "n,n,rn"))
7857		 (const_int 0)))]
7858  "ix86_match_ccmode (insn, CCNOmode)
7859   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7860  "test{w}\t{%1, %0|%0, %1}"
7861  [(set_attr "type" "test")
7862   (set_attr "modrm" "0,1,1")
7863   (set_attr "mode" "HI")
7864   (set_attr "pent_pair" "uv,np,uv")])
7865
7866(define_expand "testqi_ccz_1"
7867  [(set (reg:CCZ FLAGS_REG)
7868        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7869			     (match_operand:QI 1 "nonmemory_operand" ""))
7870		 (const_int 0)))]
7871  ""
7872  "")
7873
7874(define_insn "*testqi_1_maybe_si"
7875  [(set (reg FLAGS_REG)
7876        (compare
7877	  (and:QI
7878	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7879	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7880	  (const_int 0)))]
7881   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7882    && ix86_match_ccmode (insn,
7883 			 GET_CODE (operands[1]) == CONST_INT
7884 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7885{
7886  if (which_alternative == 3)
7887    {
7888      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7889	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7890      return "test{l}\t{%1, %k0|%k0, %1}";
7891    }
7892  return "test{b}\t{%1, %0|%0, %1}";
7893}
7894  [(set_attr "type" "test")
7895   (set_attr "modrm" "0,1,1,1")
7896   (set_attr "mode" "QI,QI,QI,SI")
7897   (set_attr "pent_pair" "uv,np,uv,np")])
7898
7899(define_insn "*testqi_1"
7900  [(set (reg FLAGS_REG)
7901        (compare
7902	  (and:QI
7903	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7904	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7905	  (const_int 0)))]
7906  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7907   && ix86_match_ccmode (insn, CCNOmode)"
7908  "test{b}\t{%1, %0|%0, %1}"
7909  [(set_attr "type" "test")
7910   (set_attr "modrm" "0,1,1")
7911   (set_attr "mode" "QI")
7912   (set_attr "pent_pair" "uv,np,uv")])
7913
7914(define_expand "testqi_ext_ccno_0"
7915  [(set (reg:CCNO FLAGS_REG)
7916	(compare:CCNO
7917	  (and:SI
7918	    (zero_extract:SI
7919	      (match_operand 0 "ext_register_operand" "")
7920	      (const_int 8)
7921	      (const_int 8))
7922	    (match_operand 1 "const_int_operand" ""))
7923	  (const_int 0)))]
7924  ""
7925  "")
7926
7927(define_insn "*testqi_ext_0"
7928  [(set (reg FLAGS_REG)
7929	(compare
7930	  (and:SI
7931	    (zero_extract:SI
7932	      (match_operand 0 "ext_register_operand" "Q")
7933	      (const_int 8)
7934	      (const_int 8))
7935	    (match_operand 1 "const_int_operand" "n"))
7936	  (const_int 0)))]
7937  "ix86_match_ccmode (insn, CCNOmode)"
7938  "test{b}\t{%1, %h0|%h0, %1}"
7939  [(set_attr "type" "test")
7940   (set_attr "mode" "QI")
7941   (set_attr "length_immediate" "1")
7942   (set_attr "pent_pair" "np")])
7943
7944(define_insn "*testqi_ext_1"
7945  [(set (reg FLAGS_REG)
7946	(compare
7947	  (and:SI
7948	    (zero_extract:SI
7949	      (match_operand 0 "ext_register_operand" "Q")
7950	      (const_int 8)
7951	      (const_int 8))
7952	    (zero_extend:SI
7953	      (match_operand:QI 1 "general_operand" "Qm")))
7954	  (const_int 0)))]
7955  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7956   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7957  "test{b}\t{%1, %h0|%h0, %1}"
7958  [(set_attr "type" "test")
7959   (set_attr "mode" "QI")])
7960
7961(define_insn "*testqi_ext_1_rex64"
7962  [(set (reg FLAGS_REG)
7963	(compare
7964	  (and:SI
7965	    (zero_extract:SI
7966	      (match_operand 0 "ext_register_operand" "Q")
7967	      (const_int 8)
7968	      (const_int 8))
7969	    (zero_extend:SI
7970	      (match_operand:QI 1 "register_operand" "Q")))
7971	  (const_int 0)))]
7972  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7973  "test{b}\t{%1, %h0|%h0, %1}"
7974  [(set_attr "type" "test")
7975   (set_attr "mode" "QI")])
7976
7977(define_insn "*testqi_ext_2"
7978  [(set (reg FLAGS_REG)
7979	(compare
7980	  (and:SI
7981	    (zero_extract:SI
7982	      (match_operand 0 "ext_register_operand" "Q")
7983	      (const_int 8)
7984	      (const_int 8))
7985	    (zero_extract:SI
7986	      (match_operand 1 "ext_register_operand" "Q")
7987	      (const_int 8)
7988	      (const_int 8)))
7989	  (const_int 0)))]
7990  "ix86_match_ccmode (insn, CCNOmode)"
7991  "test{b}\t{%h1, %h0|%h0, %h1}"
7992  [(set_attr "type" "test")
7993   (set_attr "mode" "QI")])
7994
7995;; Combine likes to form bit extractions for some tests.  Humor it.
7996(define_insn "*testqi_ext_3"
7997  [(set (reg FLAGS_REG)
7998        (compare (zero_extract:SI
7999		   (match_operand 0 "nonimmediate_operand" "rm")
8000		   (match_operand:SI 1 "const_int_operand" "")
8001		   (match_operand:SI 2 "const_int_operand" ""))
8002		 (const_int 0)))]
8003  "ix86_match_ccmode (insn, CCNOmode)
8004   && INTVAL (operands[1]) > 0
8005   && INTVAL (operands[2]) >= 0
8006   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8007   && (GET_MODE (operands[0]) == SImode
8008       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8009       || GET_MODE (operands[0]) == HImode
8010       || GET_MODE (operands[0]) == QImode)"
8011  "#")
8012
8013(define_insn "*testqi_ext_3_rex64"
8014  [(set (reg FLAGS_REG)
8015        (compare (zero_extract:DI
8016		   (match_operand 0 "nonimmediate_operand" "rm")
8017		   (match_operand:DI 1 "const_int_operand" "")
8018		   (match_operand:DI 2 "const_int_operand" ""))
8019		 (const_int 0)))]
8020  "TARGET_64BIT
8021   && ix86_match_ccmode (insn, CCNOmode)
8022   && INTVAL (operands[1]) > 0
8023   && INTVAL (operands[2]) >= 0
8024   /* Ensure that resulting mask is zero or sign extended operand.  */
8025   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8026       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8027	   && INTVAL (operands[1]) > 32))
8028   && (GET_MODE (operands[0]) == SImode
8029       || GET_MODE (operands[0]) == DImode
8030       || GET_MODE (operands[0]) == HImode
8031       || GET_MODE (operands[0]) == QImode)"
8032  "#")
8033
8034(define_split
8035  [(set (match_operand 0 "flags_reg_operand" "")
8036        (match_operator 1 "compare_operator"
8037	  [(zero_extract
8038	     (match_operand 2 "nonimmediate_operand" "")
8039	     (match_operand 3 "const_int_operand" "")
8040	     (match_operand 4 "const_int_operand" ""))
8041	   (const_int 0)]))]
8042  "ix86_match_ccmode (insn, CCNOmode)"
8043  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8044{
8045  rtx val = operands[2];
8046  HOST_WIDE_INT len = INTVAL (operands[3]);
8047  HOST_WIDE_INT pos = INTVAL (operands[4]);
8048  HOST_WIDE_INT mask;
8049  enum machine_mode mode, submode;
8050
8051  mode = GET_MODE (val);
8052  if (GET_CODE (val) == MEM)
8053    {
8054      /* ??? Combine likes to put non-volatile mem extractions in QImode
8055	 no matter the size of the test.  So find a mode that works.  */
8056      if (! MEM_VOLATILE_P (val))
8057	{
8058	  mode = smallest_mode_for_size (pos + len, MODE_INT);
8059	  val = adjust_address (val, mode, 0);
8060	}
8061    }
8062  else if (GET_CODE (val) == SUBREG
8063	   && (submode = GET_MODE (SUBREG_REG (val)),
8064	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8065	   && pos + len <= GET_MODE_BITSIZE (submode))
8066    {
8067      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8068      mode = submode;
8069      val = SUBREG_REG (val);
8070    }
8071  else if (mode == HImode && pos + len <= 8)
8072    {
8073      /* Small HImode tests can be converted to QImode.  */
8074      mode = QImode;
8075      val = gen_lowpart (QImode, val);
8076    }
8077
8078  if (len == HOST_BITS_PER_WIDE_INT)
8079    mask = -1;
8080  else
8081    mask = ((HOST_WIDE_INT)1 << len) - 1;
8082  mask <<= pos;
8083
8084  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8085})
8086
8087;; Convert HImode/SImode test instructions with immediate to QImode ones.
8088;; i386 does not allow to encode test with 8bit sign extended immediate, so
8089;; this is relatively important trick.
8090;; Do the conversion only post-reload to avoid limiting of the register class
8091;; to QI regs.
8092(define_split
8093  [(set (match_operand 0 "flags_reg_operand" "")
8094	(match_operator 1 "compare_operator"
8095	  [(and (match_operand 2 "register_operand" "")
8096	        (match_operand 3 "const_int_operand" ""))
8097	   (const_int 0)]))]
8098   "reload_completed
8099    && QI_REG_P (operands[2])
8100    && GET_MODE (operands[2]) != QImode
8101    && ((ix86_match_ccmode (insn, CCZmode)
8102    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8103	|| (ix86_match_ccmode (insn, CCNOmode)
8104	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8105  [(set (match_dup 0)
8106	(match_op_dup 1
8107	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8108		   (match_dup 3))
8109	   (const_int 0)]))]
8110  "operands[2] = gen_lowpart (SImode, operands[2]);
8111   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8112
8113(define_split
8114  [(set (match_operand 0 "flags_reg_operand" "")
8115	(match_operator 1 "compare_operator"
8116	  [(and (match_operand 2 "nonimmediate_operand" "")
8117	        (match_operand 3 "const_int_operand" ""))
8118	   (const_int 0)]))]
8119   "reload_completed
8120    && GET_MODE (operands[2]) != QImode
8121    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8122    && ((ix86_match_ccmode (insn, CCZmode)
8123	 && !(INTVAL (operands[3]) & ~255))
8124	|| (ix86_match_ccmode (insn, CCNOmode)
8125	    && !(INTVAL (operands[3]) & ~127)))"
8126  [(set (match_dup 0)
8127	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8128			 (const_int 0)]))]
8129  "operands[2] = gen_lowpart (QImode, operands[2]);
8130   operands[3] = gen_lowpart (QImode, operands[3]);")
8131
8132
8133;; %%% This used to optimize known byte-wide and operations to memory,
8134;; and sometimes to QImode registers.  If this is considered useful,
8135;; it should be done with splitters.
8136
8137(define_expand "anddi3"
8138  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8139	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8140		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8141   (clobber (reg:CC FLAGS_REG))]
8142  "TARGET_64BIT"
8143  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8144
8145(define_insn "*anddi_1_rex64"
8146  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8147	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8148		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8149   (clobber (reg:CC FLAGS_REG))]
8150  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8151{
8152  switch (get_attr_type (insn))
8153    {
8154    case TYPE_IMOVX:
8155      {
8156	enum machine_mode mode;
8157
8158	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8159        if (INTVAL (operands[2]) == 0xff)
8160	  mode = QImode;
8161	else
8162	  {
8163	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8164	    mode = HImode;
8165	  }
8166	
8167	operands[1] = gen_lowpart (mode, operands[1]);
8168	if (mode == QImode)
8169	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8170	else
8171	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8172      }
8173
8174    default:
8175      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8176      if (get_attr_mode (insn) == MODE_SI)
8177	return "and{l}\t{%k2, %k0|%k0, %k2}";
8178      else
8179	return "and{q}\t{%2, %0|%0, %2}";
8180    }
8181}
8182  [(set_attr "type" "alu,alu,alu,imovx")
8183   (set_attr "length_immediate" "*,*,*,0")
8184   (set_attr "mode" "SI,DI,DI,DI")])
8185
8186(define_insn "*anddi_2"
8187  [(set (reg FLAGS_REG)
8188	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8189			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8190		 (const_int 0)))
8191   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8192	(and:DI (match_dup 1) (match_dup 2)))]
8193  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8194   && ix86_binary_operator_ok (AND, DImode, operands)"
8195  "@
8196   and{l}\t{%k2, %k0|%k0, %k2}
8197   and{q}\t{%2, %0|%0, %2}
8198   and{q}\t{%2, %0|%0, %2}"
8199  [(set_attr "type" "alu")
8200   (set_attr "mode" "SI,DI,DI")])
8201
8202(define_expand "andsi3"
8203  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8204	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8205		(match_operand:SI 2 "general_operand" "")))
8206   (clobber (reg:CC FLAGS_REG))]
8207  ""
8208  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8209
8210(define_insn "*andsi_1"
8211  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8212	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8213		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8214   (clobber (reg:CC FLAGS_REG))]
8215  "ix86_binary_operator_ok (AND, SImode, operands)"
8216{
8217  switch (get_attr_type (insn))
8218    {
8219    case TYPE_IMOVX:
8220      {
8221	enum machine_mode mode;
8222
8223	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8224        if (INTVAL (operands[2]) == 0xff)
8225	  mode = QImode;
8226	else
8227	  {
8228	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8229	    mode = HImode;
8230	  }
8231	
8232	operands[1] = gen_lowpart (mode, operands[1]);
8233	if (mode == QImode)
8234	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8235	else
8236	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8237      }
8238
8239    default:
8240      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8241      return "and{l}\t{%2, %0|%0, %2}";
8242    }
8243}
8244  [(set_attr "type" "alu,alu,imovx")
8245   (set_attr "length_immediate" "*,*,0")
8246   (set_attr "mode" "SI")])
8247
8248(define_split
8249  [(set (match_operand 0 "register_operand" "")
8250	(and (match_dup 0)
8251	     (const_int -65536)))
8252   (clobber (reg:CC FLAGS_REG))]
8253  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8254  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8255  "operands[1] = gen_lowpart (HImode, operands[0]);")
8256
8257(define_split
8258  [(set (match_operand 0 "ext_register_operand" "")
8259	(and (match_dup 0)
8260	     (const_int -256)))
8261   (clobber (reg:CC FLAGS_REG))]
8262  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8263  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8264  "operands[1] = gen_lowpart (QImode, operands[0]);")
8265
8266(define_split
8267  [(set (match_operand 0 "ext_register_operand" "")
8268	(and (match_dup 0)
8269	     (const_int -65281)))
8270   (clobber (reg:CC FLAGS_REG))]
8271  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8272  [(parallel [(set (zero_extract:SI (match_dup 0)
8273				    (const_int 8)
8274				    (const_int 8))
8275		   (xor:SI 
8276		     (zero_extract:SI (match_dup 0)
8277				      (const_int 8)
8278				      (const_int 8))
8279		     (zero_extract:SI (match_dup 0)
8280				      (const_int 8)
8281				      (const_int 8))))
8282	      (clobber (reg:CC FLAGS_REG))])]
8283  "operands[0] = gen_lowpart (SImode, operands[0]);")
8284
8285;; See comment for addsi_1_zext why we do use nonimmediate_operand
8286(define_insn "*andsi_1_zext"
8287  [(set (match_operand:DI 0 "register_operand" "=r")
8288	(zero_extend:DI
8289	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8290		  (match_operand:SI 2 "general_operand" "rim"))))
8291   (clobber (reg:CC FLAGS_REG))]
8292  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8293  "and{l}\t{%2, %k0|%k0, %2}"
8294  [(set_attr "type" "alu")
8295   (set_attr "mode" "SI")])
8296
8297(define_insn "*andsi_2"
8298  [(set (reg FLAGS_REG)
8299	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8300			 (match_operand:SI 2 "general_operand" "rim,ri"))
8301		 (const_int 0)))
8302   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8303	(and:SI (match_dup 1) (match_dup 2)))]
8304  "ix86_match_ccmode (insn, CCNOmode)
8305   && ix86_binary_operator_ok (AND, SImode, operands)"
8306  "and{l}\t{%2, %0|%0, %2}"
8307  [(set_attr "type" "alu")
8308   (set_attr "mode" "SI")])
8309
8310;; See comment for addsi_1_zext why we do use nonimmediate_operand
8311(define_insn "*andsi_2_zext"
8312  [(set (reg FLAGS_REG)
8313	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8314			 (match_operand:SI 2 "general_operand" "rim"))
8315		 (const_int 0)))
8316   (set (match_operand:DI 0 "register_operand" "=r")
8317	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8318  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8319   && ix86_binary_operator_ok (AND, SImode, operands)"
8320  "and{l}\t{%2, %k0|%k0, %2}"
8321  [(set_attr "type" "alu")
8322   (set_attr "mode" "SI")])
8323
8324(define_expand "andhi3"
8325  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8326	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8327		(match_operand:HI 2 "general_operand" "")))
8328   (clobber (reg:CC FLAGS_REG))]
8329  "TARGET_HIMODE_MATH"
8330  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8331
8332(define_insn "*andhi_1"
8333  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8334	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8335		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8336   (clobber (reg:CC FLAGS_REG))]
8337  "ix86_binary_operator_ok (AND, HImode, operands)"
8338{
8339  switch (get_attr_type (insn))
8340    {
8341    case TYPE_IMOVX:
8342      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8343      gcc_assert (INTVAL (operands[2]) == 0xff);
8344      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8345
8346    default:
8347      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8348
8349      return "and{w}\t{%2, %0|%0, %2}";
8350    }
8351}
8352  [(set_attr "type" "alu,alu,imovx")
8353   (set_attr "length_immediate" "*,*,0")
8354   (set_attr "mode" "HI,HI,SI")])
8355
8356(define_insn "*andhi_2"
8357  [(set (reg FLAGS_REG)
8358	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8359			 (match_operand:HI 2 "general_operand" "rim,ri"))
8360		 (const_int 0)))
8361   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8362	(and:HI (match_dup 1) (match_dup 2)))]
8363  "ix86_match_ccmode (insn, CCNOmode)
8364   && ix86_binary_operator_ok (AND, HImode, operands)"
8365  "and{w}\t{%2, %0|%0, %2}"
8366  [(set_attr "type" "alu")
8367   (set_attr "mode" "HI")])
8368
8369(define_expand "andqi3"
8370  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8371	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8372		(match_operand:QI 2 "general_operand" "")))
8373   (clobber (reg:CC FLAGS_REG))]
8374  "TARGET_QIMODE_MATH"
8375  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8376
8377;; %%% Potential partial reg stall on alternative 2.  What to do?
8378(define_insn "*andqi_1"
8379  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8380	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8381		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8382   (clobber (reg:CC FLAGS_REG))]
8383  "ix86_binary_operator_ok (AND, QImode, operands)"
8384  "@
8385   and{b}\t{%2, %0|%0, %2}
8386   and{b}\t{%2, %0|%0, %2}
8387   and{l}\t{%k2, %k0|%k0, %k2}"
8388  [(set_attr "type" "alu")
8389   (set_attr "mode" "QI,QI,SI")])
8390
8391(define_insn "*andqi_1_slp"
8392  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8393	(and:QI (match_dup 0)
8394		(match_operand:QI 1 "general_operand" "qi,qmi")))
8395   (clobber (reg:CC FLAGS_REG))]
8396  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8397   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8398  "and{b}\t{%1, %0|%0, %1}"
8399  [(set_attr "type" "alu1")
8400   (set_attr "mode" "QI")])
8401
8402(define_insn "*andqi_2_maybe_si"
8403  [(set (reg FLAGS_REG)
8404	(compare (and:QI
8405		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8406		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8407		 (const_int 0)))
8408   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8409	(and:QI (match_dup 1) (match_dup 2)))]
8410  "ix86_binary_operator_ok (AND, QImode, operands)
8411   && ix86_match_ccmode (insn,
8412			 GET_CODE (operands[2]) == CONST_INT
8413			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8414{
8415  if (which_alternative == 2)
8416    {
8417      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8418        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8419      return "and{l}\t{%2, %k0|%k0, %2}";
8420    }
8421  return "and{b}\t{%2, %0|%0, %2}";
8422}
8423  [(set_attr "type" "alu")
8424   (set_attr "mode" "QI,QI,SI")])
8425
8426(define_insn "*andqi_2"
8427  [(set (reg FLAGS_REG)
8428	(compare (and:QI
8429		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8430		   (match_operand:QI 2 "general_operand" "qim,qi"))
8431		 (const_int 0)))
8432   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8433	(and:QI (match_dup 1) (match_dup 2)))]
8434  "ix86_match_ccmode (insn, CCNOmode)
8435   && ix86_binary_operator_ok (AND, QImode, operands)"
8436  "and{b}\t{%2, %0|%0, %2}"
8437  [(set_attr "type" "alu")
8438   (set_attr "mode" "QI")])
8439
8440(define_insn "*andqi_2_slp"
8441  [(set (reg FLAGS_REG)
8442	(compare (and:QI
8443		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8444		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8445		 (const_int 0)))
8446   (set (strict_low_part (match_dup 0))
8447	(and:QI (match_dup 0) (match_dup 1)))]
8448  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8449   && ix86_match_ccmode (insn, CCNOmode)
8450   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8451  "and{b}\t{%1, %0|%0, %1}"
8452  [(set_attr "type" "alu1")
8453   (set_attr "mode" "QI")])
8454
8455;; ??? A bug in recog prevents it from recognizing a const_int as an
8456;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8457;; for a QImode operand, which of course failed.
8458
8459(define_insn "andqi_ext_0"
8460  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8461			 (const_int 8)
8462			 (const_int 8))
8463	(and:SI 
8464	  (zero_extract:SI
8465	    (match_operand 1 "ext_register_operand" "0")
8466	    (const_int 8)
8467	    (const_int 8))
8468	  (match_operand 2 "const_int_operand" "n")))
8469   (clobber (reg:CC FLAGS_REG))]
8470  ""
8471  "and{b}\t{%2, %h0|%h0, %2}"
8472  [(set_attr "type" "alu")
8473   (set_attr "length_immediate" "1")
8474   (set_attr "mode" "QI")])
8475
8476;; Generated by peephole translating test to and.  This shows up
8477;; often in fp comparisons.
8478
8479(define_insn "*andqi_ext_0_cc"
8480  [(set (reg FLAGS_REG)
8481	(compare
8482	  (and:SI
8483	    (zero_extract:SI
8484	      (match_operand 1 "ext_register_operand" "0")
8485	      (const_int 8)
8486	      (const_int 8))
8487	    (match_operand 2 "const_int_operand" "n"))
8488	  (const_int 0)))
8489   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8490			 (const_int 8)
8491			 (const_int 8))
8492	(and:SI 
8493	  (zero_extract:SI
8494	    (match_dup 1)
8495	    (const_int 8)
8496	    (const_int 8))
8497	  (match_dup 2)))]
8498  "ix86_match_ccmode (insn, CCNOmode)"
8499  "and{b}\t{%2, %h0|%h0, %2}"
8500  [(set_attr "type" "alu")
8501   (set_attr "length_immediate" "1")
8502   (set_attr "mode" "QI")])
8503
8504(define_insn "*andqi_ext_1"
8505  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8506			 (const_int 8)
8507			 (const_int 8))
8508	(and:SI 
8509	  (zero_extract:SI
8510	    (match_operand 1 "ext_register_operand" "0")
8511	    (const_int 8)
8512	    (const_int 8))
8513	  (zero_extend:SI
8514	    (match_operand:QI 2 "general_operand" "Qm"))))
8515   (clobber (reg:CC FLAGS_REG))]
8516  "!TARGET_64BIT"
8517  "and{b}\t{%2, %h0|%h0, %2}"
8518  [(set_attr "type" "alu")
8519   (set_attr "length_immediate" "0")
8520   (set_attr "mode" "QI")])
8521
8522(define_insn "*andqi_ext_1_rex64"
8523  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8524			 (const_int 8)
8525			 (const_int 8))
8526	(and:SI 
8527	  (zero_extract:SI
8528	    (match_operand 1 "ext_register_operand" "0")
8529	    (const_int 8)
8530	    (const_int 8))
8531	  (zero_extend:SI
8532	    (match_operand 2 "ext_register_operand" "Q"))))
8533   (clobber (reg:CC FLAGS_REG))]
8534  "TARGET_64BIT"
8535  "and{b}\t{%2, %h0|%h0, %2}"
8536  [(set_attr "type" "alu")
8537   (set_attr "length_immediate" "0")
8538   (set_attr "mode" "QI")])
8539
8540(define_insn "*andqi_ext_2"
8541  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8542			 (const_int 8)
8543			 (const_int 8))
8544	(and:SI
8545	  (zero_extract:SI
8546	    (match_operand 1 "ext_register_operand" "%0")
8547	    (const_int 8)
8548	    (const_int 8))
8549	  (zero_extract:SI
8550	    (match_operand 2 "ext_register_operand" "Q")
8551	    (const_int 8)
8552	    (const_int 8))))
8553   (clobber (reg:CC FLAGS_REG))]
8554  ""
8555  "and{b}\t{%h2, %h0|%h0, %h2}"
8556  [(set_attr "type" "alu")
8557   (set_attr "length_immediate" "0")
8558   (set_attr "mode" "QI")])
8559
8560;; Convert wide AND instructions with immediate operand to shorter QImode
8561;; equivalents when possible.
8562;; Don't do the splitting with memory operands, since it introduces risk
8563;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8564;; for size, but that can (should?) be handled by generic code instead.
8565(define_split
8566  [(set (match_operand 0 "register_operand" "")
8567	(and (match_operand 1 "register_operand" "")
8568	     (match_operand 2 "const_int_operand" "")))
8569   (clobber (reg:CC FLAGS_REG))]
8570   "reload_completed
8571    && QI_REG_P (operands[0])
8572    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8573    && !(~INTVAL (operands[2]) & ~(255 << 8))
8574    && GET_MODE (operands[0]) != QImode"
8575  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8576		   (and:SI (zero_extract:SI (match_dup 1)
8577					    (const_int 8) (const_int 8))
8578			   (match_dup 2)))
8579	      (clobber (reg:CC FLAGS_REG))])]
8580  "operands[0] = gen_lowpart (SImode, operands[0]);
8581   operands[1] = gen_lowpart (SImode, operands[1]);
8582   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8583
8584;; Since AND can be encoded with sign extended immediate, this is only
8585;; profitable when 7th bit is not set.
8586(define_split
8587  [(set (match_operand 0 "register_operand" "")
8588	(and (match_operand 1 "general_operand" "")
8589	     (match_operand 2 "const_int_operand" "")))
8590   (clobber (reg:CC FLAGS_REG))]
8591   "reload_completed
8592    && ANY_QI_REG_P (operands[0])
8593    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8594    && !(~INTVAL (operands[2]) & ~255)
8595    && !(INTVAL (operands[2]) & 128)
8596    && GET_MODE (operands[0]) != QImode"
8597  [(parallel [(set (strict_low_part (match_dup 0))
8598		   (and:QI (match_dup 1)
8599			   (match_dup 2)))
8600	      (clobber (reg:CC FLAGS_REG))])]
8601  "operands[0] = gen_lowpart (QImode, operands[0]);
8602   operands[1] = gen_lowpart (QImode, operands[1]);
8603   operands[2] = gen_lowpart (QImode, operands[2]);")
8604
8605;; Logical inclusive OR instructions
8606
8607;; %%% This used to optimize known byte-wide and operations to memory.
8608;; If this is considered useful, it should be done with splitters.
8609
8610(define_expand "iordi3"
8611  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8612	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8613		(match_operand:DI 2 "x86_64_general_operand" "")))
8614   (clobber (reg:CC FLAGS_REG))]
8615  "TARGET_64BIT"
8616  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8617
8618(define_insn "*iordi_1_rex64"
8619  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8620	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8621		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8622   (clobber (reg:CC FLAGS_REG))]
8623  "TARGET_64BIT
8624   && ix86_binary_operator_ok (IOR, DImode, operands)"
8625  "or{q}\t{%2, %0|%0, %2}"
8626  [(set_attr "type" "alu")
8627   (set_attr "mode" "DI")])
8628
8629(define_insn "*iordi_2_rex64"
8630  [(set (reg FLAGS_REG)
8631	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8632			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8633		 (const_int 0)))
8634   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8635	(ior:DI (match_dup 1) (match_dup 2)))]
8636  "TARGET_64BIT
8637   && ix86_match_ccmode (insn, CCNOmode)
8638   && ix86_binary_operator_ok (IOR, DImode, operands)"
8639  "or{q}\t{%2, %0|%0, %2}"
8640  [(set_attr "type" "alu")
8641   (set_attr "mode" "DI")])
8642
8643(define_insn "*iordi_3_rex64"
8644  [(set (reg FLAGS_REG)
8645	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8646			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8647		 (const_int 0)))
8648   (clobber (match_scratch:DI 0 "=r"))]
8649  "TARGET_64BIT
8650   && ix86_match_ccmode (insn, CCNOmode)
8651   && ix86_binary_operator_ok (IOR, DImode, operands)"
8652  "or{q}\t{%2, %0|%0, %2}"
8653  [(set_attr "type" "alu")
8654   (set_attr "mode" "DI")])
8655
8656
8657(define_expand "iorsi3"
8658  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8659	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8660		(match_operand:SI 2 "general_operand" "")))
8661   (clobber (reg:CC FLAGS_REG))]
8662  ""
8663  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8664
8665(define_insn "*iorsi_1"
8666  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8667	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8668		(match_operand:SI 2 "general_operand" "ri,rmi")))
8669   (clobber (reg:CC FLAGS_REG))]
8670  "ix86_binary_operator_ok (IOR, SImode, operands)"
8671  "or{l}\t{%2, %0|%0, %2}"
8672  [(set_attr "type" "alu")
8673   (set_attr "mode" "SI")])
8674
8675;; See comment for addsi_1_zext why we do use nonimmediate_operand
8676(define_insn "*iorsi_1_zext"
8677  [(set (match_operand:DI 0 "register_operand" "=rm")
8678	(zero_extend:DI
8679	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680		  (match_operand:SI 2 "general_operand" "rim"))))
8681   (clobber (reg:CC FLAGS_REG))]
8682  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8683  "or{l}\t{%2, %k0|%k0, %2}"
8684  [(set_attr "type" "alu")
8685   (set_attr "mode" "SI")])
8686
8687(define_insn "*iorsi_1_zext_imm"
8688  [(set (match_operand:DI 0 "register_operand" "=rm")
8689	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8690		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8691   (clobber (reg:CC FLAGS_REG))]
8692  "TARGET_64BIT"
8693  "or{l}\t{%2, %k0|%k0, %2}"
8694  [(set_attr "type" "alu")
8695   (set_attr "mode" "SI")])
8696
8697(define_insn "*iorsi_2"
8698  [(set (reg FLAGS_REG)
8699	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8700			 (match_operand:SI 2 "general_operand" "rim,ri"))
8701		 (const_int 0)))
8702   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8703	(ior:SI (match_dup 1) (match_dup 2)))]
8704  "ix86_match_ccmode (insn, CCNOmode)
8705   && ix86_binary_operator_ok (IOR, SImode, operands)"
8706  "or{l}\t{%2, %0|%0, %2}"
8707  [(set_attr "type" "alu")
8708   (set_attr "mode" "SI")])
8709
8710;; See comment for addsi_1_zext why we do use nonimmediate_operand
8711;; ??? Special case for immediate operand is missing - it is tricky.
8712(define_insn "*iorsi_2_zext"
8713  [(set (reg FLAGS_REG)
8714	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8715			 (match_operand:SI 2 "general_operand" "rim"))
8716		 (const_int 0)))
8717   (set (match_operand:DI 0 "register_operand" "=r")
8718	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8719  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8720   && ix86_binary_operator_ok (IOR, SImode, operands)"
8721  "or{l}\t{%2, %k0|%k0, %2}"
8722  [(set_attr "type" "alu")
8723   (set_attr "mode" "SI")])
8724
8725(define_insn "*iorsi_2_zext_imm"
8726  [(set (reg FLAGS_REG)
8727	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8728			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8729		 (const_int 0)))
8730   (set (match_operand:DI 0 "register_operand" "=r")
8731	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8732  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8733   && ix86_binary_operator_ok (IOR, SImode, operands)"
8734  "or{l}\t{%2, %k0|%k0, %2}"
8735  [(set_attr "type" "alu")
8736   (set_attr "mode" "SI")])
8737
8738(define_insn "*iorsi_3"
8739  [(set (reg FLAGS_REG)
8740	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8741			 (match_operand:SI 2 "general_operand" "rim"))
8742		 (const_int 0)))
8743   (clobber (match_scratch:SI 0 "=r"))]
8744  "ix86_match_ccmode (insn, CCNOmode)
8745   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8746  "or{l}\t{%2, %0|%0, %2}"
8747  [(set_attr "type" "alu")
8748   (set_attr "mode" "SI")])
8749
8750(define_expand "iorhi3"
8751  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8752	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8753		(match_operand:HI 2 "general_operand" "")))
8754   (clobber (reg:CC FLAGS_REG))]
8755  "TARGET_HIMODE_MATH"
8756  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8757
8758(define_insn "*iorhi_1"
8759  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8760	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8761		(match_operand:HI 2 "general_operand" "rmi,ri")))
8762   (clobber (reg:CC FLAGS_REG))]
8763  "ix86_binary_operator_ok (IOR, HImode, operands)"
8764  "or{w}\t{%2, %0|%0, %2}"
8765  [(set_attr "type" "alu")
8766   (set_attr "mode" "HI")])
8767
8768(define_insn "*iorhi_2"
8769  [(set (reg FLAGS_REG)
8770	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8771			 (match_operand:HI 2 "general_operand" "rim,ri"))
8772		 (const_int 0)))
8773   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8774	(ior:HI (match_dup 1) (match_dup 2)))]
8775  "ix86_match_ccmode (insn, CCNOmode)
8776   && ix86_binary_operator_ok (IOR, HImode, operands)"
8777  "or{w}\t{%2, %0|%0, %2}"
8778  [(set_attr "type" "alu")
8779   (set_attr "mode" "HI")])
8780
8781(define_insn "*iorhi_3"
8782  [(set (reg FLAGS_REG)
8783	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8784			 (match_operand:HI 2 "general_operand" "rim"))
8785		 (const_int 0)))
8786   (clobber (match_scratch:HI 0 "=r"))]
8787  "ix86_match_ccmode (insn, CCNOmode)
8788   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8789  "or{w}\t{%2, %0|%0, %2}"
8790  [(set_attr "type" "alu")
8791   (set_attr "mode" "HI")])
8792
8793(define_expand "iorqi3"
8794  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8795	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8796		(match_operand:QI 2 "general_operand" "")))
8797   (clobber (reg:CC FLAGS_REG))]
8798  "TARGET_QIMODE_MATH"
8799  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8800
8801;; %%% Potential partial reg stall on alternative 2.  What to do?
8802(define_insn "*iorqi_1"
8803  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8804	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8805		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8806   (clobber (reg:CC FLAGS_REG))]
8807  "ix86_binary_operator_ok (IOR, QImode, operands)"
8808  "@
8809   or{b}\t{%2, %0|%0, %2}
8810   or{b}\t{%2, %0|%0, %2}
8811   or{l}\t{%k2, %k0|%k0, %k2}"
8812  [(set_attr "type" "alu")
8813   (set_attr "mode" "QI,QI,SI")])
8814
8815(define_insn "*iorqi_1_slp"
8816  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8817	(ior:QI (match_dup 0)
8818		(match_operand:QI 1 "general_operand" "qmi,qi")))
8819   (clobber (reg:CC FLAGS_REG))]
8820  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8821   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8822  "or{b}\t{%1, %0|%0, %1}"
8823  [(set_attr "type" "alu1")
8824   (set_attr "mode" "QI")])
8825
8826(define_insn "*iorqi_2"
8827  [(set (reg FLAGS_REG)
8828	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8829			 (match_operand:QI 2 "general_operand" "qim,qi"))
8830		 (const_int 0)))
8831   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8832	(ior:QI (match_dup 1) (match_dup 2)))]
8833  "ix86_match_ccmode (insn, CCNOmode)
8834   && ix86_binary_operator_ok (IOR, QImode, operands)"
8835  "or{b}\t{%2, %0|%0, %2}"
8836  [(set_attr "type" "alu")
8837   (set_attr "mode" "QI")])
8838
8839(define_insn "*iorqi_2_slp"
8840  [(set (reg FLAGS_REG)
8841	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8842			 (match_operand:QI 1 "general_operand" "qim,qi"))
8843		 (const_int 0)))
8844   (set (strict_low_part (match_dup 0))
8845	(ior:QI (match_dup 0) (match_dup 1)))]
8846  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8847   && ix86_match_ccmode (insn, CCNOmode)
8848   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8849  "or{b}\t{%1, %0|%0, %1}"
8850  [(set_attr "type" "alu1")
8851   (set_attr "mode" "QI")])
8852
8853(define_insn "*iorqi_3"
8854  [(set (reg FLAGS_REG)
8855	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8856			 (match_operand:QI 2 "general_operand" "qim"))
8857		 (const_int 0)))
8858   (clobber (match_scratch:QI 0 "=q"))]
8859  "ix86_match_ccmode (insn, CCNOmode)
8860   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8861  "or{b}\t{%2, %0|%0, %2}"
8862  [(set_attr "type" "alu")
8863   (set_attr "mode" "QI")])
8864
8865(define_insn "iorqi_ext_0"
8866  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8867			 (const_int 8)
8868			 (const_int 8))
8869	(ior:SI 
8870	  (zero_extract:SI
8871	    (match_operand 1 "ext_register_operand" "0")
8872	    (const_int 8)
8873	    (const_int 8))
8874	  (match_operand 2 "const_int_operand" "n")))
8875   (clobber (reg:CC FLAGS_REG))]
8876  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8877  "or{b}\t{%2, %h0|%h0, %2}"
8878  [(set_attr "type" "alu")
8879   (set_attr "length_immediate" "1")
8880   (set_attr "mode" "QI")])
8881
8882(define_insn "*iorqi_ext_1"
8883  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8884			 (const_int 8)
8885			 (const_int 8))
8886	(ior:SI 
8887	  (zero_extract:SI
8888	    (match_operand 1 "ext_register_operand" "0")
8889	    (const_int 8)
8890	    (const_int 8))
8891	  (zero_extend:SI
8892	    (match_operand:QI 2 "general_operand" "Qm"))))
8893   (clobber (reg:CC FLAGS_REG))]
8894  "!TARGET_64BIT
8895   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8896  "or{b}\t{%2, %h0|%h0, %2}"
8897  [(set_attr "type" "alu")
8898   (set_attr "length_immediate" "0")
8899   (set_attr "mode" "QI")])
8900
8901(define_insn "*iorqi_ext_1_rex64"
8902  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8903			 (const_int 8)
8904			 (const_int 8))
8905	(ior:SI 
8906	  (zero_extract:SI
8907	    (match_operand 1 "ext_register_operand" "0")
8908	    (const_int 8)
8909	    (const_int 8))
8910	  (zero_extend:SI
8911	    (match_operand 2 "ext_register_operand" "Q"))))
8912   (clobber (reg:CC FLAGS_REG))]
8913  "TARGET_64BIT
8914   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8915  "or{b}\t{%2, %h0|%h0, %2}"
8916  [(set_attr "type" "alu")
8917   (set_attr "length_immediate" "0")
8918   (set_attr "mode" "QI")])
8919
8920(define_insn "*iorqi_ext_2"
8921  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8922			 (const_int 8)
8923			 (const_int 8))
8924	(ior:SI 
8925	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8926	  		   (const_int 8)
8927			   (const_int 8))
8928	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8929	  		   (const_int 8)
8930			   (const_int 8))))
8931   (clobber (reg:CC FLAGS_REG))]
8932  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8933  "ior{b}\t{%h2, %h0|%h0, %h2}"
8934  [(set_attr "type" "alu")
8935   (set_attr "length_immediate" "0")
8936   (set_attr "mode" "QI")])
8937
8938(define_split
8939  [(set (match_operand 0 "register_operand" "")
8940	(ior (match_operand 1 "register_operand" "")
8941	     (match_operand 2 "const_int_operand" "")))
8942   (clobber (reg:CC FLAGS_REG))]
8943   "reload_completed
8944    && QI_REG_P (operands[0])
8945    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8946    && !(INTVAL (operands[2]) & ~(255 << 8))
8947    && GET_MODE (operands[0]) != QImode"
8948  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8949		   (ior:SI (zero_extract:SI (match_dup 1)
8950					    (const_int 8) (const_int 8))
8951			   (match_dup 2)))
8952	      (clobber (reg:CC FLAGS_REG))])]
8953  "operands[0] = gen_lowpart (SImode, operands[0]);
8954   operands[1] = gen_lowpart (SImode, operands[1]);
8955   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8956
8957;; Since OR can be encoded with sign extended immediate, this is only
8958;; profitable when 7th bit is set.
8959(define_split
8960  [(set (match_operand 0 "register_operand" "")
8961	(ior (match_operand 1 "general_operand" "")
8962	     (match_operand 2 "const_int_operand" "")))
8963   (clobber (reg:CC FLAGS_REG))]
8964   "reload_completed
8965    && ANY_QI_REG_P (operands[0])
8966    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8967    && !(INTVAL (operands[2]) & ~255)
8968    && (INTVAL (operands[2]) & 128)
8969    && GET_MODE (operands[0]) != QImode"
8970  [(parallel [(set (strict_low_part (match_dup 0))
8971		   (ior:QI (match_dup 1)
8972			   (match_dup 2)))
8973	      (clobber (reg:CC FLAGS_REG))])]
8974  "operands[0] = gen_lowpart (QImode, operands[0]);
8975   operands[1] = gen_lowpart (QImode, operands[1]);
8976   operands[2] = gen_lowpart (QImode, operands[2]);")
8977
8978;; Logical XOR instructions
8979
8980;; %%% This used to optimize known byte-wide and operations to memory.
8981;; If this is considered useful, it should be done with splitters.
8982
8983(define_expand "xordi3"
8984  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8985	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8986		(match_operand:DI 2 "x86_64_general_operand" "")))
8987   (clobber (reg:CC FLAGS_REG))]
8988  "TARGET_64BIT"
8989  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8990
8991(define_insn "*xordi_1_rex64"
8992  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8993	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8994		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8995   (clobber (reg:CC FLAGS_REG))]
8996  "TARGET_64BIT
8997   && ix86_binary_operator_ok (XOR, DImode, operands)"
8998  "@
8999   xor{q}\t{%2, %0|%0, %2}
9000   xor{q}\t{%2, %0|%0, %2}"
9001  [(set_attr "type" "alu")
9002   (set_attr "mode" "DI,DI")])
9003
9004(define_insn "*xordi_2_rex64"
9005  [(set (reg FLAGS_REG)
9006	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9007			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9008		 (const_int 0)))
9009   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9010	(xor:DI (match_dup 1) (match_dup 2)))]
9011  "TARGET_64BIT
9012   && ix86_match_ccmode (insn, CCNOmode)
9013   && ix86_binary_operator_ok (XOR, DImode, operands)"
9014  "@
9015   xor{q}\t{%2, %0|%0, %2}
9016   xor{q}\t{%2, %0|%0, %2}"
9017  [(set_attr "type" "alu")
9018   (set_attr "mode" "DI,DI")])
9019
9020(define_insn "*xordi_3_rex64"
9021  [(set (reg FLAGS_REG)
9022	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9023			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9024		 (const_int 0)))
9025   (clobber (match_scratch:DI 0 "=r"))]
9026  "TARGET_64BIT
9027   && ix86_match_ccmode (insn, CCNOmode)
9028   && ix86_binary_operator_ok (XOR, DImode, operands)"
9029  "xor{q}\t{%2, %0|%0, %2}"
9030  [(set_attr "type" "alu")
9031   (set_attr "mode" "DI")])
9032
9033(define_expand "xorsi3"
9034  [(set (match_operand:SI 0 "nonimmediate_operand" "")
9035	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9036		(match_operand:SI 2 "general_operand" "")))
9037   (clobber (reg:CC FLAGS_REG))]
9038  ""
9039  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9040
9041(define_insn "*xorsi_1"
9042  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9043	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9044		(match_operand:SI 2 "general_operand" "ri,rm")))
9045   (clobber (reg:CC FLAGS_REG))]
9046  "ix86_binary_operator_ok (XOR, SImode, operands)"
9047  "xor{l}\t{%2, %0|%0, %2}"
9048  [(set_attr "type" "alu")
9049   (set_attr "mode" "SI")])
9050
9051;; See comment for addsi_1_zext why we do use nonimmediate_operand
9052;; Add speccase for immediates
9053(define_insn "*xorsi_1_zext"
9054  [(set (match_operand:DI 0 "register_operand" "=r")
9055	(zero_extend:DI
9056	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057		  (match_operand:SI 2 "general_operand" "rim"))))
9058   (clobber (reg:CC FLAGS_REG))]
9059  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9060  "xor{l}\t{%2, %k0|%k0, %2}"
9061  [(set_attr "type" "alu")
9062   (set_attr "mode" "SI")])
9063
9064(define_insn "*xorsi_1_zext_imm"
9065  [(set (match_operand:DI 0 "register_operand" "=r")
9066	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9067		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9068   (clobber (reg:CC FLAGS_REG))]
9069  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9070  "xor{l}\t{%2, %k0|%k0, %2}"
9071  [(set_attr "type" "alu")
9072   (set_attr "mode" "SI")])
9073
9074(define_insn "*xorsi_2"
9075  [(set (reg FLAGS_REG)
9076	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9077			 (match_operand:SI 2 "general_operand" "rim,ri"))
9078		 (const_int 0)))
9079   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9080	(xor:SI (match_dup 1) (match_dup 2)))]
9081  "ix86_match_ccmode (insn, CCNOmode)
9082   && ix86_binary_operator_ok (XOR, SImode, operands)"
9083  "xor{l}\t{%2, %0|%0, %2}"
9084  [(set_attr "type" "alu")
9085   (set_attr "mode" "SI")])
9086
9087;; See comment for addsi_1_zext why we do use nonimmediate_operand
9088;; ??? Special case for immediate operand is missing - it is tricky.
9089(define_insn "*xorsi_2_zext"
9090  [(set (reg FLAGS_REG)
9091	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9092			 (match_operand:SI 2 "general_operand" "rim"))
9093		 (const_int 0)))
9094   (set (match_operand:DI 0 "register_operand" "=r")
9095	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9096  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9097   && ix86_binary_operator_ok (XOR, SImode, operands)"
9098  "xor{l}\t{%2, %k0|%k0, %2}"
9099  [(set_attr "type" "alu")
9100   (set_attr "mode" "SI")])
9101
9102(define_insn "*xorsi_2_zext_imm"
9103  [(set (reg FLAGS_REG)
9104	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9105			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9106		 (const_int 0)))
9107   (set (match_operand:DI 0 "register_operand" "=r")
9108	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9109  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9110   && ix86_binary_operator_ok (XOR, SImode, operands)"
9111  "xor{l}\t{%2, %k0|%k0, %2}"
9112  [(set_attr "type" "alu")
9113   (set_attr "mode" "SI")])
9114
9115(define_insn "*xorsi_3"
9116  [(set (reg FLAGS_REG)
9117	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9118			 (match_operand:SI 2 "general_operand" "rim"))
9119		 (const_int 0)))
9120   (clobber (match_scratch:SI 0 "=r"))]
9121  "ix86_match_ccmode (insn, CCNOmode)
9122   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9123  "xor{l}\t{%2, %0|%0, %2}"
9124  [(set_attr "type" "alu")
9125   (set_attr "mode" "SI")])
9126
9127(define_expand "xorhi3"
9128  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9129	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9130		(match_operand:HI 2 "general_operand" "")))
9131   (clobber (reg:CC FLAGS_REG))]
9132  "TARGET_HIMODE_MATH"
9133  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9134
9135(define_insn "*xorhi_1"
9136  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9137	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9138		(match_operand:HI 2 "general_operand" "rmi,ri")))
9139   (clobber (reg:CC FLAGS_REG))]
9140  "ix86_binary_operator_ok (XOR, HImode, operands)"
9141  "xor{w}\t{%2, %0|%0, %2}"
9142  [(set_attr "type" "alu")
9143   (set_attr "mode" "HI")])
9144
9145(define_insn "*xorhi_2"
9146  [(set (reg FLAGS_REG)
9147	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9148			 (match_operand:HI 2 "general_operand" "rim,ri"))
9149		 (const_int 0)))
9150   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9151	(xor:HI (match_dup 1) (match_dup 2)))]
9152  "ix86_match_ccmode (insn, CCNOmode)
9153   && ix86_binary_operator_ok (XOR, HImode, operands)"
9154  "xor{w}\t{%2, %0|%0, %2}"
9155  [(set_attr "type" "alu")
9156   (set_attr "mode" "HI")])
9157
9158(define_insn "*xorhi_3"
9159  [(set (reg FLAGS_REG)
9160	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9161			 (match_operand:HI 2 "general_operand" "rim"))
9162		 (const_int 0)))
9163   (clobber (match_scratch:HI 0 "=r"))]
9164  "ix86_match_ccmode (insn, CCNOmode)
9165   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9166  "xor{w}\t{%2, %0|%0, %2}"
9167  [(set_attr "type" "alu")
9168   (set_attr "mode" "HI")])
9169
9170(define_expand "xorqi3"
9171  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9172	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9173		(match_operand:QI 2 "general_operand" "")))
9174   (clobber (reg:CC FLAGS_REG))]
9175  "TARGET_QIMODE_MATH"
9176  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9177
9178;; %%% Potential partial reg stall on alternative 2.  What to do?
9179(define_insn "*xorqi_1"
9180  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9181	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9182		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9183   (clobber (reg:CC FLAGS_REG))]
9184  "ix86_binary_operator_ok (XOR, QImode, operands)"
9185  "@
9186   xor{b}\t{%2, %0|%0, %2}
9187   xor{b}\t{%2, %0|%0, %2}
9188   xor{l}\t{%k2, %k0|%k0, %k2}"
9189  [(set_attr "type" "alu")
9190   (set_attr "mode" "QI,QI,SI")])
9191
9192(define_insn "*xorqi_1_slp"
9193  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9194	(xor:QI (match_dup 0)
9195		(match_operand:QI 1 "general_operand" "qi,qmi")))
9196   (clobber (reg:CC FLAGS_REG))]
9197  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9198   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9199  "xor{b}\t{%1, %0|%0, %1}"
9200  [(set_attr "type" "alu1")
9201   (set_attr "mode" "QI")])
9202
9203(define_insn "xorqi_ext_0"
9204  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9205			 (const_int 8)
9206			 (const_int 8))
9207	(xor:SI 
9208	  (zero_extract:SI
9209	    (match_operand 1 "ext_register_operand" "0")
9210	    (const_int 8)
9211	    (const_int 8))
9212	  (match_operand 2 "const_int_operand" "n")))
9213   (clobber (reg:CC FLAGS_REG))]
9214  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9215  "xor{b}\t{%2, %h0|%h0, %2}"
9216  [(set_attr "type" "alu")
9217   (set_attr "length_immediate" "1")
9218   (set_attr "mode" "QI")])
9219
9220(define_insn "*xorqi_ext_1"
9221  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222			 (const_int 8)
9223			 (const_int 8))
9224	(xor:SI 
9225	  (zero_extract:SI
9226	    (match_operand 1 "ext_register_operand" "0")
9227	    (const_int 8)
9228	    (const_int 8))
9229	  (zero_extend:SI
9230	    (match_operand:QI 2 "general_operand" "Qm"))))
9231   (clobber (reg:CC FLAGS_REG))]
9232  "!TARGET_64BIT
9233   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9234  "xor{b}\t{%2, %h0|%h0, %2}"
9235  [(set_attr "type" "alu")
9236   (set_attr "length_immediate" "0")
9237   (set_attr "mode" "QI")])
9238
9239(define_insn "*xorqi_ext_1_rex64"
9240  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9241			 (const_int 8)
9242			 (const_int 8))
9243	(xor:SI 
9244	  (zero_extract:SI
9245	    (match_operand 1 "ext_register_operand" "0")
9246	    (const_int 8)
9247	    (const_int 8))
9248	  (zero_extend:SI
9249	    (match_operand 2 "ext_register_operand" "Q"))))
9250   (clobber (reg:CC FLAGS_REG))]
9251  "TARGET_64BIT
9252   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9253  "xor{b}\t{%2, %h0|%h0, %2}"
9254  [(set_attr "type" "alu")
9255   (set_attr "length_immediate" "0")
9256   (set_attr "mode" "QI")])
9257
9258(define_insn "*xorqi_ext_2"
9259  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9260			 (const_int 8)
9261			 (const_int 8))
9262	(xor:SI 
9263	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9264	  		   (const_int 8)
9265			   (const_int 8))
9266	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9267	  		   (const_int 8)
9268			   (const_int 8))))
9269   (clobber (reg:CC FLAGS_REG))]
9270  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9271  "xor{b}\t{%h2, %h0|%h0, %h2}"
9272  [(set_attr "type" "alu")
9273   (set_attr "length_immediate" "0")
9274   (set_attr "mode" "QI")])
9275
9276(define_insn "*xorqi_cc_1"
9277  [(set (reg FLAGS_REG)
9278	(compare
9279	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9280		  (match_operand:QI 2 "general_operand" "qim,qi"))
9281	  (const_int 0)))
9282   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9283	(xor:QI (match_dup 1) (match_dup 2)))]
9284  "ix86_match_ccmode (insn, CCNOmode)
9285   && ix86_binary_operator_ok (XOR, QImode, operands)"
9286  "xor{b}\t{%2, %0|%0, %2}"
9287  [(set_attr "type" "alu")
9288   (set_attr "mode" "QI")])
9289
9290(define_insn "*xorqi_2_slp"
9291  [(set (reg FLAGS_REG)
9292	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9293			 (match_operand:QI 1 "general_operand" "qim,qi"))
9294		 (const_int 0)))
9295   (set (strict_low_part (match_dup 0))
9296	(xor:QI (match_dup 0) (match_dup 1)))]
9297  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9298   && ix86_match_ccmode (insn, CCNOmode)
9299   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9300  "xor{b}\t{%1, %0|%0, %1}"
9301  [(set_attr "type" "alu1")
9302   (set_attr "mode" "QI")])
9303
9304(define_insn "*xorqi_cc_2"
9305  [(set (reg FLAGS_REG)
9306	(compare
9307	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9308		  (match_operand:QI 2 "general_operand" "qim"))
9309	  (const_int 0)))
9310   (clobber (match_scratch:QI 0 "=q"))]
9311  "ix86_match_ccmode (insn, CCNOmode)
9312   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9313  "xor{b}\t{%2, %0|%0, %2}"
9314  [(set_attr "type" "alu")
9315   (set_attr "mode" "QI")])
9316
9317(define_insn "*xorqi_cc_ext_1"
9318  [(set (reg FLAGS_REG)
9319	(compare
9320	  (xor:SI
9321	    (zero_extract:SI
9322	      (match_operand 1 "ext_register_operand" "0")
9323	      (const_int 8)
9324	      (const_int 8))
9325	    (match_operand:QI 2 "general_operand" "qmn"))
9326	  (const_int 0)))
9327   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9328			 (const_int 8)
9329			 (const_int 8))
9330	(xor:SI 
9331	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9332	  (match_dup 2)))]
9333  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9334  "xor{b}\t{%2, %h0|%h0, %2}"
9335  [(set_attr "type" "alu")
9336   (set_attr "mode" "QI")])
9337
9338(define_insn "*xorqi_cc_ext_1_rex64"
9339  [(set (reg FLAGS_REG)
9340	(compare
9341	  (xor:SI
9342	    (zero_extract:SI
9343	      (match_operand 1 "ext_register_operand" "0")
9344	      (const_int 8)
9345	      (const_int 8))
9346	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9347	  (const_int 0)))
9348   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9349			 (const_int 8)
9350			 (const_int 8))
9351	(xor:SI 
9352	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9353	  (match_dup 2)))]
9354  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9355  "xor{b}\t{%2, %h0|%h0, %2}"
9356  [(set_attr "type" "alu")
9357   (set_attr "mode" "QI")])
9358
9359(define_expand "xorqi_cc_ext_1"
9360  [(parallel [
9361     (set (reg:CCNO FLAGS_REG)
9362	  (compare:CCNO
9363	    (xor:SI
9364	      (zero_extract:SI
9365		(match_operand 1 "ext_register_operand" "")
9366		(const_int 8)
9367		(const_int 8))
9368	      (match_operand:QI 2 "general_operand" ""))
9369	    (const_int 0)))
9370     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9371			   (const_int 8)
9372			   (const_int 8))
9373	  (xor:SI 
9374	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9375	    (match_dup 2)))])]
9376  ""
9377  "")
9378
9379(define_split
9380  [(set (match_operand 0 "register_operand" "")
9381	(xor (match_operand 1 "register_operand" "")
9382	     (match_operand 2 "const_int_operand" "")))
9383   (clobber (reg:CC FLAGS_REG))]
9384   "reload_completed
9385    && QI_REG_P (operands[0])
9386    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9387    && !(INTVAL (operands[2]) & ~(255 << 8))
9388    && GET_MODE (operands[0]) != QImode"
9389  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9390		   (xor:SI (zero_extract:SI (match_dup 1)
9391					    (const_int 8) (const_int 8))
9392			   (match_dup 2)))
9393	      (clobber (reg:CC FLAGS_REG))])]
9394  "operands[0] = gen_lowpart (SImode, operands[0]);
9395   operands[1] = gen_lowpart (SImode, operands[1]);
9396   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9397
9398;; Since XOR can be encoded with sign extended immediate, this is only
9399;; profitable when 7th bit is set.
9400(define_split
9401  [(set (match_operand 0 "register_operand" "")
9402	(xor (match_operand 1 "general_operand" "")
9403	     (match_operand 2 "const_int_operand" "")))
9404   (clobber (reg:CC FLAGS_REG))]
9405   "reload_completed
9406    && ANY_QI_REG_P (operands[0])
9407    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9408    && !(INTVAL (operands[2]) & ~255)
9409    && (INTVAL (operands[2]) & 128)
9410    && GET_MODE (operands[0]) != QImode"
9411  [(parallel [(set (strict_low_part (match_dup 0))
9412		   (xor:QI (match_dup 1)
9413			   (match_dup 2)))
9414	      (clobber (reg:CC FLAGS_REG))])]
9415  "operands[0] = gen_lowpart (QImode, operands[0]);
9416   operands[1] = gen_lowpart (QImode, operands[1]);
9417   operands[2] = gen_lowpart (QImode, operands[2]);")
9418
9419;; Negation instructions
9420
9421(define_expand "negti2"
9422  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9423		   (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9424	      (clobber (reg:CC FLAGS_REG))])]
9425  "TARGET_64BIT"
9426  "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9427
9428(define_insn "*negti2_1"
9429  [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9430	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9431   (clobber (reg:CC FLAGS_REG))]
9432  "TARGET_64BIT
9433   && ix86_unary_operator_ok (NEG, TImode, operands)"
9434  "#")
9435
9436(define_split
9437  [(set (match_operand:TI 0 "nonimmediate_operand" "")
9438	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9439   (clobber (reg:CC FLAGS_REG))]
9440  "TARGET_64BIT && reload_completed"
9441  [(parallel
9442    [(set (reg:CCZ FLAGS_REG)
9443	  (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9444     (set (match_dup 0) (neg:DI (match_dup 2)))])
9445   (parallel
9446    [(set (match_dup 1)
9447	  (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9448			    (match_dup 3))
9449		   (const_int 0)))
9450     (clobber (reg:CC FLAGS_REG))])
9451   (parallel
9452    [(set (match_dup 1)
9453	  (neg:DI (match_dup 1)))
9454     (clobber (reg:CC FLAGS_REG))])]
9455  "split_ti (operands+1, 1, operands+2, operands+3);
9456   split_ti (operands+0, 1, operands+0, operands+1);")
9457
9458(define_expand "negdi2"
9459  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9460		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9461	      (clobber (reg:CC FLAGS_REG))])]
9462  ""
9463  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9464
9465(define_insn "*negdi2_1"
9466  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9467	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9468   (clobber (reg:CC FLAGS_REG))]
9469  "!TARGET_64BIT
9470   && ix86_unary_operator_ok (NEG, DImode, operands)"
9471  "#")
9472
9473(define_split
9474  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9475	(neg:DI (match_operand:DI 1 "general_operand" "")))
9476   (clobber (reg:CC FLAGS_REG))]
9477  "!TARGET_64BIT && reload_completed"
9478  [(parallel
9479    [(set (reg:CCZ FLAGS_REG)
9480	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9481     (set (match_dup 0) (neg:SI (match_dup 2)))])
9482   (parallel
9483    [(set (match_dup 1)
9484	  (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9485			    (match_dup 3))
9486		   (const_int 0)))
9487     (clobber (reg:CC FLAGS_REG))])
9488   (parallel
9489    [(set (match_dup 1)
9490	  (neg:SI (match_dup 1)))
9491     (clobber (reg:CC FLAGS_REG))])]
9492  "split_di (operands+1, 1, operands+2, operands+3);
9493   split_di (operands+0, 1, operands+0, operands+1);")
9494
9495(define_insn "*negdi2_1_rex64"
9496  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9497	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9498   (clobber (reg:CC FLAGS_REG))]
9499  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9500  "neg{q}\t%0"
9501  [(set_attr "type" "negnot")
9502   (set_attr "mode" "DI")])
9503
9504;; The problem with neg is that it does not perform (compare x 0),
9505;; it really performs (compare 0 x), which leaves us with the zero
9506;; flag being the only useful item.
9507
9508(define_insn "*negdi2_cmpz_rex64"
9509  [(set (reg:CCZ FLAGS_REG)
9510	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9511		     (const_int 0)))
9512   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9513	(neg:DI (match_dup 1)))]
9514  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9515  "neg{q}\t%0"
9516  [(set_attr "type" "negnot")
9517   (set_attr "mode" "DI")])
9518
9519
9520(define_expand "negsi2"
9521  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9522		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9523	      (clobber (reg:CC FLAGS_REG))])]
9524  ""
9525  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9526
9527(define_insn "*negsi2_1"
9528  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9529	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9530   (clobber (reg:CC FLAGS_REG))]
9531  "ix86_unary_operator_ok (NEG, SImode, operands)"
9532  "neg{l}\t%0"
9533  [(set_attr "type" "negnot")
9534   (set_attr "mode" "SI")])
9535
9536;; Combine is quite creative about this pattern.
9537(define_insn "*negsi2_1_zext"
9538  [(set (match_operand:DI 0 "register_operand" "=r")
9539	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9540					(const_int 32)))
9541		     (const_int 32)))
9542   (clobber (reg:CC FLAGS_REG))]
9543  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9544  "neg{l}\t%k0"
9545  [(set_attr "type" "negnot")
9546   (set_attr "mode" "SI")])
9547
9548;; The problem with neg is that it does not perform (compare x 0),
9549;; it really performs (compare 0 x), which leaves us with the zero
9550;; flag being the only useful item.
9551
9552(define_insn "*negsi2_cmpz"
9553  [(set (reg:CCZ FLAGS_REG)
9554	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9555		     (const_int 0)))
9556   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9557	(neg:SI (match_dup 1)))]
9558  "ix86_unary_operator_ok (NEG, SImode, operands)"
9559  "neg{l}\t%0"
9560  [(set_attr "type" "negnot")
9561   (set_attr "mode" "SI")])
9562
9563(define_insn "*negsi2_cmpz_zext"
9564  [(set (reg:CCZ FLAGS_REG)
9565	(compare:CCZ (lshiftrt:DI
9566		       (neg:DI (ashift:DI
9567				 (match_operand:DI 1 "register_operand" "0")
9568				 (const_int 32)))
9569		       (const_int 32))
9570		     (const_int 0)))
9571   (set (match_operand:DI 0 "register_operand" "=r")
9572	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9573					(const_int 32)))
9574		     (const_int 32)))]
9575  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9576  "neg{l}\t%k0"
9577  [(set_attr "type" "negnot")
9578   (set_attr "mode" "SI")])
9579
9580(define_expand "neghi2"
9581  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9582		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9583	      (clobber (reg:CC FLAGS_REG))])]
9584  "TARGET_HIMODE_MATH"
9585  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9586
9587(define_insn "*neghi2_1"
9588  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9589	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9590   (clobber (reg:CC FLAGS_REG))]
9591  "ix86_unary_operator_ok (NEG, HImode, operands)"
9592  "neg{w}\t%0"
9593  [(set_attr "type" "negnot")
9594   (set_attr "mode" "HI")])
9595
9596(define_insn "*neghi2_cmpz"
9597  [(set (reg:CCZ FLAGS_REG)
9598	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9599		     (const_int 0)))
9600   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9601	(neg:HI (match_dup 1)))]
9602  "ix86_unary_operator_ok (NEG, HImode, operands)"
9603  "neg{w}\t%0"
9604  [(set_attr "type" "negnot")
9605   (set_attr "mode" "HI")])
9606
9607(define_expand "negqi2"
9608  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9609		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9610	      (clobber (reg:CC FLAGS_REG))])]
9611  "TARGET_QIMODE_MATH"
9612  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9613
9614(define_insn "*negqi2_1"
9615  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9616	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9617   (clobber (reg:CC FLAGS_REG))]
9618  "ix86_unary_operator_ok (NEG, QImode, operands)"
9619  "neg{b}\t%0"
9620  [(set_attr "type" "negnot")
9621   (set_attr "mode" "QI")])
9622
9623(define_insn "*negqi2_cmpz"
9624  [(set (reg:CCZ FLAGS_REG)
9625	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9626		     (const_int 0)))
9627   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9628	(neg:QI (match_dup 1)))]
9629  "ix86_unary_operator_ok (NEG, QImode, operands)"
9630  "neg{b}\t%0"
9631  [(set_attr "type" "negnot")
9632   (set_attr "mode" "QI")])
9633
9634;; Changing of sign for FP values is doable using integer unit too.
9635
9636(define_expand "negsf2"
9637  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9638	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9639  "TARGET_80387 || TARGET_SSE_MATH"
9640  "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9641
9642(define_expand "abssf2"
9643  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9644	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9645  "TARGET_80387 || TARGET_SSE_MATH"
9646  "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9647
9648(define_insn "*absnegsf2_mixed"
9649  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9650	(match_operator:SF 3 "absneg_operator"
9651	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9652   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9653   (clobber (reg:CC FLAGS_REG))]
9654  "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9655   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9656  "#")
9657
9658(define_insn "*absnegsf2_sse"
9659  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9660	(match_operator:SF 3 "absneg_operator"
9661	  [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9662   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9663   (clobber (reg:CC FLAGS_REG))]
9664  "TARGET_SSE_MATH
9665   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9666  "#")
9667
9668(define_insn "*absnegsf2_i387"
9669  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9670	(match_operator:SF 3 "absneg_operator"
9671	  [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9672   (use (match_operand 2 "" ""))
9673   (clobber (reg:CC FLAGS_REG))]
9674  "TARGET_80387 && !TARGET_SSE_MATH
9675   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9676  "#")
9677
9678(define_expand "copysignsf3"
9679  [(match_operand:SF 0 "register_operand" "")
9680   (match_operand:SF 1 "nonmemory_operand" "")
9681   (match_operand:SF 2 "register_operand" "")]
9682  "TARGET_SSE_MATH"
9683{
9684  ix86_expand_copysign (operands);
9685  DONE;
9686})
9687
9688(define_insn_and_split "copysignsf3_const"
9689  [(set (match_operand:SF 0 "register_operand"          "=x")
9690	(unspec:SF
9691	  [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9692	   (match_operand:SF 2 "register_operand"       "0")
9693	   (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9694	  UNSPEC_COPYSIGN))]
9695  "TARGET_SSE_MATH"
9696  "#"
9697  "&& reload_completed"
9698  [(const_int 0)]
9699{
9700  ix86_split_copysign_const (operands);
9701  DONE;
9702})
9703
9704(define_insn "copysignsf3_var"
9705  [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9706	(unspec:SF
9707	  [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9708	   (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9709	   (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9710	   (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9711	  UNSPEC_COPYSIGN))
9712   (clobber (match_scratch:V4SF 1			"=x, x, x, x,x"))]
9713  "TARGET_SSE_MATH"
9714  "#")
9715
9716(define_split
9717  [(set (match_operand:SF 0 "register_operand" "")
9718	(unspec:SF
9719	  [(match_operand:SF 2 "register_operand" "")
9720	   (match_operand:SF 3 "register_operand" "")
9721	   (match_operand:V4SF 4 "" "")
9722	   (match_operand:V4SF 5 "" "")]
9723	  UNSPEC_COPYSIGN))
9724   (clobber (match_scratch:V4SF 1 ""))]
9725  "TARGET_SSE_MATH && reload_completed"
9726  [(const_int 0)]
9727{
9728  ix86_split_copysign_var (operands);
9729  DONE;
9730})
9731
9732(define_expand "negdf2"
9733  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9734	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9735  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9736  "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9737
9738(define_expand "absdf2"
9739  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9740	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9741  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9742  "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9743
9744(define_insn "*absnegdf2_mixed"
9745  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9746	(match_operator:DF 3 "absneg_operator"
9747	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9748   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9749   (clobber (reg:CC FLAGS_REG))]
9750  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9751   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9752  "#")
9753
9754(define_insn "*absnegdf2_sse"
9755  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9756	(match_operator:DF 3 "absneg_operator"
9757	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9758   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9759   (clobber (reg:CC FLAGS_REG))]
9760  "TARGET_SSE2 && TARGET_SSE_MATH
9761   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9762  "#")
9763
9764(define_insn "*absnegdf2_i387"
9765  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9766	(match_operator:DF 3 "absneg_operator"
9767	  [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9768   (use (match_operand 2 "" ""))
9769   (clobber (reg:CC FLAGS_REG))]
9770  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9771   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9772  "#")
9773
9774(define_expand "copysigndf3"
9775  [(match_operand:DF 0 "register_operand" "")
9776   (match_operand:DF 1 "nonmemory_operand" "")
9777   (match_operand:DF 2 "register_operand" "")]
9778  "TARGET_SSE2 && TARGET_SSE_MATH"
9779{
9780  ix86_expand_copysign (operands);
9781  DONE;
9782})
9783
9784(define_insn_and_split "copysigndf3_const"
9785  [(set (match_operand:DF 0 "register_operand"          "=x")
9786	(unspec:DF
9787	  [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9788	   (match_operand:DF 2 "register_operand"       "0")
9789	   (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9790	  UNSPEC_COPYSIGN))]
9791  "TARGET_SSE2 && TARGET_SSE_MATH"
9792  "#"
9793  "&& reload_completed"
9794  [(const_int 0)]
9795{
9796  ix86_split_copysign_const (operands);
9797  DONE;
9798})
9799
9800(define_insn "copysigndf3_var"
9801  [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9802	(unspec:DF
9803	  [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9804	   (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9805	   (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9806	   (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9807	  UNSPEC_COPYSIGN))
9808   (clobber (match_scratch:V2DF 1			"=x, x, x, x,x"))]
9809  "TARGET_SSE2 && TARGET_SSE_MATH"
9810  "#")
9811
9812(define_split
9813  [(set (match_operand:DF 0 "register_operand" "")
9814	(unspec:DF
9815	  [(match_operand:DF 2 "register_operand" "")
9816	   (match_operand:DF 3 "register_operand" "")
9817	   (match_operand:V2DF 4 "" "")
9818	   (match_operand:V2DF 5 "" "")]
9819	  UNSPEC_COPYSIGN))
9820   (clobber (match_scratch:V2DF 1 ""))]
9821  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9822  [(const_int 0)]
9823{
9824  ix86_split_copysign_var (operands);
9825  DONE;
9826})
9827
9828(define_expand "negxf2"
9829  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9830	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9831  "TARGET_80387"
9832  "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9833
9834(define_expand "absxf2"
9835  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9836	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9837  "TARGET_80387"
9838  "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9839
9840(define_insn "*absnegxf2_i387"
9841  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9842	(match_operator:XF 3 "absneg_operator"
9843	  [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9844   (use (match_operand 2 "" ""))
9845   (clobber (reg:CC FLAGS_REG))]
9846  "TARGET_80387
9847   && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9848  "#")
9849
9850;; Splitters for fp abs and neg.
9851
9852(define_split
9853  [(set (match_operand 0 "fp_register_operand" "")
9854	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9855   (use (match_operand 2 "" ""))
9856   (clobber (reg:CC FLAGS_REG))]
9857  "reload_completed"
9858  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9859
9860(define_split
9861  [(set (match_operand 0 "register_operand" "")
9862	(match_operator 3 "absneg_operator"
9863	  [(match_operand 1 "register_operand" "")]))
9864   (use (match_operand 2 "nonimmediate_operand" ""))
9865   (clobber (reg:CC FLAGS_REG))]
9866  "reload_completed && SSE_REG_P (operands[0])"
9867  [(set (match_dup 0) (match_dup 3))]
9868{
9869  enum machine_mode mode = GET_MODE (operands[0]);
9870  enum machine_mode vmode = GET_MODE (operands[2]);
9871  rtx tmp;
9872  
9873  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9874  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9875  if (operands_match_p (operands[0], operands[2]))
9876    {
9877      tmp = operands[1];
9878      operands[1] = operands[2];
9879      operands[2] = tmp;
9880    }
9881  if (GET_CODE (operands[3]) == ABS)
9882    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9883  else
9884    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9885  operands[3] = tmp;
9886})
9887
9888(define_split
9889  [(set (match_operand:SF 0 "register_operand" "")
9890	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9891   (use (match_operand:V4SF 2 "" ""))
9892   (clobber (reg:CC FLAGS_REG))]
9893  "reload_completed"
9894  [(parallel [(set (match_dup 0) (match_dup 1))
9895	      (clobber (reg:CC FLAGS_REG))])]
9896{ 
9897  rtx tmp;
9898  operands[0] = gen_lowpart (SImode, operands[0]);
9899  if (GET_CODE (operands[1]) == ABS)
9900    {
9901      tmp = gen_int_mode (0x7fffffff, SImode);
9902      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9903    }
9904  else
9905    {
9906      tmp = gen_int_mode (0x80000000, SImode);
9907      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9908    }
9909  operands[1] = tmp;
9910})
9911
9912(define_split
9913  [(set (match_operand:DF 0 "register_operand" "")
9914	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9915   (use (match_operand 2 "" ""))
9916   (clobber (reg:CC FLAGS_REG))]
9917  "reload_completed"
9918  [(parallel [(set (match_dup 0) (match_dup 1))
9919	      (clobber (reg:CC FLAGS_REG))])]
9920{
9921  rtx tmp;
9922  if (TARGET_64BIT)
9923    {
9924      tmp = gen_lowpart (DImode, operands[0]);
9925      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9926      operands[0] = tmp;
9927
9928      if (GET_CODE (operands[1]) == ABS)
9929	tmp = const0_rtx;
9930      else
9931	tmp = gen_rtx_NOT (DImode, tmp);
9932    }
9933  else
9934    {
9935      operands[0] = gen_highpart (SImode, operands[0]);
9936      if (GET_CODE (operands[1]) == ABS)
9937	{
9938	  tmp = gen_int_mode (0x7fffffff, SImode);
9939	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
9940	}
9941      else
9942	{
9943	  tmp = gen_int_mode (0x80000000, SImode);
9944	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9945	}
9946    }
9947  operands[1] = tmp;
9948})
9949
9950(define_split
9951  [(set (match_operand:XF 0 "register_operand" "")
9952	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9953   (use (match_operand 2 "" ""))
9954   (clobber (reg:CC FLAGS_REG))]
9955  "reload_completed"
9956  [(parallel [(set (match_dup 0) (match_dup 1))
9957	      (clobber (reg:CC FLAGS_REG))])]
9958{
9959  rtx tmp;
9960  operands[0] = gen_rtx_REG (SImode,
9961			     true_regnum (operands[0])
9962			     + (TARGET_64BIT ? 1 : 2));
9963  if (GET_CODE (operands[1]) == ABS)
9964    {
9965      tmp = GEN_INT (0x7fff);
9966      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9967    }
9968  else
9969    {
9970      tmp = GEN_INT (0x8000);
9971      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9972    }
9973  operands[1] = tmp;
9974})
9975
9976(define_split
9977  [(set (match_operand 0 "memory_operand" "")
9978	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9979   (use (match_operand 2 "" ""))
9980   (clobber (reg:CC FLAGS_REG))]
9981  "reload_completed"
9982  [(parallel [(set (match_dup 0) (match_dup 1))
9983	      (clobber (reg:CC FLAGS_REG))])]
9984{
9985  enum machine_mode mode = GET_MODE (operands[0]);
9986  int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9987  rtx tmp;
9988
9989  operands[0] = adjust_address (operands[0], QImode, size - 1);
9990  if (GET_CODE (operands[1]) == ABS)
9991    {
9992      tmp = gen_int_mode (0x7f, QImode);
9993      tmp = gen_rtx_AND (QImode, operands[0], tmp);
9994    }
9995  else
9996    {
9997      tmp = gen_int_mode (0x80, QImode);
9998      tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9999    }
10000  operands[1] = tmp;
10001})
10002
10003;; Conditionalize these after reload. If they match before reload, we 
10004;; lose the clobber and ability to use integer instructions.
10005
10006(define_insn "*negsf2_1"
10007  [(set (match_operand:SF 0 "register_operand" "=f")
10008	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
10009  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10010  "fchs"
10011  [(set_attr "type" "fsgn")
10012   (set_attr "mode" "SF")])
10013
10014(define_insn "*negdf2_1"
10015  [(set (match_operand:DF 0 "register_operand" "=f")
10016	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
10017  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10018  "fchs"
10019  [(set_attr "type" "fsgn")
10020   (set_attr "mode" "DF")])
10021
10022(define_insn "*negxf2_1"
10023  [(set (match_operand:XF 0 "register_operand" "=f")
10024	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
10025  "TARGET_80387"
10026  "fchs"
10027  [(set_attr "type" "fsgn")
10028   (set_attr "mode" "XF")])
10029
10030(define_insn "*abssf2_1"
10031  [(set (match_operand:SF 0 "register_operand" "=f")
10032	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
10033  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10034  "fabs"
10035  [(set_attr "type" "fsgn")
10036   (set_attr "mode" "SF")])
10037
10038(define_insn "*absdf2_1"
10039  [(set (match_operand:DF 0 "register_operand" "=f")
10040	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
10041  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10042  "fabs"
10043  [(set_attr "type" "fsgn")
10044   (set_attr "mode" "DF")])
10045
10046(define_insn "*absxf2_1"
10047  [(set (match_operand:XF 0 "register_operand" "=f")
10048	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
10049  "TARGET_80387"
10050  "fabs"
10051  [(set_attr "type" "fsgn")
10052   (set_attr "mode" "DF")])
10053
10054(define_insn "*negextendsfdf2"
10055  [(set (match_operand:DF 0 "register_operand" "=f")
10056	(neg:DF (float_extend:DF
10057		  (match_operand:SF 1 "register_operand" "0"))))]
10058  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10059  "fchs"
10060  [(set_attr "type" "fsgn")
10061   (set_attr "mode" "DF")])
10062
10063(define_insn "*negextenddfxf2"
10064  [(set (match_operand:XF 0 "register_operand" "=f")
10065	(neg:XF (float_extend:XF
10066		  (match_operand:DF 1 "register_operand" "0"))))]
10067  "TARGET_80387"
10068  "fchs"
10069  [(set_attr "type" "fsgn")
10070   (set_attr "mode" "XF")])
10071
10072(define_insn "*negextendsfxf2"
10073  [(set (match_operand:XF 0 "register_operand" "=f")
10074	(neg:XF (float_extend:XF
10075		  (match_operand:SF 1 "register_operand" "0"))))]
10076  "TARGET_80387"
10077  "fchs"
10078  [(set_attr "type" "fsgn")
10079   (set_attr "mode" "XF")])
10080
10081(define_insn "*absextendsfdf2"
10082  [(set (match_operand:DF 0 "register_operand" "=f")
10083	(abs:DF (float_extend:DF
10084		  (match_operand:SF 1 "register_operand" "0"))))]
10085  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10086  "fabs"
10087  [(set_attr "type" "fsgn")
10088   (set_attr "mode" "DF")])
10089
10090(define_insn "*absextenddfxf2"
10091  [(set (match_operand:XF 0 "register_operand" "=f")
10092	(abs:XF (float_extend:XF
10093	  (match_operand:DF 1 "register_operand" "0"))))]
10094  "TARGET_80387"
10095  "fabs"
10096  [(set_attr "type" "fsgn")
10097   (set_attr "mode" "XF")])
10098
10099(define_insn "*absextendsfxf2"
10100  [(set (match_operand:XF 0 "register_operand" "=f")
10101	(abs:XF (float_extend:XF
10102	  (match_operand:SF 1 "register_operand" "0"))))]
10103  "TARGET_80387"
10104  "fabs"
10105  [(set_attr "type" "fsgn")
10106   (set_attr "mode" "XF")])
10107
10108;; One complement instructions
10109
10110(define_expand "one_cmpldi2"
10111  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10112	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10113  "TARGET_64BIT"
10114  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10115
10116(define_insn "*one_cmpldi2_1_rex64"
10117  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10118	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10119  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10120  "not{q}\t%0"
10121  [(set_attr "type" "negnot")
10122   (set_attr "mode" "DI")])
10123
10124(define_insn "*one_cmpldi2_2_rex64"
10125  [(set (reg FLAGS_REG)
10126	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10127		 (const_int 0)))
10128   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10129	(not:DI (match_dup 1)))]
10130  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10131   && ix86_unary_operator_ok (NOT, DImode, operands)"
10132  "#"
10133  [(set_attr "type" "alu1")
10134   (set_attr "mode" "DI")])
10135
10136(define_split
10137  [(set (match_operand 0 "flags_reg_operand" "")
10138	(match_operator 2 "compare_operator"
10139	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10140	   (const_int 0)]))
10141   (set (match_operand:DI 1 "nonimmediate_operand" "")
10142	(not:DI (match_dup 3)))]
10143  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10144  [(parallel [(set (match_dup 0)
10145		   (match_op_dup 2
10146		     [(xor:DI (match_dup 3) (const_int -1))
10147		      (const_int 0)]))
10148	      (set (match_dup 1)
10149		   (xor:DI (match_dup 3) (const_int -1)))])]
10150  "")
10151
10152(define_expand "one_cmplsi2"
10153  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10154	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10155  ""
10156  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10157
10158(define_insn "*one_cmplsi2_1"
10159  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10160	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10161  "ix86_unary_operator_ok (NOT, SImode, operands)"
10162  "not{l}\t%0"
10163  [(set_attr "type" "negnot")
10164   (set_attr "mode" "SI")])
10165
10166;; ??? Currently never generated - xor is used instead.
10167(define_insn "*one_cmplsi2_1_zext"
10168  [(set (match_operand:DI 0 "register_operand" "=r")
10169	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10170  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10171  "not{l}\t%k0"
10172  [(set_attr "type" "negnot")
10173   (set_attr "mode" "SI")])
10174
10175(define_insn "*one_cmplsi2_2"
10176  [(set (reg FLAGS_REG)
10177	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10178		 (const_int 0)))
10179   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10180	(not:SI (match_dup 1)))]
10181  "ix86_match_ccmode (insn, CCNOmode)
10182   && ix86_unary_operator_ok (NOT, SImode, operands)"
10183  "#"
10184  [(set_attr "type" "alu1")
10185   (set_attr "mode" "SI")])
10186
10187(define_split
10188  [(set (match_operand 0 "flags_reg_operand" "")
10189	(match_operator 2 "compare_operator"
10190	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10191	   (const_int 0)]))
10192   (set (match_operand:SI 1 "nonimmediate_operand" "")
10193	(not:SI (match_dup 3)))]
10194  "ix86_match_ccmode (insn, CCNOmode)"
10195  [(parallel [(set (match_dup 0)
10196		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10197				    (const_int 0)]))
10198	      (set (match_dup 1)
10199		   (xor:SI (match_dup 3) (const_int -1)))])]
10200  "")
10201
10202;; ??? Currently never generated - xor is used instead.
10203(define_insn "*one_cmplsi2_2_zext"
10204  [(set (reg FLAGS_REG)
10205	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10206		 (const_int 0)))
10207   (set (match_operand:DI 0 "register_operand" "=r")
10208	(zero_extend:DI (not:SI (match_dup 1))))]
10209  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10210   && ix86_unary_operator_ok (NOT, SImode, operands)"
10211  "#"
10212  [(set_attr "type" "alu1")
10213   (set_attr "mode" "SI")])
10214
10215(define_split
10216  [(set (match_operand 0 "flags_reg_operand" "")
10217	(match_operator 2 "compare_operator"
10218	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10219	   (const_int 0)]))
10220   (set (match_operand:DI 1 "register_operand" "")
10221	(zero_extend:DI (not:SI (match_dup 3))))]
10222  "ix86_match_ccmode (insn, CCNOmode)"
10223  [(parallel [(set (match_dup 0)
10224		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10225				    (const_int 0)]))
10226	      (set (match_dup 1)
10227		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10228  "")
10229
10230(define_expand "one_cmplhi2"
10231  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10232	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10233  "TARGET_HIMODE_MATH"
10234  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10235
10236(define_insn "*one_cmplhi2_1"
10237  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10238	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10239  "ix86_unary_operator_ok (NOT, HImode, operands)"
10240  "not{w}\t%0"
10241  [(set_attr "type" "negnot")
10242   (set_attr "mode" "HI")])
10243
10244(define_insn "*one_cmplhi2_2"
10245  [(set (reg FLAGS_REG)
10246	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10247		 (const_int 0)))
10248   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10249	(not:HI (match_dup 1)))]
10250  "ix86_match_ccmode (insn, CCNOmode)
10251   && ix86_unary_operator_ok (NEG, HImode, operands)"
10252  "#"
10253  [(set_attr "type" "alu1")
10254   (set_attr "mode" "HI")])
10255
10256(define_split
10257  [(set (match_operand 0 "flags_reg_operand" "")
10258	(match_operator 2 "compare_operator"
10259	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10260	   (const_int 0)]))
10261   (set (match_operand:HI 1 "nonimmediate_operand" "")
10262	(not:HI (match_dup 3)))]
10263  "ix86_match_ccmode (insn, CCNOmode)"
10264  [(parallel [(set (match_dup 0)
10265		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10266		      		    (const_int 0)]))
10267	      (set (match_dup 1)
10268		   (xor:HI (match_dup 3) (const_int -1)))])]
10269  "")
10270
10271;; %%% Potential partial reg stall on alternative 1.  What to do?
10272(define_expand "one_cmplqi2"
10273  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10274	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10275  "TARGET_QIMODE_MATH"
10276  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10277
10278(define_insn "*one_cmplqi2_1"
10279  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10280	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10281  "ix86_unary_operator_ok (NOT, QImode, operands)"
10282  "@
10283   not{b}\t%0
10284   not{l}\t%k0"
10285  [(set_attr "type" "negnot")
10286   (set_attr "mode" "QI,SI")])
10287
10288(define_insn "*one_cmplqi2_2"
10289  [(set (reg FLAGS_REG)
10290	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10291		 (const_int 0)))
10292   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10293	(not:QI (match_dup 1)))]
10294  "ix86_match_ccmode (insn, CCNOmode)
10295   && ix86_unary_operator_ok (NOT, QImode, operands)"
10296  "#"
10297  [(set_attr "type" "alu1")
10298   (set_attr "mode" "QI")])
10299
10300(define_split
10301  [(set (match_operand 0 "flags_reg_operand" "")
10302	(match_operator 2 "compare_operator"
10303	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10304	   (const_int 0)]))
10305   (set (match_operand:QI 1 "nonimmediate_operand" "")
10306	(not:QI (match_dup 3)))]
10307  "ix86_match_ccmode (insn, CCNOmode)"
10308  [(parallel [(set (match_dup 0)
10309		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10310		      		    (const_int 0)]))
10311	      (set (match_dup 1)
10312		   (xor:QI (match_dup 3) (const_int -1)))])]
10313  "")
10314
10315;; Arithmetic shift instructions
10316
10317;; DImode shifts are implemented using the i386 "shift double" opcode,
10318;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10319;; is variable, then the count is in %cl and the "imm" operand is dropped
10320;; from the assembler input.
10321;;
10322;; This instruction shifts the target reg/mem as usual, but instead of
10323;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10324;; is a left shift double, bits are taken from the high order bits of
10325;; reg, else if the insn is a shift right double, bits are taken from the
10326;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10327;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10328;;
10329;; Since sh[lr]d does not change the `reg' operand, that is done
10330;; separately, making all shifts emit pairs of shift double and normal
10331;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10332;; support a 63 bit shift, each shift where the count is in a reg expands
10333;; to a pair of shifts, a branch, a shift by 32 and a label.
10334;;
10335;; If the shift count is a constant, we need never emit more than one
10336;; shift pair, instead using moves and sign extension for counts greater
10337;; than 31.
10338
10339(define_expand "ashlti3"
10340  [(parallel [(set (match_operand:TI 0 "register_operand" "")
10341		   (ashift:TI (match_operand:TI 1 "register_operand" "")
10342			      (match_operand:QI 2 "nonmemory_operand" "")))
10343	      (clobber (reg:CC FLAGS_REG))])]
10344  "TARGET_64BIT"
10345{
10346  if (! immediate_operand (operands[2], QImode))
10347    {
10348      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10349      DONE;
10350    }
10351  ix86_expand_binary_operator (ASHIFT, TImode, operands);
10352  DONE;
10353})
10354
10355(define_insn "ashlti3_1"
10356  [(set (match_operand:TI 0 "register_operand" "=r")
10357	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10358		   (match_operand:QI 2 "register_operand" "c")))
10359   (clobber (match_scratch:DI 3 "=&r"))
10360   (clobber (reg:CC FLAGS_REG))]
10361  "TARGET_64BIT"
10362  "#"
10363  [(set_attr "type" "multi")])
10364
10365(define_insn "*ashlti3_2"
10366  [(set (match_operand:TI 0 "register_operand" "=r")
10367	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10368		   (match_operand:QI 2 "immediate_operand" "O")))
10369   (clobber (reg:CC FLAGS_REG))]
10370  "TARGET_64BIT"
10371  "#"
10372  [(set_attr "type" "multi")])
10373
10374(define_split
10375  [(set (match_operand:TI 0 "register_operand" "")
10376	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10377		   (match_operand:QI 2 "register_operand" "")))
10378   (clobber (match_scratch:DI 3 ""))
10379   (clobber (reg:CC FLAGS_REG))]
10380  "TARGET_64BIT && reload_completed"
10381  [(const_int 0)]
10382  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10383
10384(define_split
10385  [(set (match_operand:TI 0 "register_operand" "")
10386	(ashift:TI (match_operand:TI 1 "register_operand" "")
10387		   (match_operand:QI 2 "immediate_operand" "")))
10388   (clobber (reg:CC FLAGS_REG))]
10389  "TARGET_64BIT && reload_completed"
10390  [(const_int 0)]
10391  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10392
10393(define_insn "x86_64_shld"
10394  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10395        (ior:DI (ashift:DI (match_dup 0)
10396		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
10397		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10398		  (minus:QI (const_int 64) (match_dup 2)))))
10399   (clobber (reg:CC FLAGS_REG))]
10400  "TARGET_64BIT"
10401  "@
10402   shld{q}\t{%2, %1, %0|%0, %1, %2}
10403   shld{q}\t{%s2%1, %0|%0, %1, %2}"
10404  [(set_attr "type" "ishift")
10405   (set_attr "prefix_0f" "1")
10406   (set_attr "mode" "DI")
10407   (set_attr "athlon_decode" "vector")
10408   (set_attr "amdfam10_decode" "vector")])   
10409
10410(define_expand "x86_64_shift_adj"
10411  [(set (reg:CCZ FLAGS_REG)
10412	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10413			     (const_int 64))
10414		     (const_int 0)))
10415   (set (match_operand:DI 0 "register_operand" "")
10416        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10417			 (match_operand:DI 1 "register_operand" "")
10418			 (match_dup 0)))
10419   (set (match_dup 1)
10420	(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10421			 (match_operand:DI 3 "register_operand" "r")
10422			 (match_dup 1)))]
10423  "TARGET_64BIT"
10424  "")
10425
10426(define_expand "ashldi3"
10427  [(set (match_operand:DI 0 "shiftdi_operand" "")
10428	(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10429		   (match_operand:QI 2 "nonmemory_operand" "")))]
10430  ""
10431  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10432
10433(define_insn "*ashldi3_1_rex64"
10434  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10435	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10436		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10437   (clobber (reg:CC FLAGS_REG))]
10438  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10439{
10440  switch (get_attr_type (insn))
10441    {
10442    case TYPE_ALU:
10443      gcc_assert (operands[2] == const1_rtx);
10444      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10445      return "add{q}\t{%0, %0|%0, %0}";
10446
10447    case TYPE_LEA:
10448      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10449      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10450      operands[1] = gen_rtx_MULT (DImode, operands[1],
10451				  GEN_INT (1 << INTVAL (operands[2])));
10452      return "lea{q}\t{%a1, %0|%0, %a1}";
10453
10454    default:
10455      if (REG_P (operands[2]))
10456	return "sal{q}\t{%b2, %0|%0, %b2}";
10457      else if (operands[2] == const1_rtx
10458	       && (TARGET_SHIFT1 || optimize_size))
10459	return "sal{q}\t%0";
10460      else
10461	return "sal{q}\t{%2, %0|%0, %2}";
10462    }
10463}
10464  [(set (attr "type")
10465     (cond [(eq_attr "alternative" "1")
10466	      (const_string "lea")
10467            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10468		          (const_int 0))
10469		      (match_operand 0 "register_operand" ""))
10470		 (match_operand 2 "const1_operand" ""))
10471	      (const_string "alu")
10472	   ]
10473	   (const_string "ishift")))
10474   (set_attr "mode" "DI")])
10475
10476;; Convert lea to the lea pattern to avoid flags dependency.
10477(define_split
10478  [(set (match_operand:DI 0 "register_operand" "")
10479	(ashift:DI (match_operand:DI 1 "index_register_operand" "")
10480		   (match_operand:QI 2 "immediate_operand" "")))
10481   (clobber (reg:CC FLAGS_REG))]
10482  "TARGET_64BIT && reload_completed
10483   && true_regnum (operands[0]) != true_regnum (operands[1])"
10484  [(set (match_dup 0)
10485	(mult:DI (match_dup 1)
10486		 (match_dup 2)))]
10487  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10488
10489;; This pattern can't accept a variable shift count, since shifts by
10490;; zero don't affect the flags.  We assume that shifts by constant
10491;; zero are optimized away.
10492(define_insn "*ashldi3_cmp_rex64"
10493  [(set (reg FLAGS_REG)
10494	(compare
10495	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10496		     (match_operand:QI 2 "immediate_operand" "e"))
10497	  (const_int 0)))
10498   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10499	(ashift:DI (match_dup 1) (match_dup 2)))]
10500  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10501   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10502   && (optimize_size
10503       || !TARGET_PARTIAL_FLAG_REG_STALL
10504       || (operands[2] == const1_rtx
10505	   && (TARGET_SHIFT1
10506	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10507{
10508  switch (get_attr_type (insn))
10509    {
10510    case TYPE_ALU:
10511      gcc_assert (operands[2] == const1_rtx);
10512      return "add{q}\t{%0, %0|%0, %0}";
10513
10514    default:
10515      if (REG_P (operands[2]))
10516	return "sal{q}\t{%b2, %0|%0, %b2}";
10517      else if (operands[2] == const1_rtx
10518	       && (TARGET_SHIFT1 || optimize_size))
10519	return "sal{q}\t%0";
10520      else
10521	return "sal{q}\t{%2, %0|%0, %2}";
10522    }
10523}
10524  [(set (attr "type")
10525     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10526		          (const_int 0))
10527		      (match_operand 0 "register_operand" ""))
10528		 (match_operand 2 "const1_operand" ""))
10529	      (const_string "alu")
10530	   ]
10531	   (const_string "ishift")))
10532   (set_attr "mode" "DI")])
10533
10534(define_insn "*ashldi3_cconly_rex64"
10535  [(set (reg FLAGS_REG)
10536	(compare
10537	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10538		     (match_operand:QI 2 "immediate_operand" "e"))
10539	  (const_int 0)))
10540   (clobber (match_scratch:DI 0 "=r"))]
10541  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10542   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10543   && (optimize_size
10544       || !TARGET_PARTIAL_FLAG_REG_STALL
10545       || (operands[2] == const1_rtx
10546	   && (TARGET_SHIFT1
10547	       || TARGET_DOUBLE_WITH_ADD)))"
10548{
10549  switch (get_attr_type (insn))
10550    {
10551    case TYPE_ALU:
10552      gcc_assert (operands[2] == const1_rtx);
10553      return "add{q}\t{%0, %0|%0, %0}";
10554
10555    default:
10556      if (REG_P (operands[2]))
10557	return "sal{q}\t{%b2, %0|%0, %b2}";
10558      else if (operands[2] == const1_rtx
10559	       && (TARGET_SHIFT1 || optimize_size))
10560	return "sal{q}\t%0";
10561      else
10562	return "sal{q}\t{%2, %0|%0, %2}";
10563    }
10564}
10565  [(set (attr "type")
10566     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10567		          (const_int 0))
10568		      (match_operand 0 "register_operand" ""))
10569		 (match_operand 2 "const1_operand" ""))
10570	      (const_string "alu")
10571	   ]
10572	   (const_string "ishift")))
10573   (set_attr "mode" "DI")])
10574
10575(define_insn "*ashldi3_1"
10576  [(set (match_operand:DI 0 "register_operand" "=&r,r")
10577	(ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10578		   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10579   (clobber (reg:CC FLAGS_REG))]
10580  "!TARGET_64BIT"
10581  "#"
10582  [(set_attr "type" "multi")])
10583
10584;; By default we don't ask for a scratch register, because when DImode
10585;; values are manipulated, registers are already at a premium.  But if
10586;; we have one handy, we won't turn it away.
10587(define_peephole2
10588  [(match_scratch:SI 3 "r")
10589   (parallel [(set (match_operand:DI 0 "register_operand" "")
10590		   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10591			      (match_operand:QI 2 "nonmemory_operand" "")))
10592	      (clobber (reg:CC FLAGS_REG))])
10593   (match_dup 3)]
10594  "!TARGET_64BIT && TARGET_CMOVE"
10595  [(const_int 0)]
10596  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10597
10598(define_split
10599  [(set (match_operand:DI 0 "register_operand" "")
10600	(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10601		   (match_operand:QI 2 "nonmemory_operand" "")))
10602   (clobber (reg:CC FLAGS_REG))]
10603  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10604		     ? flow2_completed : reload_completed)"
10605  [(const_int 0)]
10606  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10607
10608(define_insn "x86_shld_1"
10609  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10610        (ior:SI (ashift:SI (match_dup 0)
10611		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10612		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10613		  (minus:QI (const_int 32) (match_dup 2)))))
10614   (clobber (reg:CC FLAGS_REG))]
10615  ""
10616  "@
10617   shld{l}\t{%2, %1, %0|%0, %1, %2}
10618   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10619  [(set_attr "type" "ishift")
10620   (set_attr "prefix_0f" "1")
10621   (set_attr "mode" "SI")
10622   (set_attr "pent_pair" "np")
10623   (set_attr "athlon_decode" "vector")
10624   (set_attr "amdfam10_decode" "vector")])   
10625
10626(define_expand "x86_shift_adj_1"
10627  [(set (reg:CCZ FLAGS_REG)
10628	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10629			     (const_int 32))
10630		     (const_int 0)))
10631   (set (match_operand:SI 0 "register_operand" "")
10632        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10633			 (match_operand:SI 1 "register_operand" "")
10634			 (match_dup 0)))
10635   (set (match_dup 1)
10636	(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10637			 (match_operand:SI 3 "register_operand" "r")
10638			 (match_dup 1)))]
10639  "TARGET_CMOVE"
10640  "")
10641
10642(define_expand "x86_shift_adj_2"
10643  [(use (match_operand:SI 0 "register_operand" ""))
10644   (use (match_operand:SI 1 "register_operand" ""))
10645   (use (match_operand:QI 2 "register_operand" ""))]
10646  ""
10647{
10648  rtx label = gen_label_rtx ();
10649  rtx tmp;
10650
10651  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10652
10653  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10654  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10655  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10656			      gen_rtx_LABEL_REF (VOIDmode, label),
10657			      pc_rtx);
10658  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10659  JUMP_LABEL (tmp) = label;
10660
10661  emit_move_insn (operands[0], operands[1]);
10662  ix86_expand_clear (operands[1]);
10663
10664  emit_label (label);
10665  LABEL_NUSES (label) = 1;
10666
10667  DONE;
10668})
10669
10670(define_expand "ashlsi3"
10671  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10672	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10673		   (match_operand:QI 2 "nonmemory_operand" "")))
10674   (clobber (reg:CC FLAGS_REG))]
10675  ""
10676  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10677
10678(define_insn "*ashlsi3_1"
10679  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10680	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10681		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10682   (clobber (reg:CC FLAGS_REG))]
10683  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10684{
10685  switch (get_attr_type (insn))
10686    {
10687    case TYPE_ALU:
10688      gcc_assert (operands[2] == const1_rtx);
10689      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10690      return "add{l}\t{%0, %0|%0, %0}";
10691
10692    case TYPE_LEA:
10693      return "#";
10694
10695    default:
10696      if (REG_P (operands[2]))
10697	return "sal{l}\t{%b2, %0|%0, %b2}";
10698      else if (operands[2] == const1_rtx
10699	       && (TARGET_SHIFT1 || optimize_size))
10700	return "sal{l}\t%0";
10701      else
10702	return "sal{l}\t{%2, %0|%0, %2}";
10703    }
10704}
10705  [(set (attr "type")
10706     (cond [(eq_attr "alternative" "1")
10707	      (const_string "lea")
10708            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10709		          (const_int 0))
10710		      (match_operand 0 "register_operand" ""))
10711		 (match_operand 2 "const1_operand" ""))
10712	      (const_string "alu")
10713	   ]
10714	   (const_string "ishift")))
10715   (set_attr "mode" "SI")])
10716
10717;; Convert lea to the lea pattern to avoid flags dependency.
10718(define_split
10719  [(set (match_operand 0 "register_operand" "")
10720	(ashift (match_operand 1 "index_register_operand" "")
10721                (match_operand:QI 2 "const_int_operand" "")))
10722   (clobber (reg:CC FLAGS_REG))]
10723  "reload_completed
10724   && true_regnum (operands[0]) != true_regnum (operands[1])
10725   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10726  [(const_int 0)]
10727{
10728  rtx pat;
10729  enum machine_mode mode = GET_MODE (operands[0]);
10730
10731  if (GET_MODE_SIZE (mode) < 4)
10732    operands[0] = gen_lowpart (SImode, operands[0]);
10733  if (mode != Pmode)
10734    operands[1] = gen_lowpart (Pmode, operands[1]);
10735  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10736
10737  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10738  if (Pmode != SImode)
10739    pat = gen_rtx_SUBREG (SImode, pat, 0);
10740  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10741  DONE;
10742})
10743
10744;; Rare case of shifting RSP is handled by generating move and shift
10745(define_split
10746  [(set (match_operand 0 "register_operand" "")
10747	(ashift (match_operand 1 "register_operand" "")
10748                (match_operand:QI 2 "const_int_operand" "")))
10749   (clobber (reg:CC FLAGS_REG))]
10750  "reload_completed
10751   && true_regnum (operands[0]) != true_regnum (operands[1])"
10752  [(const_int 0)]
10753{
10754  rtx pat, clob;
10755  emit_move_insn (operands[0], operands[1]);
10756  pat = gen_rtx_SET (VOIDmode, operands[0],
10757		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10758				     operands[0], operands[2]));
10759  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10760  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10761  DONE;
10762})
10763
10764(define_insn "*ashlsi3_1_zext"
10765  [(set (match_operand:DI 0 "register_operand" "=r,r")
10766	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10767			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10768   (clobber (reg:CC FLAGS_REG))]
10769  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10770{
10771  switch (get_attr_type (insn))
10772    {
10773    case TYPE_ALU:
10774      gcc_assert (operands[2] == const1_rtx);
10775      return "add{l}\t{%k0, %k0|%k0, %k0}";
10776
10777    case TYPE_LEA:
10778      return "#";
10779
10780    default:
10781      if (REG_P (operands[2]))
10782	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10783      else if (operands[2] == const1_rtx
10784	       && (TARGET_SHIFT1 || optimize_size))
10785	return "sal{l}\t%k0";
10786      else
10787	return "sal{l}\t{%2, %k0|%k0, %2}";
10788    }
10789}
10790  [(set (attr "type")
10791     (cond [(eq_attr "alternative" "1")
10792	      (const_string "lea")
10793            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10794		     (const_int 0))
10795		 (match_operand 2 "const1_operand" ""))
10796	      (const_string "alu")
10797	   ]
10798	   (const_string "ishift")))
10799   (set_attr "mode" "SI")])
10800
10801;; Convert lea to the lea pattern to avoid flags dependency.
10802(define_split
10803  [(set (match_operand:DI 0 "register_operand" "")
10804	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10805				(match_operand:QI 2 "const_int_operand" ""))))
10806   (clobber (reg:CC FLAGS_REG))]
10807  "TARGET_64BIT && reload_completed
10808   && true_regnum (operands[0]) != true_regnum (operands[1])"
10809  [(set (match_dup 0) (zero_extend:DI
10810			(subreg:SI (mult:SI (match_dup 1)
10811					    (match_dup 2)) 0)))]
10812{
10813  operands[1] = gen_lowpart (Pmode, operands[1]);
10814  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10815})
10816
10817;; This pattern can't accept a variable shift count, since shifts by
10818;; zero don't affect the flags.  We assume that shifts by constant
10819;; zero are optimized away.
10820(define_insn "*ashlsi3_cmp"
10821  [(set (reg FLAGS_REG)
10822	(compare
10823	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10824		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10825	  (const_int 0)))
10826   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10827	(ashift:SI (match_dup 1) (match_dup 2)))]
10828  "ix86_match_ccmode (insn, CCGOCmode)
10829   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10830   && (optimize_size
10831       || !TARGET_PARTIAL_FLAG_REG_STALL
10832       || (operands[2] == const1_rtx
10833	   && (TARGET_SHIFT1
10834	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10835{
10836  switch (get_attr_type (insn))
10837    {
10838    case TYPE_ALU:
10839      gcc_assert (operands[2] == const1_rtx);
10840      return "add{l}\t{%0, %0|%0, %0}";
10841
10842    default:
10843      if (REG_P (operands[2]))
10844	return "sal{l}\t{%b2, %0|%0, %b2}";
10845      else if (operands[2] == const1_rtx
10846	       && (TARGET_SHIFT1 || optimize_size))
10847	return "sal{l}\t%0";
10848      else
10849	return "sal{l}\t{%2, %0|%0, %2}";
10850    }
10851}
10852  [(set (attr "type")
10853     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10854		          (const_int 0))
10855		      (match_operand 0 "register_operand" ""))
10856		 (match_operand 2 "const1_operand" ""))
10857	      (const_string "alu")
10858	   ]
10859	   (const_string "ishift")))
10860   (set_attr "mode" "SI")])
10861
10862(define_insn "*ashlsi3_cconly"
10863  [(set (reg FLAGS_REG)
10864	(compare
10865	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10866		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10867	  (const_int 0)))
10868   (clobber (match_scratch:SI 0 "=r"))]
10869  "ix86_match_ccmode (insn, CCGOCmode)
10870   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10871   && (optimize_size
10872       || !TARGET_PARTIAL_FLAG_REG_STALL
10873       || (operands[2] == const1_rtx
10874	   && (TARGET_SHIFT1
10875	       || TARGET_DOUBLE_WITH_ADD)))"
10876{
10877  switch (get_attr_type (insn))
10878    {
10879    case TYPE_ALU:
10880      gcc_assert (operands[2] == const1_rtx);
10881      return "add{l}\t{%0, %0|%0, %0}";
10882
10883    default:
10884      if (REG_P (operands[2]))
10885	return "sal{l}\t{%b2, %0|%0, %b2}";
10886      else if (operands[2] == const1_rtx
10887	       && (TARGET_SHIFT1 || optimize_size))
10888	return "sal{l}\t%0";
10889      else
10890	return "sal{l}\t{%2, %0|%0, %2}";
10891    }
10892}
10893  [(set (attr "type")
10894     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10895		          (const_int 0))
10896		      (match_operand 0 "register_operand" ""))
10897		 (match_operand 2 "const1_operand" ""))
10898	      (const_string "alu")
10899	   ]
10900	   (const_string "ishift")))
10901   (set_attr "mode" "SI")])
10902
10903(define_insn "*ashlsi3_cmp_zext"
10904  [(set (reg FLAGS_REG)
10905	(compare
10906	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10907		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10908	  (const_int 0)))
10909   (set (match_operand:DI 0 "register_operand" "=r")
10910	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10911  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10912   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10913   && (optimize_size
10914       || !TARGET_PARTIAL_FLAG_REG_STALL
10915       || (operands[2] == const1_rtx
10916	   && (TARGET_SHIFT1
10917	       || TARGET_DOUBLE_WITH_ADD)))"
10918{
10919  switch (get_attr_type (insn))
10920    {
10921    case TYPE_ALU:
10922      gcc_assert (operands[2] == const1_rtx);
10923      return "add{l}\t{%k0, %k0|%k0, %k0}";
10924
10925    default:
10926      if (REG_P (operands[2]))
10927	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10928      else if (operands[2] == const1_rtx
10929	       && (TARGET_SHIFT1 || optimize_size))
10930	return "sal{l}\t%k0";
10931      else
10932	return "sal{l}\t{%2, %k0|%k0, %2}";
10933    }
10934}
10935  [(set (attr "type")
10936     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937		     (const_int 0))
10938		 (match_operand 2 "const1_operand" ""))
10939	      (const_string "alu")
10940	   ]
10941	   (const_string "ishift")))
10942   (set_attr "mode" "SI")])
10943
10944(define_expand "ashlhi3"
10945  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10946	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10947		   (match_operand:QI 2 "nonmemory_operand" "")))
10948   (clobber (reg:CC FLAGS_REG))]
10949  "TARGET_HIMODE_MATH"
10950  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10951
10952(define_insn "*ashlhi3_1_lea"
10953  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10954	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10955		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10956   (clobber (reg:CC FLAGS_REG))]
10957  "!TARGET_PARTIAL_REG_STALL
10958   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10959{
10960  switch (get_attr_type (insn))
10961    {
10962    case TYPE_LEA:
10963      return "#";
10964    case TYPE_ALU:
10965      gcc_assert (operands[2] == const1_rtx);
10966      return "add{w}\t{%0, %0|%0, %0}";
10967
10968    default:
10969      if (REG_P (operands[2]))
10970	return "sal{w}\t{%b2, %0|%0, %b2}";
10971      else if (operands[2] == const1_rtx
10972	       && (TARGET_SHIFT1 || optimize_size))
10973	return "sal{w}\t%0";
10974      else
10975	return "sal{w}\t{%2, %0|%0, %2}";
10976    }
10977}
10978  [(set (attr "type")
10979     (cond [(eq_attr "alternative" "1")
10980	      (const_string "lea")
10981            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10982		          (const_int 0))
10983		      (match_operand 0 "register_operand" ""))
10984		 (match_operand 2 "const1_operand" ""))
10985	      (const_string "alu")
10986	   ]
10987	   (const_string "ishift")))
10988   (set_attr "mode" "HI,SI")])
10989
10990(define_insn "*ashlhi3_1"
10991  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10992	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10993		   (match_operand:QI 2 "nonmemory_operand" "cI")))
10994   (clobber (reg:CC FLAGS_REG))]
10995  "TARGET_PARTIAL_REG_STALL
10996   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10997{
10998  switch (get_attr_type (insn))
10999    {
11000    case TYPE_ALU:
11001      gcc_assert (operands[2] == const1_rtx);
11002      return "add{w}\t{%0, %0|%0, %0}";
11003
11004    default:
11005      if (REG_P (operands[2]))
11006	return "sal{w}\t{%b2, %0|%0, %b2}";
11007      else if (operands[2] == const1_rtx
11008	       && (TARGET_SHIFT1 || optimize_size))
11009	return "sal{w}\t%0";
11010      else
11011	return "sal{w}\t{%2, %0|%0, %2}";
11012    }
11013}
11014  [(set (attr "type")
11015     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11016		          (const_int 0))
11017		      (match_operand 0 "register_operand" ""))
11018		 (match_operand 2 "const1_operand" ""))
11019	      (const_string "alu")
11020	   ]
11021	   (const_string "ishift")))
11022   (set_attr "mode" "HI")])
11023
11024;; This pattern can't accept a variable shift count, since shifts by
11025;; zero don't affect the flags.  We assume that shifts by constant
11026;; zero are optimized away.
11027(define_insn "*ashlhi3_cmp"
11028  [(set (reg FLAGS_REG)
11029	(compare
11030	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11031		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11032	  (const_int 0)))
11033   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11034	(ashift:HI (match_dup 1) (match_dup 2)))]
11035  "ix86_match_ccmode (insn, CCGOCmode)
11036   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11037   && (optimize_size
11038       || !TARGET_PARTIAL_FLAG_REG_STALL
11039       || (operands[2] == const1_rtx
11040	   && (TARGET_SHIFT1
11041	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11042{
11043  switch (get_attr_type (insn))
11044    {
11045    case TYPE_ALU:
11046      gcc_assert (operands[2] == const1_rtx);
11047      return "add{w}\t{%0, %0|%0, %0}";
11048
11049    default:
11050      if (REG_P (operands[2]))
11051	return "sal{w}\t{%b2, %0|%0, %b2}";
11052      else if (operands[2] == const1_rtx
11053	       && (TARGET_SHIFT1 || optimize_size))
11054	return "sal{w}\t%0";
11055      else
11056	return "sal{w}\t{%2, %0|%0, %2}";
11057    }
11058}
11059  [(set (attr "type")
11060     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11061		          (const_int 0))
11062		      (match_operand 0 "register_operand" ""))
11063		 (match_operand 2 "const1_operand" ""))
11064	      (const_string "alu")
11065	   ]
11066	   (const_string "ishift")))
11067   (set_attr "mode" "HI")])
11068
11069(define_insn "*ashlhi3_cconly"
11070  [(set (reg FLAGS_REG)
11071	(compare
11072	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11073		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11074	  (const_int 0)))
11075   (clobber (match_scratch:HI 0 "=r"))]
11076  "ix86_match_ccmode (insn, CCGOCmode)
11077   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11078   && (optimize_size
11079       || !TARGET_PARTIAL_FLAG_REG_STALL
11080       || (operands[2] == const1_rtx
11081	   && (TARGET_SHIFT1
11082	       || TARGET_DOUBLE_WITH_ADD)))"
11083{
11084  switch (get_attr_type (insn))
11085    {
11086    case TYPE_ALU:
11087      gcc_assert (operands[2] == const1_rtx);
11088      return "add{w}\t{%0, %0|%0, %0}";
11089
11090    default:
11091      if (REG_P (operands[2]))
11092	return "sal{w}\t{%b2, %0|%0, %b2}";
11093      else if (operands[2] == const1_rtx
11094	       && (TARGET_SHIFT1 || optimize_size))
11095	return "sal{w}\t%0";
11096      else
11097	return "sal{w}\t{%2, %0|%0, %2}";
11098    }
11099}
11100  [(set (attr "type")
11101     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102		          (const_int 0))
11103		      (match_operand 0 "register_operand" ""))
11104		 (match_operand 2 "const1_operand" ""))
11105	      (const_string "alu")
11106	   ]
11107	   (const_string "ishift")))
11108   (set_attr "mode" "HI")])
11109
11110(define_expand "ashlqi3"
11111  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11112	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11113		   (match_operand:QI 2 "nonmemory_operand" "")))
11114   (clobber (reg:CC FLAGS_REG))]
11115  "TARGET_QIMODE_MATH"
11116  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11117
11118;; %%% Potential partial reg stall on alternative 2.  What to do?
11119
11120(define_insn "*ashlqi3_1_lea"
11121  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11122	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11123		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11124   (clobber (reg:CC FLAGS_REG))]
11125  "!TARGET_PARTIAL_REG_STALL
11126   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11127{
11128  switch (get_attr_type (insn))
11129    {
11130    case TYPE_LEA:
11131      return "#";
11132    case TYPE_ALU:
11133      gcc_assert (operands[2] == const1_rtx);
11134      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11135        return "add{l}\t{%k0, %k0|%k0, %k0}";
11136      else
11137        return "add{b}\t{%0, %0|%0, %0}";
11138
11139    default:
11140      if (REG_P (operands[2]))
11141	{
11142	  if (get_attr_mode (insn) == MODE_SI)
11143	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11144	  else
11145	    return "sal{b}\t{%b2, %0|%0, %b2}";
11146	}
11147      else if (operands[2] == const1_rtx
11148	       && (TARGET_SHIFT1 || optimize_size))
11149	{
11150	  if (get_attr_mode (insn) == MODE_SI)
11151	    return "sal{l}\t%0";
11152	  else
11153	    return "sal{b}\t%0";
11154	}
11155      else
11156	{
11157	  if (get_attr_mode (insn) == MODE_SI)
11158	    return "sal{l}\t{%2, %k0|%k0, %2}";
11159	  else
11160	    return "sal{b}\t{%2, %0|%0, %2}";
11161	}
11162    }
11163}
11164  [(set (attr "type")
11165     (cond [(eq_attr "alternative" "2")
11166	      (const_string "lea")
11167            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11168		          (const_int 0))
11169		      (match_operand 0 "register_operand" ""))
11170		 (match_operand 2 "const1_operand" ""))
11171	      (const_string "alu")
11172	   ]
11173	   (const_string "ishift")))
11174   (set_attr "mode" "QI,SI,SI")])
11175
11176(define_insn "*ashlqi3_1"
11177  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11178	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11179		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11180   (clobber (reg:CC FLAGS_REG))]
11181  "TARGET_PARTIAL_REG_STALL
11182   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11183{
11184  switch (get_attr_type (insn))
11185    {
11186    case TYPE_ALU:
11187      gcc_assert (operands[2] == const1_rtx);
11188      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11189        return "add{l}\t{%k0, %k0|%k0, %k0}";
11190      else
11191        return "add{b}\t{%0, %0|%0, %0}";
11192
11193    default:
11194      if (REG_P (operands[2]))
11195	{
11196	  if (get_attr_mode (insn) == MODE_SI)
11197	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11198	  else
11199	    return "sal{b}\t{%b2, %0|%0, %b2}";
11200	}
11201      else if (operands[2] == const1_rtx
11202	       && (TARGET_SHIFT1 || optimize_size))
11203	{
11204	  if (get_attr_mode (insn) == MODE_SI)
11205	    return "sal{l}\t%0";
11206	  else
11207	    return "sal{b}\t%0";
11208	}
11209      else
11210	{
11211	  if (get_attr_mode (insn) == MODE_SI)
11212	    return "sal{l}\t{%2, %k0|%k0, %2}";
11213	  else
11214	    return "sal{b}\t{%2, %0|%0, %2}";
11215	}
11216    }
11217}
11218  [(set (attr "type")
11219     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11220		          (const_int 0))
11221		      (match_operand 0 "register_operand" ""))
11222		 (match_operand 2 "const1_operand" ""))
11223	      (const_string "alu")
11224	   ]
11225	   (const_string "ishift")))
11226   (set_attr "mode" "QI,SI")])
11227
11228;; This pattern can't accept a variable shift count, since shifts by
11229;; zero don't affect the flags.  We assume that shifts by constant
11230;; zero are optimized away.
11231(define_insn "*ashlqi3_cmp"
11232  [(set (reg FLAGS_REG)
11233	(compare
11234	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11235		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11236	  (const_int 0)))
11237   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11238	(ashift:QI (match_dup 1) (match_dup 2)))]
11239  "ix86_match_ccmode (insn, CCGOCmode)
11240   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11241   && (optimize_size
11242       || !TARGET_PARTIAL_FLAG_REG_STALL
11243       || (operands[2] == const1_rtx
11244	   && (TARGET_SHIFT1
11245	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11246{
11247  switch (get_attr_type (insn))
11248    {
11249    case TYPE_ALU:
11250      gcc_assert (operands[2] == const1_rtx);
11251      return "add{b}\t{%0, %0|%0, %0}";
11252
11253    default:
11254      if (REG_P (operands[2]))
11255	return "sal{b}\t{%b2, %0|%0, %b2}";
11256      else if (operands[2] == const1_rtx
11257	       && (TARGET_SHIFT1 || optimize_size))
11258	return "sal{b}\t%0";
11259      else
11260	return "sal{b}\t{%2, %0|%0, %2}";
11261    }
11262}
11263  [(set (attr "type")
11264     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11265		          (const_int 0))
11266		      (match_operand 0 "register_operand" ""))
11267		 (match_operand 2 "const1_operand" ""))
11268	      (const_string "alu")
11269	   ]
11270	   (const_string "ishift")))
11271   (set_attr "mode" "QI")])
11272
11273(define_insn "*ashlqi3_cconly"
11274  [(set (reg FLAGS_REG)
11275	(compare
11276	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11277		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11278	  (const_int 0)))
11279   (clobber (match_scratch:QI 0 "=q"))]
11280  "ix86_match_ccmode (insn, CCGOCmode)
11281   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11282   && (optimize_size
11283       || !TARGET_PARTIAL_FLAG_REG_STALL
11284       || (operands[2] == const1_rtx
11285	   && (TARGET_SHIFT1
11286	       || TARGET_DOUBLE_WITH_ADD)))"
11287{
11288  switch (get_attr_type (insn))
11289    {
11290    case TYPE_ALU:
11291      gcc_assert (operands[2] == const1_rtx);
11292      return "add{b}\t{%0, %0|%0, %0}";
11293
11294    default:
11295      if (REG_P (operands[2]))
11296	return "sal{b}\t{%b2, %0|%0, %b2}";
11297      else if (operands[2] == const1_rtx
11298	       && (TARGET_SHIFT1 || optimize_size))
11299	return "sal{b}\t%0";
11300      else
11301	return "sal{b}\t{%2, %0|%0, %2}";
11302    }
11303}
11304  [(set (attr "type")
11305     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11306		          (const_int 0))
11307		      (match_operand 0 "register_operand" ""))
11308		 (match_operand 2 "const1_operand" ""))
11309	      (const_string "alu")
11310	   ]
11311	   (const_string "ishift")))
11312   (set_attr "mode" "QI")])
11313
11314;; See comment above `ashldi3' about how this works.
11315
11316(define_expand "ashrti3"
11317  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11318		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11319				(match_operand:QI 2 "nonmemory_operand" "")))
11320	      (clobber (reg:CC FLAGS_REG))])]
11321  "TARGET_64BIT"
11322{
11323  if (! immediate_operand (operands[2], QImode))
11324    {
11325      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11326      DONE;
11327    }
11328  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11329  DONE;
11330})
11331
11332(define_insn "ashrti3_1"
11333  [(set (match_operand:TI 0 "register_operand" "=r")
11334	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11335		     (match_operand:QI 2 "register_operand" "c")))
11336   (clobber (match_scratch:DI 3 "=&r"))
11337   (clobber (reg:CC FLAGS_REG))]
11338  "TARGET_64BIT"
11339  "#"
11340  [(set_attr "type" "multi")])
11341
11342(define_insn "*ashrti3_2"
11343  [(set (match_operand:TI 0 "register_operand" "=r")
11344	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11345		     (match_operand:QI 2 "immediate_operand" "O")))
11346   (clobber (reg:CC FLAGS_REG))]
11347  "TARGET_64BIT"
11348  "#"
11349  [(set_attr "type" "multi")])
11350
11351(define_split
11352  [(set (match_operand:TI 0 "register_operand" "")
11353	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11354		     (match_operand:QI 2 "register_operand" "")))
11355   (clobber (match_scratch:DI 3 ""))
11356   (clobber (reg:CC FLAGS_REG))]
11357  "TARGET_64BIT && reload_completed"
11358  [(const_int 0)]
11359  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11360
11361(define_split
11362  [(set (match_operand:TI 0 "register_operand" "")
11363	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11364		     (match_operand:QI 2 "immediate_operand" "")))
11365   (clobber (reg:CC FLAGS_REG))]
11366  "TARGET_64BIT && reload_completed"
11367  [(const_int 0)]
11368  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11369
11370(define_insn "x86_64_shrd"
11371  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11372        (ior:DI (ashiftrt:DI (match_dup 0)
11373		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
11374		(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11375		  (minus:QI (const_int 64) (match_dup 2)))))
11376   (clobber (reg:CC FLAGS_REG))]
11377  "TARGET_64BIT"
11378  "@
11379   shrd{q}\t{%2, %1, %0|%0, %1, %2}
11380   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11381  [(set_attr "type" "ishift")
11382   (set_attr "prefix_0f" "1")
11383   (set_attr "mode" "DI")
11384   (set_attr "athlon_decode" "vector")
11385   (set_attr "amdfam10_decode" "vector")])   
11386
11387(define_expand "ashrdi3"
11388  [(set (match_operand:DI 0 "shiftdi_operand" "")
11389	(ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11390		     (match_operand:QI 2 "nonmemory_operand" "")))]
11391  ""
11392  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11393
11394(define_insn "*ashrdi3_63_rex64"
11395  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11396	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11397		     (match_operand:DI 2 "const_int_operand" "i,i")))
11398   (clobber (reg:CC FLAGS_REG))]
11399  "TARGET_64BIT && INTVAL (operands[2]) == 63
11400   && (TARGET_USE_CLTD || optimize_size)
11401   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402  "@
11403   {cqto|cqo}
11404   sar{q}\t{%2, %0|%0, %2}"
11405  [(set_attr "type" "imovx,ishift")
11406   (set_attr "prefix_0f" "0,*")
11407   (set_attr "length_immediate" "0,*")
11408   (set_attr "modrm" "0,1")
11409   (set_attr "mode" "DI")])
11410
11411(define_insn "*ashrdi3_1_one_bit_rex64"
11412  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11413	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11414		     (match_operand:QI 2 "const1_operand" "")))
11415   (clobber (reg:CC FLAGS_REG))]
11416  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11417   && (TARGET_SHIFT1 || optimize_size)"
11418  "sar{q}\t%0"
11419  [(set_attr "type" "ishift")
11420   (set (attr "length") 
11421     (if_then_else (match_operand:DI 0 "register_operand" "") 
11422	(const_string "2")
11423	(const_string "*")))])
11424
11425(define_insn "*ashrdi3_1_rex64"
11426  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11427	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11428		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11429   (clobber (reg:CC FLAGS_REG))]
11430  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11431  "@
11432   sar{q}\t{%2, %0|%0, %2}
11433   sar{q}\t{%b2, %0|%0, %b2}"
11434  [(set_attr "type" "ishift")
11435   (set_attr "mode" "DI")])
11436
11437;; This pattern can't accept a variable shift count, since shifts by
11438;; zero don't affect the flags.  We assume that shifts by constant
11439;; zero are optimized away.
11440(define_insn "*ashrdi3_one_bit_cmp_rex64"
11441  [(set (reg FLAGS_REG)
11442	(compare
11443	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11444		       (match_operand:QI 2 "const1_operand" ""))
11445	  (const_int 0)))
11446   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11447	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11448  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11449   && (TARGET_SHIFT1 || optimize_size)
11450   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11451  "sar{q}\t%0"
11452  [(set_attr "type" "ishift")
11453   (set (attr "length") 
11454     (if_then_else (match_operand:DI 0 "register_operand" "") 
11455	(const_string "2")
11456	(const_string "*")))])
11457
11458(define_insn "*ashrdi3_one_bit_cconly_rex64"
11459  [(set (reg FLAGS_REG)
11460	(compare
11461	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11462		       (match_operand:QI 2 "const1_operand" ""))
11463	  (const_int 0)))
11464   (clobber (match_scratch:DI 0 "=r"))]
11465  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11466   && (TARGET_SHIFT1 || optimize_size)
11467   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11468  "sar{q}\t%0"
11469  [(set_attr "type" "ishift")
11470   (set_attr "length" "2")])
11471
11472;; This pattern can't accept a variable shift count, since shifts by
11473;; zero don't affect the flags.  We assume that shifts by constant
11474;; zero are optimized away.
11475(define_insn "*ashrdi3_cmp_rex64"
11476  [(set (reg FLAGS_REG)
11477	(compare
11478	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11479		       (match_operand:QI 2 "const_int_operand" "n"))
11480	  (const_int 0)))
11481   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11482	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11483  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11484   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11485   && (optimize_size
11486       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11487  "sar{q}\t{%2, %0|%0, %2}"
11488  [(set_attr "type" "ishift")
11489   (set_attr "mode" "DI")])
11490
11491(define_insn "*ashrdi3_cconly_rex64"
11492  [(set (reg FLAGS_REG)
11493	(compare
11494	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11495		       (match_operand:QI 2 "const_int_operand" "n"))
11496	  (const_int 0)))
11497   (clobber (match_scratch:DI 0 "=r"))]
11498  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11499   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11500   && (optimize_size
11501       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11502  "sar{q}\t{%2, %0|%0, %2}"
11503  [(set_attr "type" "ishift")
11504   (set_attr "mode" "DI")])
11505
11506(define_insn "*ashrdi3_1"
11507  [(set (match_operand:DI 0 "register_operand" "=r")
11508	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11509		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11510   (clobber (reg:CC FLAGS_REG))]
11511  "!TARGET_64BIT"
11512  "#"
11513  [(set_attr "type" "multi")])
11514
11515;; By default we don't ask for a scratch register, because when DImode
11516;; values are manipulated, registers are already at a premium.  But if
11517;; we have one handy, we won't turn it away.
11518(define_peephole2
11519  [(match_scratch:SI 3 "r")
11520   (parallel [(set (match_operand:DI 0 "register_operand" "")
11521		   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11522			        (match_operand:QI 2 "nonmemory_operand" "")))
11523	      (clobber (reg:CC FLAGS_REG))])
11524   (match_dup 3)]
11525  "!TARGET_64BIT && TARGET_CMOVE"
11526  [(const_int 0)]
11527  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11528
11529(define_split
11530  [(set (match_operand:DI 0 "register_operand" "")
11531	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11532		     (match_operand:QI 2 "nonmemory_operand" "")))
11533   (clobber (reg:CC FLAGS_REG))]
11534  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11535		     ? flow2_completed : reload_completed)"
11536  [(const_int 0)]
11537  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11538
11539(define_insn "x86_shrd_1"
11540  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11541        (ior:SI (ashiftrt:SI (match_dup 0)
11542		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11543		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11544		  (minus:QI (const_int 32) (match_dup 2)))))
11545   (clobber (reg:CC FLAGS_REG))]
11546  ""
11547  "@
11548   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11549   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11550  [(set_attr "type" "ishift")
11551   (set_attr "prefix_0f" "1")
11552   (set_attr "pent_pair" "np")
11553   (set_attr "mode" "SI")])
11554
11555(define_expand "x86_shift_adj_3"
11556  [(use (match_operand:SI 0 "register_operand" ""))
11557   (use (match_operand:SI 1 "register_operand" ""))
11558   (use (match_operand:QI 2 "register_operand" ""))]
11559  ""
11560{
11561  rtx label = gen_label_rtx ();
11562  rtx tmp;
11563
11564  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11565
11566  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11567  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11568  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11569			      gen_rtx_LABEL_REF (VOIDmode, label),
11570			      pc_rtx);
11571  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11572  JUMP_LABEL (tmp) = label;
11573
11574  emit_move_insn (operands[0], operands[1]);
11575  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11576
11577  emit_label (label);
11578  LABEL_NUSES (label) = 1;
11579
11580  DONE;
11581})
11582
11583(define_insn "ashrsi3_31"
11584  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11585	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11586		     (match_operand:SI 2 "const_int_operand" "i,i")))
11587   (clobber (reg:CC FLAGS_REG))]
11588  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11589   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11590  "@
11591   {cltd|cdq}
11592   sar{l}\t{%2, %0|%0, %2}"
11593  [(set_attr "type" "imovx,ishift")
11594   (set_attr "prefix_0f" "0,*")
11595   (set_attr "length_immediate" "0,*")
11596   (set_attr "modrm" "0,1")
11597   (set_attr "mode" "SI")])
11598
11599(define_insn "*ashrsi3_31_zext"
11600  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11601	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11602				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11603   (clobber (reg:CC FLAGS_REG))]
11604  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11605   && INTVAL (operands[2]) == 31
11606   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607  "@
11608   {cltd|cdq}
11609   sar{l}\t{%2, %k0|%k0, %2}"
11610  [(set_attr "type" "imovx,ishift")
11611   (set_attr "prefix_0f" "0,*")
11612   (set_attr "length_immediate" "0,*")
11613   (set_attr "modrm" "0,1")
11614   (set_attr "mode" "SI")])
11615
11616(define_expand "ashrsi3"
11617  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11618	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11619		     (match_operand:QI 2 "nonmemory_operand" "")))
11620   (clobber (reg:CC FLAGS_REG))]
11621  ""
11622  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11623
11624(define_insn "*ashrsi3_1_one_bit"
11625  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11626	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11627		     (match_operand:QI 2 "const1_operand" "")))
11628   (clobber (reg:CC FLAGS_REG))]
11629  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11630   && (TARGET_SHIFT1 || optimize_size)"
11631  "sar{l}\t%0"
11632  [(set_attr "type" "ishift")
11633   (set (attr "length") 
11634     (if_then_else (match_operand:SI 0 "register_operand" "") 
11635	(const_string "2")
11636	(const_string "*")))])
11637
11638(define_insn "*ashrsi3_1_one_bit_zext"
11639  [(set (match_operand:DI 0 "register_operand" "=r")
11640	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11641				     (match_operand:QI 2 "const1_operand" ""))))
11642   (clobber (reg:CC FLAGS_REG))]
11643  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11644   && (TARGET_SHIFT1 || optimize_size)"
11645  "sar{l}\t%k0"
11646  [(set_attr "type" "ishift")
11647   (set_attr "length" "2")])
11648
11649(define_insn "*ashrsi3_1"
11650  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11651	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11652		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11653   (clobber (reg:CC FLAGS_REG))]
11654  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655  "@
11656   sar{l}\t{%2, %0|%0, %2}
11657   sar{l}\t{%b2, %0|%0, %b2}"
11658  [(set_attr "type" "ishift")
11659   (set_attr "mode" "SI")])
11660
11661(define_insn "*ashrsi3_1_zext"
11662  [(set (match_operand:DI 0 "register_operand" "=r,r")
11663	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11664				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11665   (clobber (reg:CC FLAGS_REG))]
11666  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11667  "@
11668   sar{l}\t{%2, %k0|%k0, %2}
11669   sar{l}\t{%b2, %k0|%k0, %b2}"
11670  [(set_attr "type" "ishift")
11671   (set_attr "mode" "SI")])
11672
11673;; This pattern can't accept a variable shift count, since shifts by
11674;; zero don't affect the flags.  We assume that shifts by constant
11675;; zero are optimized away.
11676(define_insn "*ashrsi3_one_bit_cmp"
11677  [(set (reg FLAGS_REG)
11678	(compare
11679	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11680		       (match_operand:QI 2 "const1_operand" ""))
11681	  (const_int 0)))
11682   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11683	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11684  "ix86_match_ccmode (insn, CCGOCmode)
11685   && (TARGET_SHIFT1 || optimize_size)
11686   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11687  "sar{l}\t%0"
11688  [(set_attr "type" "ishift")
11689   (set (attr "length") 
11690     (if_then_else (match_operand:SI 0 "register_operand" "") 
11691	(const_string "2")
11692	(const_string "*")))])
11693
11694(define_insn "*ashrsi3_one_bit_cconly"
11695  [(set (reg FLAGS_REG)
11696	(compare
11697	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11698		       (match_operand:QI 2 "const1_operand" ""))
11699	  (const_int 0)))
11700   (clobber (match_scratch:SI 0 "=r"))]
11701  "ix86_match_ccmode (insn, CCGOCmode)
11702   && (TARGET_SHIFT1 || optimize_size)
11703   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11704  "sar{l}\t%0"
11705  [(set_attr "type" "ishift")
11706   (set_attr "length" "2")])
11707
11708(define_insn "*ashrsi3_one_bit_cmp_zext"
11709  [(set (reg FLAGS_REG)
11710	(compare
11711	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712		       (match_operand:QI 2 "const1_operand" ""))
11713	  (const_int 0)))
11714   (set (match_operand:DI 0 "register_operand" "=r")
11715	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11716  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11717   && (TARGET_SHIFT1 || optimize_size)
11718   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11719  "sar{l}\t%k0"
11720  [(set_attr "type" "ishift")
11721   (set_attr "length" "2")])
11722
11723;; This pattern can't accept a variable shift count, since shifts by
11724;; zero don't affect the flags.  We assume that shifts by constant
11725;; zero are optimized away.
11726(define_insn "*ashrsi3_cmp"
11727  [(set (reg FLAGS_REG)
11728	(compare
11729	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11730		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11731	  (const_int 0)))
11732   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11733	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11734  "ix86_match_ccmode (insn, CCGOCmode)
11735   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11736   && (optimize_size
11737       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11738  "sar{l}\t{%2, %0|%0, %2}"
11739  [(set_attr "type" "ishift")
11740   (set_attr "mode" "SI")])
11741
11742(define_insn "*ashrsi3_cconly"
11743  [(set (reg FLAGS_REG)
11744	(compare
11745	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11746		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11747	  (const_int 0)))
11748   (clobber (match_scratch:SI 0 "=r"))]
11749  "ix86_match_ccmode (insn, CCGOCmode)
11750   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11751   && (optimize_size
11752       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11753  "sar{l}\t{%2, %0|%0, %2}"
11754  [(set_attr "type" "ishift")
11755   (set_attr "mode" "SI")])
11756
11757(define_insn "*ashrsi3_cmp_zext"
11758  [(set (reg FLAGS_REG)
11759	(compare
11760	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11761		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11762	  (const_int 0)))
11763   (set (match_operand:DI 0 "register_operand" "=r")
11764	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11765  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11766   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11767   && (optimize_size
11768       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11769  "sar{l}\t{%2, %k0|%k0, %2}"
11770  [(set_attr "type" "ishift")
11771   (set_attr "mode" "SI")])
11772
11773(define_expand "ashrhi3"
11774  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11775	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11776		     (match_operand:QI 2 "nonmemory_operand" "")))
11777   (clobber (reg:CC FLAGS_REG))]
11778  "TARGET_HIMODE_MATH"
11779  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11780
11781(define_insn "*ashrhi3_1_one_bit"
11782  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11783	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11784		     (match_operand:QI 2 "const1_operand" "")))
11785   (clobber (reg:CC FLAGS_REG))]
11786  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11787   && (TARGET_SHIFT1 || optimize_size)"
11788  "sar{w}\t%0"
11789  [(set_attr "type" "ishift")
11790   (set (attr "length") 
11791     (if_then_else (match_operand 0 "register_operand" "") 
11792	(const_string "2")
11793	(const_string "*")))])
11794
11795(define_insn "*ashrhi3_1"
11796  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11797	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11798		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11799   (clobber (reg:CC FLAGS_REG))]
11800  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11801  "@
11802   sar{w}\t{%2, %0|%0, %2}
11803   sar{w}\t{%b2, %0|%0, %b2}"
11804  [(set_attr "type" "ishift")
11805   (set_attr "mode" "HI")])
11806
11807;; This pattern can't accept a variable shift count, since shifts by
11808;; zero don't affect the flags.  We assume that shifts by constant
11809;; zero are optimized away.
11810(define_insn "*ashrhi3_one_bit_cmp"
11811  [(set (reg FLAGS_REG)
11812	(compare
11813	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11814		       (match_operand:QI 2 "const1_operand" ""))
11815	  (const_int 0)))
11816   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11817	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11818  "ix86_match_ccmode (insn, CCGOCmode)
11819   && (TARGET_SHIFT1 || optimize_size)
11820   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11821  "sar{w}\t%0"
11822  [(set_attr "type" "ishift")
11823   (set (attr "length") 
11824     (if_then_else (match_operand 0 "register_operand" "") 
11825	(const_string "2")
11826	(const_string "*")))])
11827
11828(define_insn "*ashrhi3_one_bit_cconly"
11829  [(set (reg FLAGS_REG)
11830	(compare
11831	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11832		       (match_operand:QI 2 "const1_operand" ""))
11833	  (const_int 0)))
11834   (clobber (match_scratch:HI 0 "=r"))]
11835  "ix86_match_ccmode (insn, CCGOCmode)
11836   && (TARGET_SHIFT1 || optimize_size)
11837   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11838  "sar{w}\t%0"
11839  [(set_attr "type" "ishift")
11840   (set_attr "length" "2")])
11841
11842;; This pattern can't accept a variable shift count, since shifts by
11843;; zero don't affect the flags.  We assume that shifts by constant
11844;; zero are optimized away.
11845(define_insn "*ashrhi3_cmp"
11846  [(set (reg FLAGS_REG)
11847	(compare
11848	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11849		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11850	  (const_int 0)))
11851   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11852	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11853  "ix86_match_ccmode (insn, CCGOCmode)
11854   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11855   && (optimize_size
11856       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11857  "sar{w}\t{%2, %0|%0, %2}"
11858  [(set_attr "type" "ishift")
11859   (set_attr "mode" "HI")])
11860
11861(define_insn "*ashrhi3_cconly"
11862  [(set (reg FLAGS_REG)
11863	(compare
11864	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11865		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11866	  (const_int 0)))
11867   (clobber (match_scratch:HI 0 "=r"))]
11868  "ix86_match_ccmode (insn, CCGOCmode)
11869   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11870   && (optimize_size
11871       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11872  "sar{w}\t{%2, %0|%0, %2}"
11873  [(set_attr "type" "ishift")
11874   (set_attr "mode" "HI")])
11875
11876(define_expand "ashrqi3"
11877  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11878	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11879		     (match_operand:QI 2 "nonmemory_operand" "")))
11880   (clobber (reg:CC FLAGS_REG))]
11881  "TARGET_QIMODE_MATH"
11882  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11883
11884(define_insn "*ashrqi3_1_one_bit"
11885  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11886	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11887		     (match_operand:QI 2 "const1_operand" "")))
11888   (clobber (reg:CC FLAGS_REG))]
11889  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11890   && (TARGET_SHIFT1 || optimize_size)"
11891  "sar{b}\t%0"
11892  [(set_attr "type" "ishift")
11893   (set (attr "length") 
11894     (if_then_else (match_operand 0 "register_operand" "") 
11895	(const_string "2")
11896	(const_string "*")))])
11897
11898(define_insn "*ashrqi3_1_one_bit_slp"
11899  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11900	(ashiftrt:QI (match_dup 0)
11901		     (match_operand:QI 1 "const1_operand" "")))
11902   (clobber (reg:CC FLAGS_REG))]
11903  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11904   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11905   && (TARGET_SHIFT1 || optimize_size)"
11906  "sar{b}\t%0"
11907  [(set_attr "type" "ishift1")
11908   (set (attr "length") 
11909     (if_then_else (match_operand 0 "register_operand" "") 
11910	(const_string "2")
11911	(const_string "*")))])
11912
11913(define_insn "*ashrqi3_1"
11914  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11915	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11916		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11917   (clobber (reg:CC FLAGS_REG))]
11918  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11919  "@
11920   sar{b}\t{%2, %0|%0, %2}
11921   sar{b}\t{%b2, %0|%0, %b2}"
11922  [(set_attr "type" "ishift")
11923   (set_attr "mode" "QI")])
11924
11925(define_insn "*ashrqi3_1_slp"
11926  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11927	(ashiftrt:QI (match_dup 0)
11928		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11929   (clobber (reg:CC FLAGS_REG))]
11930  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11931   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11932  "@
11933   sar{b}\t{%1, %0|%0, %1}
11934   sar{b}\t{%b1, %0|%0, %b1}"
11935  [(set_attr "type" "ishift1")
11936   (set_attr "mode" "QI")])
11937
11938;; This pattern can't accept a variable shift count, since shifts by
11939;; zero don't affect the flags.  We assume that shifts by constant
11940;; zero are optimized away.
11941(define_insn "*ashrqi3_one_bit_cmp"
11942  [(set (reg FLAGS_REG)
11943	(compare
11944	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11945		       (match_operand:QI 2 "const1_operand" "I"))
11946	  (const_int 0)))
11947   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11948	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11949  "ix86_match_ccmode (insn, CCGOCmode)
11950   && (TARGET_SHIFT1 || optimize_size)
11951   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11952  "sar{b}\t%0"
11953  [(set_attr "type" "ishift")
11954   (set (attr "length") 
11955     (if_then_else (match_operand 0 "register_operand" "") 
11956	(const_string "2")
11957	(const_string "*")))])
11958
11959(define_insn "*ashrqi3_one_bit_cconly"
11960  [(set (reg FLAGS_REG)
11961	(compare
11962	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11963		       (match_operand:QI 2 "const1_operand" "I"))
11964	  (const_int 0)))
11965   (clobber (match_scratch:QI 0 "=q"))]
11966  "ix86_match_ccmode (insn, CCGOCmode)
11967   && (TARGET_SHIFT1 || optimize_size)
11968   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11969  "sar{b}\t%0"
11970  [(set_attr "type" "ishift")
11971   (set_attr "length" "2")])
11972
11973;; This pattern can't accept a variable shift count, since shifts by
11974;; zero don't affect the flags.  We assume that shifts by constant
11975;; zero are optimized away.
11976(define_insn "*ashrqi3_cmp"
11977  [(set (reg FLAGS_REG)
11978	(compare
11979	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11980		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11981	  (const_int 0)))
11982   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11983	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11984  "ix86_match_ccmode (insn, CCGOCmode)
11985   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11986   && (optimize_size
11987       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11988  "sar{b}\t{%2, %0|%0, %2}"
11989  [(set_attr "type" "ishift")
11990   (set_attr "mode" "QI")])
11991
11992(define_insn "*ashrqi3_cconly"
11993  [(set (reg FLAGS_REG)
11994	(compare
11995	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11996		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11997	  (const_int 0)))
11998   (clobber (match_scratch:QI 0 "=q"))]
11999  "ix86_match_ccmode (insn, CCGOCmode)
12000   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12001   && (optimize_size
12002       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12003  "sar{b}\t{%2, %0|%0, %2}"
12004  [(set_attr "type" "ishift")
12005   (set_attr "mode" "QI")])
12006
12007
12008;; Logical shift instructions
12009
12010;; See comment above `ashldi3' about how this works.
12011
12012(define_expand "lshrti3"
12013  [(parallel [(set (match_operand:TI 0 "register_operand" "")
12014		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12015			        (match_operand:QI 2 "nonmemory_operand" "")))
12016	      (clobber (reg:CC FLAGS_REG))])]
12017  "TARGET_64BIT"
12018{
12019  if (! immediate_operand (operands[2], QImode))
12020    {
12021      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12022      DONE;
12023    }
12024  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12025  DONE;
12026})
12027
12028(define_insn "lshrti3_1"
12029  [(set (match_operand:TI 0 "register_operand" "=r")
12030	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12031		     (match_operand:QI 2 "register_operand" "c")))
12032   (clobber (match_scratch:DI 3 "=&r"))
12033   (clobber (reg:CC FLAGS_REG))]
12034  "TARGET_64BIT"
12035  "#"
12036  [(set_attr "type" "multi")])
12037
12038(define_insn "*lshrti3_2"
12039  [(set (match_operand:TI 0 "register_operand" "=r")
12040	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12041		     (match_operand:QI 2 "immediate_operand" "O")))
12042   (clobber (reg:CC FLAGS_REG))]
12043  "TARGET_64BIT"
12044  "#"
12045  [(set_attr "type" "multi")])
12046
12047(define_split 
12048  [(set (match_operand:TI 0 "register_operand" "")
12049	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12050		     (match_operand:QI 2 "register_operand" "")))
12051   (clobber (match_scratch:DI 3 ""))
12052   (clobber (reg:CC FLAGS_REG))]
12053  "TARGET_64BIT && reload_completed"
12054  [(const_int 0)]
12055  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12056
12057(define_split 
12058  [(set (match_operand:TI 0 "register_operand" "")
12059	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12060		     (match_operand:QI 2 "immediate_operand" "")))
12061   (clobber (reg:CC FLAGS_REG))]
12062  "TARGET_64BIT && reload_completed"
12063  [(const_int 0)]
12064  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12065
12066(define_expand "lshrdi3"
12067  [(set (match_operand:DI 0 "shiftdi_operand" "")
12068	(lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12069		     (match_operand:QI 2 "nonmemory_operand" "")))]
12070  ""
12071  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12072
12073(define_insn "*lshrdi3_1_one_bit_rex64"
12074  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12075	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12076		     (match_operand:QI 2 "const1_operand" "")))
12077   (clobber (reg:CC FLAGS_REG))]
12078  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12079   && (TARGET_SHIFT1 || optimize_size)"
12080  "shr{q}\t%0"
12081  [(set_attr "type" "ishift")
12082   (set (attr "length") 
12083     (if_then_else (match_operand:DI 0 "register_operand" "") 
12084	(const_string "2")
12085	(const_string "*")))])
12086
12087(define_insn "*lshrdi3_1_rex64"
12088  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12089	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12090		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12091   (clobber (reg:CC FLAGS_REG))]
12092  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12093  "@
12094   shr{q}\t{%2, %0|%0, %2}
12095   shr{q}\t{%b2, %0|%0, %b2}"
12096  [(set_attr "type" "ishift")
12097   (set_attr "mode" "DI")])
12098
12099;; This pattern can't accept a variable shift count, since shifts by
12100;; zero don't affect the flags.  We assume that shifts by constant
12101;; zero are optimized away.
12102(define_insn "*lshrdi3_cmp_one_bit_rex64"
12103  [(set (reg FLAGS_REG)
12104	(compare
12105	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12106		       (match_operand:QI 2 "const1_operand" ""))
12107	  (const_int 0)))
12108   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12109	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12110  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12111   && (TARGET_SHIFT1 || optimize_size)
12112   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12113  "shr{q}\t%0"
12114  [(set_attr "type" "ishift")
12115   (set (attr "length") 
12116     (if_then_else (match_operand:DI 0 "register_operand" "") 
12117	(const_string "2")
12118	(const_string "*")))])
12119
12120(define_insn "*lshrdi3_cconly_one_bit_rex64"
12121  [(set (reg FLAGS_REG)
12122	(compare
12123	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12124		       (match_operand:QI 2 "const1_operand" ""))
12125	  (const_int 0)))
12126   (clobber (match_scratch:DI 0 "=r"))]
12127  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12128   && (TARGET_SHIFT1 || optimize_size)
12129   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12130  "shr{q}\t%0"
12131  [(set_attr "type" "ishift")
12132   (set_attr "length" "2")])
12133
12134;; This pattern can't accept a variable shift count, since shifts by
12135;; zero don't affect the flags.  We assume that shifts by constant
12136;; zero are optimized away.
12137(define_insn "*lshrdi3_cmp_rex64"
12138  [(set (reg FLAGS_REG)
12139	(compare
12140	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12141		       (match_operand:QI 2 "const_int_operand" "e"))
12142	  (const_int 0)))
12143   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12144	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12145  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12146   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12147   && (optimize_size
12148       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12149  "shr{q}\t{%2, %0|%0, %2}"
12150  [(set_attr "type" "ishift")
12151   (set_attr "mode" "DI")])
12152
12153(define_insn "*lshrdi3_cconly_rex64"
12154  [(set (reg FLAGS_REG)
12155	(compare
12156	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12157		       (match_operand:QI 2 "const_int_operand" "e"))
12158	  (const_int 0)))
12159   (clobber (match_scratch:DI 0 "=r"))]
12160  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12161   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12162   && (optimize_size
12163       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12164  "shr{q}\t{%2, %0|%0, %2}"
12165  [(set_attr "type" "ishift")
12166   (set_attr "mode" "DI")])
12167
12168(define_insn "*lshrdi3_1"
12169  [(set (match_operand:DI 0 "register_operand" "=r")
12170	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12171		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
12172   (clobber (reg:CC FLAGS_REG))]
12173  "!TARGET_64BIT"
12174  "#"
12175  [(set_attr "type" "multi")])
12176
12177;; By default we don't ask for a scratch register, because when DImode
12178;; values are manipulated, registers are already at a premium.  But if
12179;; we have one handy, we won't turn it away.
12180(define_peephole2
12181  [(match_scratch:SI 3 "r")
12182   (parallel [(set (match_operand:DI 0 "register_operand" "")
12183		   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12184			        (match_operand:QI 2 "nonmemory_operand" "")))
12185	      (clobber (reg:CC FLAGS_REG))])
12186   (match_dup 3)]
12187  "!TARGET_64BIT && TARGET_CMOVE"
12188  [(const_int 0)]
12189  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12190
12191(define_split 
12192  [(set (match_operand:DI 0 "register_operand" "")
12193	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12194		     (match_operand:QI 2 "nonmemory_operand" "")))
12195   (clobber (reg:CC FLAGS_REG))]
12196  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12197		     ? flow2_completed : reload_completed)"
12198  [(const_int 0)]
12199  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12200
12201(define_expand "lshrsi3"
12202  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12203	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12204		     (match_operand:QI 2 "nonmemory_operand" "")))
12205   (clobber (reg:CC FLAGS_REG))]
12206  ""
12207  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12208
12209(define_insn "*lshrsi3_1_one_bit"
12210  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12211	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12212		     (match_operand:QI 2 "const1_operand" "")))
12213   (clobber (reg:CC FLAGS_REG))]
12214  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12215   && (TARGET_SHIFT1 || optimize_size)"
12216  "shr{l}\t%0"
12217  [(set_attr "type" "ishift")
12218   (set (attr "length") 
12219     (if_then_else (match_operand:SI 0 "register_operand" "") 
12220	(const_string "2")
12221	(const_string "*")))])
12222
12223(define_insn "*lshrsi3_1_one_bit_zext"
12224  [(set (match_operand:DI 0 "register_operand" "=r")
12225	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12226		     (match_operand:QI 2 "const1_operand" "")))
12227   (clobber (reg:CC FLAGS_REG))]
12228  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12229   && (TARGET_SHIFT1 || optimize_size)"
12230  "shr{l}\t%k0"
12231  [(set_attr "type" "ishift")
12232   (set_attr "length" "2")])
12233
12234(define_insn "*lshrsi3_1"
12235  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12236	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12237		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12238   (clobber (reg:CC FLAGS_REG))]
12239  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12240  "@
12241   shr{l}\t{%2, %0|%0, %2}
12242   shr{l}\t{%b2, %0|%0, %b2}"
12243  [(set_attr "type" "ishift")
12244   (set_attr "mode" "SI")])
12245
12246(define_insn "*lshrsi3_1_zext"
12247  [(set (match_operand:DI 0 "register_operand" "=r,r")
12248	(zero_extend:DI
12249	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12250		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12251   (clobber (reg:CC FLAGS_REG))]
12252  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12253  "@
12254   shr{l}\t{%2, %k0|%k0, %2}
12255   shr{l}\t{%b2, %k0|%k0, %b2}"
12256  [(set_attr "type" "ishift")
12257   (set_attr "mode" "SI")])
12258
12259;; This pattern can't accept a variable shift count, since shifts by
12260;; zero don't affect the flags.  We assume that shifts by constant
12261;; zero are optimized away.
12262(define_insn "*lshrsi3_one_bit_cmp"
12263  [(set (reg FLAGS_REG)
12264	(compare
12265	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266		       (match_operand:QI 2 "const1_operand" ""))
12267	  (const_int 0)))
12268   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12269	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12270  "ix86_match_ccmode (insn, CCGOCmode)
12271   && (TARGET_SHIFT1 || optimize_size)
12272   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12273  "shr{l}\t%0"
12274  [(set_attr "type" "ishift")
12275   (set (attr "length") 
12276     (if_then_else (match_operand:SI 0 "register_operand" "") 
12277	(const_string "2")
12278	(const_string "*")))])
12279
12280(define_insn "*lshrsi3_one_bit_cconly"
12281  [(set (reg FLAGS_REG)
12282	(compare
12283	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12284		       (match_operand:QI 2 "const1_operand" ""))
12285	  (const_int 0)))
12286   (clobber (match_scratch:SI 0 "=r"))]
12287  "ix86_match_ccmode (insn, CCGOCmode)
12288   && (TARGET_SHIFT1 || optimize_size)
12289   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12290  "shr{l}\t%0"
12291  [(set_attr "type" "ishift")
12292   (set_attr "length" "2")])
12293
12294(define_insn "*lshrsi3_cmp_one_bit_zext"
12295  [(set (reg FLAGS_REG)
12296	(compare
12297	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12298		       (match_operand:QI 2 "const1_operand" ""))
12299	  (const_int 0)))
12300   (set (match_operand:DI 0 "register_operand" "=r")
12301	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12302  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12303   && (TARGET_SHIFT1 || optimize_size)
12304   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12305  "shr{l}\t%k0"
12306  [(set_attr "type" "ishift")
12307   (set_attr "length" "2")])
12308
12309;; This pattern can't accept a variable shift count, since shifts by
12310;; zero don't affect the flags.  We assume that shifts by constant
12311;; zero are optimized away.
12312(define_insn "*lshrsi3_cmp"
12313  [(set (reg FLAGS_REG)
12314	(compare
12315	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12316		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12317	  (const_int 0)))
12318   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12319	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12320  "ix86_match_ccmode (insn, CCGOCmode)
12321   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12322   && (optimize_size
12323       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12324  "shr{l}\t{%2, %0|%0, %2}"
12325  [(set_attr "type" "ishift")
12326   (set_attr "mode" "SI")])
12327
12328(define_insn "*lshrsi3_cconly"
12329  [(set (reg FLAGS_REG)
12330      (compare
12331	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12332		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
12333        (const_int 0)))
12334   (clobber (match_scratch:SI 0 "=r"))]
12335  "ix86_match_ccmode (insn, CCGOCmode)
12336   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12337   && (optimize_size
12338       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12339  "shr{l}\t{%2, %0|%0, %2}"
12340  [(set_attr "type" "ishift")
12341   (set_attr "mode" "SI")])
12342
12343(define_insn "*lshrsi3_cmp_zext"
12344  [(set (reg FLAGS_REG)
12345	(compare
12346	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12347		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12348	  (const_int 0)))
12349   (set (match_operand:DI 0 "register_operand" "=r")
12350	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12351  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12352   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12353   && (optimize_size
12354       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12355  "shr{l}\t{%2, %k0|%k0, %2}"
12356  [(set_attr "type" "ishift")
12357   (set_attr "mode" "SI")])
12358
12359(define_expand "lshrhi3"
12360  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12361	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12362		     (match_operand:QI 2 "nonmemory_operand" "")))
12363   (clobber (reg:CC FLAGS_REG))]
12364  "TARGET_HIMODE_MATH"
12365  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12366
12367(define_insn "*lshrhi3_1_one_bit"
12368  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12369	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12370		     (match_operand:QI 2 "const1_operand" "")))
12371   (clobber (reg:CC FLAGS_REG))]
12372  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12373   && (TARGET_SHIFT1 || optimize_size)"
12374  "shr{w}\t%0"
12375  [(set_attr "type" "ishift")
12376   (set (attr "length") 
12377     (if_then_else (match_operand 0 "register_operand" "") 
12378	(const_string "2")
12379	(const_string "*")))])
12380
12381(define_insn "*lshrhi3_1"
12382  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12383	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12384		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12385   (clobber (reg:CC FLAGS_REG))]
12386  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12387  "@
12388   shr{w}\t{%2, %0|%0, %2}
12389   shr{w}\t{%b2, %0|%0, %b2}"
12390  [(set_attr "type" "ishift")
12391   (set_attr "mode" "HI")])
12392
12393;; This pattern can't accept a variable shift count, since shifts by
12394;; zero don't affect the flags.  We assume that shifts by constant
12395;; zero are optimized away.
12396(define_insn "*lshrhi3_one_bit_cmp"
12397  [(set (reg FLAGS_REG)
12398	(compare
12399	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12400		       (match_operand:QI 2 "const1_operand" ""))
12401	  (const_int 0)))
12402   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12403	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12404  "ix86_match_ccmode (insn, CCGOCmode)
12405   && (TARGET_SHIFT1 || optimize_size)
12406   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12407  "shr{w}\t%0"
12408  [(set_attr "type" "ishift")
12409   (set (attr "length") 
12410     (if_then_else (match_operand:SI 0 "register_operand" "") 
12411	(const_string "2")
12412	(const_string "*")))])
12413
12414(define_insn "*lshrhi3_one_bit_cconly"
12415  [(set (reg FLAGS_REG)
12416	(compare
12417	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12418		       (match_operand:QI 2 "const1_operand" ""))
12419	  (const_int 0)))
12420   (clobber (match_scratch:HI 0 "=r"))]
12421  "ix86_match_ccmode (insn, CCGOCmode)
12422   && (TARGET_SHIFT1 || optimize_size)
12423   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12424  "shr{w}\t%0"
12425  [(set_attr "type" "ishift")
12426   (set_attr "length" "2")])
12427
12428;; This pattern can't accept a variable shift count, since shifts by
12429;; zero don't affect the flags.  We assume that shifts by constant
12430;; zero are optimized away.
12431(define_insn "*lshrhi3_cmp"
12432  [(set (reg FLAGS_REG)
12433	(compare
12434	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12435		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12436	  (const_int 0)))
12437   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12438	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12439  "ix86_match_ccmode (insn, CCGOCmode)
12440   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12441   && (optimize_size
12442       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12443  "shr{w}\t{%2, %0|%0, %2}"
12444  [(set_attr "type" "ishift")
12445   (set_attr "mode" "HI")])
12446
12447(define_insn "*lshrhi3_cconly"
12448  [(set (reg FLAGS_REG)
12449	(compare
12450	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12451		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12452	  (const_int 0)))
12453   (clobber (match_scratch:HI 0 "=r"))]
12454  "ix86_match_ccmode (insn, CCGOCmode)
12455   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12456   && (optimize_size
12457       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12458  "shr{w}\t{%2, %0|%0, %2}"
12459  [(set_attr "type" "ishift")
12460   (set_attr "mode" "HI")])
12461
12462(define_expand "lshrqi3"
12463  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12464	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12465		     (match_operand:QI 2 "nonmemory_operand" "")))
12466   (clobber (reg:CC FLAGS_REG))]
12467  "TARGET_QIMODE_MATH"
12468  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12469
12470(define_insn "*lshrqi3_1_one_bit"
12471  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12472	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12473		     (match_operand:QI 2 "const1_operand" "")))
12474   (clobber (reg:CC FLAGS_REG))]
12475  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12476   && (TARGET_SHIFT1 || optimize_size)"
12477  "shr{b}\t%0"
12478  [(set_attr "type" "ishift")
12479   (set (attr "length") 
12480     (if_then_else (match_operand 0 "register_operand" "") 
12481	(const_string "2")
12482	(const_string "*")))])
12483
12484(define_insn "*lshrqi3_1_one_bit_slp"
12485  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12486	(lshiftrt:QI (match_dup 0)
12487		     (match_operand:QI 1 "const1_operand" "")))
12488   (clobber (reg:CC FLAGS_REG))]
12489  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12490   && (TARGET_SHIFT1 || optimize_size)"
12491  "shr{b}\t%0"
12492  [(set_attr "type" "ishift1")
12493   (set (attr "length") 
12494     (if_then_else (match_operand 0 "register_operand" "") 
12495	(const_string "2")
12496	(const_string "*")))])
12497
12498(define_insn "*lshrqi3_1"
12499  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12500	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12501		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12502   (clobber (reg:CC FLAGS_REG))]
12503  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12504  "@
12505   shr{b}\t{%2, %0|%0, %2}
12506   shr{b}\t{%b2, %0|%0, %b2}"
12507  [(set_attr "type" "ishift")
12508   (set_attr "mode" "QI")])
12509
12510(define_insn "*lshrqi3_1_slp"
12511  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12512	(lshiftrt:QI (match_dup 0)
12513		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12514   (clobber (reg:CC FLAGS_REG))]
12515  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12516   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12517  "@
12518   shr{b}\t{%1, %0|%0, %1}
12519   shr{b}\t{%b1, %0|%0, %b1}"
12520  [(set_attr "type" "ishift1")
12521   (set_attr "mode" "QI")])
12522
12523;; This pattern can't accept a variable shift count, since shifts by
12524;; zero don't affect the flags.  We assume that shifts by constant
12525;; zero are optimized away.
12526(define_insn "*lshrqi2_one_bit_cmp"
12527  [(set (reg FLAGS_REG)
12528	(compare
12529	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12530		       (match_operand:QI 2 "const1_operand" ""))
12531	  (const_int 0)))
12532   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12533	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12534  "ix86_match_ccmode (insn, CCGOCmode)
12535   && (TARGET_SHIFT1 || optimize_size)
12536   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12537  "shr{b}\t%0"
12538  [(set_attr "type" "ishift")
12539   (set (attr "length") 
12540     (if_then_else (match_operand:SI 0 "register_operand" "") 
12541	(const_string "2")
12542	(const_string "*")))])
12543
12544(define_insn "*lshrqi2_one_bit_cconly"
12545  [(set (reg FLAGS_REG)
12546	(compare
12547	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12548		       (match_operand:QI 2 "const1_operand" ""))
12549	  (const_int 0)))
12550   (clobber (match_scratch:QI 0 "=q"))]
12551  "ix86_match_ccmode (insn, CCGOCmode)
12552   && (TARGET_SHIFT1 || optimize_size)
12553   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12554  "shr{b}\t%0"
12555  [(set_attr "type" "ishift")
12556   (set_attr "length" "2")])
12557
12558;; This pattern can't accept a variable shift count, since shifts by
12559;; zero don't affect the flags.  We assume that shifts by constant
12560;; zero are optimized away.
12561(define_insn "*lshrqi2_cmp"
12562  [(set (reg FLAGS_REG)
12563	(compare
12564	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12565		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12566	  (const_int 0)))
12567   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12568	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12569  "ix86_match_ccmode (insn, CCGOCmode)
12570   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12571   && (optimize_size
12572       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12573  "shr{b}\t{%2, %0|%0, %2}"
12574  [(set_attr "type" "ishift")
12575   (set_attr "mode" "QI")])
12576
12577(define_insn "*lshrqi2_cconly"
12578  [(set (reg FLAGS_REG)
12579	(compare
12580	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12581		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12582	  (const_int 0)))
12583   (clobber (match_scratch:QI 0 "=q"))]
12584  "ix86_match_ccmode (insn, CCGOCmode)
12585   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12586   && (optimize_size
12587       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12588  "shr{b}\t{%2, %0|%0, %2}"
12589  [(set_attr "type" "ishift")
12590   (set_attr "mode" "QI")])
12591
12592;; Rotate instructions
12593
12594(define_expand "rotldi3"
12595  [(set (match_operand:DI 0 "shiftdi_operand" "")
12596	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12597		   (match_operand:QI 2 "nonmemory_operand" "")))
12598   (clobber (reg:CC FLAGS_REG))]
12599 ""
12600{
12601  if (TARGET_64BIT)
12602    {
12603      ix86_expand_binary_operator (ROTATE, DImode, operands);
12604      DONE;
12605    }
12606  if (!const_1_to_31_operand (operands[2], VOIDmode))
12607    FAIL;
12608  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12609  DONE;
12610})
12611
12612;; Implement rotation using two double-precision shift instructions
12613;; and a scratch register.   
12614(define_insn_and_split "ix86_rotldi3"
12615 [(set (match_operand:DI 0 "register_operand" "=r")
12616       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12617                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12618  (clobber (reg:CC FLAGS_REG))
12619  (clobber (match_scratch:SI 3 "=&r"))]
12620 "!TARGET_64BIT"
12621 "" 
12622 "&& reload_completed"
12623 [(set (match_dup 3) (match_dup 4))
12624  (parallel
12625   [(set (match_dup 4)
12626         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12627                 (lshiftrt:SI (match_dup 5)
12628                              (minus:QI (const_int 32) (match_dup 2)))))
12629    (clobber (reg:CC FLAGS_REG))])
12630  (parallel
12631   [(set (match_dup 5)
12632         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12633                 (lshiftrt:SI (match_dup 3)
12634                              (minus:QI (const_int 32) (match_dup 2)))))
12635    (clobber (reg:CC FLAGS_REG))])]
12636 "split_di (operands, 1, operands + 4, operands + 5);")
12637 
12638(define_insn "*rotlsi3_1_one_bit_rex64"
12639  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12640	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12641		   (match_operand:QI 2 "const1_operand" "")))
12642   (clobber (reg:CC FLAGS_REG))]
12643  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12644   && (TARGET_SHIFT1 || optimize_size)"
12645  "rol{q}\t%0"
12646  [(set_attr "type" "rotate")
12647   (set (attr "length") 
12648     (if_then_else (match_operand:DI 0 "register_operand" "") 
12649	(const_string "2")
12650	(const_string "*")))])
12651
12652(define_insn "*rotldi3_1_rex64"
12653  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12654	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12655		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12656   (clobber (reg:CC FLAGS_REG))]
12657  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12658  "@
12659   rol{q}\t{%2, %0|%0, %2}
12660   rol{q}\t{%b2, %0|%0, %b2}"
12661  [(set_attr "type" "rotate")
12662   (set_attr "mode" "DI")])
12663
12664(define_expand "rotlsi3"
12665  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12666	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12667		   (match_operand:QI 2 "nonmemory_operand" "")))
12668   (clobber (reg:CC FLAGS_REG))]
12669  ""
12670  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12671
12672(define_insn "*rotlsi3_1_one_bit"
12673  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12674	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12675		   (match_operand:QI 2 "const1_operand" "")))
12676   (clobber (reg:CC FLAGS_REG))]
12677  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12678   && (TARGET_SHIFT1 || optimize_size)"
12679  "rol{l}\t%0"
12680  [(set_attr "type" "rotate")
12681   (set (attr "length") 
12682     (if_then_else (match_operand:SI 0 "register_operand" "") 
12683	(const_string "2")
12684	(const_string "*")))])
12685
12686(define_insn "*rotlsi3_1_one_bit_zext"
12687  [(set (match_operand:DI 0 "register_operand" "=r")
12688	(zero_extend:DI
12689	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12690		     (match_operand:QI 2 "const1_operand" ""))))
12691   (clobber (reg:CC FLAGS_REG))]
12692  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12693   && (TARGET_SHIFT1 || optimize_size)"
12694  "rol{l}\t%k0"
12695  [(set_attr "type" "rotate")
12696   (set_attr "length" "2")])
12697
12698(define_insn "*rotlsi3_1"
12699  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12700	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12701		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12702   (clobber (reg:CC FLAGS_REG))]
12703  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12704  "@
12705   rol{l}\t{%2, %0|%0, %2}
12706   rol{l}\t{%b2, %0|%0, %b2}"
12707  [(set_attr "type" "rotate")
12708   (set_attr "mode" "SI")])
12709
12710(define_insn "*rotlsi3_1_zext"
12711  [(set (match_operand:DI 0 "register_operand" "=r,r")
12712	(zero_extend:DI
12713	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12714		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12715   (clobber (reg:CC FLAGS_REG))]
12716  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12717  "@
12718   rol{l}\t{%2, %k0|%k0, %2}
12719   rol{l}\t{%b2, %k0|%k0, %b2}"
12720  [(set_attr "type" "rotate")
12721   (set_attr "mode" "SI")])
12722
12723(define_expand "rotlhi3"
12724  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12725	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12726		   (match_operand:QI 2 "nonmemory_operand" "")))
12727   (clobber (reg:CC FLAGS_REG))]
12728  "TARGET_HIMODE_MATH"
12729  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12730
12731(define_insn "*rotlhi3_1_one_bit"
12732  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12733	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12734		   (match_operand:QI 2 "const1_operand" "")))
12735   (clobber (reg:CC FLAGS_REG))]
12736  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12737   && (TARGET_SHIFT1 || optimize_size)"
12738  "rol{w}\t%0"
12739  [(set_attr "type" "rotate")
12740   (set (attr "length") 
12741     (if_then_else (match_operand 0 "register_operand" "") 
12742	(const_string "2")
12743	(const_string "*")))])
12744
12745(define_insn "*rotlhi3_1"
12746  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12747	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12748		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12749   (clobber (reg:CC FLAGS_REG))]
12750  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12751  "@
12752   rol{w}\t{%2, %0|%0, %2}
12753   rol{w}\t{%b2, %0|%0, %b2}"
12754  [(set_attr "type" "rotate")
12755   (set_attr "mode" "HI")])
12756
12757(define_expand "rotlqi3"
12758  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12759	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12760		   (match_operand:QI 2 "nonmemory_operand" "")))
12761   (clobber (reg:CC FLAGS_REG))]
12762  "TARGET_QIMODE_MATH"
12763  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12764
12765(define_insn "*rotlqi3_1_one_bit_slp"
12766  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12767	(rotate:QI (match_dup 0)
12768		   (match_operand:QI 1 "const1_operand" "")))
12769   (clobber (reg:CC FLAGS_REG))]
12770  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12771   && (TARGET_SHIFT1 || optimize_size)"
12772  "rol{b}\t%0"
12773  [(set_attr "type" "rotate1")
12774   (set (attr "length") 
12775     (if_then_else (match_operand 0 "register_operand" "") 
12776	(const_string "2")
12777	(const_string "*")))])
12778
12779(define_insn "*rotlqi3_1_one_bit"
12780  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12781	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12782		   (match_operand:QI 2 "const1_operand" "")))
12783   (clobber (reg:CC FLAGS_REG))]
12784  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12785   && (TARGET_SHIFT1 || optimize_size)"
12786  "rol{b}\t%0"
12787  [(set_attr "type" "rotate")
12788   (set (attr "length") 
12789     (if_then_else (match_operand 0 "register_operand" "") 
12790	(const_string "2")
12791	(const_string "*")))])
12792
12793(define_insn "*rotlqi3_1_slp"
12794  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12795	(rotate:QI (match_dup 0)
12796		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12797   (clobber (reg:CC FLAGS_REG))]
12798  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12799   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12800  "@
12801   rol{b}\t{%1, %0|%0, %1}
12802   rol{b}\t{%b1, %0|%0, %b1}"
12803  [(set_attr "type" "rotate1")
12804   (set_attr "mode" "QI")])
12805
12806(define_insn "*rotlqi3_1"
12807  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12808	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12809		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12810   (clobber (reg:CC FLAGS_REG))]
12811  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12812  "@
12813   rol{b}\t{%2, %0|%0, %2}
12814   rol{b}\t{%b2, %0|%0, %b2}"
12815  [(set_attr "type" "rotate")
12816   (set_attr "mode" "QI")])
12817
12818(define_expand "rotrdi3"
12819  [(set (match_operand:DI 0 "shiftdi_operand" "")
12820	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12821		   (match_operand:QI 2 "nonmemory_operand" "")))
12822   (clobber (reg:CC FLAGS_REG))]
12823 ""
12824{
12825  if (TARGET_64BIT)
12826    {
12827      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12828      DONE;
12829    }
12830  if (!const_1_to_31_operand (operands[2], VOIDmode))
12831    FAIL;
12832  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12833  DONE;
12834})
12835  
12836;; Implement rotation using two double-precision shift instructions
12837;; and a scratch register.   
12838(define_insn_and_split "ix86_rotrdi3"
12839 [(set (match_operand:DI 0 "register_operand" "=r")
12840       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12841                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12842  (clobber (reg:CC FLAGS_REG))
12843  (clobber (match_scratch:SI 3 "=&r"))]
12844 "!TARGET_64BIT"
12845 ""
12846 "&& reload_completed"
12847 [(set (match_dup 3) (match_dup 4))
12848  (parallel
12849   [(set (match_dup 4)
12850         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12851                 (ashift:SI (match_dup 5)
12852                            (minus:QI (const_int 32) (match_dup 2)))))
12853    (clobber (reg:CC FLAGS_REG))])
12854  (parallel
12855   [(set (match_dup 5)
12856         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12857                 (ashift:SI (match_dup 3)
12858                            (minus:QI (const_int 32) (match_dup 2)))))
12859    (clobber (reg:CC FLAGS_REG))])]
12860 "split_di (operands, 1, operands + 4, operands + 5);")
12861
12862(define_insn "*rotrdi3_1_one_bit_rex64"
12863  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12864	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12865		     (match_operand:QI 2 "const1_operand" "")))
12866   (clobber (reg:CC FLAGS_REG))]
12867  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12868   && (TARGET_SHIFT1 || optimize_size)"
12869  "ror{q}\t%0"
12870  [(set_attr "type" "rotate")
12871   (set (attr "length") 
12872     (if_then_else (match_operand:DI 0 "register_operand" "") 
12873	(const_string "2")
12874	(const_string "*")))])
12875
12876(define_insn "*rotrdi3_1_rex64"
12877  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12878	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12879		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12880   (clobber (reg:CC FLAGS_REG))]
12881  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12882  "@
12883   ror{q}\t{%2, %0|%0, %2}
12884   ror{q}\t{%b2, %0|%0, %b2}"
12885  [(set_attr "type" "rotate")
12886   (set_attr "mode" "DI")])
12887
12888(define_expand "rotrsi3"
12889  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12890	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12891		     (match_operand:QI 2 "nonmemory_operand" "")))
12892   (clobber (reg:CC FLAGS_REG))]
12893  ""
12894  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12895
12896(define_insn "*rotrsi3_1_one_bit"
12897  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12898	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12899		     (match_operand:QI 2 "const1_operand" "")))
12900   (clobber (reg:CC FLAGS_REG))]
12901  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12902   && (TARGET_SHIFT1 || optimize_size)"
12903  "ror{l}\t%0"
12904  [(set_attr "type" "rotate")
12905   (set (attr "length") 
12906     (if_then_else (match_operand:SI 0 "register_operand" "") 
12907	(const_string "2")
12908	(const_string "*")))])
12909
12910(define_insn "*rotrsi3_1_one_bit_zext"
12911  [(set (match_operand:DI 0 "register_operand" "=r")
12912	(zero_extend:DI
12913	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12914		       (match_operand:QI 2 "const1_operand" ""))))
12915   (clobber (reg:CC FLAGS_REG))]
12916  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12917   && (TARGET_SHIFT1 || optimize_size)"
12918  "ror{l}\t%k0"
12919  [(set_attr "type" "rotate")
12920   (set (attr "length") 
12921     (if_then_else (match_operand:SI 0 "register_operand" "") 
12922	(const_string "2")
12923	(const_string "*")))])
12924
12925(define_insn "*rotrsi3_1"
12926  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12927	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12928		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12929   (clobber (reg:CC FLAGS_REG))]
12930  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12931  "@
12932   ror{l}\t{%2, %0|%0, %2}
12933   ror{l}\t{%b2, %0|%0, %b2}"
12934  [(set_attr "type" "rotate")
12935   (set_attr "mode" "SI")])
12936
12937(define_insn "*rotrsi3_1_zext"
12938  [(set (match_operand:DI 0 "register_operand" "=r,r")
12939	(zero_extend:DI
12940	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12941		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12942   (clobber (reg:CC FLAGS_REG))]
12943  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12944  "@
12945   ror{l}\t{%2, %k0|%k0, %2}
12946   ror{l}\t{%b2, %k0|%k0, %b2}"
12947  [(set_attr "type" "rotate")
12948   (set_attr "mode" "SI")])
12949
12950(define_expand "rotrhi3"
12951  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12952	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12953		     (match_operand:QI 2 "nonmemory_operand" "")))
12954   (clobber (reg:CC FLAGS_REG))]
12955  "TARGET_HIMODE_MATH"
12956  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12957
12958(define_insn "*rotrhi3_one_bit"
12959  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12960	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12961		     (match_operand:QI 2 "const1_operand" "")))
12962   (clobber (reg:CC FLAGS_REG))]
12963  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12964   && (TARGET_SHIFT1 || optimize_size)"
12965  "ror{w}\t%0"
12966  [(set_attr "type" "rotate")
12967   (set (attr "length") 
12968     (if_then_else (match_operand 0 "register_operand" "") 
12969	(const_string "2")
12970	(const_string "*")))])
12971
12972(define_insn "*rotrhi3"
12973  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12974	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12975		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12976   (clobber (reg:CC FLAGS_REG))]
12977  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12978  "@
12979   ror{w}\t{%2, %0|%0, %2}
12980   ror{w}\t{%b2, %0|%0, %b2}"
12981  [(set_attr "type" "rotate")
12982   (set_attr "mode" "HI")])
12983
12984(define_expand "rotrqi3"
12985  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12986	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12987		     (match_operand:QI 2 "nonmemory_operand" "")))
12988   (clobber (reg:CC FLAGS_REG))]
12989  "TARGET_QIMODE_MATH"
12990  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12991
12992(define_insn "*rotrqi3_1_one_bit"
12993  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12994	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12995		     (match_operand:QI 2 "const1_operand" "")))
12996   (clobber (reg:CC FLAGS_REG))]
12997  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12998   && (TARGET_SHIFT1 || optimize_size)"
12999  "ror{b}\t%0"
13000  [(set_attr "type" "rotate")
13001   (set (attr "length") 
13002     (if_then_else (match_operand 0 "register_operand" "") 
13003	(const_string "2")
13004	(const_string "*")))])
13005
13006(define_insn "*rotrqi3_1_one_bit_slp"
13007  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13008	(rotatert:QI (match_dup 0)
13009		     (match_operand:QI 1 "const1_operand" "")))
13010   (clobber (reg:CC FLAGS_REG))]
13011  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13012   && (TARGET_SHIFT1 || optimize_size)"
13013  "ror{b}\t%0"
13014  [(set_attr "type" "rotate1")
13015   (set (attr "length") 
13016     (if_then_else (match_operand 0 "register_operand" "") 
13017	(const_string "2")
13018	(const_string "*")))])
13019
13020(define_insn "*rotrqi3_1"
13021  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13022	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13023		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024   (clobber (reg:CC FLAGS_REG))]
13025  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13026  "@
13027   ror{b}\t{%2, %0|%0, %2}
13028   ror{b}\t{%b2, %0|%0, %b2}"
13029  [(set_attr "type" "rotate")
13030   (set_attr "mode" "QI")])
13031
13032(define_insn "*rotrqi3_1_slp"
13033  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13034	(rotatert:QI (match_dup 0)
13035		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
13036   (clobber (reg:CC FLAGS_REG))]
13037  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13038   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13039  "@
13040   ror{b}\t{%1, %0|%0, %1}
13041   ror{b}\t{%b1, %0|%0, %b1}"
13042  [(set_attr "type" "rotate1")
13043   (set_attr "mode" "QI")])
13044
13045;; Bit set / bit test instructions
13046
13047(define_expand "extv"
13048  [(set (match_operand:SI 0 "register_operand" "")
13049	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
13050			 (match_operand:SI 2 "const8_operand" "")
13051			 (match_operand:SI 3 "const8_operand" "")))]
13052  ""
13053{
13054  /* Handle extractions from %ah et al.  */
13055  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13056    FAIL;
13057
13058  /* From mips.md: extract_bit_field doesn't verify that our source
13059     matches the predicate, so check it again here.  */
13060  if (! ext_register_operand (operands[1], VOIDmode))
13061    FAIL;
13062})
13063
13064(define_expand "extzv"
13065  [(set (match_operand:SI 0 "register_operand" "")
13066	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
13067			 (match_operand:SI 2 "const8_operand" "")
13068			 (match_operand:SI 3 "const8_operand" "")))]
13069  ""
13070{
13071  /* Handle extractions from %ah et al.  */
13072  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13073    FAIL;
13074
13075  /* From mips.md: extract_bit_field doesn't verify that our source
13076     matches the predicate, so check it again here.  */
13077  if (! ext_register_operand (operands[1], VOIDmode))
13078    FAIL;
13079})
13080
13081(define_expand "insv"
13082  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13083		      (match_operand 1 "const8_operand" "")
13084		      (match_operand 2 "const8_operand" ""))
13085        (match_operand 3 "register_operand" ""))]
13086  ""
13087{
13088  /* Handle insertions to %ah et al.  */
13089  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13090    FAIL;
13091
13092  /* From mips.md: insert_bit_field doesn't verify that our source
13093     matches the predicate, so check it again here.  */
13094  if (! ext_register_operand (operands[0], VOIDmode))
13095    FAIL;
13096
13097  if (TARGET_64BIT)
13098    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13099  else
13100    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13101
13102  DONE;
13103})
13104
13105;; %%% bts, btr, btc, bt.
13106;; In general these instructions are *slow* when applied to memory,
13107;; since they enforce atomic operation.  When applied to registers,
13108;; it depends on the cpu implementation.  They're never faster than
13109;; the corresponding and/ior/xor operations, so with 32-bit there's
13110;; no point.  But in 64-bit, we can't hold the relevant immediates
13111;; within the instruction itself, so operating on bits in the high
13112;; 32-bits of a register becomes easier.
13113;;
13114;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13115;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13116;; negdf respectively, so they can never be disabled entirely.
13117
13118(define_insn "*btsq"
13119  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13120			 (const_int 1)
13121			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13122	(const_int 1))
13123   (clobber (reg:CC FLAGS_REG))]
13124  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13125  "bts{q} %1,%0"
13126  [(set_attr "type" "alu1")])
13127
13128(define_insn "*btrq"
13129  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13130			 (const_int 1)
13131			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13132	(const_int 0))
13133   (clobber (reg:CC FLAGS_REG))]
13134  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13135  "btr{q} %1,%0"
13136  [(set_attr "type" "alu1")])
13137
13138(define_insn "*btcq"
13139  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13140			 (const_int 1)
13141			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13142	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13143   (clobber (reg:CC FLAGS_REG))]
13144  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13145  "btc{q} %1,%0"
13146  [(set_attr "type" "alu1")])
13147
13148;; Allow Nocona to avoid these instructions if a register is available.
13149
13150(define_peephole2
13151  [(match_scratch:DI 2 "r")
13152   (parallel [(set (zero_extract:DI
13153		     (match_operand:DI 0 "register_operand" "")
13154		     (const_int 1)
13155		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13156		   (const_int 1))
13157	      (clobber (reg:CC FLAGS_REG))])]
13158  "TARGET_64BIT && !TARGET_USE_BT"
13159  [(const_int 0)]
13160{
13161  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13162  rtx op1;
13163
13164  if (HOST_BITS_PER_WIDE_INT >= 64)
13165    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166  else if (i < HOST_BITS_PER_WIDE_INT)
13167    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13168  else
13169    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13170
13171  op1 = immed_double_const (lo, hi, DImode);
13172  if (i >= 31)
13173    {
13174      emit_move_insn (operands[2], op1);
13175      op1 = operands[2];
13176    }
13177
13178  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13179  DONE;
13180})
13181
13182(define_peephole2
13183  [(match_scratch:DI 2 "r")
13184   (parallel [(set (zero_extract:DI
13185		     (match_operand:DI 0 "register_operand" "")
13186		     (const_int 1)
13187		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13188		   (const_int 0))
13189	      (clobber (reg:CC FLAGS_REG))])]
13190  "TARGET_64BIT && !TARGET_USE_BT"
13191  [(const_int 0)]
13192{
13193  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13194  rtx op1;
13195
13196  if (HOST_BITS_PER_WIDE_INT >= 64)
13197    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13198  else if (i < HOST_BITS_PER_WIDE_INT)
13199    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13200  else
13201    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13202
13203  op1 = immed_double_const (~lo, ~hi, DImode);
13204  if (i >= 32)
13205    {
13206      emit_move_insn (operands[2], op1);
13207      op1 = operands[2];
13208    }
13209
13210  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13211  DONE;
13212})
13213
13214(define_peephole2
13215  [(match_scratch:DI 2 "r")
13216   (parallel [(set (zero_extract:DI
13217		     (match_operand:DI 0 "register_operand" "")
13218		     (const_int 1)
13219		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13220	      (not:DI (zero_extract:DI
13221			(match_dup 0) (const_int 1) (match_dup 1))))
13222	      (clobber (reg:CC FLAGS_REG))])]
13223  "TARGET_64BIT && !TARGET_USE_BT"
13224  [(const_int 0)]
13225{
13226  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13227  rtx op1;
13228
13229  if (HOST_BITS_PER_WIDE_INT >= 64)
13230    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13231  else if (i < HOST_BITS_PER_WIDE_INT)
13232    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13233  else
13234    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13235
13236  op1 = immed_double_const (lo, hi, DImode);
13237  if (i >= 31)
13238    {
13239      emit_move_insn (operands[2], op1);
13240      op1 = operands[2];
13241    }
13242
13243  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13244  DONE;
13245})
13246
13247;; Store-flag instructions.
13248
13249;; For all sCOND expanders, also expand the compare or test insn that
13250;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13251
13252;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13253;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13254;; way, which can later delete the movzx if only QImode is needed.
13255
13256(define_expand "seq"
13257  [(set (match_operand:QI 0 "register_operand" "")
13258        (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13259  ""
13260  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13261
13262(define_expand "sne"
13263  [(set (match_operand:QI 0 "register_operand" "")
13264        (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13265  ""
13266  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13267
13268(define_expand "sgt"
13269  [(set (match_operand:QI 0 "register_operand" "")
13270        (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13271  ""
13272  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13273
13274(define_expand "sgtu"
13275  [(set (match_operand:QI 0 "register_operand" "")
13276        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13277  ""
13278  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13279
13280(define_expand "slt"
13281  [(set (match_operand:QI 0 "register_operand" "")
13282        (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13283  ""
13284  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13285
13286(define_expand "sltu"
13287  [(set (match_operand:QI 0 "register_operand" "")
13288        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13289  ""
13290  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13291
13292(define_expand "sge"
13293  [(set (match_operand:QI 0 "register_operand" "")
13294        (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13295  ""
13296  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13297
13298(define_expand "sgeu"
13299  [(set (match_operand:QI 0 "register_operand" "")
13300        (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13301  ""
13302  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13303
13304(define_expand "sle"
13305  [(set (match_operand:QI 0 "register_operand" "")
13306        (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13307  ""
13308  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13309
13310(define_expand "sleu"
13311  [(set (match_operand:QI 0 "register_operand" "")
13312        (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13313  ""
13314  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13315
13316(define_expand "sunordered"
13317  [(set (match_operand:QI 0 "register_operand" "")
13318        (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13319  "TARGET_80387 || TARGET_SSE"
13320  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13321
13322(define_expand "sordered"
13323  [(set (match_operand:QI 0 "register_operand" "")
13324        (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13325  "TARGET_80387"
13326  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13327
13328(define_expand "suneq"
13329  [(set (match_operand:QI 0 "register_operand" "")
13330        (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13331  "TARGET_80387 || TARGET_SSE"
13332  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13333
13334(define_expand "sunge"
13335  [(set (match_operand:QI 0 "register_operand" "")
13336        (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13337  "TARGET_80387 || TARGET_SSE"
13338  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13339
13340(define_expand "sungt"
13341  [(set (match_operand:QI 0 "register_operand" "")
13342        (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13343  "TARGET_80387 || TARGET_SSE"
13344  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13345
13346(define_expand "sunle"
13347  [(set (match_operand:QI 0 "register_operand" "")
13348        (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13349  "TARGET_80387 || TARGET_SSE"
13350  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13351
13352(define_expand "sunlt"
13353  [(set (match_operand:QI 0 "register_operand" "")
13354        (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13355  "TARGET_80387 || TARGET_SSE"
13356  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13357
13358(define_expand "sltgt"
13359  [(set (match_operand:QI 0 "register_operand" "")
13360        (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13361  "TARGET_80387 || TARGET_SSE"
13362  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13363
13364(define_insn "*setcc_1"
13365  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13366	(match_operator:QI 1 "ix86_comparison_operator"
13367	  [(reg FLAGS_REG) (const_int 0)]))]
13368  ""
13369  "set%C1\t%0"
13370  [(set_attr "type" "setcc")
13371   (set_attr "mode" "QI")])
13372
13373(define_insn "*setcc_2"
13374  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13375	(match_operator:QI 1 "ix86_comparison_operator"
13376	  [(reg FLAGS_REG) (const_int 0)]))]
13377  ""
13378  "set%C1\t%0"
13379  [(set_attr "type" "setcc")
13380   (set_attr "mode" "QI")])
13381
13382;; In general it is not safe to assume too much about CCmode registers,
13383;; so simplify-rtx stops when it sees a second one.  Under certain 
13384;; conditions this is safe on x86, so help combine not create
13385;;
13386;;	seta	%al
13387;;	testb	%al, %al
13388;;	sete	%al
13389
13390(define_split 
13391  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13392	(ne:QI (match_operator 1 "ix86_comparison_operator"
13393	         [(reg FLAGS_REG) (const_int 0)])
13394	    (const_int 0)))]
13395  ""
13396  [(set (match_dup 0) (match_dup 1))]
13397{
13398  PUT_MODE (operands[1], QImode);
13399})
13400
13401(define_split 
13402  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13403	(ne:QI (match_operator 1 "ix86_comparison_operator"
13404	         [(reg FLAGS_REG) (const_int 0)])
13405	    (const_int 0)))]
13406  ""
13407  [(set (match_dup 0) (match_dup 1))]
13408{
13409  PUT_MODE (operands[1], QImode);
13410})
13411
13412(define_split 
13413  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13414	(eq:QI (match_operator 1 "ix86_comparison_operator"
13415	         [(reg FLAGS_REG) (const_int 0)])
13416	    (const_int 0)))]
13417  ""
13418  [(set (match_dup 0) (match_dup 1))]
13419{
13420  rtx new_op1 = copy_rtx (operands[1]);
13421  operands[1] = new_op1;
13422  PUT_MODE (new_op1, QImode);
13423  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13424					     GET_MODE (XEXP (new_op1, 0))));
13425
13426  /* Make sure that (a) the CCmode we have for the flags is strong
13427     enough for the reversed compare or (b) we have a valid FP compare.  */
13428  if (! ix86_comparison_operator (new_op1, VOIDmode))
13429    FAIL;
13430})
13431
13432(define_split 
13433  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13434	(eq:QI (match_operator 1 "ix86_comparison_operator"
13435	         [(reg FLAGS_REG) (const_int 0)])
13436	    (const_int 0)))]
13437  ""
13438  [(set (match_dup 0) (match_dup 1))]
13439{
13440  rtx new_op1 = copy_rtx (operands[1]);
13441  operands[1] = new_op1;
13442  PUT_MODE (new_op1, QImode);
13443  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13444					     GET_MODE (XEXP (new_op1, 0))));
13445
13446  /* Make sure that (a) the CCmode we have for the flags is strong
13447     enough for the reversed compare or (b) we have a valid FP compare.  */
13448  if (! ix86_comparison_operator (new_op1, VOIDmode))
13449    FAIL;
13450})
13451
13452;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13453;; subsequent logical operations are used to imitate conditional moves.
13454;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13455;; it directly.
13456
13457(define_insn "*sse_setccsf"
13458  [(set (match_operand:SF 0 "register_operand" "=x")
13459	(match_operator:SF 1 "sse_comparison_operator"
13460	  [(match_operand:SF 2 "register_operand" "0")
13461	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13462  "TARGET_SSE"
13463  "cmp%D1ss\t{%3, %0|%0, %3}"
13464  [(set_attr "type" "ssecmp")
13465   (set_attr "mode" "SF")])
13466
13467(define_insn "*sse_setccdf"
13468  [(set (match_operand:DF 0 "register_operand" "=Y")
13469	(match_operator:DF 1 "sse_comparison_operator"
13470	  [(match_operand:DF 2 "register_operand" "0")
13471	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13472  "TARGET_SSE2"
13473  "cmp%D1sd\t{%3, %0|%0, %3}"
13474  [(set_attr "type" "ssecmp")
13475   (set_attr "mode" "DF")])
13476
13477;; Basic conditional jump instructions.
13478;; We ignore the overflow flag for signed branch instructions.
13479
13480;; For all bCOND expanders, also expand the compare or test insn that
13481;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13482
13483(define_expand "beq"
13484  [(set (pc)
13485	(if_then_else (match_dup 1)
13486		      (label_ref (match_operand 0 "" ""))
13487		      (pc)))]
13488  ""
13489  "ix86_expand_branch (EQ, operands[0]); DONE;")
13490
13491(define_expand "bne"
13492  [(set (pc)
13493	(if_then_else (match_dup 1)
13494		      (label_ref (match_operand 0 "" ""))
13495		      (pc)))]
13496  ""
13497  "ix86_expand_branch (NE, operands[0]); DONE;")
13498
13499(define_expand "bgt"
13500  [(set (pc)
13501	(if_then_else (match_dup 1)
13502		      (label_ref (match_operand 0 "" ""))
13503		      (pc)))]
13504  ""
13505  "ix86_expand_branch (GT, operands[0]); DONE;")
13506
13507(define_expand "bgtu"
13508  [(set (pc)
13509	(if_then_else (match_dup 1)
13510		      (label_ref (match_operand 0 "" ""))
13511		      (pc)))]
13512  ""
13513  "ix86_expand_branch (GTU, operands[0]); DONE;")
13514
13515(define_expand "blt"
13516  [(set (pc)
13517	(if_then_else (match_dup 1)
13518		      (label_ref (match_operand 0 "" ""))
13519		      (pc)))]
13520  ""
13521  "ix86_expand_branch (LT, operands[0]); DONE;")
13522
13523(define_expand "bltu"
13524  [(set (pc)
13525	(if_then_else (match_dup 1)
13526		      (label_ref (match_operand 0 "" ""))
13527		      (pc)))]
13528  ""
13529  "ix86_expand_branch (LTU, operands[0]); DONE;")
13530
13531(define_expand "bge"
13532  [(set (pc)
13533	(if_then_else (match_dup 1)
13534		      (label_ref (match_operand 0 "" ""))
13535		      (pc)))]
13536  ""
13537  "ix86_expand_branch (GE, operands[0]); DONE;")
13538
13539(define_expand "bgeu"
13540  [(set (pc)
13541	(if_then_else (match_dup 1)
13542		      (label_ref (match_operand 0 "" ""))
13543		      (pc)))]
13544  ""
13545  "ix86_expand_branch (GEU, operands[0]); DONE;")
13546
13547(define_expand "ble"
13548  [(set (pc)
13549	(if_then_else (match_dup 1)
13550		      (label_ref (match_operand 0 "" ""))
13551		      (pc)))]
13552  ""
13553  "ix86_expand_branch (LE, operands[0]); DONE;")
13554
13555(define_expand "bleu"
13556  [(set (pc)
13557	(if_then_else (match_dup 1)
13558		      (label_ref (match_operand 0 "" ""))
13559		      (pc)))]
13560  ""
13561  "ix86_expand_branch (LEU, operands[0]); DONE;")
13562
13563(define_expand "bunordered"
13564  [(set (pc)
13565	(if_then_else (match_dup 1)
13566		      (label_ref (match_operand 0 "" ""))
13567		      (pc)))]
13568  "TARGET_80387 || TARGET_SSE_MATH"
13569  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13570
13571(define_expand "bordered"
13572  [(set (pc)
13573	(if_then_else (match_dup 1)
13574		      (label_ref (match_operand 0 "" ""))
13575		      (pc)))]
13576  "TARGET_80387 || TARGET_SSE_MATH"
13577  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13578
13579(define_expand "buneq"
13580  [(set (pc)
13581	(if_then_else (match_dup 1)
13582		      (label_ref (match_operand 0 "" ""))
13583		      (pc)))]
13584  "TARGET_80387 || TARGET_SSE_MATH"
13585  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13586
13587(define_expand "bunge"
13588  [(set (pc)
13589	(if_then_else (match_dup 1)
13590		      (label_ref (match_operand 0 "" ""))
13591		      (pc)))]
13592  "TARGET_80387 || TARGET_SSE_MATH"
13593  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13594
13595(define_expand "bungt"
13596  [(set (pc)
13597	(if_then_else (match_dup 1)
13598		      (label_ref (match_operand 0 "" ""))
13599		      (pc)))]
13600  "TARGET_80387 || TARGET_SSE_MATH"
13601  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13602
13603(define_expand "bunle"
13604  [(set (pc)
13605	(if_then_else (match_dup 1)
13606		      (label_ref (match_operand 0 "" ""))
13607		      (pc)))]
13608  "TARGET_80387 || TARGET_SSE_MATH"
13609  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13610
13611(define_expand "bunlt"
13612  [(set (pc)
13613	(if_then_else (match_dup 1)
13614		      (label_ref (match_operand 0 "" ""))
13615		      (pc)))]
13616  "TARGET_80387 || TARGET_SSE_MATH"
13617  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13618
13619(define_expand "bltgt"
13620  [(set (pc)
13621	(if_then_else (match_dup 1)
13622		      (label_ref (match_operand 0 "" ""))
13623		      (pc)))]
13624  "TARGET_80387 || TARGET_SSE_MATH"
13625  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13626
13627(define_insn "*jcc_1"
13628  [(set (pc)
13629	(if_then_else (match_operator 1 "ix86_comparison_operator"
13630				      [(reg FLAGS_REG) (const_int 0)])
13631		      (label_ref (match_operand 0 "" ""))
13632		      (pc)))]
13633  ""
13634  "%+j%C1\t%l0"
13635  [(set_attr "type" "ibr")
13636   (set_attr "modrm" "0")
13637   (set (attr "length")
13638	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13639				  (const_int -126))
13640			      (lt (minus (match_dup 0) (pc))
13641				  (const_int 128)))
13642	     (const_int 2)
13643	     (const_int 6)))])
13644
13645(define_insn "*jcc_2"
13646  [(set (pc)
13647	(if_then_else (match_operator 1 "ix86_comparison_operator"
13648				      [(reg FLAGS_REG) (const_int 0)])
13649		      (pc)
13650		      (label_ref (match_operand 0 "" ""))))]
13651  ""
13652  "%+j%c1\t%l0"
13653  [(set_attr "type" "ibr")
13654   (set_attr "modrm" "0")
13655   (set (attr "length")
13656	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13657				  (const_int -126))
13658			      (lt (minus (match_dup 0) (pc))
13659				  (const_int 128)))
13660	     (const_int 2)
13661	     (const_int 6)))])
13662
13663;; In general it is not safe to assume too much about CCmode registers,
13664;; so simplify-rtx stops when it sees a second one.  Under certain 
13665;; conditions this is safe on x86, so help combine not create
13666;;
13667;;	seta	%al
13668;;	testb	%al, %al
13669;;	je	Lfoo
13670
13671(define_split 
13672  [(set (pc)
13673	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13674				      [(reg FLAGS_REG) (const_int 0)])
13675			  (const_int 0))
13676		      (label_ref (match_operand 1 "" ""))
13677		      (pc)))]
13678  ""
13679  [(set (pc)
13680	(if_then_else (match_dup 0)
13681		      (label_ref (match_dup 1))
13682		      (pc)))]
13683{
13684  PUT_MODE (operands[0], VOIDmode);
13685})
13686  
13687(define_split 
13688  [(set (pc)
13689	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13690				      [(reg FLAGS_REG) (const_int 0)])
13691			  (const_int 0))
13692		      (label_ref (match_operand 1 "" ""))
13693		      (pc)))]
13694  ""
13695  [(set (pc)
13696	(if_then_else (match_dup 0)
13697		      (label_ref (match_dup 1))
13698		      (pc)))]
13699{
13700  rtx new_op0 = copy_rtx (operands[0]);
13701  operands[0] = new_op0;
13702  PUT_MODE (new_op0, VOIDmode);
13703  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13704					     GET_MODE (XEXP (new_op0, 0))));
13705
13706  /* Make sure that (a) the CCmode we have for the flags is strong
13707     enough for the reversed compare or (b) we have a valid FP compare.  */
13708  if (! ix86_comparison_operator (new_op0, VOIDmode))
13709    FAIL;
13710})
13711
13712;; Define combination compare-and-branch fp compare instructions to use
13713;; during early optimization.  Splitting the operation apart early makes
13714;; for bad code when we want to reverse the operation.
13715
13716(define_insn "*fp_jcc_1_mixed"
13717  [(set (pc)
13718	(if_then_else (match_operator 0 "comparison_operator"
13719			[(match_operand 1 "register_operand" "f,x")
13720			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13721	  (label_ref (match_operand 3 "" ""))
13722	  (pc)))
13723   (clobber (reg:CCFP FPSR_REG))
13724   (clobber (reg:CCFP FLAGS_REG))]
13725  "TARGET_MIX_SSE_I387
13726   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13727   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13728   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13729  "#")
13730
13731(define_insn "*fp_jcc_1_sse"
13732  [(set (pc)
13733	(if_then_else (match_operator 0 "comparison_operator"
13734			[(match_operand 1 "register_operand" "x")
13735			 (match_operand 2 "nonimmediate_operand" "xm")])
13736	  (label_ref (match_operand 3 "" ""))
13737	  (pc)))
13738   (clobber (reg:CCFP FPSR_REG))
13739   (clobber (reg:CCFP FLAGS_REG))]
13740  "TARGET_SSE_MATH
13741   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13742   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13743   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13744  "#")
13745
13746(define_insn "*fp_jcc_1_387"
13747  [(set (pc)
13748	(if_then_else (match_operator 0 "comparison_operator"
13749			[(match_operand 1 "register_operand" "f")
13750			 (match_operand 2 "register_operand" "f")])
13751	  (label_ref (match_operand 3 "" ""))
13752	  (pc)))
13753   (clobber (reg:CCFP FPSR_REG))
13754   (clobber (reg:CCFP FLAGS_REG))]
13755  "TARGET_CMOVE && TARGET_80387
13756   && FLOAT_MODE_P (GET_MODE (operands[1]))
13757   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13758   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13759  "#")
13760
13761(define_insn "*fp_jcc_2_mixed"
13762  [(set (pc)
13763	(if_then_else (match_operator 0 "comparison_operator"
13764			[(match_operand 1 "register_operand" "f,x")
13765			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13766	  (pc)
13767	  (label_ref (match_operand 3 "" ""))))
13768   (clobber (reg:CCFP FPSR_REG))
13769   (clobber (reg:CCFP FLAGS_REG))]
13770  "TARGET_MIX_SSE_I387
13771   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13772   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13773   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774  "#")
13775
13776(define_insn "*fp_jcc_2_sse"
13777  [(set (pc)
13778	(if_then_else (match_operator 0 "comparison_operator"
13779			[(match_operand 1 "register_operand" "x")
13780			 (match_operand 2 "nonimmediate_operand" "xm")])
13781	  (pc)
13782	  (label_ref (match_operand 3 "" ""))))
13783   (clobber (reg:CCFP FPSR_REG))
13784   (clobber (reg:CCFP FLAGS_REG))]
13785  "TARGET_SSE_MATH
13786   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13787   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13788   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13789  "#")
13790
13791(define_insn "*fp_jcc_2_387"
13792  [(set (pc)
13793	(if_then_else (match_operator 0 "comparison_operator"
13794			[(match_operand 1 "register_operand" "f")
13795			 (match_operand 2 "register_operand" "f")])
13796	  (pc)
13797	  (label_ref (match_operand 3 "" ""))))
13798   (clobber (reg:CCFP FPSR_REG))
13799   (clobber (reg:CCFP FLAGS_REG))]
13800  "TARGET_CMOVE && TARGET_80387
13801   && FLOAT_MODE_P (GET_MODE (operands[1]))
13802   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13803   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13804  "#")
13805
13806(define_insn "*fp_jcc_3_387"
13807  [(set (pc)
13808	(if_then_else (match_operator 0 "comparison_operator"
13809			[(match_operand 1 "register_operand" "f")
13810			 (match_operand 2 "nonimmediate_operand" "fm")])
13811	  (label_ref (match_operand 3 "" ""))
13812	  (pc)))
13813   (clobber (reg:CCFP FPSR_REG))
13814   (clobber (reg:CCFP FLAGS_REG))
13815   (clobber (match_scratch:HI 4 "=a"))]
13816  "TARGET_80387
13817   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13818   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13819   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13820   && SELECT_CC_MODE (GET_CODE (operands[0]),
13821		      operands[1], operands[2]) == CCFPmode
13822   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13823  "#")
13824
13825(define_insn "*fp_jcc_4_387"
13826  [(set (pc)
13827	(if_then_else (match_operator 0 "comparison_operator"
13828			[(match_operand 1 "register_operand" "f")
13829			 (match_operand 2 "nonimmediate_operand" "fm")])
13830	  (pc)
13831	  (label_ref (match_operand 3 "" ""))))
13832   (clobber (reg:CCFP FPSR_REG))
13833   (clobber (reg:CCFP FLAGS_REG))
13834   (clobber (match_scratch:HI 4 "=a"))]
13835  "TARGET_80387
13836   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13837   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13838   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13839   && SELECT_CC_MODE (GET_CODE (operands[0]),
13840		      operands[1], operands[2]) == CCFPmode
13841   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13842  "#")
13843
13844(define_insn "*fp_jcc_5_387"
13845  [(set (pc)
13846	(if_then_else (match_operator 0 "comparison_operator"
13847			[(match_operand 1 "register_operand" "f")
13848			 (match_operand 2 "register_operand" "f")])
13849	  (label_ref (match_operand 3 "" ""))
13850	  (pc)))
13851   (clobber (reg:CCFP FPSR_REG))
13852   (clobber (reg:CCFP FLAGS_REG))
13853   (clobber (match_scratch:HI 4 "=a"))]
13854  "TARGET_80387
13855   && FLOAT_MODE_P (GET_MODE (operands[1]))
13856   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13857   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13858  "#")
13859
13860(define_insn "*fp_jcc_6_387"
13861  [(set (pc)
13862	(if_then_else (match_operator 0 "comparison_operator"
13863			[(match_operand 1 "register_operand" "f")
13864			 (match_operand 2 "register_operand" "f")])
13865	  (pc)
13866	  (label_ref (match_operand 3 "" ""))))
13867   (clobber (reg:CCFP FPSR_REG))
13868   (clobber (reg:CCFP FLAGS_REG))
13869   (clobber (match_scratch:HI 4 "=a"))]
13870  "TARGET_80387
13871   && FLOAT_MODE_P (GET_MODE (operands[1]))
13872   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13873   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13874  "#")
13875
13876(define_insn "*fp_jcc_7_387"
13877  [(set (pc)
13878	(if_then_else (match_operator 0 "comparison_operator"
13879			[(match_operand 1 "register_operand" "f")
13880			 (match_operand 2 "const0_operand" "X")])
13881	  (label_ref (match_operand 3 "" ""))
13882	  (pc)))
13883   (clobber (reg:CCFP FPSR_REG))
13884   (clobber (reg:CCFP FLAGS_REG))
13885   (clobber (match_scratch:HI 4 "=a"))]
13886  "TARGET_80387
13887   && FLOAT_MODE_P (GET_MODE (operands[1]))
13888   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13889   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13890   && SELECT_CC_MODE (GET_CODE (operands[0]),
13891		      operands[1], operands[2]) == CCFPmode
13892   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13893  "#")
13894
13895;; The order of operands in *fp_jcc_8_387 is forced by combine in
13896;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13897;; with a precedence over other operators and is always put in the first
13898;; place. Swap condition and operands to match ficom instruction.
13899
13900(define_insn "*fp_jcc_8<mode>_387"
13901  [(set (pc)
13902	(if_then_else (match_operator 0 "comparison_operator"
13903			[(match_operator 1 "float_operator"
13904			   [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13905			   (match_operand 3 "register_operand" "f,f")])
13906	  (label_ref (match_operand 4 "" ""))
13907	  (pc)))
13908   (clobber (reg:CCFP FPSR_REG))
13909   (clobber (reg:CCFP FLAGS_REG))
13910   (clobber (match_scratch:HI 5 "=a,a"))]
13911  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13912   && FLOAT_MODE_P (GET_MODE (operands[3]))
13913   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13914   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13915   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13916   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13917  "#")
13918
13919(define_split
13920  [(set (pc)
13921	(if_then_else (match_operator 0 "comparison_operator"
13922			[(match_operand 1 "register_operand" "")
13923			 (match_operand 2 "nonimmediate_operand" "")])
13924	  (match_operand 3 "" "")
13925	  (match_operand 4 "" "")))
13926   (clobber (reg:CCFP FPSR_REG))
13927   (clobber (reg:CCFP FLAGS_REG))]
13928  "reload_completed"
13929  [(const_int 0)]
13930{
13931  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13932	                operands[3], operands[4], NULL_RTX, NULL_RTX);
13933  DONE;
13934})
13935
13936(define_split
13937  [(set (pc)
13938	(if_then_else (match_operator 0 "comparison_operator"
13939			[(match_operand 1 "register_operand" "")
13940			 (match_operand 2 "general_operand" "")])
13941	  (match_operand 3 "" "")
13942	  (match_operand 4 "" "")))
13943   (clobber (reg:CCFP FPSR_REG))
13944   (clobber (reg:CCFP FLAGS_REG))
13945   (clobber (match_scratch:HI 5 "=a"))]
13946  "reload_completed"
13947  [(const_int 0)]
13948{
13949  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13950	     		operands[3], operands[4], operands[5], NULL_RTX);
13951  DONE;
13952})
13953
13954(define_split
13955  [(set (pc)
13956	(if_then_else (match_operator 0 "comparison_operator"
13957			[(match_operator 1 "float_operator"
13958			   [(match_operand:X87MODEI12 2 "memory_operand" "")])
13959			   (match_operand 3 "register_operand" "")])
13960	  (match_operand 4 "" "")
13961	  (match_operand 5 "" "")))
13962   (clobber (reg:CCFP FPSR_REG))
13963   (clobber (reg:CCFP FLAGS_REG))
13964   (clobber (match_scratch:HI 6 "=a"))]
13965  "reload_completed"
13966  [(const_int 0)]
13967{
13968  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13969  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13970			operands[3], operands[7],
13971			operands[4], operands[5], operands[6], NULL_RTX);
13972  DONE;
13973})
13974
13975;; %%% Kill this when reload knows how to do it.
13976(define_split
13977  [(set (pc)
13978	(if_then_else (match_operator 0 "comparison_operator"
13979			[(match_operator 1 "float_operator"
13980			   [(match_operand:X87MODEI12 2 "register_operand" "")])
13981			   (match_operand 3 "register_operand" "")])
13982	  (match_operand 4 "" "")
13983	  (match_operand 5 "" "")))
13984   (clobber (reg:CCFP FPSR_REG))
13985   (clobber (reg:CCFP FLAGS_REG))
13986   (clobber (match_scratch:HI 6 "=a"))]
13987  "reload_completed"
13988  [(const_int 0)]
13989{
13990  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13991  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13992  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13993			operands[3], operands[7],
13994			operands[4], operands[5], operands[6], operands[2]);
13995  DONE;
13996})
13997
13998;; Unconditional and other jump instructions
13999
14000(define_insn "jump"
14001  [(set (pc)
14002	(label_ref (match_operand 0 "" "")))]
14003  ""
14004  "jmp\t%l0"
14005  [(set_attr "type" "ibr")
14006   (set (attr "length")
14007	   (if_then_else (and (ge (minus (match_dup 0) (pc))
14008				  (const_int -126))
14009			      (lt (minus (match_dup 0) (pc))
14010				  (const_int 128)))
14011	     (const_int 2)
14012	     (const_int 5)))
14013   (set_attr "modrm" "0")])
14014
14015(define_expand "indirect_jump"
14016  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14017  ""
14018  "")
14019
14020(define_insn "*indirect_jump"
14021  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14022  "!TARGET_64BIT"
14023  "jmp\t%A0"
14024  [(set_attr "type" "ibr")
14025   (set_attr "length_immediate" "0")])
14026
14027(define_insn "*indirect_jump_rtx64"
14028  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14029  "TARGET_64BIT"
14030  "jmp\t%A0"
14031  [(set_attr "type" "ibr")
14032   (set_attr "length_immediate" "0")])
14033
14034(define_expand "tablejump"
14035  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14036	      (use (label_ref (match_operand 1 "" "")))])]
14037  ""
14038{
14039  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14040     relative.  Convert the relative address to an absolute address.  */
14041  if (flag_pic)
14042    {
14043      rtx op0, op1;
14044      enum rtx_code code;
14045
14046      if (TARGET_64BIT)
14047	{
14048	  code = PLUS;
14049	  op0 = operands[0];
14050	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14051	}
14052      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14053	{
14054	  code = PLUS;
14055	  op0 = operands[0];
14056	  op1 = pic_offset_table_rtx;
14057	}
14058      else
14059	{
14060	  code = MINUS;
14061	  op0 = pic_offset_table_rtx;
14062	  op1 = operands[0];
14063	}
14064
14065      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14066					 OPTAB_DIRECT);
14067    }
14068})
14069
14070(define_insn "*tablejump_1"
14071  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14072   (use (label_ref (match_operand 1 "" "")))]
14073  "!TARGET_64BIT"
14074  "jmp\t%A0"
14075  [(set_attr "type" "ibr")
14076   (set_attr "length_immediate" "0")])
14077
14078(define_insn "*tablejump_1_rtx64"
14079  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14080   (use (label_ref (match_operand 1 "" "")))]
14081  "TARGET_64BIT"
14082  "jmp\t%A0"
14083  [(set_attr "type" "ibr")
14084   (set_attr "length_immediate" "0")])
14085
14086;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14087
14088(define_peephole2
14089  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14090   (set (match_operand:QI 1 "register_operand" "")
14091	(match_operator:QI 2 "ix86_comparison_operator"
14092	  [(reg FLAGS_REG) (const_int 0)]))
14093   (set (match_operand 3 "q_regs_operand" "")
14094	(zero_extend (match_dup 1)))]
14095  "(peep2_reg_dead_p (3, operands[1])
14096    || operands_match_p (operands[1], operands[3]))
14097   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14098  [(set (match_dup 4) (match_dup 0))
14099   (set (strict_low_part (match_dup 5))
14100	(match_dup 2))]
14101{
14102  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14103  operands[5] = gen_lowpart (QImode, operands[3]);
14104  ix86_expand_clear (operands[3]);
14105})
14106
14107;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14108
14109(define_peephole2
14110  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14111   (set (match_operand:QI 1 "register_operand" "")
14112	(match_operator:QI 2 "ix86_comparison_operator"
14113	  [(reg FLAGS_REG) (const_int 0)]))
14114   (parallel [(set (match_operand 3 "q_regs_operand" "")
14115		   (zero_extend (match_dup 1)))
14116	      (clobber (reg:CC FLAGS_REG))])]
14117  "(peep2_reg_dead_p (3, operands[1])
14118    || operands_match_p (operands[1], operands[3]))
14119   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14120  [(set (match_dup 4) (match_dup 0))
14121   (set (strict_low_part (match_dup 5))
14122	(match_dup 2))]
14123{
14124  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14125  operands[5] = gen_lowpart (QImode, operands[3]);
14126  ix86_expand_clear (operands[3]);
14127})
14128
14129;; Call instructions.
14130
14131;; The predicates normally associated with named expanders are not properly
14132;; checked for calls.  This is a bug in the generic code, but it isn't that
14133;; easy to fix.  Ignore it for now and be prepared to fix things up.
14134
14135;; Call subroutine returning no value.
14136
14137(define_expand "call_pop"
14138  [(parallel [(call (match_operand:QI 0 "" "")
14139		    (match_operand:SI 1 "" ""))
14140	      (set (reg:SI SP_REG)
14141		   (plus:SI (reg:SI SP_REG)
14142			    (match_operand:SI 3 "" "")))])]
14143  "!TARGET_64BIT"
14144{
14145  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14146  DONE;
14147})
14148
14149(define_insn "*call_pop_0"
14150  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14151	 (match_operand:SI 1 "" ""))
14152   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14153			    (match_operand:SI 2 "immediate_operand" "")))]
14154  "!TARGET_64BIT"
14155{
14156  if (SIBLING_CALL_P (insn))
14157    return "jmp\t%P0";
14158  else
14159    return "call\t%P0";
14160}
14161  [(set_attr "type" "call")])
14162  
14163(define_insn "*call_pop_1"
14164  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14165	 (match_operand:SI 1 "" ""))
14166   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14167			    (match_operand:SI 2 "immediate_operand" "i")))]
14168  "!TARGET_64BIT"
14169{
14170  if (constant_call_address_operand (operands[0], Pmode))
14171    {
14172      if (SIBLING_CALL_P (insn))
14173	return "jmp\t%P0";
14174      else
14175	return "call\t%P0";
14176    }
14177  if (SIBLING_CALL_P (insn))
14178    return "jmp\t%A0";
14179  else
14180    return "call\t%A0";
14181}
14182  [(set_attr "type" "call")])
14183
14184(define_expand "call"
14185  [(call (match_operand:QI 0 "" "")
14186	 (match_operand 1 "" ""))
14187   (use (match_operand 2 "" ""))]
14188  ""
14189{
14190  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14191  DONE;
14192})
14193
14194(define_expand "sibcall"
14195  [(call (match_operand:QI 0 "" "")
14196	 (match_operand 1 "" ""))
14197   (use (match_operand 2 "" ""))]
14198  ""
14199{
14200  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14201  DONE;
14202})
14203
14204(define_insn "*call_0"
14205  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14206	 (match_operand 1 "" ""))]
14207  ""
14208{
14209  if (SIBLING_CALL_P (insn))
14210    return "jmp\t%P0";
14211  else
14212    return "call\t%P0";
14213}
14214  [(set_attr "type" "call")])
14215
14216(define_insn "*call_1"
14217  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14218	 (match_operand 1 "" ""))]
14219  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14220{
14221  if (constant_call_address_operand (operands[0], Pmode))
14222    return "call\t%P0";
14223  return "call\t%A0";
14224}
14225  [(set_attr "type" "call")])
14226
14227(define_insn "*sibcall_1"
14228  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14229	 (match_operand 1 "" ""))]
14230  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14231{
14232  if (constant_call_address_operand (operands[0], Pmode))
14233    return "jmp\t%P0";
14234  return "jmp\t%A0";
14235}
14236  [(set_attr "type" "call")])
14237
14238(define_insn "*call_1_rex64"
14239  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14240	 (match_operand 1 "" ""))]
14241  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14242{
14243  if (constant_call_address_operand (operands[0], Pmode))
14244    return "call\t%P0";
14245  return "call\t%A0";
14246}
14247  [(set_attr "type" "call")])
14248
14249(define_insn "*sibcall_1_rex64"
14250  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14251	 (match_operand 1 "" ""))]
14252  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14253  "jmp\t%P0"
14254  [(set_attr "type" "call")])
14255
14256(define_insn "*sibcall_1_rex64_v"
14257  [(call (mem:QI (reg:DI R11_REG))
14258	 (match_operand 0 "" ""))]
14259  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14260  "jmp\t*%%r11"
14261  [(set_attr "type" "call")])
14262
14263
14264;; Call subroutine, returning value in operand 0
14265
14266(define_expand "call_value_pop"
14267  [(parallel [(set (match_operand 0 "" "")
14268		   (call (match_operand:QI 1 "" "")
14269			 (match_operand:SI 2 "" "")))
14270	      (set (reg:SI SP_REG)
14271		   (plus:SI (reg:SI SP_REG)
14272			    (match_operand:SI 4 "" "")))])]
14273  "!TARGET_64BIT"
14274{
14275  ix86_expand_call (operands[0], operands[1], operands[2],
14276		    operands[3], operands[4], 0);
14277  DONE;
14278})
14279
14280(define_expand "call_value"
14281  [(set (match_operand 0 "" "")
14282	(call (match_operand:QI 1 "" "")
14283	      (match_operand:SI 2 "" "")))
14284   (use (match_operand:SI 3 "" ""))]
14285  ;; Operand 2 not used on the i386.
14286  ""
14287{
14288  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14289  DONE;
14290})
14291
14292(define_expand "sibcall_value"
14293  [(set (match_operand 0 "" "")
14294	(call (match_operand:QI 1 "" "")
14295	      (match_operand:SI 2 "" "")))
14296   (use (match_operand:SI 3 "" ""))]
14297  ;; Operand 2 not used on the i386.
14298  ""
14299{
14300  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14301  DONE;
14302})
14303
14304;; Call subroutine returning any type.
14305
14306(define_expand "untyped_call"
14307  [(parallel [(call (match_operand 0 "" "")
14308		    (const_int 0))
14309	      (match_operand 1 "" "")
14310	      (match_operand 2 "" "")])]
14311  ""
14312{
14313  int i;
14314
14315  /* In order to give reg-stack an easier job in validating two
14316     coprocessor registers as containing a possible return value,
14317     simply pretend the untyped call returns a complex long double
14318     value.  */
14319
14320  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14321		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14322		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14323		    NULL, 0);
14324
14325  for (i = 0; i < XVECLEN (operands[2], 0); i++)
14326    {
14327      rtx set = XVECEXP (operands[2], 0, i);
14328      emit_move_insn (SET_DEST (set), SET_SRC (set));
14329    }
14330
14331  /* The optimizer does not know that the call sets the function value
14332     registers we stored in the result block.  We avoid problems by
14333     claiming that all hard registers are used and clobbered at this
14334     point.  */
14335  emit_insn (gen_blockage (const0_rtx));
14336
14337  DONE;
14338})
14339
14340;; Prologue and epilogue instructions
14341
14342;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14343;; all of memory.  This blocks insns from being moved across this point.
14344
14345(define_insn "blockage"
14346  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14347  ""
14348  ""
14349  [(set_attr "length" "0")])
14350
14351;; Insn emitted into the body of a function to return from a function.
14352;; This is only done if the function's epilogue is known to be simple.
14353;; See comments for ix86_can_use_return_insn_p in i386.c.
14354
14355(define_expand "return"
14356  [(return)]
14357  "ix86_can_use_return_insn_p ()"
14358{
14359  if (current_function_pops_args)
14360    {
14361      rtx popc = GEN_INT (current_function_pops_args);
14362      emit_jump_insn (gen_return_pop_internal (popc));
14363      DONE;
14364    }
14365})
14366
14367(define_insn "return_internal"
14368  [(return)]
14369  "reload_completed"
14370  "ret"
14371  [(set_attr "length" "1")
14372   (set_attr "length_immediate" "0")
14373   (set_attr "modrm" "0")])
14374
14375;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14376;; instruction Athlon and K8 have.
14377
14378(define_insn "return_internal_long"
14379  [(return)
14380   (unspec [(const_int 0)] UNSPEC_REP)]
14381  "reload_completed"
14382  "rep {;} ret"
14383  [(set_attr "length" "1")
14384   (set_attr "length_immediate" "0")
14385   (set_attr "prefix_rep" "1")
14386   (set_attr "modrm" "0")])
14387
14388(define_insn "return_pop_internal"
14389  [(return)
14390   (use (match_operand:SI 0 "const_int_operand" ""))]
14391  "reload_completed"
14392  "ret\t%0"
14393  [(set_attr "length" "3")
14394   (set_attr "length_immediate" "2")
14395   (set_attr "modrm" "0")])
14396
14397(define_insn "return_indirect_internal"
14398  [(return)
14399   (use (match_operand:SI 0 "register_operand" "r"))]
14400  "reload_completed"
14401  "jmp\t%A0"
14402  [(set_attr "type" "ibr")
14403   (set_attr "length_immediate" "0")])
14404
14405(define_insn "nop"
14406  [(const_int 0)]
14407  ""
14408  "nop"
14409  [(set_attr "length" "1")
14410   (set_attr "length_immediate" "0")
14411   (set_attr "modrm" "0")])
14412
14413;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14414;; branch prediction penalty for the third jump in a 16-byte
14415;; block on K8.
14416
14417(define_insn "align"
14418  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14419  ""
14420{
14421#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14422  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14423#else
14424  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14425     The align insn is used to avoid 3 jump instructions in the row to improve
14426     branch prediction and the benefits hardly outweigh the cost of extra 8
14427     nops on the average inserted by full alignment pseudo operation.  */
14428#endif
14429  return "";
14430}
14431  [(set_attr "length" "16")])
14432
14433(define_expand "prologue"
14434  [(const_int 1)]
14435  ""
14436  "ix86_expand_prologue (); DONE;")
14437
14438(define_insn "set_got"
14439  [(set (match_operand:SI 0 "register_operand" "=r")
14440	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14441   (clobber (reg:CC FLAGS_REG))]
14442  "!TARGET_64BIT"
14443  { return output_set_got (operands[0], NULL_RTX); }
14444  [(set_attr "type" "multi")
14445   (set_attr "length" "12")])
14446
14447(define_insn "set_got_labelled"
14448  [(set (match_operand:SI 0 "register_operand" "=r")
14449	(unspec:SI [(label_ref (match_operand 1 "" ""))]
14450	 UNSPEC_SET_GOT))
14451   (clobber (reg:CC FLAGS_REG))]
14452  "!TARGET_64BIT"
14453  { return output_set_got (operands[0], operands[1]); }
14454  [(set_attr "type" "multi")
14455   (set_attr "length" "12")])
14456
14457(define_insn "set_got_rex64"
14458  [(set (match_operand:DI 0 "register_operand" "=r")
14459	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14460  "TARGET_64BIT"
14461  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14462  [(set_attr "type" "lea")
14463   (set_attr "length" "6")])
14464
14465(define_expand "epilogue"
14466  [(const_int 1)]
14467  ""
14468  "ix86_expand_epilogue (1); DONE;")
14469
14470(define_expand "sibcall_epilogue"
14471  [(const_int 1)]
14472  ""
14473  "ix86_expand_epilogue (0); DONE;")
14474
14475(define_expand "eh_return"
14476  [(use (match_operand 0 "register_operand" ""))]
14477  ""
14478{
14479  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14480
14481  /* Tricky bit: we write the address of the handler to which we will
14482     be returning into someone else's stack frame, one word below the
14483     stack address we wish to restore.  */
14484  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14485  tmp = plus_constant (tmp, -UNITS_PER_WORD);
14486  tmp = gen_rtx_MEM (Pmode, tmp);
14487  emit_move_insn (tmp, ra);
14488
14489  if (Pmode == SImode)
14490    emit_jump_insn (gen_eh_return_si (sa));
14491  else
14492    emit_jump_insn (gen_eh_return_di (sa));
14493  emit_barrier ();
14494  DONE;
14495})
14496
14497(define_insn_and_split "eh_return_si"
14498  [(set (pc) 
14499        (unspec [(match_operand:SI 0 "register_operand" "c")]
14500	         UNSPEC_EH_RETURN))]
14501  "!TARGET_64BIT"
14502  "#"
14503  "reload_completed"
14504  [(const_int 1)]
14505  "ix86_expand_epilogue (2); DONE;")
14506
14507(define_insn_and_split "eh_return_di"
14508  [(set (pc) 
14509        (unspec [(match_operand:DI 0 "register_operand" "c")]
14510	         UNSPEC_EH_RETURN))]
14511  "TARGET_64BIT"
14512  "#"
14513  "reload_completed"
14514  [(const_int 1)]
14515  "ix86_expand_epilogue (2); DONE;")
14516
14517(define_insn "leave"
14518  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14519   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14520   (clobber (mem:BLK (scratch)))]
14521  "!TARGET_64BIT"
14522  "leave"
14523  [(set_attr "type" "leave")])
14524
14525(define_insn "leave_rex64"
14526  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14527   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14528   (clobber (mem:BLK (scratch)))]
14529  "TARGET_64BIT"
14530  "leave"
14531  [(set_attr "type" "leave")])
14532
14533(define_expand "ffssi2"
14534  [(parallel
14535     [(set (match_operand:SI 0 "register_operand" "") 
14536	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14537      (clobber (match_scratch:SI 2 ""))
14538      (clobber (reg:CC FLAGS_REG))])]
14539  ""
14540  "")
14541
14542(define_insn_and_split "*ffs_cmove"
14543  [(set (match_operand:SI 0 "register_operand" "=r") 
14544	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14545   (clobber (match_scratch:SI 2 "=&r"))
14546   (clobber (reg:CC FLAGS_REG))]
14547  "TARGET_CMOVE"
14548  "#"
14549  "&& reload_completed"
14550  [(set (match_dup 2) (const_int -1))
14551   (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14552	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14553   (set (match_dup 0) (if_then_else:SI
14554			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14555			(match_dup 2)
14556			(match_dup 0)))
14557   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14558	      (clobber (reg:CC FLAGS_REG))])]
14559  "")
14560
14561(define_insn_and_split "*ffs_no_cmove"
14562  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14563	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14564   (clobber (match_scratch:SI 2 "=&q"))
14565   (clobber (reg:CC FLAGS_REG))]
14566  ""
14567  "#"
14568  "reload_completed"
14569  [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14570	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14571   (set (strict_low_part (match_dup 3))
14572	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14573   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14574	      (clobber (reg:CC FLAGS_REG))])
14575   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14576	      (clobber (reg:CC FLAGS_REG))])
14577   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14578	      (clobber (reg:CC FLAGS_REG))])]
14579{
14580  operands[3] = gen_lowpart (QImode, operands[2]);
14581  ix86_expand_clear (operands[2]);
14582})
14583
14584(define_insn "*ffssi_1"
14585  [(set (reg:CCZ FLAGS_REG)
14586	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14587		     (const_int 0)))
14588   (set (match_operand:SI 0 "register_operand" "=r")
14589	(ctz:SI (match_dup 1)))]
14590  ""
14591  "bsf{l}\t{%1, %0|%0, %1}"
14592  [(set_attr "prefix_0f" "1")])
14593
14594(define_expand "ffsdi2"
14595  [(parallel
14596     [(set (match_operand:DI 0 "register_operand" "") 
14597	   (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14598      (clobber (match_scratch:DI 2 ""))
14599      (clobber (reg:CC FLAGS_REG))])]
14600  "TARGET_64BIT && TARGET_CMOVE"
14601  "")
14602
14603(define_insn_and_split "*ffs_rex64"
14604  [(set (match_operand:DI 0 "register_operand" "=r") 
14605	(ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14606   (clobber (match_scratch:DI 2 "=&r"))
14607   (clobber (reg:CC FLAGS_REG))]
14608  "TARGET_64BIT && TARGET_CMOVE"
14609  "#"
14610  "&& reload_completed"
14611  [(set (match_dup 2) (const_int -1))
14612   (parallel [(set (reg:CCZ FLAGS_REG)
14613		   (compare:CCZ (match_dup 1) (const_int 0)))
14614	      (set (match_dup 0) (ctz:DI (match_dup 1)))])
14615   (set (match_dup 0) (if_then_else:DI
14616			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14617			(match_dup 2)
14618			(match_dup 0)))
14619   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14620	      (clobber (reg:CC FLAGS_REG))])]
14621  "")
14622
14623(define_insn "*ffsdi_1"
14624  [(set (reg:CCZ FLAGS_REG)
14625	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14626		     (const_int 0)))
14627   (set (match_operand:DI 0 "register_operand" "=r")
14628	(ctz:DI (match_dup 1)))]
14629  "TARGET_64BIT"
14630  "bsf{q}\t{%1, %0|%0, %1}"
14631  [(set_attr "prefix_0f" "1")])
14632
14633(define_insn "ctzsi2"
14634  [(set (match_operand:SI 0 "register_operand" "=r")
14635	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14636   (clobber (reg:CC FLAGS_REG))]
14637  ""
14638  "bsf{l}\t{%1, %0|%0, %1}"
14639  [(set_attr "prefix_0f" "1")])
14640
14641(define_insn "ctzdi2"
14642  [(set (match_operand:DI 0 "register_operand" "=r")
14643	(ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14644   (clobber (reg:CC FLAGS_REG))]
14645  "TARGET_64BIT"
14646  "bsf{q}\t{%1, %0|%0, %1}"
14647  [(set_attr "prefix_0f" "1")])
14648
14649(define_expand "clzsi2"
14650  [(parallel
14651     [(set (match_operand:SI 0 "register_operand" "")
14652	   (minus:SI (const_int 31)
14653		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14654      (clobber (reg:CC FLAGS_REG))])
14655   (parallel
14656     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14657      (clobber (reg:CC FLAGS_REG))])]
14658  ""
14659{
14660  if (TARGET_ABM)
14661    {
14662      emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14663      DONE;
14664    }
14665})
14666
14667(define_insn "clzsi2_abm"
14668  [(set (match_operand:SI 0 "register_operand" "=r")
14669        (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14670   (clobber (reg:CC FLAGS_REG))]
14671  "TARGET_ABM"
14672  "lzcnt{l}\t{%1, %0|%0, %1}"
14673  [(set_attr "prefix_rep" "1")
14674   (set_attr "type" "bitmanip")
14675   (set_attr "mode" "SI")])
14676
14677(define_insn "*bsr"
14678  [(set (match_operand:SI 0 "register_operand" "=r")
14679	(minus:SI (const_int 31)
14680		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14681   (clobber (reg:CC FLAGS_REG))]
14682  ""
14683  "bsr{l}\t{%1, %0|%0, %1}"
14684  [(set_attr "prefix_0f" "1")
14685   (set_attr "mode" "SI")])
14686
14687(define_insn "popcountsi2"
14688  [(set (match_operand:SI 0 "register_operand" "=r")
14689	(popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14690   (clobber (reg:CC FLAGS_REG))]
14691  "TARGET_POPCNT"
14692  "popcnt{l}\t{%1, %0|%0, %1}"
14693  [(set_attr "prefix_rep" "1")
14694   (set_attr "type" "bitmanip")
14695   (set_attr "mode" "SI")])
14696
14697(define_insn "*popcountsi2_cmp"
14698  [(set (reg FLAGS_REG)
14699	(compare
14700	  (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14701	  (const_int 0)))
14702   (set (match_operand:SI 0 "register_operand" "=r")
14703	(popcount:SI (match_dup 1)))]
14704  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14705  "popcnt{l}\t{%1, %0|%0, %1}"
14706  [(set_attr "prefix_rep" "1")
14707   (set_attr "type" "bitmanip")
14708   (set_attr "mode" "SI")])
14709
14710(define_insn "*popcountsi2_cmp_zext"
14711  [(set (reg FLAGS_REG)
14712        (compare
14713          (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14714          (const_int 0)))
14715   (set (match_operand:DI 0 "register_operand" "=r")
14716        (zero_extend:DI(popcount:SI (match_dup 1))))]
14717  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14718  "popcnt{l}\t{%1, %0|%0, %1}"
14719  [(set_attr "prefix_rep" "1")
14720   (set_attr "type" "bitmanip")
14721   (set_attr "mode" "SI")])
14722
14723(define_expand "clzdi2"
14724  [(parallel
14725     [(set (match_operand:DI 0 "register_operand" "")
14726	   (minus:DI (const_int 63)
14727		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14728      (clobber (reg:CC FLAGS_REG))])
14729   (parallel
14730     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14731      (clobber (reg:CC FLAGS_REG))])]
14732  "TARGET_64BIT"
14733{
14734  if (TARGET_ABM)
14735    {
14736      emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14737      DONE;
14738    }
14739})
14740
14741(define_insn "clzdi2_abm"
14742  [(set (match_operand:DI 0 "register_operand" "=r")
14743	(clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14744   (clobber (reg:CC FLAGS_REG))]
14745  "TARGET_64BIT && TARGET_ABM"
14746  "lzcnt{q}\t{%1, %0|%0, %1}"
14747  [(set_attr "prefix_rep" "1")
14748   (set_attr "type" "bitmanip")
14749   (set_attr "mode" "DI")])
14750
14751(define_insn "*bsr_rex64"
14752  [(set (match_operand:DI 0 "register_operand" "=r")
14753	(minus:DI (const_int 63)
14754		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14755   (clobber (reg:CC FLAGS_REG))]
14756  "TARGET_64BIT"
14757  "bsr{q}\t{%1, %0|%0, %1}"
14758  [(set_attr "prefix_0f" "1")
14759   (set_attr "mode" "DI")])
14760
14761(define_insn "popcountdi2"
14762  [(set (match_operand:DI 0 "register_operand" "=r")
14763	(popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14764   (clobber (reg:CC FLAGS_REG))]
14765  "TARGET_64BIT && TARGET_POPCNT"
14766  "popcnt{q}\t{%1, %0|%0, %1}"
14767  [(set_attr "prefix_rep" "1")
14768   (set_attr "type" "bitmanip")
14769   (set_attr "mode" "DI")])
14770
14771(define_insn "*popcountdi2_cmp"
14772  [(set (reg FLAGS_REG)
14773	(compare
14774	  (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14775	  (const_int 0)))
14776   (set (match_operand:DI 0 "register_operand" "=r")
14777	(popcount:DI (match_dup 1)))]
14778  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14779  "popcnt{q}\t{%1, %0|%0, %1}"
14780  [(set_attr "prefix_rep" "1")
14781   (set_attr "type" "bitmanip")
14782   (set_attr "mode" "DI")])
14783
14784(define_expand "clzhi2"
14785  [(parallel
14786     [(set (match_operand:HI 0 "register_operand" "")
14787	   (minus:HI (const_int 15)
14788		     (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14789      (clobber (reg:CC FLAGS_REG))])
14790   (parallel
14791     [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14792      (clobber (reg:CC FLAGS_REG))])]
14793  ""
14794{
14795  if (TARGET_ABM)
14796    {
14797      emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14798      DONE;
14799    }
14800})
14801
14802(define_insn "clzhi2_abm"
14803  [(set (match_operand:HI 0 "register_operand" "=r")
14804	(clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14805   (clobber (reg:CC FLAGS_REG))]
14806  "TARGET_ABM"
14807  "lzcnt{w}\t{%1, %0|%0, %1}"
14808  [(set_attr "prefix_rep" "1")
14809   (set_attr "type" "bitmanip")
14810   (set_attr "mode" "HI")])
14811
14812(define_insn "*bsrhi"
14813  [(set (match_operand:HI 0 "register_operand" "=r")
14814	(minus:HI (const_int 15)
14815		  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14816   (clobber (reg:CC FLAGS_REG))]
14817  ""
14818  "bsr{w}\t{%1, %0|%0, %1}"
14819  [(set_attr "prefix_0f" "1")
14820   (set_attr "mode" "HI")])
14821
14822(define_insn "popcounthi2"
14823  [(set (match_operand:HI 0 "register_operand" "=r")
14824	(popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14825   (clobber (reg:CC FLAGS_REG))]
14826  "TARGET_POPCNT"
14827  "popcnt{w}\t{%1, %0|%0, %1}"
14828  [(set_attr "prefix_rep" "1")
14829   (set_attr "type" "bitmanip")
14830   (set_attr "mode" "HI")])
14831
14832(define_insn "*popcounthi2_cmp"
14833  [(set (reg FLAGS_REG)
14834        (compare
14835          (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14836          (const_int 0)))
14837   (set (match_operand:HI 0 "register_operand" "=r")
14838        (popcount:HI (match_dup 1)))]
14839  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14840  "popcnt{w}\t{%1, %0|%0, %1}"
14841  [(set_attr "prefix_rep" "1")
14842   (set_attr "type" "bitmanip")
14843   (set_attr "mode" "HI")])
14844
14845;; Thread-local storage patterns for ELF.
14846;;
14847;; Note that these code sequences must appear exactly as shown
14848;; in order to allow linker relaxation.
14849
14850(define_insn "*tls_global_dynamic_32_gnu"
14851  [(set (match_operand:SI 0 "register_operand" "=a")
14852	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14853		    (match_operand:SI 2 "tls_symbolic_operand" "")
14854		    (match_operand:SI 3 "call_insn_operand" "")]
14855		    UNSPEC_TLS_GD))
14856   (clobber (match_scratch:SI 4 "=d"))
14857   (clobber (match_scratch:SI 5 "=c"))
14858   (clobber (reg:CC FLAGS_REG))]
14859  "!TARGET_64BIT && TARGET_GNU_TLS"
14860  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14861  [(set_attr "type" "multi")
14862   (set_attr "length" "12")])
14863
14864(define_insn "*tls_global_dynamic_32_sun"
14865  [(set (match_operand:SI 0 "register_operand" "=a")
14866	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14867		    (match_operand:SI 2 "tls_symbolic_operand" "")
14868		    (match_operand:SI 3 "call_insn_operand" "")]
14869		    UNSPEC_TLS_GD))
14870   (clobber (match_scratch:SI 4 "=d"))
14871   (clobber (match_scratch:SI 5 "=c"))
14872   (clobber (reg:CC FLAGS_REG))]
14873  "!TARGET_64BIT && TARGET_SUN_TLS"
14874  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14875	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14876  [(set_attr "type" "multi")
14877   (set_attr "length" "14")])
14878
14879(define_expand "tls_global_dynamic_32"
14880  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14881		   (unspec:SI
14882		    [(match_dup 2)
14883		     (match_operand:SI 1 "tls_symbolic_operand" "")
14884		     (match_dup 3)]
14885		    UNSPEC_TLS_GD))
14886	      (clobber (match_scratch:SI 4 ""))
14887	      (clobber (match_scratch:SI 5 ""))
14888	      (clobber (reg:CC FLAGS_REG))])]
14889  ""
14890{
14891  if (flag_pic)
14892    operands[2] = pic_offset_table_rtx;
14893  else
14894    {
14895      operands[2] = gen_reg_rtx (Pmode);
14896      emit_insn (gen_set_got (operands[2]));
14897    }
14898  if (TARGET_GNU2_TLS)
14899    {
14900       emit_insn (gen_tls_dynamic_gnu2_32
14901		  (operands[0], operands[1], operands[2]));
14902       DONE;
14903    }
14904  operands[3] = ix86_tls_get_addr ();
14905})
14906
14907(define_insn "*tls_global_dynamic_64"
14908  [(set (match_operand:DI 0 "register_operand" "=a")
14909	(call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14910		 (match_operand:DI 3 "" "")))
14911   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14912	      UNSPEC_TLS_GD)]
14913  "TARGET_64BIT"
14914  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14915  [(set_attr "type" "multi")
14916   (set_attr "length" "16")])
14917
14918(define_expand "tls_global_dynamic_64"
14919  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14920		   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14921	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14922			 UNSPEC_TLS_GD)])]
14923  ""
14924{
14925  if (TARGET_GNU2_TLS)
14926    {
14927       emit_insn (gen_tls_dynamic_gnu2_64
14928		  (operands[0], operands[1]));
14929       DONE;
14930    }
14931  operands[2] = ix86_tls_get_addr ();
14932})
14933
14934(define_insn "*tls_local_dynamic_base_32_gnu"
14935  [(set (match_operand:SI 0 "register_operand" "=a")
14936	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14937                    (match_operand:SI 2 "call_insn_operand" "")]
14938		   UNSPEC_TLS_LD_BASE))
14939   (clobber (match_scratch:SI 3 "=d"))
14940   (clobber (match_scratch:SI 4 "=c"))
14941   (clobber (reg:CC FLAGS_REG))]
14942  "!TARGET_64BIT && TARGET_GNU_TLS"
14943  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14944  [(set_attr "type" "multi")
14945   (set_attr "length" "11")])
14946
14947(define_insn "*tls_local_dynamic_base_32_sun"
14948  [(set (match_operand:SI 0 "register_operand" "=a")
14949	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14950                    (match_operand:SI 2 "call_insn_operand" "")]
14951		   UNSPEC_TLS_LD_BASE))
14952   (clobber (match_scratch:SI 3 "=d"))
14953   (clobber (match_scratch:SI 4 "=c"))
14954   (clobber (reg:CC FLAGS_REG))]
14955  "!TARGET_64BIT && TARGET_SUN_TLS"
14956  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14957	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14958  [(set_attr "type" "multi")
14959   (set_attr "length" "13")])
14960
14961(define_expand "tls_local_dynamic_base_32"
14962  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14963		   (unspec:SI [(match_dup 1) (match_dup 2)]
14964			      UNSPEC_TLS_LD_BASE))
14965	      (clobber (match_scratch:SI 3 ""))
14966	      (clobber (match_scratch:SI 4 ""))
14967	      (clobber (reg:CC FLAGS_REG))])]
14968  ""
14969{
14970  if (flag_pic)
14971    operands[1] = pic_offset_table_rtx;
14972  else
14973    {
14974      operands[1] = gen_reg_rtx (Pmode);
14975      emit_insn (gen_set_got (operands[1]));
14976    }
14977  if (TARGET_GNU2_TLS)
14978    {
14979       emit_insn (gen_tls_dynamic_gnu2_32
14980		  (operands[0], ix86_tls_module_base (), operands[1]));
14981       DONE;
14982    }
14983  operands[2] = ix86_tls_get_addr ();
14984})
14985
14986(define_insn "*tls_local_dynamic_base_64"
14987  [(set (match_operand:DI 0 "register_operand" "=a")
14988	(call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14989		 (match_operand:DI 2 "" "")))
14990   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14991  "TARGET_64BIT"
14992  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14993  [(set_attr "type" "multi")
14994   (set_attr "length" "12")])
14995
14996(define_expand "tls_local_dynamic_base_64"
14997  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14998		   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14999	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15000  ""
15001{
15002  if (TARGET_GNU2_TLS)
15003    {
15004       emit_insn (gen_tls_dynamic_gnu2_64
15005		  (operands[0], ix86_tls_module_base ()));
15006       DONE;
15007    }
15008  operands[1] = ix86_tls_get_addr ();
15009})
15010
15011;; Local dynamic of a single variable is a lose.  Show combine how
15012;; to convert that back to global dynamic.
15013
15014(define_insn_and_split "*tls_local_dynamic_32_once"
15015  [(set (match_operand:SI 0 "register_operand" "=a")
15016	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15017			     (match_operand:SI 2 "call_insn_operand" "")]
15018			    UNSPEC_TLS_LD_BASE)
15019		 (const:SI (unspec:SI
15020			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
15021			    UNSPEC_DTPOFF))))
15022   (clobber (match_scratch:SI 4 "=d"))
15023   (clobber (match_scratch:SI 5 "=c"))
15024   (clobber (reg:CC FLAGS_REG))]
15025  ""
15026  "#"
15027  ""
15028  [(parallel [(set (match_dup 0)
15029		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15030			      UNSPEC_TLS_GD))
15031	      (clobber (match_dup 4))
15032	      (clobber (match_dup 5))
15033	      (clobber (reg:CC FLAGS_REG))])]
15034  "")
15035
15036;; Load and add the thread base pointer from %gs:0.
15037
15038(define_insn "*load_tp_si"
15039  [(set (match_operand:SI 0 "register_operand" "=r")
15040	(unspec:SI [(const_int 0)] UNSPEC_TP))]
15041  "!TARGET_64BIT"
15042  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15043  [(set_attr "type" "imov")
15044   (set_attr "modrm" "0")
15045   (set_attr "length" "7")
15046   (set_attr "memory" "load")
15047   (set_attr "imm_disp" "false")])
15048
15049(define_insn "*add_tp_si"
15050  [(set (match_operand:SI 0 "register_operand" "=r")
15051	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15052		 (match_operand:SI 1 "register_operand" "0")))
15053   (clobber (reg:CC FLAGS_REG))]
15054  "!TARGET_64BIT"
15055  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15056  [(set_attr "type" "alu")
15057   (set_attr "modrm" "0")
15058   (set_attr "length" "7")
15059   (set_attr "memory" "load")
15060   (set_attr "imm_disp" "false")])
15061
15062(define_insn "*load_tp_di"
15063  [(set (match_operand:DI 0 "register_operand" "=r")
15064	(unspec:DI [(const_int 0)] UNSPEC_TP))]
15065  "TARGET_64BIT"
15066  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15067  [(set_attr "type" "imov")
15068   (set_attr "modrm" "0")
15069   (set_attr "length" "7")
15070   (set_attr "memory" "load")
15071   (set_attr "imm_disp" "false")])
15072
15073(define_insn "*add_tp_di"
15074  [(set (match_operand:DI 0 "register_operand" "=r")
15075	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15076		 (match_operand:DI 1 "register_operand" "0")))
15077   (clobber (reg:CC FLAGS_REG))]
15078  "TARGET_64BIT"
15079  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15080  [(set_attr "type" "alu")
15081   (set_attr "modrm" "0")
15082   (set_attr "length" "7")
15083   (set_attr "memory" "load")
15084   (set_attr "imm_disp" "false")])
15085
15086;; GNU2 TLS patterns can be split.
15087
15088(define_expand "tls_dynamic_gnu2_32"
15089  [(set (match_dup 3)
15090	(plus:SI (match_operand:SI 2 "register_operand" "")
15091		 (const:SI
15092		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15093			     UNSPEC_TLSDESC))))
15094   (parallel
15095    [(set (match_operand:SI 0 "register_operand" "")
15096	  (unspec:SI [(match_dup 1) (match_dup 3)
15097		      (match_dup 2) (reg:SI SP_REG)]
15098		      UNSPEC_TLSDESC))
15099     (clobber (reg:CC FLAGS_REG))])]
15100  "!TARGET_64BIT && TARGET_GNU2_TLS"
15101{
15102  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15103  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15104})
15105
15106(define_insn "*tls_dynamic_lea_32"
15107  [(set (match_operand:SI 0 "register_operand" "=r")
15108	(plus:SI (match_operand:SI 1 "register_operand" "b")
15109		 (const:SI
15110		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15111			      UNSPEC_TLSDESC))))]
15112  "!TARGET_64BIT && TARGET_GNU2_TLS"
15113  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15114  [(set_attr "type" "lea")
15115   (set_attr "mode" "SI")
15116   (set_attr "length" "6")
15117   (set_attr "length_address" "4")])
15118
15119(define_insn "*tls_dynamic_call_32"
15120  [(set (match_operand:SI 0 "register_operand" "=a")
15121	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15122		    (match_operand:SI 2 "register_operand" "0")
15123		    ;; we have to make sure %ebx still points to the GOT
15124		    (match_operand:SI 3 "register_operand" "b")
15125		    (reg:SI SP_REG)]
15126		   UNSPEC_TLSDESC))
15127   (clobber (reg:CC FLAGS_REG))]
15128  "!TARGET_64BIT && TARGET_GNU2_TLS"
15129  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15130  [(set_attr "type" "call")
15131   (set_attr "length" "2")
15132   (set_attr "length_address" "0")])
15133
15134(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15135  [(set (match_operand:SI 0 "register_operand" "=&a")
15136	(plus:SI
15137	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15138		     (match_operand:SI 4 "" "")
15139		     (match_operand:SI 2 "register_operand" "b")
15140		     (reg:SI SP_REG)]
15141		    UNSPEC_TLSDESC)
15142	 (const:SI (unspec:SI
15143		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
15144		    UNSPEC_DTPOFF))))
15145   (clobber (reg:CC FLAGS_REG))]
15146  "!TARGET_64BIT && TARGET_GNU2_TLS"
15147  "#"
15148  ""
15149  [(set (match_dup 0) (match_dup 5))]
15150{
15151  operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15152  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15153})
15154
15155(define_expand "tls_dynamic_gnu2_64"
15156  [(set (match_dup 2)
15157	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15158		   UNSPEC_TLSDESC))
15159   (parallel
15160    [(set (match_operand:DI 0 "register_operand" "")
15161	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15162		     UNSPEC_TLSDESC))
15163     (clobber (reg:CC FLAGS_REG))])]
15164  "TARGET_64BIT && TARGET_GNU2_TLS"
15165{
15166  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15167  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15168})
15169
15170(define_insn "*tls_dynamic_lea_64"
15171  [(set (match_operand:DI 0 "register_operand" "=r")
15172	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15173		   UNSPEC_TLSDESC))]
15174  "TARGET_64BIT && TARGET_GNU2_TLS"
15175  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15176  [(set_attr "type" "lea")
15177   (set_attr "mode" "DI")
15178   (set_attr "length" "7")
15179   (set_attr "length_address" "4")])
15180
15181(define_insn "*tls_dynamic_call_64"
15182  [(set (match_operand:DI 0 "register_operand" "=a")
15183	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15184		    (match_operand:DI 2 "register_operand" "0")
15185		    (reg:DI SP_REG)]
15186		   UNSPEC_TLSDESC))
15187   (clobber (reg:CC FLAGS_REG))]
15188  "TARGET_64BIT && TARGET_GNU2_TLS"
15189  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15190  [(set_attr "type" "call")
15191   (set_attr "length" "2")
15192   (set_attr "length_address" "0")])
15193
15194(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15195  [(set (match_operand:DI 0 "register_operand" "=&a")
15196	(plus:DI
15197	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15198		     (match_operand:DI 3 "" "")
15199		     (reg:DI SP_REG)]
15200		    UNSPEC_TLSDESC)
15201	 (const:DI (unspec:DI
15202		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
15203		    UNSPEC_DTPOFF))))
15204   (clobber (reg:CC FLAGS_REG))]
15205  "TARGET_64BIT && TARGET_GNU2_TLS"
15206  "#"
15207  ""
15208  [(set (match_dup 0) (match_dup 4))]
15209{
15210  operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15211  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15212})
15213
15214;;
15215
15216;; These patterns match the binary 387 instructions for addM3, subM3,
15217;; mulM3 and divM3.  There are three patterns for each of DFmode and
15218;; SFmode.  The first is the normal insn, the second the same insn but
15219;; with one operand a conversion, and the third the same insn but with
15220;; the other operand a conversion.  The conversion may be SFmode or
15221;; SImode if the target mode DFmode, but only SImode if the target mode
15222;; is SFmode.
15223
15224;; Gcc is slightly more smart about handling normal two address instructions
15225;; so use special patterns for add and mull.
15226
15227(define_insn "*fop_sf_comm_mixed"
15228  [(set (match_operand:SF 0 "register_operand" "=f,x")
15229	(match_operator:SF 3 "binary_fp_operator"
15230			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15231			 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15232  "TARGET_MIX_SSE_I387
15233   && COMMUTATIVE_ARITH_P (operands[3])
15234   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15235  "* return output_387_binary_op (insn, operands);"
15236  [(set (attr "type") 
15237	(if_then_else (eq_attr "alternative" "1")
15238	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
15239	      (const_string "ssemul")
15240	      (const_string "sseadd"))
15241	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
15242	      (const_string "fmul")
15243	      (const_string "fop"))))
15244   (set_attr "mode" "SF")])
15245
15246(define_insn "*fop_sf_comm_sse"
15247  [(set (match_operand:SF 0 "register_operand" "=x")
15248	(match_operator:SF 3 "binary_fp_operator"
15249			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15250			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15251  "TARGET_SSE_MATH
15252   && COMMUTATIVE_ARITH_P (operands[3])
15253   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15254  "* return output_387_binary_op (insn, operands);"
15255  [(set (attr "type") 
15256        (if_then_else (match_operand:SF 3 "mult_operator" "") 
15257	   (const_string "ssemul")
15258	   (const_string "sseadd")))
15259   (set_attr "mode" "SF")])
15260
15261(define_insn "*fop_sf_comm_i387"
15262  [(set (match_operand:SF 0 "register_operand" "=f")
15263	(match_operator:SF 3 "binary_fp_operator"
15264			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15265			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15266  "TARGET_80387
15267   && COMMUTATIVE_ARITH_P (operands[3])
15268   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15269  "* return output_387_binary_op (insn, operands);"
15270  [(set (attr "type") 
15271	(if_then_else (match_operand:SF 3 "mult_operator" "") 
15272	   (const_string "fmul")
15273	   (const_string "fop")))
15274   (set_attr "mode" "SF")])
15275
15276(define_insn "*fop_sf_1_mixed"
15277  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15278	(match_operator:SF 3 "binary_fp_operator"
15279			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15280			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15281  "TARGET_MIX_SSE_I387
15282   && !COMMUTATIVE_ARITH_P (operands[3])
15283   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15284  "* return output_387_binary_op (insn, operands);"
15285  [(set (attr "type") 
15286        (cond [(and (eq_attr "alternative" "2")
15287	            (match_operand:SF 3 "mult_operator" ""))
15288                 (const_string "ssemul")
15289	       (and (eq_attr "alternative" "2")
15290	            (match_operand:SF 3 "div_operator" ""))
15291                 (const_string "ssediv")
15292	       (eq_attr "alternative" "2")
15293                 (const_string "sseadd")
15294	       (match_operand:SF 3 "mult_operator" "") 
15295                 (const_string "fmul")
15296               (match_operand:SF 3 "div_operator" "") 
15297                 (const_string "fdiv")
15298              ]
15299              (const_string "fop")))
15300   (set_attr "mode" "SF")])
15301
15302(define_insn "*fop_sf_1_sse"
15303  [(set (match_operand:SF 0 "register_operand" "=x")
15304	(match_operator:SF 3 "binary_fp_operator"
15305			[(match_operand:SF 1 "register_operand" "0")
15306			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15307  "TARGET_SSE_MATH
15308   && !COMMUTATIVE_ARITH_P (operands[3])"
15309  "* return output_387_binary_op (insn, operands);"
15310  [(set (attr "type") 
15311        (cond [(match_operand:SF 3 "mult_operator" "")
15312                 (const_string "ssemul")
15313	       (match_operand:SF 3 "div_operator" "")
15314                 (const_string "ssediv")
15315              ]
15316              (const_string "sseadd")))
15317   (set_attr "mode" "SF")])
15318
15319;; This pattern is not fully shadowed by the pattern above.
15320(define_insn "*fop_sf_1_i387"
15321  [(set (match_operand:SF 0 "register_operand" "=f,f")
15322	(match_operator:SF 3 "binary_fp_operator"
15323			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15324			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15325  "TARGET_80387 && !TARGET_SSE_MATH
15326   && !COMMUTATIVE_ARITH_P (operands[3])
15327   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15328  "* return output_387_binary_op (insn, operands);"
15329  [(set (attr "type") 
15330        (cond [(match_operand:SF 3 "mult_operator" "") 
15331                 (const_string "fmul")
15332               (match_operand:SF 3 "div_operator" "") 
15333                 (const_string "fdiv")
15334              ]
15335              (const_string "fop")))
15336   (set_attr "mode" "SF")])
15337
15338;; ??? Add SSE splitters for these!
15339(define_insn "*fop_sf_2<mode>_i387"
15340  [(set (match_operand:SF 0 "register_operand" "=f,f")
15341	(match_operator:SF 3 "binary_fp_operator"
15342	  [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15343	   (match_operand:SF 2 "register_operand" "0,0")]))]
15344  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15345  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15346  [(set (attr "type") 
15347        (cond [(match_operand:SF 3 "mult_operator" "") 
15348                 (const_string "fmul")
15349               (match_operand:SF 3 "div_operator" "") 
15350                 (const_string "fdiv")
15351              ]
15352              (const_string "fop")))
15353   (set_attr "fp_int_src" "true")
15354   (set_attr "mode" "<MODE>")])
15355
15356(define_insn "*fop_sf_3<mode>_i387"
15357  [(set (match_operand:SF 0 "register_operand" "=f,f")
15358	(match_operator:SF 3 "binary_fp_operator"
15359	  [(match_operand:SF 1 "register_operand" "0,0")
15360	   (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15361  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15362  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15363  [(set (attr "type") 
15364        (cond [(match_operand:SF 3 "mult_operator" "") 
15365                 (const_string "fmul")
15366               (match_operand:SF 3 "div_operator" "") 
15367                 (const_string "fdiv")
15368              ]
15369              (const_string "fop")))
15370   (set_attr "fp_int_src" "true")
15371   (set_attr "mode" "<MODE>")])
15372
15373(define_insn "*fop_df_comm_mixed"
15374  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15375	(match_operator:DF 3 "binary_fp_operator"
15376			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15377			 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15378  "TARGET_SSE2 && TARGET_MIX_SSE_I387
15379   && COMMUTATIVE_ARITH_P (operands[3])
15380   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15381  "* return output_387_binary_op (insn, operands);"
15382  [(set (attr "type") 
15383	(if_then_else (eq_attr "alternative" "1")
15384	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15385	      (const_string "ssemul")
15386	      (const_string "sseadd"))
15387	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15388	      (const_string "fmul")
15389	      (const_string "fop"))))
15390   (set_attr "mode" "DF")])
15391
15392(define_insn "*fop_df_comm_sse"
15393  [(set (match_operand:DF 0 "register_operand" "=Y")
15394	(match_operator:DF 3 "binary_fp_operator"
15395			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15396			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15397  "TARGET_SSE2 && TARGET_SSE_MATH
15398   && COMMUTATIVE_ARITH_P (operands[3])
15399   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15400  "* return output_387_binary_op (insn, operands);"
15401  [(set (attr "type") 
15402        (if_then_else (match_operand:DF 3 "mult_operator" "") 
15403	   (const_string "ssemul")
15404	   (const_string "sseadd")))
15405   (set_attr "mode" "DF")])
15406
15407(define_insn "*fop_df_comm_i387"
15408  [(set (match_operand:DF 0 "register_operand" "=f")
15409	(match_operator:DF 3 "binary_fp_operator"
15410			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15411			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15412  "TARGET_80387
15413   && COMMUTATIVE_ARITH_P (operands[3])
15414   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15415  "* return output_387_binary_op (insn, operands);"
15416  [(set (attr "type") 
15417	(if_then_else (match_operand:DF 3 "mult_operator" "") 
15418	   (const_string "fmul")
15419	   (const_string "fop")))
15420   (set_attr "mode" "DF")])
15421
15422(define_insn "*fop_df_1_mixed"
15423  [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15424	(match_operator:DF 3 "binary_fp_operator"
15425			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15426			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15427  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15428   && !COMMUTATIVE_ARITH_P (operands[3])
15429   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15430  "* return output_387_binary_op (insn, operands);"
15431  [(set (attr "type") 
15432        (cond [(and (eq_attr "alternative" "2")
15433	            (match_operand:DF 3 "mult_operator" ""))
15434                 (const_string "ssemul")
15435	       (and (eq_attr "alternative" "2")
15436	            (match_operand:DF 3 "div_operator" ""))
15437                 (const_string "ssediv")
15438	       (eq_attr "alternative" "2")
15439                 (const_string "sseadd")
15440	       (match_operand:DF 3 "mult_operator" "") 
15441                 (const_string "fmul")
15442               (match_operand:DF 3 "div_operator" "") 
15443                 (const_string "fdiv")
15444              ]
15445              (const_string "fop")))
15446   (set_attr "mode" "DF")])
15447
15448(define_insn "*fop_df_1_sse"
15449  [(set (match_operand:DF 0 "register_operand" "=Y")
15450	(match_operator:DF 3 "binary_fp_operator"
15451			[(match_operand:DF 1 "register_operand" "0")
15452			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15453  "TARGET_SSE2 && TARGET_SSE_MATH
15454   && !COMMUTATIVE_ARITH_P (operands[3])"
15455  "* return output_387_binary_op (insn, operands);"
15456  [(set_attr "mode" "DF")
15457   (set (attr "type") 
15458        (cond [(match_operand:DF 3 "mult_operator" "")
15459                 (const_string "ssemul")
15460	       (match_operand:DF 3 "div_operator" "")
15461                 (const_string "ssediv")
15462              ]
15463              (const_string "sseadd")))])
15464
15465;; This pattern is not fully shadowed by the pattern above.
15466(define_insn "*fop_df_1_i387"
15467  [(set (match_operand:DF 0 "register_operand" "=f,f")
15468	(match_operator:DF 3 "binary_fp_operator"
15469			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15470			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15471  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15472   && !COMMUTATIVE_ARITH_P (operands[3])
15473   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15474  "* return output_387_binary_op (insn, operands);"
15475  [(set (attr "type") 
15476        (cond [(match_operand:DF 3 "mult_operator" "") 
15477                 (const_string "fmul")
15478               (match_operand:DF 3 "div_operator" "")
15479                 (const_string "fdiv")
15480              ]
15481              (const_string "fop")))
15482   (set_attr "mode" "DF")])
15483
15484;; ??? Add SSE splitters for these!
15485(define_insn "*fop_df_2<mode>_i387"
15486  [(set (match_operand:DF 0 "register_operand" "=f,f")
15487	(match_operator:DF 3 "binary_fp_operator"
15488	   [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15489	    (match_operand:DF 2 "register_operand" "0,0")]))]
15490  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15491   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15492  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15493  [(set (attr "type") 
15494        (cond [(match_operand:DF 3 "mult_operator" "") 
15495                 (const_string "fmul")
15496               (match_operand:DF 3 "div_operator" "") 
15497                 (const_string "fdiv")
15498              ]
15499              (const_string "fop")))
15500   (set_attr "fp_int_src" "true")
15501   (set_attr "mode" "<MODE>")])
15502
15503(define_insn "*fop_df_3<mode>_i387"
15504  [(set (match_operand:DF 0 "register_operand" "=f,f")
15505	(match_operator:DF 3 "binary_fp_operator"
15506	   [(match_operand:DF 1 "register_operand" "0,0")
15507	    (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15508  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15509   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15510  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15511  [(set (attr "type") 
15512        (cond [(match_operand:DF 3 "mult_operator" "") 
15513                 (const_string "fmul")
15514               (match_operand:DF 3 "div_operator" "") 
15515                 (const_string "fdiv")
15516              ]
15517              (const_string "fop")))
15518   (set_attr "fp_int_src" "true")
15519   (set_attr "mode" "<MODE>")])
15520
15521(define_insn "*fop_df_4_i387"
15522  [(set (match_operand:DF 0 "register_operand" "=f,f")
15523	(match_operator:DF 3 "binary_fp_operator"
15524	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15525	    (match_operand:DF 2 "register_operand" "0,f")]))]
15526  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15527   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15528  "* return output_387_binary_op (insn, operands);"
15529  [(set (attr "type") 
15530        (cond [(match_operand:DF 3 "mult_operator" "") 
15531                 (const_string "fmul")
15532               (match_operand:DF 3 "div_operator" "") 
15533                 (const_string "fdiv")
15534              ]
15535              (const_string "fop")))
15536   (set_attr "mode" "SF")])
15537
15538(define_insn "*fop_df_5_i387"
15539  [(set (match_operand:DF 0 "register_operand" "=f,f")
15540	(match_operator:DF 3 "binary_fp_operator"
15541	  [(match_operand:DF 1 "register_operand" "0,f")
15542	   (float_extend:DF
15543	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15544  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15545  "* return output_387_binary_op (insn, operands);"
15546  [(set (attr "type") 
15547        (cond [(match_operand:DF 3 "mult_operator" "") 
15548                 (const_string "fmul")
15549               (match_operand:DF 3 "div_operator" "") 
15550                 (const_string "fdiv")
15551              ]
15552              (const_string "fop")))
15553   (set_attr "mode" "SF")])
15554
15555(define_insn "*fop_df_6_i387"
15556  [(set (match_operand:DF 0 "register_operand" "=f,f")
15557	(match_operator:DF 3 "binary_fp_operator"
15558	  [(float_extend:DF
15559	    (match_operand:SF 1 "register_operand" "0,f"))
15560	   (float_extend:DF
15561	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15562  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15563  "* return output_387_binary_op (insn, operands);"
15564  [(set (attr "type") 
15565        (cond [(match_operand:DF 3 "mult_operator" "") 
15566                 (const_string "fmul")
15567               (match_operand:DF 3 "div_operator" "") 
15568                 (const_string "fdiv")
15569              ]
15570              (const_string "fop")))
15571   (set_attr "mode" "SF")])
15572
15573(define_insn "*fop_xf_comm_i387"
15574  [(set (match_operand:XF 0 "register_operand" "=f")
15575	(match_operator:XF 3 "binary_fp_operator"
15576			[(match_operand:XF 1 "register_operand" "%0")
15577			 (match_operand:XF 2 "register_operand" "f")]))]
15578  "TARGET_80387
15579   && COMMUTATIVE_ARITH_P (operands[3])"
15580  "* return output_387_binary_op (insn, operands);"
15581  [(set (attr "type") 
15582        (if_then_else (match_operand:XF 3 "mult_operator" "") 
15583           (const_string "fmul")
15584           (const_string "fop")))
15585   (set_attr "mode" "XF")])
15586
15587(define_insn "*fop_xf_1_i387"
15588  [(set (match_operand:XF 0 "register_operand" "=f,f")
15589	(match_operator:XF 3 "binary_fp_operator"
15590			[(match_operand:XF 1 "register_operand" "0,f")
15591			 (match_operand:XF 2 "register_operand" "f,0")]))]
15592  "TARGET_80387
15593   && !COMMUTATIVE_ARITH_P (operands[3])"
15594  "* return output_387_binary_op (insn, operands);"
15595  [(set (attr "type") 
15596        (cond [(match_operand:XF 3 "mult_operator" "") 
15597                 (const_string "fmul")
15598               (match_operand:XF 3 "div_operator" "") 
15599                 (const_string "fdiv")
15600              ]
15601              (const_string "fop")))
15602   (set_attr "mode" "XF")])
15603
15604(define_insn "*fop_xf_2<mode>_i387"
15605  [(set (match_operand:XF 0 "register_operand" "=f,f")
15606	(match_operator:XF 3 "binary_fp_operator"
15607	   [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15608	    (match_operand:XF 2 "register_operand" "0,0")]))]
15609  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15610  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15611  [(set (attr "type") 
15612        (cond [(match_operand:XF 3 "mult_operator" "") 
15613                 (const_string "fmul")
15614               (match_operand:XF 3 "div_operator" "") 
15615                 (const_string "fdiv")
15616              ]
15617              (const_string "fop")))
15618   (set_attr "fp_int_src" "true")
15619   (set_attr "mode" "<MODE>")])
15620
15621(define_insn "*fop_xf_3<mode>_i387"
15622  [(set (match_operand:XF 0 "register_operand" "=f,f")
15623	(match_operator:XF 3 "binary_fp_operator"
15624	  [(match_operand:XF 1 "register_operand" "0,0")
15625	   (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15626  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15627  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15628  [(set (attr "type") 
15629        (cond [(match_operand:XF 3 "mult_operator" "") 
15630                 (const_string "fmul")
15631               (match_operand:XF 3 "div_operator" "") 
15632                 (const_string "fdiv")
15633              ]
15634              (const_string "fop")))
15635   (set_attr "fp_int_src" "true")
15636   (set_attr "mode" "<MODE>")])
15637
15638(define_insn "*fop_xf_4_i387"
15639  [(set (match_operand:XF 0 "register_operand" "=f,f")
15640	(match_operator:XF 3 "binary_fp_operator"
15641	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15642	    (match_operand:XF 2 "register_operand" "0,f")]))]
15643  "TARGET_80387"
15644  "* return output_387_binary_op (insn, operands);"
15645  [(set (attr "type") 
15646        (cond [(match_operand:XF 3 "mult_operator" "") 
15647                 (const_string "fmul")
15648               (match_operand:XF 3 "div_operator" "") 
15649                 (const_string "fdiv")
15650              ]
15651              (const_string "fop")))
15652   (set_attr "mode" "SF")])
15653
15654(define_insn "*fop_xf_5_i387"
15655  [(set (match_operand:XF 0 "register_operand" "=f,f")
15656	(match_operator:XF 3 "binary_fp_operator"
15657	  [(match_operand:XF 1 "register_operand" "0,f")
15658	   (float_extend:XF
15659	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15660  "TARGET_80387"
15661  "* return output_387_binary_op (insn, operands);"
15662  [(set (attr "type") 
15663        (cond [(match_operand:XF 3 "mult_operator" "") 
15664                 (const_string "fmul")
15665               (match_operand:XF 3 "div_operator" "") 
15666                 (const_string "fdiv")
15667              ]
15668              (const_string "fop")))
15669   (set_attr "mode" "SF")])
15670
15671(define_insn "*fop_xf_6_i387"
15672  [(set (match_operand:XF 0 "register_operand" "=f,f")
15673	(match_operator:XF 3 "binary_fp_operator"
15674	  [(float_extend:XF
15675	    (match_operand 1 "register_operand" "0,f"))
15676	   (float_extend:XF
15677	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15678  "TARGET_80387"
15679  "* return output_387_binary_op (insn, operands);"
15680  [(set (attr "type") 
15681        (cond [(match_operand:XF 3 "mult_operator" "") 
15682                 (const_string "fmul")
15683               (match_operand:XF 3 "div_operator" "") 
15684                 (const_string "fdiv")
15685              ]
15686              (const_string "fop")))
15687   (set_attr "mode" "SF")])
15688
15689(define_split
15690  [(set (match_operand 0 "register_operand" "")
15691	(match_operator 3 "binary_fp_operator"
15692	   [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15693	    (match_operand 2 "register_operand" "")]))]
15694  "TARGET_80387 && reload_completed
15695   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15696  [(const_int 0)]
15697{ 
15698  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15699  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15700  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15701			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15702					  GET_MODE (operands[3]),
15703					  operands[4],
15704					  operands[2])));
15705  ix86_free_from_memory (GET_MODE (operands[1]));
15706  DONE;
15707})
15708
15709(define_split
15710  [(set (match_operand 0 "register_operand" "")
15711	(match_operator 3 "binary_fp_operator"
15712	   [(match_operand 1 "register_operand" "")
15713	    (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15714  "TARGET_80387 && reload_completed
15715   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15716  [(const_int 0)]
15717{
15718  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15719  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15720  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15721			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15722					  GET_MODE (operands[3]),
15723					  operands[1],
15724					  operands[4])));
15725  ix86_free_from_memory (GET_MODE (operands[2]));
15726  DONE;
15727})
15728
15729;; FPU special functions.
15730
15731(define_expand "sqrtsf2"
15732  [(set (match_operand:SF 0 "register_operand" "")
15733	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15734  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15735{
15736  if (!TARGET_SSE_MATH)
15737    operands[1] = force_reg (SFmode, operands[1]);
15738})
15739
15740(define_insn "*sqrtsf2_mixed"
15741  [(set (match_operand:SF 0 "register_operand" "=f,x")
15742	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15743  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15744  "@
15745   fsqrt
15746   sqrtss\t{%1, %0|%0, %1}"
15747  [(set_attr "type" "fpspc,sse")
15748   (set_attr "mode" "SF,SF")
15749   (set_attr "athlon_decode" "direct,*")])
15750
15751(define_insn "*sqrtsf2_sse"
15752  [(set (match_operand:SF 0 "register_operand" "=x")
15753	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15754  "TARGET_SSE_MATH"
15755  "sqrtss\t{%1, %0|%0, %1}"
15756  [(set_attr "type" "sse")
15757   (set_attr "mode" "SF")
15758   (set_attr "athlon_decode" "*")
15759   (set_attr "amdfam10_decode" "*")])
15760
15761(define_insn "*sqrtsf2_i387"
15762  [(set (match_operand:SF 0 "register_operand" "=f")
15763	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15764  "TARGET_USE_FANCY_MATH_387"
15765  "fsqrt"
15766  [(set_attr "type" "fpspc")
15767   (set_attr "mode" "SF")
15768   (set_attr "athlon_decode" "direct")])
15769
15770(define_expand "sqrtdf2"
15771  [(set (match_operand:DF 0 "register_operand" "")
15772	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15773  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15774{
15775  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15776    operands[1] = force_reg (DFmode, operands[1]);
15777})
15778
15779(define_insn "*sqrtdf2_mixed"
15780  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15781	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15782  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15783  "@
15784   fsqrt
15785   sqrtsd\t{%1, %0|%0, %1}"
15786  [(set_attr "type" "fpspc,sse")
15787   (set_attr "mode" "DF,DF")
15788   (set_attr "athlon_decode" "direct,*")])
15789
15790(define_insn "*sqrtdf2_sse"
15791  [(set (match_operand:DF 0 "register_operand" "=Y")
15792	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15793  "TARGET_SSE2 && TARGET_SSE_MATH"
15794  "sqrtsd\t{%1, %0|%0, %1}"
15795  [(set_attr "type" "sse")
15796   (set_attr "mode" "DF")
15797   (set_attr "athlon_decode" "*")
15798   (set_attr "amdfam10_decode" "*")])
15799
15800(define_insn "*sqrtdf2_i387"
15801  [(set (match_operand:DF 0 "register_operand" "=f")
15802	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15803  "TARGET_USE_FANCY_MATH_387"
15804  "fsqrt"
15805  [(set_attr "type" "fpspc")
15806   (set_attr "mode" "DF")
15807   (set_attr "athlon_decode" "direct")])
15808
15809(define_insn "*sqrtextendsfdf2_i387"
15810  [(set (match_operand:DF 0 "register_operand" "=f")
15811	(sqrt:DF (float_extend:DF
15812		  (match_operand:SF 1 "register_operand" "0"))))]
15813  "TARGET_USE_FANCY_MATH_387
15814   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15815  "fsqrt"
15816  [(set_attr "type" "fpspc")
15817   (set_attr "mode" "DF")
15818   (set_attr "athlon_decode" "direct")])
15819
15820(define_insn "sqrtxf2"
15821  [(set (match_operand:XF 0 "register_operand" "=f")
15822	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15823  "TARGET_USE_FANCY_MATH_387"
15824  "fsqrt"
15825  [(set_attr "type" "fpspc")
15826   (set_attr "mode" "XF")
15827   (set_attr "athlon_decode" "direct")
15828   (set_attr "amdfam10_decode" "direct")])
15829
15830(define_insn "*sqrtextendsfxf2_i387"
15831  [(set (match_operand:XF 0 "register_operand" "=f")
15832	(sqrt:XF (float_extend:XF
15833		  (match_operand:SF 1 "register_operand" "0"))))]
15834  "TARGET_USE_FANCY_MATH_387"
15835  "fsqrt"
15836  [(set_attr "type" "fpspc")
15837   (set_attr "mode" "XF")
15838   (set_attr "athlon_decode" "direct")])
15839
15840(define_insn "*sqrtextenddfxf2_i387"
15841  [(set (match_operand:XF 0 "register_operand" "=f")
15842	(sqrt:XF (float_extend:XF
15843		  (match_operand:DF 1 "register_operand" "0"))))]
15844  "TARGET_USE_FANCY_MATH_387"
15845  "fsqrt"
15846  [(set_attr "type" "fpspc")
15847   (set_attr "mode" "XF")
15848   (set_attr "athlon_decode" "direct")   
15849   (set_attr "amdfam10_decode" "direct")])
15850
15851(define_insn "fpremxf4"
15852  [(set (match_operand:XF 0 "register_operand" "=f")
15853	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15854		    (match_operand:XF 3 "register_operand" "1")]
15855		   UNSPEC_FPREM_F))
15856   (set (match_operand:XF 1 "register_operand" "=u")
15857	(unspec:XF [(match_dup 2) (match_dup 3)]
15858		   UNSPEC_FPREM_U))
15859   (set (reg:CCFP FPSR_REG)
15860	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15861  "TARGET_USE_FANCY_MATH_387
15862   && flag_unsafe_math_optimizations"
15863  "fprem"
15864  [(set_attr "type" "fpspc")
15865   (set_attr "mode" "XF")])
15866
15867(define_expand "fmodsf3"
15868  [(use (match_operand:SF 0 "register_operand" ""))
15869   (use (match_operand:SF 1 "register_operand" ""))
15870   (use (match_operand:SF 2 "register_operand" ""))]
15871  "TARGET_USE_FANCY_MATH_387
15872   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15873   && flag_unsafe_math_optimizations"
15874{
15875  rtx label = gen_label_rtx ();
15876
15877  rtx op1 = gen_reg_rtx (XFmode);
15878  rtx op2 = gen_reg_rtx (XFmode);
15879
15880  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15881  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15882
15883  emit_label (label);
15884
15885  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15886  ix86_emit_fp_unordered_jump (label);
15887
15888  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15889  DONE;
15890})
15891
15892(define_expand "fmoddf3"
15893  [(use (match_operand:DF 0 "register_operand" ""))
15894   (use (match_operand:DF 1 "register_operand" ""))
15895   (use (match_operand:DF 2 "register_operand" ""))]
15896  "TARGET_USE_FANCY_MATH_387
15897   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15898   && flag_unsafe_math_optimizations"
15899{
15900  rtx label = gen_label_rtx ();
15901
15902  rtx op1 = gen_reg_rtx (XFmode);
15903  rtx op2 = gen_reg_rtx (XFmode);
15904
15905  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15906  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15907
15908  emit_label (label);
15909
15910  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15911  ix86_emit_fp_unordered_jump (label);
15912
15913  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15914  DONE;
15915})
15916
15917(define_expand "fmodxf3"
15918  [(use (match_operand:XF 0 "register_operand" ""))
15919   (use (match_operand:XF 1 "register_operand" ""))
15920   (use (match_operand:XF 2 "register_operand" ""))]
15921  "TARGET_USE_FANCY_MATH_387
15922   && flag_unsafe_math_optimizations"
15923{
15924  rtx label = gen_label_rtx ();
15925
15926  emit_label (label);
15927
15928  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15929			   operands[1], operands[2]));
15930  ix86_emit_fp_unordered_jump (label);
15931
15932  emit_move_insn (operands[0], operands[1]);
15933  DONE;
15934})
15935
15936(define_insn "fprem1xf4"
15937  [(set (match_operand:XF 0 "register_operand" "=f")
15938	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15939		    (match_operand:XF 3 "register_operand" "1")]
15940		   UNSPEC_FPREM1_F))
15941   (set (match_operand:XF 1 "register_operand" "=u")
15942	(unspec:XF [(match_dup 2) (match_dup 3)]
15943		   UNSPEC_FPREM1_U))
15944   (set (reg:CCFP FPSR_REG)
15945	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15946  "TARGET_USE_FANCY_MATH_387
15947   && flag_unsafe_math_optimizations"
15948  "fprem1"
15949  [(set_attr "type" "fpspc")
15950   (set_attr "mode" "XF")])
15951
15952(define_expand "dremsf3"
15953  [(use (match_operand:SF 0 "register_operand" ""))
15954   (use (match_operand:SF 1 "register_operand" ""))
15955   (use (match_operand:SF 2 "register_operand" ""))]
15956  "TARGET_USE_FANCY_MATH_387
15957   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15958   && flag_unsafe_math_optimizations"
15959{
15960  rtx label = gen_label_rtx ();
15961
15962  rtx op1 = gen_reg_rtx (XFmode);
15963  rtx op2 = gen_reg_rtx (XFmode);
15964
15965  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15966  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15967
15968  emit_label (label);
15969
15970  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15971  ix86_emit_fp_unordered_jump (label);
15972
15973  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15974  DONE;
15975})
15976
15977(define_expand "dremdf3"
15978  [(use (match_operand:DF 0 "register_operand" ""))
15979   (use (match_operand:DF 1 "register_operand" ""))
15980   (use (match_operand:DF 2 "register_operand" ""))]
15981  "TARGET_USE_FANCY_MATH_387
15982   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15983   && flag_unsafe_math_optimizations"
15984{
15985  rtx label = gen_label_rtx ();
15986
15987  rtx op1 = gen_reg_rtx (XFmode);
15988  rtx op2 = gen_reg_rtx (XFmode);
15989
15990  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15991  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15992
15993  emit_label (label);
15994
15995  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15996  ix86_emit_fp_unordered_jump (label);
15997
15998  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15999  DONE;
16000})
16001
16002(define_expand "dremxf3"
16003  [(use (match_operand:XF 0 "register_operand" ""))
16004   (use (match_operand:XF 1 "register_operand" ""))
16005   (use (match_operand:XF 2 "register_operand" ""))]
16006  "TARGET_USE_FANCY_MATH_387
16007   && flag_unsafe_math_optimizations"
16008{
16009  rtx label = gen_label_rtx ();
16010
16011  emit_label (label);
16012
16013  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16014			    operands[1], operands[2]));
16015  ix86_emit_fp_unordered_jump (label);
16016
16017  emit_move_insn (operands[0], operands[1]);
16018  DONE;
16019})
16020
16021(define_insn "*sindf2"
16022  [(set (match_operand:DF 0 "register_operand" "=f")
16023	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16024  "TARGET_USE_FANCY_MATH_387
16025   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16026   && flag_unsafe_math_optimizations"
16027  "fsin"
16028  [(set_attr "type" "fpspc")
16029   (set_attr "mode" "DF")])
16030
16031(define_insn "*sinsf2"
16032  [(set (match_operand:SF 0 "register_operand" "=f")
16033	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16034  "TARGET_USE_FANCY_MATH_387
16035   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16036   && flag_unsafe_math_optimizations"
16037  "fsin"
16038  [(set_attr "type" "fpspc")
16039   (set_attr "mode" "SF")])
16040
16041(define_insn "*sinextendsfdf2"
16042  [(set (match_operand:DF 0 "register_operand" "=f")
16043	(unspec:DF [(float_extend:DF
16044		     (match_operand:SF 1 "register_operand" "0"))]
16045		   UNSPEC_SIN))]
16046  "TARGET_USE_FANCY_MATH_387
16047   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048   && flag_unsafe_math_optimizations"
16049  "fsin"
16050  [(set_attr "type" "fpspc")
16051   (set_attr "mode" "DF")])
16052
16053(define_insn "*sinxf2"
16054  [(set (match_operand:XF 0 "register_operand" "=f")
16055	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16056  "TARGET_USE_FANCY_MATH_387
16057   && flag_unsafe_math_optimizations"
16058  "fsin"
16059  [(set_attr "type" "fpspc")
16060   (set_attr "mode" "XF")])
16061
16062(define_insn "*cosdf2"
16063  [(set (match_operand:DF 0 "register_operand" "=f")
16064	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16065  "TARGET_USE_FANCY_MATH_387
16066   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16067   && flag_unsafe_math_optimizations"
16068  "fcos"
16069  [(set_attr "type" "fpspc")
16070   (set_attr "mode" "DF")])
16071
16072(define_insn "*cossf2"
16073  [(set (match_operand:SF 0 "register_operand" "=f")
16074	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16075  "TARGET_USE_FANCY_MATH_387
16076   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16077   && flag_unsafe_math_optimizations"
16078  "fcos"
16079  [(set_attr "type" "fpspc")
16080   (set_attr "mode" "SF")])
16081
16082(define_insn "*cosextendsfdf2"
16083  [(set (match_operand:DF 0 "register_operand" "=f")
16084	(unspec:DF [(float_extend:DF
16085		     (match_operand:SF 1 "register_operand" "0"))]
16086		   UNSPEC_COS))]
16087  "TARGET_USE_FANCY_MATH_387
16088   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16089   && flag_unsafe_math_optimizations"
16090  "fcos"
16091  [(set_attr "type" "fpspc")
16092   (set_attr "mode" "DF")])
16093
16094(define_insn "*cosxf2"
16095  [(set (match_operand:XF 0 "register_operand" "=f")
16096	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16097  "TARGET_USE_FANCY_MATH_387
16098   && flag_unsafe_math_optimizations"
16099  "fcos"
16100  [(set_attr "type" "fpspc")
16101   (set_attr "mode" "XF")])
16102
16103;; With sincos pattern defined, sin and cos builtin function will be
16104;; expanded to sincos pattern with one of its outputs left unused. 
16105;; Cse pass  will detected, if two sincos patterns can be combined,
16106;; otherwise sincos pattern will be split back to sin or cos pattern,
16107;; depending on the unused output.
16108
16109(define_insn "sincosdf3"
16110  [(set (match_operand:DF 0 "register_operand" "=f")
16111	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16112		   UNSPEC_SINCOS_COS))
16113   (set (match_operand:DF 1 "register_operand" "=u")
16114        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16115  "TARGET_USE_FANCY_MATH_387
16116   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16117   && flag_unsafe_math_optimizations"
16118  "fsincos"
16119  [(set_attr "type" "fpspc")
16120   (set_attr "mode" "DF")])
16121
16122(define_split
16123  [(set (match_operand:DF 0 "register_operand" "")
16124	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
16125		   UNSPEC_SINCOS_COS))
16126   (set (match_operand:DF 1 "register_operand" "")
16127	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16128  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16129   && !reload_completed && !reload_in_progress"
16130  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16131  "")
16132
16133(define_split
16134  [(set (match_operand:DF 0 "register_operand" "")
16135	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
16136		   UNSPEC_SINCOS_COS))
16137   (set (match_operand:DF 1 "register_operand" "")
16138	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16139  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16140   && !reload_completed && !reload_in_progress"
16141  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16142  "")
16143
16144(define_insn "sincossf3"
16145  [(set (match_operand:SF 0 "register_operand" "=f")
16146	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16147		   UNSPEC_SINCOS_COS))
16148   (set (match_operand:SF 1 "register_operand" "=u")
16149        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16150  "TARGET_USE_FANCY_MATH_387
16151   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16152   && flag_unsafe_math_optimizations"
16153  "fsincos"
16154  [(set_attr "type" "fpspc")
16155   (set_attr "mode" "SF")])
16156
16157(define_split
16158  [(set (match_operand:SF 0 "register_operand" "")
16159	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
16160		   UNSPEC_SINCOS_COS))
16161   (set (match_operand:SF 1 "register_operand" "")
16162	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16163  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16164   && !reload_completed && !reload_in_progress"
16165  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16166  "")
16167
16168(define_split
16169  [(set (match_operand:SF 0 "register_operand" "")
16170	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
16171		   UNSPEC_SINCOS_COS))
16172   (set (match_operand:SF 1 "register_operand" "")
16173	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16174  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16175   && !reload_completed && !reload_in_progress"
16176  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16177  "")
16178
16179(define_insn "*sincosextendsfdf3"
16180  [(set (match_operand:DF 0 "register_operand" "=f")
16181	(unspec:DF [(float_extend:DF
16182		     (match_operand:SF 2 "register_operand" "0"))]
16183		   UNSPEC_SINCOS_COS))
16184   (set (match_operand:DF 1 "register_operand" "=u")
16185        (unspec:DF [(float_extend:DF
16186		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16187  "TARGET_USE_FANCY_MATH_387
16188   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16189   && flag_unsafe_math_optimizations"
16190  "fsincos"
16191  [(set_attr "type" "fpspc")
16192   (set_attr "mode" "DF")])
16193
16194(define_split
16195  [(set (match_operand:DF 0 "register_operand" "")
16196	(unspec:DF [(float_extend:DF
16197		     (match_operand:SF 2 "register_operand" ""))]
16198		   UNSPEC_SINCOS_COS))
16199   (set (match_operand:DF 1 "register_operand" "")
16200        (unspec:DF [(float_extend:DF
16201		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16202  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16203   && !reload_completed && !reload_in_progress"
16204  [(set (match_dup 1) (unspec:DF [(float_extend:DF
16205				   (match_dup 2))] UNSPEC_SIN))]
16206  "")
16207
16208(define_split
16209  [(set (match_operand:DF 0 "register_operand" "")
16210	(unspec:DF [(float_extend:DF
16211		     (match_operand:SF 2 "register_operand" ""))]
16212		   UNSPEC_SINCOS_COS))
16213   (set (match_operand:DF 1 "register_operand" "")
16214        (unspec:DF [(float_extend:DF
16215		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16216  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16217   && !reload_completed && !reload_in_progress"
16218  [(set (match_dup 0) (unspec:DF [(float_extend:DF
16219				   (match_dup 2))] UNSPEC_COS))]
16220  "")
16221
16222(define_insn "sincosxf3"
16223  [(set (match_operand:XF 0 "register_operand" "=f")
16224	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16225		   UNSPEC_SINCOS_COS))
16226   (set (match_operand:XF 1 "register_operand" "=u")
16227        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16228  "TARGET_USE_FANCY_MATH_387
16229   && flag_unsafe_math_optimizations"
16230  "fsincos"
16231  [(set_attr "type" "fpspc")
16232   (set_attr "mode" "XF")])
16233
16234(define_split
16235  [(set (match_operand:XF 0 "register_operand" "")
16236	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
16237		   UNSPEC_SINCOS_COS))
16238   (set (match_operand:XF 1 "register_operand" "")
16239	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16240  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16241   && !reload_completed && !reload_in_progress"
16242  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16243  "")
16244
16245(define_split
16246  [(set (match_operand:XF 0 "register_operand" "")
16247	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
16248		   UNSPEC_SINCOS_COS))
16249   (set (match_operand:XF 1 "register_operand" "")
16250	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16251  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16252   && !reload_completed && !reload_in_progress"
16253  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16254  "")
16255
16256(define_insn "*tandf3_1"
16257  [(set (match_operand:DF 0 "register_operand" "=f")
16258	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16259		   UNSPEC_TAN_ONE))
16260   (set (match_operand:DF 1 "register_operand" "=u")
16261        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16262  "TARGET_USE_FANCY_MATH_387
16263   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16264   && flag_unsafe_math_optimizations"
16265  "fptan"
16266  [(set_attr "type" "fpspc")
16267   (set_attr "mode" "DF")])
16268
16269;; optimize sequence: fptan
16270;;		      fstp    %st(0)
16271;;		      fld1
16272;; into fptan insn.
16273
16274(define_peephole2
16275  [(parallel[(set (match_operand:DF 0 "register_operand" "")
16276		  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16277			     UNSPEC_TAN_ONE))
16278	     (set (match_operand:DF 1 "register_operand" "")
16279		  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16280   (set (match_dup 0)
16281        (match_operand:DF 3 "immediate_operand" ""))]
16282  "standard_80387_constant_p (operands[3]) == 2"
16283  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16284   	     (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16285  "")
16286
16287(define_expand "tandf2"
16288  [(parallel [(set (match_dup 2)
16289		   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16290			      UNSPEC_TAN_ONE))
16291	      (set (match_operand:DF 0 "register_operand" "")
16292		   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16293  "TARGET_USE_FANCY_MATH_387
16294   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16295   && flag_unsafe_math_optimizations"
16296{
16297  operands[2] = gen_reg_rtx (DFmode);
16298})
16299
16300(define_insn "*tansf3_1"
16301  [(set (match_operand:SF 0 "register_operand" "=f")
16302	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16303		   UNSPEC_TAN_ONE))
16304   (set (match_operand:SF 1 "register_operand" "=u")
16305        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16306  "TARGET_USE_FANCY_MATH_387
16307   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16308   && flag_unsafe_math_optimizations"
16309  "fptan"
16310  [(set_attr "type" "fpspc")
16311   (set_attr "mode" "SF")])
16312
16313;; optimize sequence: fptan
16314;;		      fstp    %st(0)
16315;;		      fld1
16316;; into fptan insn.
16317
16318(define_peephole2
16319  [(parallel[(set (match_operand:SF 0 "register_operand" "")
16320		  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16321			     UNSPEC_TAN_ONE))
16322	     (set (match_operand:SF 1 "register_operand" "")
16323		  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16324   (set (match_dup 0)
16325        (match_operand:SF 3 "immediate_operand" ""))]
16326  "standard_80387_constant_p (operands[3]) == 2"
16327  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16328   	     (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16329  "")
16330
16331(define_expand "tansf2"
16332  [(parallel [(set (match_dup 2)
16333		   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16334			      UNSPEC_TAN_ONE))
16335	      (set (match_operand:SF 0 "register_operand" "")
16336		   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16337  "TARGET_USE_FANCY_MATH_387
16338   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16339   && flag_unsafe_math_optimizations"
16340{
16341  operands[2] = gen_reg_rtx (SFmode);
16342})
16343
16344(define_insn "*tanxf3_1"
16345  [(set (match_operand:XF 0 "register_operand" "=f")
16346	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16347		   UNSPEC_TAN_ONE))
16348   (set (match_operand:XF 1 "register_operand" "=u")
16349        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16350  "TARGET_USE_FANCY_MATH_387
16351   && flag_unsafe_math_optimizations"
16352  "fptan"
16353  [(set_attr "type" "fpspc")
16354   (set_attr "mode" "XF")])
16355
16356;; optimize sequence: fptan
16357;;		      fstp    %st(0)
16358;;		      fld1
16359;; into fptan insn.
16360
16361(define_peephole2
16362  [(parallel[(set (match_operand:XF 0 "register_operand" "")
16363		  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16364			     UNSPEC_TAN_ONE))
16365	     (set (match_operand:XF 1 "register_operand" "")
16366		  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16367   (set (match_dup 0)
16368        (match_operand:XF 3 "immediate_operand" ""))]
16369  "standard_80387_constant_p (operands[3]) == 2"
16370  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16371   	     (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16372  "")
16373
16374(define_expand "tanxf2"
16375  [(parallel [(set (match_dup 2)
16376		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16377			      UNSPEC_TAN_ONE))
16378	      (set (match_operand:XF 0 "register_operand" "")
16379		   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16380  "TARGET_USE_FANCY_MATH_387
16381   && flag_unsafe_math_optimizations"
16382{
16383  operands[2] = gen_reg_rtx (XFmode);
16384})
16385
16386(define_insn "atan2df3_1"
16387  [(set (match_operand:DF 0 "register_operand" "=f")
16388	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
16389		    (match_operand:DF 1 "register_operand" "u")]
16390		   UNSPEC_FPATAN))
16391   (clobber (match_scratch:DF 3 "=1"))]
16392  "TARGET_USE_FANCY_MATH_387
16393   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16394   && flag_unsafe_math_optimizations"
16395  "fpatan"
16396  [(set_attr "type" "fpspc")
16397   (set_attr "mode" "DF")])
16398
16399(define_expand "atan2df3"
16400  [(use (match_operand:DF 0 "register_operand" ""))
16401   (use (match_operand:DF 2 "register_operand" ""))
16402   (use (match_operand:DF 1 "register_operand" ""))]
16403  "TARGET_USE_FANCY_MATH_387
16404   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16405   && flag_unsafe_math_optimizations"
16406{
16407  rtx copy = gen_reg_rtx (DFmode);
16408  emit_move_insn (copy, operands[1]);
16409  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16410  DONE;
16411})
16412
16413(define_expand "atandf2"
16414  [(parallel [(set (match_operand:DF 0 "register_operand" "")
16415		   (unspec:DF [(match_dup 2)
16416			       (match_operand:DF 1 "register_operand" "")]
16417		    UNSPEC_FPATAN))
16418	      (clobber (match_scratch:DF 3 ""))])]
16419  "TARGET_USE_FANCY_MATH_387
16420   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16421   && flag_unsafe_math_optimizations"
16422{
16423  operands[2] = gen_reg_rtx (DFmode);
16424  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16425})
16426
16427(define_insn "atan2sf3_1"
16428  [(set (match_operand:SF 0 "register_operand" "=f")
16429        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16430		    (match_operand:SF 1 "register_operand" "u")]
16431		   UNSPEC_FPATAN))
16432   (clobber (match_scratch:SF 3 "=1"))]
16433  "TARGET_USE_FANCY_MATH_387
16434   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16435   && flag_unsafe_math_optimizations"
16436  "fpatan"
16437  [(set_attr "type" "fpspc")
16438   (set_attr "mode" "SF")])
16439
16440(define_expand "atan2sf3"
16441  [(use (match_operand:SF 0 "register_operand" ""))
16442   (use (match_operand:SF 2 "register_operand" ""))
16443   (use (match_operand:SF 1 "register_operand" ""))]
16444  "TARGET_USE_FANCY_MATH_387
16445   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16446   && flag_unsafe_math_optimizations"
16447{
16448  rtx copy = gen_reg_rtx (SFmode);
16449  emit_move_insn (copy, operands[1]);
16450  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16451  DONE;
16452})
16453
16454(define_expand "atansf2"
16455  [(parallel [(set (match_operand:SF 0 "register_operand" "")
16456		   (unspec:SF [(match_dup 2)
16457			       (match_operand:SF 1 "register_operand" "")]
16458		    UNSPEC_FPATAN))
16459	      (clobber (match_scratch:SF 3 ""))])]
16460  "TARGET_USE_FANCY_MATH_387
16461   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16462   && flag_unsafe_math_optimizations"
16463{
16464  operands[2] = gen_reg_rtx (SFmode);
16465  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16466})
16467
16468(define_insn "atan2xf3_1"
16469  [(set (match_operand:XF 0 "register_operand" "=f")
16470        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16471	            (match_operand:XF 1 "register_operand" "u")]
16472	           UNSPEC_FPATAN))
16473   (clobber (match_scratch:XF 3 "=1"))]
16474  "TARGET_USE_FANCY_MATH_387
16475   && flag_unsafe_math_optimizations"
16476  "fpatan"
16477  [(set_attr "type" "fpspc")
16478   (set_attr "mode" "XF")])
16479
16480(define_expand "atan2xf3"
16481  [(use (match_operand:XF 0 "register_operand" ""))
16482   (use (match_operand:XF 2 "register_operand" ""))
16483   (use (match_operand:XF 1 "register_operand" ""))]
16484  "TARGET_USE_FANCY_MATH_387
16485   && flag_unsafe_math_optimizations"
16486{
16487  rtx copy = gen_reg_rtx (XFmode);
16488  emit_move_insn (copy, operands[1]);
16489  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16490  DONE;
16491})
16492
16493(define_expand "atanxf2"
16494  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16495		   (unspec:XF [(match_dup 2)
16496			       (match_operand:XF 1 "register_operand" "")]
16497		    UNSPEC_FPATAN))
16498	      (clobber (match_scratch:XF 3 ""))])]
16499  "TARGET_USE_FANCY_MATH_387
16500   && flag_unsafe_math_optimizations"
16501{
16502  operands[2] = gen_reg_rtx (XFmode);
16503  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16504})
16505
16506(define_expand "asindf2"
16507  [(set (match_dup 2)
16508	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16509   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16510   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16511   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16512   (parallel [(set (match_dup 7)
16513        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16514			      UNSPEC_FPATAN))
16515   	      (clobber (match_scratch:XF 8 ""))])
16516   (set (match_operand:DF 0 "register_operand" "")
16517	(float_truncate:DF (match_dup 7)))]
16518  "TARGET_USE_FANCY_MATH_387
16519   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16520   && flag_unsafe_math_optimizations"
16521{
16522  int i;
16523
16524  for (i=2; i<8; i++)
16525    operands[i] = gen_reg_rtx (XFmode);
16526
16527  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16528})
16529
16530(define_expand "asinsf2"
16531  [(set (match_dup 2)
16532	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16533   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16534   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16535   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16536   (parallel [(set (match_dup 7)
16537        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16538			      UNSPEC_FPATAN))
16539   	      (clobber (match_scratch:XF 8 ""))])
16540   (set (match_operand:SF 0 "register_operand" "")
16541	(float_truncate:SF (match_dup 7)))]
16542  "TARGET_USE_FANCY_MATH_387
16543   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16544   && flag_unsafe_math_optimizations"
16545{
16546  int i;
16547
16548  for (i=2; i<8; i++)
16549    operands[i] = gen_reg_rtx (XFmode);
16550
16551  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16552})
16553
16554(define_expand "asinxf2"
16555  [(set (match_dup 2)
16556	(mult:XF (match_operand:XF 1 "register_operand" "")
16557		 (match_dup 1)))
16558   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16559   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16560   (parallel [(set (match_operand:XF 0 "register_operand" "")
16561        	   (unspec:XF [(match_dup 5) (match_dup 1)]
16562			      UNSPEC_FPATAN))
16563   	      (clobber (match_scratch:XF 6 ""))])]
16564  "TARGET_USE_FANCY_MATH_387
16565   && flag_unsafe_math_optimizations"
16566{
16567  int i;
16568
16569  for (i=2; i<6; i++)
16570    operands[i] = gen_reg_rtx (XFmode);
16571
16572  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16573})
16574
16575(define_expand "acosdf2"
16576  [(set (match_dup 2)
16577	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16578   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16579   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16580   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16581   (parallel [(set (match_dup 7)
16582        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16583			      UNSPEC_FPATAN))
16584   	      (clobber (match_scratch:XF 8 ""))])
16585   (set (match_operand:DF 0 "register_operand" "")
16586	(float_truncate:DF (match_dup 7)))]
16587  "TARGET_USE_FANCY_MATH_387
16588   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16589   && flag_unsafe_math_optimizations"
16590{
16591  int i;
16592
16593  for (i=2; i<8; i++)
16594    operands[i] = gen_reg_rtx (XFmode);
16595
16596  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16597})
16598
16599(define_expand "acossf2"
16600  [(set (match_dup 2)
16601	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16602   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16603   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16604   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16605   (parallel [(set (match_dup 7)
16606        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16607			      UNSPEC_FPATAN))
16608   	      (clobber (match_scratch:XF 8 ""))])
16609   (set (match_operand:SF 0 "register_operand" "")
16610	(float_truncate:SF (match_dup 7)))]
16611  "TARGET_USE_FANCY_MATH_387
16612   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16613   && flag_unsafe_math_optimizations"
16614{
16615  int i;
16616
16617  for (i=2; i<8; i++)
16618    operands[i] = gen_reg_rtx (XFmode);
16619
16620  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16621})
16622
16623(define_expand "acosxf2"
16624  [(set (match_dup 2)
16625	(mult:XF (match_operand:XF 1 "register_operand" "")
16626		 (match_dup 1)))
16627   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16628   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16629   (parallel [(set (match_operand:XF 0 "register_operand" "")
16630        	   (unspec:XF [(match_dup 1) (match_dup 5)]
16631			      UNSPEC_FPATAN))
16632   	      (clobber (match_scratch:XF 6 ""))])]
16633  "TARGET_USE_FANCY_MATH_387
16634   && flag_unsafe_math_optimizations"
16635{
16636  int i;
16637
16638  for (i=2; i<6; i++)
16639    operands[i] = gen_reg_rtx (XFmode);
16640
16641  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16642})
16643
16644(define_insn "fyl2x_xf3"
16645  [(set (match_operand:XF 0 "register_operand" "=f")
16646        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16647		    (match_operand:XF 1 "register_operand" "u")]
16648	           UNSPEC_FYL2X))
16649   (clobber (match_scratch:XF 3 "=1"))]
16650  "TARGET_USE_FANCY_MATH_387
16651   && flag_unsafe_math_optimizations"
16652  "fyl2x"
16653  [(set_attr "type" "fpspc")
16654   (set_attr "mode" "XF")])
16655
16656(define_expand "logsf2"
16657  [(set (match_dup 2)
16658	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16659   (parallel [(set (match_dup 4)
16660		   (unspec:XF [(match_dup 2)
16661			       (match_dup 3)] UNSPEC_FYL2X))
16662	      (clobber (match_scratch:XF 5 ""))])
16663   (set (match_operand:SF 0 "register_operand" "")
16664	(float_truncate:SF (match_dup 4)))]
16665  "TARGET_USE_FANCY_MATH_387
16666   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16667   && flag_unsafe_math_optimizations"
16668{
16669  rtx temp;
16670
16671  operands[2] = gen_reg_rtx (XFmode);
16672  operands[3] = gen_reg_rtx (XFmode);
16673  operands[4] = gen_reg_rtx (XFmode);
16674
16675  temp = standard_80387_constant_rtx (4); /* fldln2 */
16676  emit_move_insn (operands[3], temp);
16677})
16678
16679(define_expand "logdf2"
16680  [(set (match_dup 2)
16681	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16682   (parallel [(set (match_dup 4)
16683		   (unspec:XF [(match_dup 2)
16684			       (match_dup 3)] UNSPEC_FYL2X))
16685	      (clobber (match_scratch:XF 5 ""))])
16686   (set (match_operand:DF 0 "register_operand" "")
16687	(float_truncate:DF (match_dup 4)))]
16688  "TARGET_USE_FANCY_MATH_387
16689   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16690   && flag_unsafe_math_optimizations"
16691{
16692  rtx temp;
16693
16694  operands[2] = gen_reg_rtx (XFmode);
16695  operands[3] = gen_reg_rtx (XFmode);
16696  operands[4] = gen_reg_rtx (XFmode);
16697
16698  temp = standard_80387_constant_rtx (4); /* fldln2 */
16699  emit_move_insn (operands[3], temp);
16700})
16701
16702(define_expand "logxf2"
16703  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16704		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16705			       (match_dup 2)] UNSPEC_FYL2X))
16706	      (clobber (match_scratch:XF 3 ""))])]
16707  "TARGET_USE_FANCY_MATH_387
16708   && flag_unsafe_math_optimizations"
16709{
16710  rtx temp;
16711
16712  operands[2] = gen_reg_rtx (XFmode);
16713  temp = standard_80387_constant_rtx (4); /* fldln2 */
16714  emit_move_insn (operands[2], temp);
16715})
16716
16717(define_expand "log10sf2"
16718  [(set (match_dup 2)
16719	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16720   (parallel [(set (match_dup 4)
16721		   (unspec:XF [(match_dup 2)
16722			       (match_dup 3)] UNSPEC_FYL2X))
16723	      (clobber (match_scratch:XF 5 ""))])
16724   (set (match_operand:SF 0 "register_operand" "")
16725	(float_truncate:SF (match_dup 4)))]
16726  "TARGET_USE_FANCY_MATH_387
16727   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16728   && flag_unsafe_math_optimizations"
16729{
16730  rtx temp;
16731
16732  operands[2] = gen_reg_rtx (XFmode);
16733  operands[3] = gen_reg_rtx (XFmode);
16734  operands[4] = gen_reg_rtx (XFmode);
16735
16736  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16737  emit_move_insn (operands[3], temp);
16738})
16739
16740(define_expand "log10df2"
16741  [(set (match_dup 2)
16742	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16743   (parallel [(set (match_dup 4)
16744		   (unspec:XF [(match_dup 2)
16745			       (match_dup 3)] UNSPEC_FYL2X))
16746	      (clobber (match_scratch:XF 5 ""))])
16747   (set (match_operand:DF 0 "register_operand" "")
16748	(float_truncate:DF (match_dup 4)))]
16749  "TARGET_USE_FANCY_MATH_387
16750   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16751   && flag_unsafe_math_optimizations"
16752{
16753  rtx temp;
16754
16755  operands[2] = gen_reg_rtx (XFmode);
16756  operands[3] = gen_reg_rtx (XFmode);
16757  operands[4] = gen_reg_rtx (XFmode);
16758
16759  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16760  emit_move_insn (operands[3], temp);
16761})
16762
16763(define_expand "log10xf2"
16764  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16765		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16766			       (match_dup 2)] UNSPEC_FYL2X))
16767	      (clobber (match_scratch:XF 3 ""))])]
16768  "TARGET_USE_FANCY_MATH_387
16769   && flag_unsafe_math_optimizations"
16770{
16771  rtx temp;
16772
16773  operands[2] = gen_reg_rtx (XFmode);
16774  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16775  emit_move_insn (operands[2], temp);
16776})
16777
16778(define_expand "log2sf2"
16779  [(set (match_dup 2)
16780	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16781   (parallel [(set (match_dup 4)
16782		   (unspec:XF [(match_dup 2)
16783			       (match_dup 3)] UNSPEC_FYL2X))
16784	      (clobber (match_scratch:XF 5 ""))])
16785   (set (match_operand:SF 0 "register_operand" "")
16786	(float_truncate:SF (match_dup 4)))]
16787  "TARGET_USE_FANCY_MATH_387
16788   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16789   && flag_unsafe_math_optimizations"
16790{
16791  operands[2] = gen_reg_rtx (XFmode);
16792  operands[3] = gen_reg_rtx (XFmode);
16793  operands[4] = gen_reg_rtx (XFmode);
16794
16795  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16796})
16797
16798(define_expand "log2df2"
16799  [(set (match_dup 2)
16800	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16801   (parallel [(set (match_dup 4)
16802		   (unspec:XF [(match_dup 2)
16803			       (match_dup 3)] UNSPEC_FYL2X))
16804	      (clobber (match_scratch:XF 5 ""))])
16805   (set (match_operand:DF 0 "register_operand" "")
16806	(float_truncate:DF (match_dup 4)))]
16807  "TARGET_USE_FANCY_MATH_387
16808   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16809   && flag_unsafe_math_optimizations"
16810{
16811  operands[2] = gen_reg_rtx (XFmode);
16812  operands[3] = gen_reg_rtx (XFmode);
16813  operands[4] = gen_reg_rtx (XFmode);
16814
16815  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16816})
16817
16818(define_expand "log2xf2"
16819  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16820		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16821			       (match_dup 2)] UNSPEC_FYL2X))
16822	      (clobber (match_scratch:XF 3 ""))])]
16823  "TARGET_USE_FANCY_MATH_387
16824   && flag_unsafe_math_optimizations"
16825{
16826  operands[2] = gen_reg_rtx (XFmode);
16827  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16828})
16829
16830(define_insn "fyl2xp1_xf3"
16831  [(set (match_operand:XF 0 "register_operand" "=f")
16832        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16833		    (match_operand:XF 1 "register_operand" "u")]
16834	           UNSPEC_FYL2XP1))
16835   (clobber (match_scratch:XF 3 "=1"))]
16836  "TARGET_USE_FANCY_MATH_387
16837   && flag_unsafe_math_optimizations"
16838  "fyl2xp1"
16839  [(set_attr "type" "fpspc")
16840   (set_attr "mode" "XF")])
16841
16842(define_expand "log1psf2"
16843  [(use (match_operand:SF 0 "register_operand" ""))
16844   (use (match_operand:SF 1 "register_operand" ""))]
16845  "TARGET_USE_FANCY_MATH_387
16846   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16847   && flag_unsafe_math_optimizations"
16848{
16849  rtx op0 = gen_reg_rtx (XFmode);
16850  rtx op1 = gen_reg_rtx (XFmode);
16851
16852  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16853  ix86_emit_i387_log1p (op0, op1);
16854  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16855  DONE;
16856})
16857
16858(define_expand "log1pdf2"
16859  [(use (match_operand:DF 0 "register_operand" ""))
16860   (use (match_operand:DF 1 "register_operand" ""))]
16861  "TARGET_USE_FANCY_MATH_387
16862   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16863   && flag_unsafe_math_optimizations"
16864{
16865  rtx op0 = gen_reg_rtx (XFmode);
16866  rtx op1 = gen_reg_rtx (XFmode);
16867
16868  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16869  ix86_emit_i387_log1p (op0, op1);
16870  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16871  DONE;
16872})
16873
16874(define_expand "log1pxf2"
16875  [(use (match_operand:XF 0 "register_operand" ""))
16876   (use (match_operand:XF 1 "register_operand" ""))]
16877  "TARGET_USE_FANCY_MATH_387
16878   && flag_unsafe_math_optimizations"
16879{
16880  ix86_emit_i387_log1p (operands[0], operands[1]);
16881  DONE;
16882})
16883
16884(define_insn "*fxtractxf3"
16885  [(set (match_operand:XF 0 "register_operand" "=f")
16886	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16887		   UNSPEC_XTRACT_FRACT))
16888   (set (match_operand:XF 1 "register_operand" "=u")
16889        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16890  "TARGET_USE_FANCY_MATH_387
16891   && flag_unsafe_math_optimizations"
16892  "fxtract"
16893  [(set_attr "type" "fpspc")
16894   (set_attr "mode" "XF")])
16895
16896(define_expand "logbsf2"
16897  [(set (match_dup 2)
16898	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16899   (parallel [(set (match_dup 3)
16900		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16901	      (set (match_dup 4)
16902		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16903   (set (match_operand:SF 0 "register_operand" "")
16904	(float_truncate:SF (match_dup 4)))]
16905  "TARGET_USE_FANCY_MATH_387
16906   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16907   && flag_unsafe_math_optimizations"
16908{
16909  operands[2] = gen_reg_rtx (XFmode);
16910  operands[3] = gen_reg_rtx (XFmode);
16911  operands[4] = gen_reg_rtx (XFmode);
16912})
16913
16914(define_expand "logbdf2"
16915  [(set (match_dup 2)
16916	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16917   (parallel [(set (match_dup 3)
16918		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16919	      (set (match_dup 4)
16920		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16921   (set (match_operand:DF 0 "register_operand" "")
16922	(float_truncate:DF (match_dup 4)))]
16923  "TARGET_USE_FANCY_MATH_387
16924   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16925   && flag_unsafe_math_optimizations"
16926{
16927  operands[2] = gen_reg_rtx (XFmode);
16928  operands[3] = gen_reg_rtx (XFmode);
16929  operands[4] = gen_reg_rtx (XFmode);
16930})
16931
16932(define_expand "logbxf2"
16933  [(parallel [(set (match_dup 2)
16934		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16935			      UNSPEC_XTRACT_FRACT))
16936	      (set (match_operand:XF 0 "register_operand" "")
16937		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16938  "TARGET_USE_FANCY_MATH_387
16939   && flag_unsafe_math_optimizations"
16940{
16941  operands[2] = gen_reg_rtx (XFmode);
16942})
16943
16944(define_expand "ilogbsi2"
16945  [(parallel [(set (match_dup 2)
16946		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16947			      UNSPEC_XTRACT_FRACT))
16948	      (set (match_operand:XF 3 "register_operand" "")
16949		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16950   (parallel [(set (match_operand:SI 0 "register_operand" "")
16951	           (fix:SI (match_dup 3)))
16952	      (clobber (reg:CC FLAGS_REG))])]
16953  "TARGET_USE_FANCY_MATH_387
16954   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16955   && flag_unsafe_math_optimizations"
16956{
16957  operands[2] = gen_reg_rtx (XFmode);
16958  operands[3] = gen_reg_rtx (XFmode);
16959})
16960
16961(define_insn "*f2xm1xf2"
16962  [(set (match_operand:XF 0 "register_operand" "=f")
16963	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16964	 UNSPEC_F2XM1))]
16965  "TARGET_USE_FANCY_MATH_387
16966   && flag_unsafe_math_optimizations"
16967  "f2xm1"
16968  [(set_attr "type" "fpspc")
16969   (set_attr "mode" "XF")])
16970
16971(define_insn "*fscalexf4"
16972  [(set (match_operand:XF 0 "register_operand" "=f")
16973	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16974		    (match_operand:XF 3 "register_operand" "1")]
16975		   UNSPEC_FSCALE_FRACT))
16976   (set (match_operand:XF 1 "register_operand" "=u")
16977	(unspec:XF [(match_dup 2) (match_dup 3)]
16978		   UNSPEC_FSCALE_EXP))]
16979  "TARGET_USE_FANCY_MATH_387
16980   && flag_unsafe_math_optimizations"
16981  "fscale"
16982  [(set_attr "type" "fpspc")
16983   (set_attr "mode" "XF")])
16984
16985(define_expand "expsf2"
16986  [(set (match_dup 2)
16987	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16988   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16989   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16990   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16991   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16992   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16993   (parallel [(set (match_dup 10)
16994		   (unspec:XF [(match_dup 9) (match_dup 5)]
16995			      UNSPEC_FSCALE_FRACT))
16996	      (set (match_dup 11)
16997		   (unspec:XF [(match_dup 9) (match_dup 5)]
16998			      UNSPEC_FSCALE_EXP))])
16999   (set (match_operand:SF 0 "register_operand" "")
17000	(float_truncate:SF (match_dup 10)))]
17001  "TARGET_USE_FANCY_MATH_387
17002   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17003   && flag_unsafe_math_optimizations"
17004{
17005  rtx temp;
17006  int i;
17007
17008  for (i=2; i<12; i++)
17009    operands[i] = gen_reg_rtx (XFmode);
17010  temp = standard_80387_constant_rtx (5); /* fldl2e */
17011  emit_move_insn (operands[3], temp);
17012  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17013})
17014
17015(define_expand "expdf2"
17016  [(set (match_dup 2)
17017	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17018   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17019   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17020   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17021   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17022   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17023   (parallel [(set (match_dup 10)
17024		   (unspec:XF [(match_dup 9) (match_dup 5)]
17025			      UNSPEC_FSCALE_FRACT))
17026	      (set (match_dup 11)
17027		   (unspec:XF [(match_dup 9) (match_dup 5)]
17028			      UNSPEC_FSCALE_EXP))])
17029   (set (match_operand:DF 0 "register_operand" "")
17030	(float_truncate:DF (match_dup 10)))]
17031  "TARGET_USE_FANCY_MATH_387
17032   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17033   && flag_unsafe_math_optimizations"
17034{
17035  rtx temp;
17036  int i;
17037
17038  for (i=2; i<12; i++)
17039    operands[i] = gen_reg_rtx (XFmode);
17040  temp = standard_80387_constant_rtx (5); /* fldl2e */
17041  emit_move_insn (operands[3], temp);
17042  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17043})
17044
17045(define_expand "expxf2"
17046  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17047			       (match_dup 2)))
17048   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17049   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17050   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17051   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17052   (parallel [(set (match_operand:XF 0 "register_operand" "")
17053		   (unspec:XF [(match_dup 8) (match_dup 4)]
17054			      UNSPEC_FSCALE_FRACT))
17055	      (set (match_dup 9)
17056		   (unspec:XF [(match_dup 8) (match_dup 4)]
17057			      UNSPEC_FSCALE_EXP))])]
17058  "TARGET_USE_FANCY_MATH_387
17059   && flag_unsafe_math_optimizations"
17060{
17061  rtx temp;
17062  int i;
17063
17064  for (i=2; i<10; i++)
17065    operands[i] = gen_reg_rtx (XFmode);
17066  temp = standard_80387_constant_rtx (5); /* fldl2e */
17067  emit_move_insn (operands[2], temp);
17068  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17069})
17070
17071(define_expand "exp10sf2"
17072  [(set (match_dup 2)
17073	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17074   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17075   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17076   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17077   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17078   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17079   (parallel [(set (match_dup 10)
17080		   (unspec:XF [(match_dup 9) (match_dup 5)]
17081			      UNSPEC_FSCALE_FRACT))
17082	      (set (match_dup 11)
17083		   (unspec:XF [(match_dup 9) (match_dup 5)]
17084			      UNSPEC_FSCALE_EXP))])
17085   (set (match_operand:SF 0 "register_operand" "")
17086	(float_truncate:SF (match_dup 10)))]
17087  "TARGET_USE_FANCY_MATH_387
17088   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17089   && flag_unsafe_math_optimizations"
17090{
17091  rtx temp;
17092  int i;
17093
17094  for (i=2; i<12; i++)
17095    operands[i] = gen_reg_rtx (XFmode);
17096  temp = standard_80387_constant_rtx (6); /* fldl2t */
17097  emit_move_insn (operands[3], temp);
17098  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17099})
17100
17101(define_expand "exp10df2"
17102  [(set (match_dup 2)
17103	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17104   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17105   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17106   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17107   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17108   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17109   (parallel [(set (match_dup 10)
17110		   (unspec:XF [(match_dup 9) (match_dup 5)]
17111			      UNSPEC_FSCALE_FRACT))
17112	      (set (match_dup 11)
17113		   (unspec:XF [(match_dup 9) (match_dup 5)]
17114			      UNSPEC_FSCALE_EXP))])
17115   (set (match_operand:DF 0 "register_operand" "")
17116	(float_truncate:DF (match_dup 10)))]
17117  "TARGET_USE_FANCY_MATH_387
17118   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17119   && flag_unsafe_math_optimizations"
17120{
17121  rtx temp;
17122  int i;
17123
17124  for (i=2; i<12; i++)
17125    operands[i] = gen_reg_rtx (XFmode);
17126  temp = standard_80387_constant_rtx (6); /* fldl2t */
17127  emit_move_insn (operands[3], temp);
17128  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17129})
17130
17131(define_expand "exp10xf2"
17132  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17133			       (match_dup 2)))
17134   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17135   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17136   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17137   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17138   (parallel [(set (match_operand:XF 0 "register_operand" "")
17139		   (unspec:XF [(match_dup 8) (match_dup 4)]
17140			      UNSPEC_FSCALE_FRACT))
17141	      (set (match_dup 9)
17142		   (unspec:XF [(match_dup 8) (match_dup 4)]
17143			      UNSPEC_FSCALE_EXP))])]
17144  "TARGET_USE_FANCY_MATH_387
17145   && flag_unsafe_math_optimizations"
17146{
17147  rtx temp;
17148  int i;
17149
17150  for (i=2; i<10; i++)
17151    operands[i] = gen_reg_rtx (XFmode);
17152  temp = standard_80387_constant_rtx (6); /* fldl2t */
17153  emit_move_insn (operands[2], temp);
17154  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17155})
17156
17157(define_expand "exp2sf2"
17158  [(set (match_dup 2)
17159	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17160   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17161   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17162   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17163   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17164   (parallel [(set (match_dup 8)
17165		   (unspec:XF [(match_dup 7) (match_dup 3)]
17166			      UNSPEC_FSCALE_FRACT))
17167	      (set (match_dup 9)
17168		   (unspec:XF [(match_dup 7) (match_dup 3)]
17169			      UNSPEC_FSCALE_EXP))])
17170   (set (match_operand:SF 0 "register_operand" "")
17171	(float_truncate:SF (match_dup 8)))]
17172  "TARGET_USE_FANCY_MATH_387
17173   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17174   && flag_unsafe_math_optimizations"
17175{
17176  int i;
17177
17178  for (i=2; i<10; i++)
17179    operands[i] = gen_reg_rtx (XFmode);
17180  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17181})
17182
17183(define_expand "exp2df2"
17184  [(set (match_dup 2)
17185	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17186   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17187   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17188   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17189   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17190   (parallel [(set (match_dup 8)
17191		   (unspec:XF [(match_dup 7) (match_dup 3)]
17192			      UNSPEC_FSCALE_FRACT))
17193	      (set (match_dup 9)
17194		   (unspec:XF [(match_dup 7) (match_dup 3)]
17195			      UNSPEC_FSCALE_EXP))])
17196   (set (match_operand:DF 0 "register_operand" "")
17197	(float_truncate:DF (match_dup 8)))]
17198  "TARGET_USE_FANCY_MATH_387
17199   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17200   && flag_unsafe_math_optimizations"
17201{
17202  int i;
17203
17204  for (i=2; i<10; i++)
17205    operands[i] = gen_reg_rtx (XFmode);
17206  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17207})
17208
17209(define_expand "exp2xf2"
17210  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17211   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17212   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17213   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17214   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17215   (parallel [(set (match_operand:XF 0 "register_operand" "")
17216		   (unspec:XF [(match_dup 7) (match_dup 3)]
17217			      UNSPEC_FSCALE_FRACT))
17218	      (set (match_dup 8)
17219		   (unspec:XF [(match_dup 7) (match_dup 3)]
17220			      UNSPEC_FSCALE_EXP))])]
17221  "TARGET_USE_FANCY_MATH_387
17222   && flag_unsafe_math_optimizations"
17223{
17224  int i;
17225
17226  for (i=2; i<9; i++)
17227    operands[i] = gen_reg_rtx (XFmode);
17228  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17229})
17230
17231(define_expand "expm1df2"
17232  [(set (match_dup 2)
17233	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17234   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17235   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17236   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17237   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17238   (parallel [(set (match_dup 8)
17239		   (unspec:XF [(match_dup 7) (match_dup 5)]
17240			      UNSPEC_FSCALE_FRACT))
17241		   (set (match_dup 9)
17242		   (unspec:XF [(match_dup 7) (match_dup 5)]
17243			      UNSPEC_FSCALE_EXP))])
17244   (parallel [(set (match_dup 11)
17245		   (unspec:XF [(match_dup 10) (match_dup 9)]
17246			      UNSPEC_FSCALE_FRACT))
17247	      (set (match_dup 12)
17248		   (unspec:XF [(match_dup 10) (match_dup 9)]
17249			      UNSPEC_FSCALE_EXP))])
17250   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17251   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17252   (set (match_operand:DF 0 "register_operand" "")
17253	(float_truncate:DF (match_dup 14)))]
17254  "TARGET_USE_FANCY_MATH_387
17255   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17256   && flag_unsafe_math_optimizations"
17257{
17258  rtx temp;
17259  int i;
17260
17261  for (i=2; i<15; i++)
17262    operands[i] = gen_reg_rtx (XFmode);
17263  temp = standard_80387_constant_rtx (5); /* fldl2e */
17264  emit_move_insn (operands[3], temp);
17265  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17266})
17267
17268(define_expand "expm1sf2"
17269  [(set (match_dup 2)
17270	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17271   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17272   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17273   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17274   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17275   (parallel [(set (match_dup 8)
17276		   (unspec:XF [(match_dup 7) (match_dup 5)]
17277			      UNSPEC_FSCALE_FRACT))
17278		   (set (match_dup 9)
17279		   (unspec:XF [(match_dup 7) (match_dup 5)]
17280			      UNSPEC_FSCALE_EXP))])
17281   (parallel [(set (match_dup 11)
17282		   (unspec:XF [(match_dup 10) (match_dup 9)]
17283			      UNSPEC_FSCALE_FRACT))
17284	      (set (match_dup 12)
17285		   (unspec:XF [(match_dup 10) (match_dup 9)]
17286			      UNSPEC_FSCALE_EXP))])
17287   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17288   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17289   (set (match_operand:SF 0 "register_operand" "")
17290	(float_truncate:SF (match_dup 14)))]
17291  "TARGET_USE_FANCY_MATH_387
17292   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17293   && flag_unsafe_math_optimizations"
17294{
17295  rtx temp;
17296  int i;
17297
17298  for (i=2; i<15; i++)
17299    operands[i] = gen_reg_rtx (XFmode);
17300  temp = standard_80387_constant_rtx (5); /* fldl2e */
17301  emit_move_insn (operands[3], temp);
17302  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17303})
17304
17305(define_expand "expm1xf2"
17306  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17307			       (match_dup 2)))
17308   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17309   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17310   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17311   (parallel [(set (match_dup 7)
17312		   (unspec:XF [(match_dup 6) (match_dup 4)]
17313			      UNSPEC_FSCALE_FRACT))
17314		   (set (match_dup 8)
17315		   (unspec:XF [(match_dup 6) (match_dup 4)]
17316			      UNSPEC_FSCALE_EXP))])
17317   (parallel [(set (match_dup 10)
17318		   (unspec:XF [(match_dup 9) (match_dup 8)]
17319			      UNSPEC_FSCALE_FRACT))
17320	      (set (match_dup 11)
17321		   (unspec:XF [(match_dup 9) (match_dup 8)]
17322			      UNSPEC_FSCALE_EXP))])
17323   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17324   (set (match_operand:XF 0 "register_operand" "")
17325	(plus:XF (match_dup 12) (match_dup 7)))]
17326  "TARGET_USE_FANCY_MATH_387
17327   && flag_unsafe_math_optimizations"
17328{
17329  rtx temp;
17330  int i;
17331
17332  for (i=2; i<13; i++)
17333    operands[i] = gen_reg_rtx (XFmode);
17334  temp = standard_80387_constant_rtx (5); /* fldl2e */
17335  emit_move_insn (operands[2], temp);
17336  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17337})
17338
17339(define_expand "ldexpdf3"
17340  [(set (match_dup 3)
17341	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17342   (set (match_dup 4)
17343	(float:XF (match_operand:SI 2 "register_operand" "")))
17344   (parallel [(set (match_dup 5)
17345		   (unspec:XF [(match_dup 3) (match_dup 4)]
17346			      UNSPEC_FSCALE_FRACT))
17347	      (set (match_dup 6)
17348		   (unspec:XF [(match_dup 3) (match_dup 4)]
17349			      UNSPEC_FSCALE_EXP))])
17350   (set (match_operand:DF 0 "register_operand" "")
17351	(float_truncate:DF (match_dup 5)))]
17352  "TARGET_USE_FANCY_MATH_387
17353   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17354   && flag_unsafe_math_optimizations"
17355{
17356  int i;
17357
17358  for (i=3; i<7; i++)
17359    operands[i] = gen_reg_rtx (XFmode);
17360})
17361
17362(define_expand "ldexpsf3"
17363  [(set (match_dup 3)
17364	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17365   (set (match_dup 4)
17366	(float:XF (match_operand:SI 2 "register_operand" "")))
17367   (parallel [(set (match_dup 5)
17368		   (unspec:XF [(match_dup 3) (match_dup 4)]
17369			      UNSPEC_FSCALE_FRACT))
17370	      (set (match_dup 6)
17371		   (unspec:XF [(match_dup 3) (match_dup 4)]
17372			      UNSPEC_FSCALE_EXP))])
17373   (set (match_operand:SF 0 "register_operand" "")
17374	(float_truncate:SF (match_dup 5)))]
17375  "TARGET_USE_FANCY_MATH_387
17376   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17377   && flag_unsafe_math_optimizations"
17378{
17379  int i;
17380
17381  for (i=3; i<7; i++)
17382    operands[i] = gen_reg_rtx (XFmode);
17383})
17384
17385(define_expand "ldexpxf3"
17386  [(set (match_dup 3)
17387	(float:XF (match_operand:SI 2 "register_operand" "")))
17388   (parallel [(set (match_operand:XF 0 " register_operand" "")
17389		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
17390			       (match_dup 3)]
17391			      UNSPEC_FSCALE_FRACT))
17392	      (set (match_dup 4)
17393		   (unspec:XF [(match_dup 1) (match_dup 3)]
17394			      UNSPEC_FSCALE_EXP))])]
17395  "TARGET_USE_FANCY_MATH_387
17396   && flag_unsafe_math_optimizations"
17397{
17398  int i;
17399
17400  for (i=3; i<5; i++)
17401    operands[i] = gen_reg_rtx (XFmode);
17402})
17403
17404
17405(define_insn "frndintxf2"
17406  [(set (match_operand:XF 0 "register_operand" "=f")
17407	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17408	 UNSPEC_FRNDINT))]
17409  "TARGET_USE_FANCY_MATH_387
17410   && flag_unsafe_math_optimizations"
17411  "frndint"
17412  [(set_attr "type" "fpspc")
17413   (set_attr "mode" "XF")])
17414
17415(define_expand "rintdf2"
17416  [(use (match_operand:DF 0 "register_operand" ""))
17417   (use (match_operand:DF 1 "register_operand" ""))]
17418  "TARGET_USE_FANCY_MATH_387
17419   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17420   && flag_unsafe_math_optimizations"
17421{
17422  rtx op0 = gen_reg_rtx (XFmode);
17423  rtx op1 = gen_reg_rtx (XFmode);
17424
17425  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17426  emit_insn (gen_frndintxf2 (op0, op1));
17427
17428  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17429  DONE;
17430})
17431
17432(define_expand "rintsf2"
17433  [(use (match_operand:SF 0 "register_operand" ""))
17434   (use (match_operand:SF 1 "register_operand" ""))]
17435  "TARGET_USE_FANCY_MATH_387
17436   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17437   && flag_unsafe_math_optimizations"
17438{
17439  rtx op0 = gen_reg_rtx (XFmode);
17440  rtx op1 = gen_reg_rtx (XFmode);
17441
17442  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17443  emit_insn (gen_frndintxf2 (op0, op1));
17444
17445  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17446  DONE;
17447})
17448
17449(define_expand "rintxf2"
17450  [(use (match_operand:XF 0 "register_operand" ""))
17451   (use (match_operand:XF 1 "register_operand" ""))]
17452  "TARGET_USE_FANCY_MATH_387
17453   && flag_unsafe_math_optimizations"
17454{
17455  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17456  DONE;
17457})
17458
17459(define_insn_and_split "*fistdi2_1"
17460  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17461	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17462	 UNSPEC_FIST))]
17463  "TARGET_USE_FANCY_MATH_387
17464   && flag_unsafe_math_optimizations
17465   && !(reload_completed || reload_in_progress)"
17466  "#"
17467  "&& 1"
17468  [(const_int 0)]
17469{
17470  if (memory_operand (operands[0], VOIDmode))
17471    emit_insn (gen_fistdi2 (operands[0], operands[1]));
17472  else
17473    {
17474      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17475      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17476					 operands[2]));
17477    }
17478  DONE;
17479}
17480  [(set_attr "type" "fpspc")
17481   (set_attr "mode" "DI")])
17482
17483(define_insn "fistdi2"
17484  [(set (match_operand:DI 0 "memory_operand" "=m")
17485	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17486	 UNSPEC_FIST))
17487   (clobber (match_scratch:XF 2 "=&1f"))]
17488  "TARGET_USE_FANCY_MATH_387
17489   && flag_unsafe_math_optimizations"
17490  "* return output_fix_trunc (insn, operands, 0);"
17491  [(set_attr "type" "fpspc")
17492   (set_attr "mode" "DI")])
17493
17494(define_insn "fistdi2_with_temp"
17495  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17496	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17497	 UNSPEC_FIST))
17498   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17499   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17500  "TARGET_USE_FANCY_MATH_387
17501   && flag_unsafe_math_optimizations"
17502  "#"
17503  [(set_attr "type" "fpspc")
17504   (set_attr "mode" "DI")])
17505
17506(define_split 
17507  [(set (match_operand:DI 0 "register_operand" "")
17508	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17509	 UNSPEC_FIST))
17510   (clobber (match_operand:DI 2 "memory_operand" ""))
17511   (clobber (match_scratch 3 ""))]
17512  "reload_completed"
17513  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17514	      (clobber (match_dup 3))])
17515   (set (match_dup 0) (match_dup 2))]
17516  "")
17517
17518(define_split 
17519  [(set (match_operand:DI 0 "memory_operand" "")
17520	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17521	 UNSPEC_FIST))
17522   (clobber (match_operand:DI 2 "memory_operand" ""))
17523   (clobber (match_scratch 3 ""))]
17524  "reload_completed"
17525  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17526	      (clobber (match_dup 3))])]
17527  "")
17528
17529(define_insn_and_split "*fist<mode>2_1"
17530  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17531	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17532	 UNSPEC_FIST))]
17533  "TARGET_USE_FANCY_MATH_387
17534   && flag_unsafe_math_optimizations
17535   && !(reload_completed || reload_in_progress)"
17536  "#"
17537  "&& 1"
17538  [(const_int 0)]
17539{
17540  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17541  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17542					operands[2]));
17543  DONE;
17544}
17545  [(set_attr "type" "fpspc")
17546   (set_attr "mode" "<MODE>")])
17547
17548(define_insn "fist<mode>2"
17549  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17550	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17551	 UNSPEC_FIST))]
17552  "TARGET_USE_FANCY_MATH_387
17553   && flag_unsafe_math_optimizations"
17554  "* return output_fix_trunc (insn, operands, 0);"
17555  [(set_attr "type" "fpspc")
17556   (set_attr "mode" "<MODE>")])
17557
17558(define_insn "fist<mode>2_with_temp"
17559  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17560	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17561	 UNSPEC_FIST))
17562   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17563  "TARGET_USE_FANCY_MATH_387
17564   && flag_unsafe_math_optimizations"
17565  "#"
17566  [(set_attr "type" "fpspc")
17567   (set_attr "mode" "<MODE>")])
17568
17569(define_split 
17570  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17571	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17572	 UNSPEC_FIST))
17573   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17574  "reload_completed"
17575  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17576		       UNSPEC_FIST))
17577   (set (match_dup 0) (match_dup 2))]
17578  "")
17579
17580(define_split 
17581  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17582	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17583	 UNSPEC_FIST))
17584   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17585  "reload_completed"
17586  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17587		       UNSPEC_FIST))]
17588  "")
17589
17590(define_expand "lrint<mode>2"
17591  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17592	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17593	 UNSPEC_FIST))]
17594  "TARGET_USE_FANCY_MATH_387
17595   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17596   && flag_unsafe_math_optimizations"
17597  "")
17598
17599;; Rounding mode control word calculation could clobber FLAGS_REG.
17600(define_insn_and_split "frndintxf2_floor"
17601  [(set (match_operand:XF 0 "register_operand" "=f")
17602	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17603	 UNSPEC_FRNDINT_FLOOR))
17604   (clobber (reg:CC FLAGS_REG))]
17605  "TARGET_USE_FANCY_MATH_387
17606   && flag_unsafe_math_optimizations
17607   && !(reload_completed || reload_in_progress)"
17608  "#"
17609  "&& 1"
17610  [(const_int 0)]
17611{
17612  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17613
17614  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17615  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17616
17617  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17618					operands[2], operands[3]));
17619  DONE;
17620}
17621  [(set_attr "type" "frndint")
17622   (set_attr "i387_cw" "floor")
17623   (set_attr "mode" "XF")])
17624
17625(define_insn "frndintxf2_floor_i387"
17626  [(set (match_operand:XF 0 "register_operand" "=f")
17627	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17628	 UNSPEC_FRNDINT_FLOOR))
17629   (use (match_operand:HI 2 "memory_operand" "m"))
17630   (use (match_operand:HI 3 "memory_operand" "m"))]
17631  "TARGET_USE_FANCY_MATH_387
17632   && flag_unsafe_math_optimizations"
17633  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17634  [(set_attr "type" "frndint")
17635   (set_attr "i387_cw" "floor")
17636   (set_attr "mode" "XF")])
17637
17638(define_expand "floorxf2"
17639  [(use (match_operand:XF 0 "register_operand" ""))
17640   (use (match_operand:XF 1 "register_operand" ""))]
17641  "TARGET_USE_FANCY_MATH_387
17642   && flag_unsafe_math_optimizations"
17643{
17644  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17645  DONE;
17646})
17647
17648(define_expand "floordf2"
17649  [(use (match_operand:DF 0 "register_operand" ""))
17650   (use (match_operand:DF 1 "register_operand" ""))]
17651  "TARGET_USE_FANCY_MATH_387
17652   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17653   && flag_unsafe_math_optimizations"
17654{
17655  rtx op0 = gen_reg_rtx (XFmode);
17656  rtx op1 = gen_reg_rtx (XFmode);
17657
17658  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17659  emit_insn (gen_frndintxf2_floor (op0, op1));
17660
17661  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17662  DONE;
17663})
17664
17665(define_expand "floorsf2"
17666  [(use (match_operand:SF 0 "register_operand" ""))
17667   (use (match_operand:SF 1 "register_operand" ""))]
17668  "TARGET_USE_FANCY_MATH_387
17669   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17670   && flag_unsafe_math_optimizations"
17671{
17672  rtx op0 = gen_reg_rtx (XFmode);
17673  rtx op1 = gen_reg_rtx (XFmode);
17674
17675  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17676  emit_insn (gen_frndintxf2_floor (op0, op1));
17677
17678  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17679  DONE;
17680})
17681
17682(define_insn_and_split "*fist<mode>2_floor_1"
17683  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17684	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17685	 UNSPEC_FIST_FLOOR))
17686   (clobber (reg:CC FLAGS_REG))]
17687  "TARGET_USE_FANCY_MATH_387
17688   && flag_unsafe_math_optimizations
17689   && !(reload_completed || reload_in_progress)"
17690  "#"
17691  "&& 1"
17692  [(const_int 0)]
17693{
17694  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17695
17696  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17697  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17698  if (memory_operand (operands[0], VOIDmode))
17699    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17700				      operands[2], operands[3]));
17701  else
17702    {
17703      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17704      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17705						  operands[2], operands[3],
17706						  operands[4]));
17707    }
17708  DONE;
17709}
17710  [(set_attr "type" "fistp")
17711   (set_attr "i387_cw" "floor")
17712   (set_attr "mode" "<MODE>")])
17713
17714(define_insn "fistdi2_floor"
17715  [(set (match_operand:DI 0 "memory_operand" "=m")
17716	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17717	 UNSPEC_FIST_FLOOR))
17718   (use (match_operand:HI 2 "memory_operand" "m"))
17719   (use (match_operand:HI 3 "memory_operand" "m"))
17720   (clobber (match_scratch:XF 4 "=&1f"))]
17721  "TARGET_USE_FANCY_MATH_387
17722   && flag_unsafe_math_optimizations"
17723  "* return output_fix_trunc (insn, operands, 0);"
17724  [(set_attr "type" "fistp")
17725   (set_attr "i387_cw" "floor")
17726   (set_attr "mode" "DI")])
17727
17728(define_insn "fistdi2_floor_with_temp"
17729  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17730	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17731	 UNSPEC_FIST_FLOOR))
17732   (use (match_operand:HI 2 "memory_operand" "m,m"))
17733   (use (match_operand:HI 3 "memory_operand" "m,m"))
17734   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17735   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17736  "TARGET_USE_FANCY_MATH_387
17737   && flag_unsafe_math_optimizations"
17738  "#"
17739  [(set_attr "type" "fistp")
17740   (set_attr "i387_cw" "floor")
17741   (set_attr "mode" "DI")])
17742
17743(define_split 
17744  [(set (match_operand:DI 0 "register_operand" "")
17745	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17746	 UNSPEC_FIST_FLOOR))
17747   (use (match_operand:HI 2 "memory_operand" ""))
17748   (use (match_operand:HI 3 "memory_operand" ""))
17749   (clobber (match_operand:DI 4 "memory_operand" ""))
17750   (clobber (match_scratch 5 ""))]
17751  "reload_completed"
17752  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17753	      (use (match_dup 2))
17754	      (use (match_dup 3))
17755	      (clobber (match_dup 5))])
17756   (set (match_dup 0) (match_dup 4))]
17757  "")
17758
17759(define_split 
17760  [(set (match_operand:DI 0 "memory_operand" "")
17761	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17762	 UNSPEC_FIST_FLOOR))
17763   (use (match_operand:HI 2 "memory_operand" ""))
17764   (use (match_operand:HI 3 "memory_operand" ""))
17765   (clobber (match_operand:DI 4 "memory_operand" ""))
17766   (clobber (match_scratch 5 ""))]
17767  "reload_completed"
17768  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17769	      (use (match_dup 2))
17770	      (use (match_dup 3))
17771	      (clobber (match_dup 5))])]
17772  "")
17773
17774(define_insn "fist<mode>2_floor"
17775  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17776	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17777	 UNSPEC_FIST_FLOOR))
17778   (use (match_operand:HI 2 "memory_operand" "m"))
17779   (use (match_operand:HI 3 "memory_operand" "m"))]
17780  "TARGET_USE_FANCY_MATH_387
17781   && flag_unsafe_math_optimizations"
17782  "* return output_fix_trunc (insn, operands, 0);"
17783  [(set_attr "type" "fistp")
17784   (set_attr "i387_cw" "floor")
17785   (set_attr "mode" "<MODE>")])
17786
17787(define_insn "fist<mode>2_floor_with_temp"
17788  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17789	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17790	 UNSPEC_FIST_FLOOR))
17791   (use (match_operand:HI 2 "memory_operand" "m,m"))
17792   (use (match_operand:HI 3 "memory_operand" "m,m"))
17793   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17794  "TARGET_USE_FANCY_MATH_387
17795   && flag_unsafe_math_optimizations"
17796  "#"
17797  [(set_attr "type" "fistp")
17798   (set_attr "i387_cw" "floor")
17799   (set_attr "mode" "<MODE>")])
17800
17801(define_split 
17802  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17803	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17804	 UNSPEC_FIST_FLOOR))
17805   (use (match_operand:HI 2 "memory_operand" ""))
17806   (use (match_operand:HI 3 "memory_operand" ""))
17807   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17808  "reload_completed"
17809  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17810				  UNSPEC_FIST_FLOOR))
17811	      (use (match_dup 2))
17812	      (use (match_dup 3))])
17813   (set (match_dup 0) (match_dup 4))]
17814  "")
17815
17816(define_split 
17817  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17818	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17819	 UNSPEC_FIST_FLOOR))
17820   (use (match_operand:HI 2 "memory_operand" ""))
17821   (use (match_operand:HI 3 "memory_operand" ""))
17822   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17823  "reload_completed"
17824  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17825				  UNSPEC_FIST_FLOOR))
17826	      (use (match_dup 2))
17827	      (use (match_dup 3))])]
17828  "")
17829
17830(define_expand "lfloor<mode>2"
17831  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17832		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17833		    UNSPEC_FIST_FLOOR))
17834	      (clobber (reg:CC FLAGS_REG))])]
17835  "TARGET_USE_FANCY_MATH_387
17836   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17837   && flag_unsafe_math_optimizations"
17838  "")
17839
17840;; Rounding mode control word calculation could clobber FLAGS_REG.
17841(define_insn_and_split "frndintxf2_ceil"
17842  [(set (match_operand:XF 0 "register_operand" "=f")
17843	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17844	 UNSPEC_FRNDINT_CEIL))
17845   (clobber (reg:CC FLAGS_REG))]
17846  "TARGET_USE_FANCY_MATH_387
17847   && flag_unsafe_math_optimizations
17848   && !(reload_completed || reload_in_progress)"
17849  "#"
17850  "&& 1"
17851  [(const_int 0)]
17852{
17853  ix86_optimize_mode_switching[I387_CEIL] = 1;
17854
17855  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17856  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17857
17858  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17859				       operands[2], operands[3]));
17860  DONE;
17861}
17862  [(set_attr "type" "frndint")
17863   (set_attr "i387_cw" "ceil")
17864   (set_attr "mode" "XF")])
17865
17866(define_insn "frndintxf2_ceil_i387"
17867  [(set (match_operand:XF 0 "register_operand" "=f")
17868	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17869	 UNSPEC_FRNDINT_CEIL))
17870   (use (match_operand:HI 2 "memory_operand" "m"))
17871   (use (match_operand:HI 3 "memory_operand" "m"))]
17872  "TARGET_USE_FANCY_MATH_387
17873   && flag_unsafe_math_optimizations"
17874  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17875  [(set_attr "type" "frndint")
17876   (set_attr "i387_cw" "ceil")
17877   (set_attr "mode" "XF")])
17878
17879(define_expand "ceilxf2"
17880  [(use (match_operand:XF 0 "register_operand" ""))
17881   (use (match_operand:XF 1 "register_operand" ""))]
17882  "TARGET_USE_FANCY_MATH_387
17883   && flag_unsafe_math_optimizations"
17884{
17885  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17886  DONE;
17887})
17888
17889(define_expand "ceildf2"
17890  [(use (match_operand:DF 0 "register_operand" ""))
17891   (use (match_operand:DF 1 "register_operand" ""))]
17892  "TARGET_USE_FANCY_MATH_387
17893   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17894   && flag_unsafe_math_optimizations"
17895{
17896  rtx op0 = gen_reg_rtx (XFmode);
17897  rtx op1 = gen_reg_rtx (XFmode);
17898
17899  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17900  emit_insn (gen_frndintxf2_ceil (op0, op1));
17901
17902  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17903  DONE;
17904})
17905
17906(define_expand "ceilsf2"
17907  [(use (match_operand:SF 0 "register_operand" ""))
17908   (use (match_operand:SF 1 "register_operand" ""))]
17909  "TARGET_USE_FANCY_MATH_387
17910   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17911   && flag_unsafe_math_optimizations"
17912{
17913  rtx op0 = gen_reg_rtx (XFmode);
17914  rtx op1 = gen_reg_rtx (XFmode);
17915
17916  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17917  emit_insn (gen_frndintxf2_ceil (op0, op1));
17918
17919  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17920  DONE;
17921})
17922
17923(define_insn_and_split "*fist<mode>2_ceil_1"
17924  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17925	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17926	 UNSPEC_FIST_CEIL))
17927   (clobber (reg:CC FLAGS_REG))]
17928  "TARGET_USE_FANCY_MATH_387
17929   && flag_unsafe_math_optimizations
17930   && !(reload_completed || reload_in_progress)"
17931  "#"
17932  "&& 1"
17933  [(const_int 0)]
17934{
17935  ix86_optimize_mode_switching[I387_CEIL] = 1;
17936
17937  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17938  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17939  if (memory_operand (operands[0], VOIDmode))
17940    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17941				     operands[2], operands[3]));
17942  else
17943    {
17944      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17945      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17946						 operands[2], operands[3],
17947						 operands[4]));
17948    }
17949  DONE;
17950}
17951  [(set_attr "type" "fistp")
17952   (set_attr "i387_cw" "ceil")
17953   (set_attr "mode" "<MODE>")])
17954
17955(define_insn "fistdi2_ceil"
17956  [(set (match_operand:DI 0 "memory_operand" "=m")
17957	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17958	 UNSPEC_FIST_CEIL))
17959   (use (match_operand:HI 2 "memory_operand" "m"))
17960   (use (match_operand:HI 3 "memory_operand" "m"))
17961   (clobber (match_scratch:XF 4 "=&1f"))]
17962  "TARGET_USE_FANCY_MATH_387
17963   && flag_unsafe_math_optimizations"
17964  "* return output_fix_trunc (insn, operands, 0);"
17965  [(set_attr "type" "fistp")
17966   (set_attr "i387_cw" "ceil")
17967   (set_attr "mode" "DI")])
17968
17969(define_insn "fistdi2_ceil_with_temp"
17970  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17971	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17972	 UNSPEC_FIST_CEIL))
17973   (use (match_operand:HI 2 "memory_operand" "m,m"))
17974   (use (match_operand:HI 3 "memory_operand" "m,m"))
17975   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17976   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17977  "TARGET_USE_FANCY_MATH_387
17978   && flag_unsafe_math_optimizations"
17979  "#"
17980  [(set_attr "type" "fistp")
17981   (set_attr "i387_cw" "ceil")
17982   (set_attr "mode" "DI")])
17983
17984(define_split 
17985  [(set (match_operand:DI 0 "register_operand" "")
17986	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17987	 UNSPEC_FIST_CEIL))
17988   (use (match_operand:HI 2 "memory_operand" ""))
17989   (use (match_operand:HI 3 "memory_operand" ""))
17990   (clobber (match_operand:DI 4 "memory_operand" ""))
17991   (clobber (match_scratch 5 ""))]
17992  "reload_completed"
17993  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17994	      (use (match_dup 2))
17995	      (use (match_dup 3))
17996	      (clobber (match_dup 5))])
17997   (set (match_dup 0) (match_dup 4))]
17998  "")
17999
18000(define_split 
18001  [(set (match_operand:DI 0 "memory_operand" "")
18002	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
18003	 UNSPEC_FIST_CEIL))
18004   (use (match_operand:HI 2 "memory_operand" ""))
18005   (use (match_operand:HI 3 "memory_operand" ""))
18006   (clobber (match_operand:DI 4 "memory_operand" ""))
18007   (clobber (match_scratch 5 ""))]
18008  "reload_completed"
18009  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18010	      (use (match_dup 2))
18011	      (use (match_dup 3))
18012	      (clobber (match_dup 5))])]
18013  "")
18014
18015(define_insn "fist<mode>2_ceil"
18016  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18017	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18018	 UNSPEC_FIST_CEIL))
18019   (use (match_operand:HI 2 "memory_operand" "m"))
18020   (use (match_operand:HI 3 "memory_operand" "m"))]
18021  "TARGET_USE_FANCY_MATH_387
18022   && flag_unsafe_math_optimizations"
18023  "* return output_fix_trunc (insn, operands, 0);"
18024  [(set_attr "type" "fistp")
18025   (set_attr "i387_cw" "ceil")
18026   (set_attr "mode" "<MODE>")])
18027
18028(define_insn "fist<mode>2_ceil_with_temp"
18029  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18030	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18031	 UNSPEC_FIST_CEIL))
18032   (use (match_operand:HI 2 "memory_operand" "m,m"))
18033   (use (match_operand:HI 3 "memory_operand" "m,m"))
18034   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18035  "TARGET_USE_FANCY_MATH_387
18036   && flag_unsafe_math_optimizations"
18037  "#"
18038  [(set_attr "type" "fistp")
18039   (set_attr "i387_cw" "ceil")
18040   (set_attr "mode" "<MODE>")])
18041
18042(define_split 
18043  [(set (match_operand:X87MODEI12 0 "register_operand" "")
18044	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18045	 UNSPEC_FIST_CEIL))
18046   (use (match_operand:HI 2 "memory_operand" ""))
18047   (use (match_operand:HI 3 "memory_operand" ""))
18048   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18049  "reload_completed"
18050  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18051				  UNSPEC_FIST_CEIL))
18052	      (use (match_dup 2))
18053	      (use (match_dup 3))])
18054   (set (match_dup 0) (match_dup 4))]
18055  "")
18056
18057(define_split 
18058  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18059	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18060	 UNSPEC_FIST_CEIL))
18061   (use (match_operand:HI 2 "memory_operand" ""))
18062   (use (match_operand:HI 3 "memory_operand" ""))
18063   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18064  "reload_completed"
18065  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18066				  UNSPEC_FIST_CEIL))
18067	      (use (match_dup 2))
18068	      (use (match_dup 3))])]
18069  "")
18070
18071(define_expand "lceil<mode>2"
18072  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18073		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18074		    UNSPEC_FIST_CEIL))
18075	      (clobber (reg:CC FLAGS_REG))])]
18076  "TARGET_USE_FANCY_MATH_387
18077   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18078   && flag_unsafe_math_optimizations"
18079  "")
18080
18081;; Rounding mode control word calculation could clobber FLAGS_REG.
18082(define_insn_and_split "frndintxf2_trunc"
18083  [(set (match_operand:XF 0 "register_operand" "=f")
18084	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18085	 UNSPEC_FRNDINT_TRUNC))
18086   (clobber (reg:CC FLAGS_REG))]
18087  "TARGET_USE_FANCY_MATH_387
18088   && flag_unsafe_math_optimizations
18089   && !(reload_completed || reload_in_progress)"
18090  "#"
18091  "&& 1"
18092  [(const_int 0)]
18093{
18094  ix86_optimize_mode_switching[I387_TRUNC] = 1;
18095
18096  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18097  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18098
18099  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18100					operands[2], operands[3]));
18101  DONE;
18102}
18103  [(set_attr "type" "frndint")
18104   (set_attr "i387_cw" "trunc")
18105   (set_attr "mode" "XF")])
18106
18107(define_insn "frndintxf2_trunc_i387"
18108  [(set (match_operand:XF 0 "register_operand" "=f")
18109	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18110	 UNSPEC_FRNDINT_TRUNC))
18111   (use (match_operand:HI 2 "memory_operand" "m"))
18112   (use (match_operand:HI 3 "memory_operand" "m"))]
18113  "TARGET_USE_FANCY_MATH_387
18114   && flag_unsafe_math_optimizations"
18115  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18116  [(set_attr "type" "frndint")
18117   (set_attr "i387_cw" "trunc")
18118   (set_attr "mode" "XF")])
18119
18120(define_expand "btruncxf2"
18121  [(use (match_operand:XF 0 "register_operand" ""))
18122   (use (match_operand:XF 1 "register_operand" ""))]
18123  "TARGET_USE_FANCY_MATH_387
18124   && flag_unsafe_math_optimizations"
18125{
18126  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18127  DONE;
18128})
18129
18130(define_expand "btruncdf2"
18131  [(use (match_operand:DF 0 "register_operand" ""))
18132   (use (match_operand:DF 1 "register_operand" ""))]
18133  "TARGET_USE_FANCY_MATH_387
18134   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18135   && flag_unsafe_math_optimizations"
18136{
18137  rtx op0 = gen_reg_rtx (XFmode);
18138  rtx op1 = gen_reg_rtx (XFmode);
18139
18140  emit_insn (gen_extenddfxf2 (op1, operands[1]));
18141  emit_insn (gen_frndintxf2_trunc (op0, op1));
18142
18143  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18144  DONE;
18145})
18146
18147(define_expand "btruncsf2"
18148  [(use (match_operand:SF 0 "register_operand" ""))
18149   (use (match_operand:SF 1 "register_operand" ""))]
18150  "TARGET_USE_FANCY_MATH_387
18151   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18152   && flag_unsafe_math_optimizations"
18153{
18154  rtx op0 = gen_reg_rtx (XFmode);
18155  rtx op1 = gen_reg_rtx (XFmode);
18156
18157  emit_insn (gen_extendsfxf2 (op1, operands[1]));
18158  emit_insn (gen_frndintxf2_trunc (op0, op1));
18159
18160  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18161  DONE;
18162})
18163
18164;; Rounding mode control word calculation could clobber FLAGS_REG.
18165(define_insn_and_split "frndintxf2_mask_pm"
18166  [(set (match_operand:XF 0 "register_operand" "=f")
18167	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18168	 UNSPEC_FRNDINT_MASK_PM))
18169   (clobber (reg:CC FLAGS_REG))]
18170  "TARGET_USE_FANCY_MATH_387
18171   && flag_unsafe_math_optimizations
18172   && !(reload_completed || reload_in_progress)"
18173  "#"
18174  "&& 1"
18175  [(const_int 0)]
18176{
18177  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18178
18179  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18180  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18181
18182  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18183					  operands[2], operands[3]));
18184  DONE;
18185}
18186  [(set_attr "type" "frndint")
18187   (set_attr "i387_cw" "mask_pm")
18188   (set_attr "mode" "XF")])
18189
18190(define_insn "frndintxf2_mask_pm_i387"
18191  [(set (match_operand:XF 0 "register_operand" "=f")
18192	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18193	 UNSPEC_FRNDINT_MASK_PM))
18194   (use (match_operand:HI 2 "memory_operand" "m"))
18195   (use (match_operand:HI 3 "memory_operand" "m"))]
18196  "TARGET_USE_FANCY_MATH_387
18197   && flag_unsafe_math_optimizations"
18198  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18199  [(set_attr "type" "frndint")
18200   (set_attr "i387_cw" "mask_pm")
18201   (set_attr "mode" "XF")])
18202
18203(define_expand "nearbyintxf2"
18204  [(use (match_operand:XF 0 "register_operand" ""))
18205   (use (match_operand:XF 1 "register_operand" ""))]
18206  "TARGET_USE_FANCY_MATH_387
18207   && flag_unsafe_math_optimizations"
18208{
18209  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18210
18211  DONE;
18212})
18213
18214(define_expand "nearbyintdf2"
18215  [(use (match_operand:DF 0 "register_operand" ""))
18216   (use (match_operand:DF 1 "register_operand" ""))]
18217  "TARGET_USE_FANCY_MATH_387
18218   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18219   && flag_unsafe_math_optimizations"
18220{
18221  rtx op0 = gen_reg_rtx (XFmode);
18222  rtx op1 = gen_reg_rtx (XFmode);
18223
18224  emit_insn (gen_extenddfxf2 (op1, operands[1]));
18225  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18226
18227  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18228  DONE;
18229})
18230
18231(define_expand "nearbyintsf2"
18232  [(use (match_operand:SF 0 "register_operand" ""))
18233   (use (match_operand:SF 1 "register_operand" ""))]
18234  "TARGET_USE_FANCY_MATH_387
18235   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18236   && flag_unsafe_math_optimizations"
18237{
18238  rtx op0 = gen_reg_rtx (XFmode);
18239  rtx op1 = gen_reg_rtx (XFmode);
18240
18241  emit_insn (gen_extendsfxf2 (op1, operands[1]));
18242  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18243
18244  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18245  DONE;
18246})
18247
18248
18249;; Block operation instructions
18250
18251(define_insn "cld"
18252 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18253 ""
18254 "cld"
18255  [(set_attr "type" "cld")])
18256
18257(define_expand "movmemsi"
18258  [(use (match_operand:BLK 0 "memory_operand" ""))
18259   (use (match_operand:BLK 1 "memory_operand" ""))
18260   (use (match_operand:SI 2 "nonmemory_operand" ""))
18261   (use (match_operand:SI 3 "const_int_operand" ""))]
18262  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18263{
18264 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18265   DONE;
18266 else
18267   FAIL;
18268})
18269
18270(define_expand "movmemdi"
18271  [(use (match_operand:BLK 0 "memory_operand" ""))
18272   (use (match_operand:BLK 1 "memory_operand" ""))
18273   (use (match_operand:DI 2 "nonmemory_operand" ""))
18274   (use (match_operand:DI 3 "const_int_operand" ""))]
18275  "TARGET_64BIT"
18276{
18277 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18278   DONE;
18279 else
18280   FAIL;
18281})
18282
18283;; Most CPUs don't like single string operations
18284;; Handle this case here to simplify previous expander.
18285
18286(define_expand "strmov"
18287  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18288   (set (match_operand 1 "memory_operand" "") (match_dup 4))
18289   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18290	      (clobber (reg:CC FLAGS_REG))])
18291   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18292	      (clobber (reg:CC FLAGS_REG))])]
18293  ""
18294{
18295  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18296
18297  /* If .md ever supports :P for Pmode, these can be directly
18298     in the pattern above.  */
18299  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18300  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18301
18302  if (TARGET_SINGLE_STRINGOP || optimize_size)
18303    {
18304      emit_insn (gen_strmov_singleop (operands[0], operands[1],
18305				      operands[2], operands[3],
18306				      operands[5], operands[6]));
18307      DONE;
18308    }
18309
18310  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18311})
18312
18313(define_expand "strmov_singleop"
18314  [(parallel [(set (match_operand 1 "memory_operand" "")
18315		   (match_operand 3 "memory_operand" ""))
18316	      (set (match_operand 0 "register_operand" "")
18317		   (match_operand 4 "" ""))
18318	      (set (match_operand 2 "register_operand" "")
18319		   (match_operand 5 "" ""))
18320	      (use (reg:SI DIRFLAG_REG))])]
18321  "TARGET_SINGLE_STRINGOP || optimize_size"
18322  "")
18323
18324(define_insn "*strmovdi_rex_1"
18325  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18326	(mem:DI (match_operand:DI 3 "register_operand" "1")))
18327   (set (match_operand:DI 0 "register_operand" "=D")
18328	(plus:DI (match_dup 2)
18329		 (const_int 8)))
18330   (set (match_operand:DI 1 "register_operand" "=S")
18331	(plus:DI (match_dup 3)
18332		 (const_int 8)))
18333   (use (reg:SI DIRFLAG_REG))]
18334  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18335  "movsq"
18336  [(set_attr "type" "str")
18337   (set_attr "mode" "DI")
18338   (set_attr "memory" "both")])
18339
18340(define_insn "*strmovsi_1"
18341  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18342	(mem:SI (match_operand:SI 3 "register_operand" "1")))
18343   (set (match_operand:SI 0 "register_operand" "=D")
18344	(plus:SI (match_dup 2)
18345		 (const_int 4)))
18346   (set (match_operand:SI 1 "register_operand" "=S")
18347	(plus:SI (match_dup 3)
18348		 (const_int 4)))
18349   (use (reg:SI DIRFLAG_REG))]
18350  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18351  "{movsl|movsd}"
18352  [(set_attr "type" "str")
18353   (set_attr "mode" "SI")
18354   (set_attr "memory" "both")])
18355
18356(define_insn "*strmovsi_rex_1"
18357  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18358	(mem:SI (match_operand:DI 3 "register_operand" "1")))
18359   (set (match_operand:DI 0 "register_operand" "=D")
18360	(plus:DI (match_dup 2)
18361		 (const_int 4)))
18362   (set (match_operand:DI 1 "register_operand" "=S")
18363	(plus:DI (match_dup 3)
18364		 (const_int 4)))
18365   (use (reg:SI DIRFLAG_REG))]
18366  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18367  "{movsl|movsd}"
18368  [(set_attr "type" "str")
18369   (set_attr "mode" "SI")
18370   (set_attr "memory" "both")])
18371
18372(define_insn "*strmovhi_1"
18373  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18374	(mem:HI (match_operand:SI 3 "register_operand" "1")))
18375   (set (match_operand:SI 0 "register_operand" "=D")
18376	(plus:SI (match_dup 2)
18377		 (const_int 2)))
18378   (set (match_operand:SI 1 "register_operand" "=S")
18379	(plus:SI (match_dup 3)
18380		 (const_int 2)))
18381   (use (reg:SI DIRFLAG_REG))]
18382  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18383  "movsw"
18384  [(set_attr "type" "str")
18385   (set_attr "memory" "both")
18386   (set_attr "mode" "HI")])
18387
18388(define_insn "*strmovhi_rex_1"
18389  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18390	(mem:HI (match_operand:DI 3 "register_operand" "1")))
18391   (set (match_operand:DI 0 "register_operand" "=D")
18392	(plus:DI (match_dup 2)
18393		 (const_int 2)))
18394   (set (match_operand:DI 1 "register_operand" "=S")
18395	(plus:DI (match_dup 3)
18396		 (const_int 2)))
18397   (use (reg:SI DIRFLAG_REG))]
18398  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18399  "movsw"
18400  [(set_attr "type" "str")
18401   (set_attr "memory" "both")
18402   (set_attr "mode" "HI")])
18403
18404(define_insn "*strmovqi_1"
18405  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18406	(mem:QI (match_operand:SI 3 "register_operand" "1")))
18407   (set (match_operand:SI 0 "register_operand" "=D")
18408	(plus:SI (match_dup 2)
18409		 (const_int 1)))
18410   (set (match_operand:SI 1 "register_operand" "=S")
18411	(plus:SI (match_dup 3)
18412		 (const_int 1)))
18413   (use (reg:SI DIRFLAG_REG))]
18414  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18415  "movsb"
18416  [(set_attr "type" "str")
18417   (set_attr "memory" "both")
18418   (set_attr "mode" "QI")])
18419
18420(define_insn "*strmovqi_rex_1"
18421  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18422	(mem:QI (match_operand:DI 3 "register_operand" "1")))
18423   (set (match_operand:DI 0 "register_operand" "=D")
18424	(plus:DI (match_dup 2)
18425		 (const_int 1)))
18426   (set (match_operand:DI 1 "register_operand" "=S")
18427	(plus:DI (match_dup 3)
18428		 (const_int 1)))
18429   (use (reg:SI DIRFLAG_REG))]
18430  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18431  "movsb"
18432  [(set_attr "type" "str")
18433   (set_attr "memory" "both")
18434   (set_attr "mode" "QI")])
18435
18436(define_expand "rep_mov"
18437  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18438	      (set (match_operand 0 "register_operand" "")
18439		   (match_operand 5 "" ""))
18440	      (set (match_operand 2 "register_operand" "")
18441		   (match_operand 6 "" ""))
18442	      (set (match_operand 1 "memory_operand" "")
18443		   (match_operand 3 "memory_operand" ""))
18444	      (use (match_dup 4))
18445	      (use (reg:SI DIRFLAG_REG))])]
18446  ""
18447  "")
18448
18449(define_insn "*rep_movdi_rex64"
18450  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18451   (set (match_operand:DI 0 "register_operand" "=D") 
18452        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18453			    (const_int 3))
18454		 (match_operand:DI 3 "register_operand" "0")))
18455   (set (match_operand:DI 1 "register_operand" "=S") 
18456        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18457		 (match_operand:DI 4 "register_operand" "1")))
18458   (set (mem:BLK (match_dup 3))
18459	(mem:BLK (match_dup 4)))
18460   (use (match_dup 5))
18461   (use (reg:SI DIRFLAG_REG))]
18462  "TARGET_64BIT"
18463  "{rep\;movsq|rep movsq}"
18464  [(set_attr "type" "str")
18465   (set_attr "prefix_rep" "1")
18466   (set_attr "memory" "both")
18467   (set_attr "mode" "DI")])
18468
18469(define_insn "*rep_movsi"
18470  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18471   (set (match_operand:SI 0 "register_operand" "=D") 
18472        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18473			    (const_int 2))
18474		 (match_operand:SI 3 "register_operand" "0")))
18475   (set (match_operand:SI 1 "register_operand" "=S") 
18476        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18477		 (match_operand:SI 4 "register_operand" "1")))
18478   (set (mem:BLK (match_dup 3))
18479	(mem:BLK (match_dup 4)))
18480   (use (match_dup 5))
18481   (use (reg:SI DIRFLAG_REG))]
18482  "!TARGET_64BIT"
18483  "{rep\;movsl|rep movsd}"
18484  [(set_attr "type" "str")
18485   (set_attr "prefix_rep" "1")
18486   (set_attr "memory" "both")
18487   (set_attr "mode" "SI")])
18488
18489(define_insn "*rep_movsi_rex64"
18490  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18491   (set (match_operand:DI 0 "register_operand" "=D") 
18492        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18493			    (const_int 2))
18494		 (match_operand:DI 3 "register_operand" "0")))
18495   (set (match_operand:DI 1 "register_operand" "=S") 
18496        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18497		 (match_operand:DI 4 "register_operand" "1")))
18498   (set (mem:BLK (match_dup 3))
18499	(mem:BLK (match_dup 4)))
18500   (use (match_dup 5))
18501   (use (reg:SI DIRFLAG_REG))]
18502  "TARGET_64BIT"
18503  "{rep\;movsl|rep movsd}"
18504  [(set_attr "type" "str")
18505   (set_attr "prefix_rep" "1")
18506   (set_attr "memory" "both")
18507   (set_attr "mode" "SI")])
18508
18509(define_insn "*rep_movqi"
18510  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18511   (set (match_operand:SI 0 "register_operand" "=D") 
18512        (plus:SI (match_operand:SI 3 "register_operand" "0")
18513		 (match_operand:SI 5 "register_operand" "2")))
18514   (set (match_operand:SI 1 "register_operand" "=S") 
18515        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18516   (set (mem:BLK (match_dup 3))
18517	(mem:BLK (match_dup 4)))
18518   (use (match_dup 5))
18519   (use (reg:SI DIRFLAG_REG))]
18520  "!TARGET_64BIT"
18521  "{rep\;movsb|rep movsb}"
18522  [(set_attr "type" "str")
18523   (set_attr "prefix_rep" "1")
18524   (set_attr "memory" "both")
18525   (set_attr "mode" "SI")])
18526
18527(define_insn "*rep_movqi_rex64"
18528  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18529   (set (match_operand:DI 0 "register_operand" "=D") 
18530        (plus:DI (match_operand:DI 3 "register_operand" "0")
18531		 (match_operand:DI 5 "register_operand" "2")))
18532   (set (match_operand:DI 1 "register_operand" "=S") 
18533        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18534   (set (mem:BLK (match_dup 3))
18535	(mem:BLK (match_dup 4)))
18536   (use (match_dup 5))
18537   (use (reg:SI DIRFLAG_REG))]
18538  "TARGET_64BIT"
18539  "{rep\;movsb|rep movsb}"
18540  [(set_attr "type" "str")
18541   (set_attr "prefix_rep" "1")
18542   (set_attr "memory" "both")
18543   (set_attr "mode" "SI")])
18544
18545(define_expand "setmemsi"
18546   [(use (match_operand:BLK 0 "memory_operand" ""))
18547    (use (match_operand:SI 1 "nonmemory_operand" ""))
18548    (use (match_operand 2 "const_int_operand" ""))
18549    (use (match_operand 3 "const_int_operand" ""))]
18550  ""
18551{
18552 /* If value to set is not zero, use the library routine.  */
18553 if (operands[2] != const0_rtx)
18554   FAIL;
18555
18556 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18557   DONE;
18558 else
18559   FAIL;
18560})
18561
18562(define_expand "setmemdi"
18563   [(use (match_operand:BLK 0 "memory_operand" ""))
18564    (use (match_operand:DI 1 "nonmemory_operand" ""))
18565    (use (match_operand 2 "const_int_operand" ""))
18566    (use (match_operand 3 "const_int_operand" ""))]
18567  "TARGET_64BIT"
18568{
18569 /* If value to set is not zero, use the library routine.  */
18570 if (operands[2] != const0_rtx)
18571   FAIL;
18572
18573 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18574   DONE;
18575 else
18576   FAIL;
18577})
18578
18579;; Most CPUs don't like single string operations
18580;; Handle this case here to simplify previous expander.
18581
18582(define_expand "strset"
18583  [(set (match_operand 1 "memory_operand" "")
18584	(match_operand 2 "register_operand" ""))
18585   (parallel [(set (match_operand 0 "register_operand" "")
18586		   (match_dup 3))
18587	      (clobber (reg:CC FLAGS_REG))])]
18588  ""
18589{
18590  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18591    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18592
18593  /* If .md ever supports :P for Pmode, this can be directly
18594     in the pattern above.  */
18595  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18596			      GEN_INT (GET_MODE_SIZE (GET_MODE
18597						      (operands[2]))));
18598  if (TARGET_SINGLE_STRINGOP || optimize_size)
18599    {
18600      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18601				      operands[3]));
18602      DONE;
18603    }
18604})
18605
18606(define_expand "strset_singleop"
18607  [(parallel [(set (match_operand 1 "memory_operand" "")
18608		   (match_operand 2 "register_operand" ""))
18609	      (set (match_operand 0 "register_operand" "")
18610		   (match_operand 3 "" ""))
18611	      (use (reg:SI DIRFLAG_REG))])]
18612  "TARGET_SINGLE_STRINGOP || optimize_size"
18613  "")
18614
18615(define_insn "*strsetdi_rex_1"
18616  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18617	(match_operand:DI 2 "register_operand" "a"))
18618   (set (match_operand:DI 0 "register_operand" "=D")
18619	(plus:DI (match_dup 1)
18620		 (const_int 8)))
18621   (use (reg:SI DIRFLAG_REG))]
18622  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18623  "stosq"
18624  [(set_attr "type" "str")
18625   (set_attr "memory" "store")
18626   (set_attr "mode" "DI")])
18627
18628(define_insn "*strsetsi_1"
18629  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18630	(match_operand:SI 2 "register_operand" "a"))
18631   (set (match_operand:SI 0 "register_operand" "=D")
18632	(plus:SI (match_dup 1)
18633		 (const_int 4)))
18634   (use (reg:SI DIRFLAG_REG))]
18635  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18636  "{stosl|stosd}"
18637  [(set_attr "type" "str")
18638   (set_attr "memory" "store")
18639   (set_attr "mode" "SI")])
18640
18641(define_insn "*strsetsi_rex_1"
18642  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18643	(match_operand:SI 2 "register_operand" "a"))
18644   (set (match_operand:DI 0 "register_operand" "=D")
18645	(plus:DI (match_dup 1)
18646		 (const_int 4)))
18647   (use (reg:SI DIRFLAG_REG))]
18648  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18649  "{stosl|stosd}"
18650  [(set_attr "type" "str")
18651   (set_attr "memory" "store")
18652   (set_attr "mode" "SI")])
18653
18654(define_insn "*strsethi_1"
18655  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18656	(match_operand:HI 2 "register_operand" "a"))
18657   (set (match_operand:SI 0 "register_operand" "=D")
18658	(plus:SI (match_dup 1)
18659		 (const_int 2)))
18660   (use (reg:SI DIRFLAG_REG))]
18661  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18662  "stosw"
18663  [(set_attr "type" "str")
18664   (set_attr "memory" "store")
18665   (set_attr "mode" "HI")])
18666
18667(define_insn "*strsethi_rex_1"
18668  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18669	(match_operand:HI 2 "register_operand" "a"))
18670   (set (match_operand:DI 0 "register_operand" "=D")
18671	(plus:DI (match_dup 1)
18672		 (const_int 2)))
18673   (use (reg:SI DIRFLAG_REG))]
18674  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18675  "stosw"
18676  [(set_attr "type" "str")
18677   (set_attr "memory" "store")
18678   (set_attr "mode" "HI")])
18679
18680(define_insn "*strsetqi_1"
18681  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18682	(match_operand:QI 2 "register_operand" "a"))
18683   (set (match_operand:SI 0 "register_operand" "=D")
18684	(plus:SI (match_dup 1)
18685		 (const_int 1)))
18686   (use (reg:SI DIRFLAG_REG))]
18687  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18688  "stosb"
18689  [(set_attr "type" "str")
18690   (set_attr "memory" "store")
18691   (set_attr "mode" "QI")])
18692
18693(define_insn "*strsetqi_rex_1"
18694  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18695	(match_operand:QI 2 "register_operand" "a"))
18696   (set (match_operand:DI 0 "register_operand" "=D")
18697	(plus:DI (match_dup 1)
18698		 (const_int 1)))
18699   (use (reg:SI DIRFLAG_REG))]
18700  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18701  "stosb"
18702  [(set_attr "type" "str")
18703   (set_attr "memory" "store")
18704   (set_attr "mode" "QI")])
18705
18706(define_expand "rep_stos"
18707  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18708	      (set (match_operand 0 "register_operand" "")
18709		   (match_operand 4 "" ""))
18710	      (set (match_operand 2 "memory_operand" "") (const_int 0))
18711	      (use (match_operand 3 "register_operand" ""))
18712	      (use (match_dup 1))
18713	      (use (reg:SI DIRFLAG_REG))])]
18714  ""
18715  "")
18716
18717(define_insn "*rep_stosdi_rex64"
18718  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18719   (set (match_operand:DI 0 "register_operand" "=D") 
18720        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18721			    (const_int 3))
18722		 (match_operand:DI 3 "register_operand" "0")))
18723   (set (mem:BLK (match_dup 3))
18724	(const_int 0))
18725   (use (match_operand:DI 2 "register_operand" "a"))
18726   (use (match_dup 4))
18727   (use (reg:SI DIRFLAG_REG))]
18728  "TARGET_64BIT"
18729  "{rep\;stosq|rep stosq}"
18730  [(set_attr "type" "str")
18731   (set_attr "prefix_rep" "1")
18732   (set_attr "memory" "store")
18733   (set_attr "mode" "DI")])
18734
18735(define_insn "*rep_stossi"
18736  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18737   (set (match_operand:SI 0 "register_operand" "=D") 
18738        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18739			    (const_int 2))
18740		 (match_operand:SI 3 "register_operand" "0")))
18741   (set (mem:BLK (match_dup 3))
18742	(const_int 0))
18743   (use (match_operand:SI 2 "register_operand" "a"))
18744   (use (match_dup 4))
18745   (use (reg:SI DIRFLAG_REG))]
18746  "!TARGET_64BIT"
18747  "{rep\;stosl|rep stosd}"
18748  [(set_attr "type" "str")
18749   (set_attr "prefix_rep" "1")
18750   (set_attr "memory" "store")
18751   (set_attr "mode" "SI")])
18752
18753(define_insn "*rep_stossi_rex64"
18754  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18755   (set (match_operand:DI 0 "register_operand" "=D") 
18756        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18757			    (const_int 2))
18758		 (match_operand:DI 3 "register_operand" "0")))
18759   (set (mem:BLK (match_dup 3))
18760	(const_int 0))
18761   (use (match_operand:SI 2 "register_operand" "a"))
18762   (use (match_dup 4))
18763   (use (reg:SI DIRFLAG_REG))]
18764  "TARGET_64BIT"
18765  "{rep\;stosl|rep stosd}"
18766  [(set_attr "type" "str")
18767   (set_attr "prefix_rep" "1")
18768   (set_attr "memory" "store")
18769   (set_attr "mode" "SI")])
18770
18771(define_insn "*rep_stosqi"
18772  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18773   (set (match_operand:SI 0 "register_operand" "=D") 
18774        (plus:SI (match_operand:SI 3 "register_operand" "0")
18775		 (match_operand:SI 4 "register_operand" "1")))
18776   (set (mem:BLK (match_dup 3))
18777	(const_int 0))
18778   (use (match_operand:QI 2 "register_operand" "a"))
18779   (use (match_dup 4))
18780   (use (reg:SI DIRFLAG_REG))]
18781  "!TARGET_64BIT"
18782  "{rep\;stosb|rep stosb}"
18783  [(set_attr "type" "str")
18784   (set_attr "prefix_rep" "1")
18785   (set_attr "memory" "store")
18786   (set_attr "mode" "QI")])
18787
18788(define_insn "*rep_stosqi_rex64"
18789  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18790   (set (match_operand:DI 0 "register_operand" "=D") 
18791        (plus:DI (match_operand:DI 3 "register_operand" "0")
18792		 (match_operand:DI 4 "register_operand" "1")))
18793   (set (mem:BLK (match_dup 3))
18794	(const_int 0))
18795   (use (match_operand:QI 2 "register_operand" "a"))
18796   (use (match_dup 4))
18797   (use (reg:SI DIRFLAG_REG))]
18798  "TARGET_64BIT"
18799  "{rep\;stosb|rep stosb}"
18800  [(set_attr "type" "str")
18801   (set_attr "prefix_rep" "1")
18802   (set_attr "memory" "store")
18803   (set_attr "mode" "QI")])
18804
18805(define_expand "cmpstrnsi"
18806  [(set (match_operand:SI 0 "register_operand" "")
18807	(compare:SI (match_operand:BLK 1 "general_operand" "")
18808		    (match_operand:BLK 2 "general_operand" "")))
18809   (use (match_operand 3 "general_operand" ""))
18810   (use (match_operand 4 "immediate_operand" ""))]
18811  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18812{
18813  rtx addr1, addr2, out, outlow, count, countreg, align;
18814
18815  /* Can't use this if the user has appropriated esi or edi.  */
18816  if (global_regs[4] || global_regs[5])
18817    FAIL;
18818
18819  out = operands[0];
18820  if (GET_CODE (out) != REG)
18821    out = gen_reg_rtx (SImode);
18822
18823  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18824  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18825  if (addr1 != XEXP (operands[1], 0))
18826    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18827  if (addr2 != XEXP (operands[2], 0))
18828    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18829
18830  count = operands[3];
18831  countreg = ix86_zero_extend_to_Pmode (count);
18832
18833  /* %%% Iff we are testing strict equality, we can use known alignment
18834     to good advantage.  This may be possible with combine, particularly
18835     once cc0 is dead.  */
18836  align = operands[4];
18837
18838  emit_insn (gen_cld ());
18839  if (GET_CODE (count) == CONST_INT)
18840    {
18841      if (INTVAL (count) == 0)
18842	{
18843	  emit_move_insn (operands[0], const0_rtx);
18844	  DONE;
18845	}
18846      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18847				     operands[1], operands[2]));
18848    }
18849  else
18850    {
18851      if (TARGET_64BIT)
18852	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18853      else
18854	emit_insn (gen_cmpsi_1 (countreg, countreg));
18855      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18856				  operands[1], operands[2]));
18857    }
18858
18859  outlow = gen_lowpart (QImode, out);
18860  emit_insn (gen_cmpintqi (outlow));
18861  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18862
18863  if (operands[0] != out)
18864    emit_move_insn (operands[0], out);
18865
18866  DONE;
18867})
18868
18869;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18870
18871(define_expand "cmpintqi"
18872  [(set (match_dup 1)
18873	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18874   (set (match_dup 2)
18875	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18876   (parallel [(set (match_operand:QI 0 "register_operand" "")
18877		   (minus:QI (match_dup 1)
18878			     (match_dup 2)))
18879	      (clobber (reg:CC FLAGS_REG))])]
18880  ""
18881  "operands[1] = gen_reg_rtx (QImode);
18882   operands[2] = gen_reg_rtx (QImode);")
18883
18884;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18885;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18886
18887(define_expand "cmpstrnqi_nz_1"
18888  [(parallel [(set (reg:CC FLAGS_REG)
18889		   (compare:CC (match_operand 4 "memory_operand" "")
18890			       (match_operand 5 "memory_operand" "")))
18891	      (use (match_operand 2 "register_operand" ""))
18892	      (use (match_operand:SI 3 "immediate_operand" ""))
18893	      (use (reg:SI DIRFLAG_REG))
18894	      (clobber (match_operand 0 "register_operand" ""))
18895	      (clobber (match_operand 1 "register_operand" ""))
18896	      (clobber (match_dup 2))])]
18897  ""
18898  "")
18899
18900(define_insn "*cmpstrnqi_nz_1"
18901  [(set (reg:CC FLAGS_REG)
18902	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18903		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18904   (use (match_operand:SI 6 "register_operand" "2"))
18905   (use (match_operand:SI 3 "immediate_operand" "i"))
18906   (use (reg:SI DIRFLAG_REG))
18907   (clobber (match_operand:SI 0 "register_operand" "=S"))
18908   (clobber (match_operand:SI 1 "register_operand" "=D"))
18909   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18910  "!TARGET_64BIT"
18911  "repz{\;| }cmpsb"
18912  [(set_attr "type" "str")
18913   (set_attr "mode" "QI")
18914   (set_attr "prefix_rep" "1")])
18915
18916(define_insn "*cmpstrnqi_nz_rex_1"
18917  [(set (reg:CC FLAGS_REG)
18918	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18919		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18920   (use (match_operand:DI 6 "register_operand" "2"))
18921   (use (match_operand:SI 3 "immediate_operand" "i"))
18922   (use (reg:SI DIRFLAG_REG))
18923   (clobber (match_operand:DI 0 "register_operand" "=S"))
18924   (clobber (match_operand:DI 1 "register_operand" "=D"))
18925   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18926  "TARGET_64BIT"
18927  "repz{\;| }cmpsb"
18928  [(set_attr "type" "str")
18929   (set_attr "mode" "QI")
18930   (set_attr "prefix_rep" "1")])
18931
18932;; The same, but the count is not known to not be zero.
18933
18934(define_expand "cmpstrnqi_1"
18935  [(parallel [(set (reg:CC FLAGS_REG)
18936		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
18937				     (const_int 0))
18938		  (compare:CC (match_operand 4 "memory_operand" "")
18939			      (match_operand 5 "memory_operand" ""))
18940		  (const_int 0)))
18941	      (use (match_operand:SI 3 "immediate_operand" ""))
18942	      (use (reg:CC FLAGS_REG))
18943	      (use (reg:SI DIRFLAG_REG))
18944	      (clobber (match_operand 0 "register_operand" ""))
18945	      (clobber (match_operand 1 "register_operand" ""))
18946	      (clobber (match_dup 2))])]
18947  ""
18948  "")
18949
18950(define_insn "*cmpstrnqi_1"
18951  [(set (reg:CC FLAGS_REG)
18952	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18953			     (const_int 0))
18954	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18955		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18956	  (const_int 0)))
18957   (use (match_operand:SI 3 "immediate_operand" "i"))
18958   (use (reg:CC FLAGS_REG))
18959   (use (reg:SI DIRFLAG_REG))
18960   (clobber (match_operand:SI 0 "register_operand" "=S"))
18961   (clobber (match_operand:SI 1 "register_operand" "=D"))
18962   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18963  "!TARGET_64BIT"
18964  "repz{\;| }cmpsb"
18965  [(set_attr "type" "str")
18966   (set_attr "mode" "QI")
18967   (set_attr "prefix_rep" "1")])
18968
18969(define_insn "*cmpstrnqi_rex_1"
18970  [(set (reg:CC FLAGS_REG)
18971	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18972			     (const_int 0))
18973	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18974		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18975	  (const_int 0)))
18976   (use (match_operand:SI 3 "immediate_operand" "i"))
18977   (use (reg:CC FLAGS_REG))
18978   (use (reg:SI DIRFLAG_REG))
18979   (clobber (match_operand:DI 0 "register_operand" "=S"))
18980   (clobber (match_operand:DI 1 "register_operand" "=D"))
18981   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18982  "TARGET_64BIT"
18983  "repz{\;| }cmpsb"
18984  [(set_attr "type" "str")
18985   (set_attr "mode" "QI")
18986   (set_attr "prefix_rep" "1")])
18987
18988(define_expand "strlensi"
18989  [(set (match_operand:SI 0 "register_operand" "")
18990	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
18991		    (match_operand:QI 2 "immediate_operand" "")
18992		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18993  ""
18994{
18995 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18996   DONE;
18997 else
18998   FAIL;
18999})
19000
19001(define_expand "strlendi"
19002  [(set (match_operand:DI 0 "register_operand" "")
19003	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
19004		    (match_operand:QI 2 "immediate_operand" "")
19005		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19006  ""
19007{
19008 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19009   DONE;
19010 else
19011   FAIL;
19012})
19013
19014(define_expand "strlenqi_1"
19015  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19016	      (use (reg:SI DIRFLAG_REG))
19017	      (clobber (match_operand 1 "register_operand" ""))
19018	      (clobber (reg:CC FLAGS_REG))])]
19019  ""
19020  "")
19021
19022(define_insn "*strlenqi_1"
19023  [(set (match_operand:SI 0 "register_operand" "=&c")
19024	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19025		    (match_operand:QI 2 "register_operand" "a")
19026		    (match_operand:SI 3 "immediate_operand" "i")
19027		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19028   (use (reg:SI DIRFLAG_REG))
19029   (clobber (match_operand:SI 1 "register_operand" "=D"))
19030   (clobber (reg:CC FLAGS_REG))]
19031  "!TARGET_64BIT"
19032  "repnz{\;| }scasb"
19033  [(set_attr "type" "str")
19034   (set_attr "mode" "QI")
19035   (set_attr "prefix_rep" "1")])
19036
19037(define_insn "*strlenqi_rex_1"
19038  [(set (match_operand:DI 0 "register_operand" "=&c")
19039	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19040		    (match_operand:QI 2 "register_operand" "a")
19041		    (match_operand:DI 3 "immediate_operand" "i")
19042		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19043   (use (reg:SI DIRFLAG_REG))
19044   (clobber (match_operand:DI 1 "register_operand" "=D"))
19045   (clobber (reg:CC FLAGS_REG))]
19046  "TARGET_64BIT"
19047  "repnz{\;| }scasb"
19048  [(set_attr "type" "str")
19049   (set_attr "mode" "QI")
19050   (set_attr "prefix_rep" "1")])
19051
19052;; Peephole optimizations to clean up after cmpstrn*.  This should be
19053;; handled in combine, but it is not currently up to the task.
19054;; When used for their truth value, the cmpstrn* expanders generate
19055;; code like this:
19056;;
19057;;   repz cmpsb
19058;;   seta 	%al
19059;;   setb 	%dl
19060;;   cmpb 	%al, %dl
19061;;   jcc	label
19062;;
19063;; The intermediate three instructions are unnecessary.
19064
19065;; This one handles cmpstrn*_nz_1...
19066(define_peephole2
19067  [(parallel[
19068     (set (reg:CC FLAGS_REG)
19069	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19070		      (mem:BLK (match_operand 5 "register_operand" ""))))
19071     (use (match_operand 6 "register_operand" ""))
19072     (use (match_operand:SI 3 "immediate_operand" ""))
19073     (use (reg:SI DIRFLAG_REG))
19074     (clobber (match_operand 0 "register_operand" ""))
19075     (clobber (match_operand 1 "register_operand" ""))
19076     (clobber (match_operand 2 "register_operand" ""))])
19077   (set (match_operand:QI 7 "register_operand" "")
19078	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19079   (set (match_operand:QI 8 "register_operand" "")
19080	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19081   (set (reg FLAGS_REG)
19082	(compare (match_dup 7) (match_dup 8)))
19083  ]
19084  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19085  [(parallel[
19086     (set (reg:CC FLAGS_REG)
19087	  (compare:CC (mem:BLK (match_dup 4))
19088		      (mem:BLK (match_dup 5))))
19089     (use (match_dup 6))
19090     (use (match_dup 3))
19091     (use (reg:SI DIRFLAG_REG))
19092     (clobber (match_dup 0))
19093     (clobber (match_dup 1))
19094     (clobber (match_dup 2))])]
19095  "")
19096
19097;; ...and this one handles cmpstrn*_1.
19098(define_peephole2
19099  [(parallel[
19100     (set (reg:CC FLAGS_REG)
19101	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19102			       (const_int 0))
19103	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19104		        (mem:BLK (match_operand 5 "register_operand" "")))
19105	    (const_int 0)))
19106     (use (match_operand:SI 3 "immediate_operand" ""))
19107     (use (reg:CC FLAGS_REG))
19108     (use (reg:SI DIRFLAG_REG))
19109     (clobber (match_operand 0 "register_operand" ""))
19110     (clobber (match_operand 1 "register_operand" ""))
19111     (clobber (match_operand 2 "register_operand" ""))])
19112   (set (match_operand:QI 7 "register_operand" "")
19113	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19114   (set (match_operand:QI 8 "register_operand" "")
19115	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19116   (set (reg FLAGS_REG)
19117	(compare (match_dup 7) (match_dup 8)))
19118  ]
19119  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19120  [(parallel[
19121     (set (reg:CC FLAGS_REG)
19122	  (if_then_else:CC (ne (match_dup 6)
19123			       (const_int 0))
19124	    (compare:CC (mem:BLK (match_dup 4))
19125			(mem:BLK (match_dup 5)))
19126	    (const_int 0)))
19127     (use (match_dup 3))
19128     (use (reg:CC FLAGS_REG))
19129     (use (reg:SI DIRFLAG_REG))
19130     (clobber (match_dup 0))
19131     (clobber (match_dup 1))
19132     (clobber (match_dup 2))])]
19133  "")
19134
19135
19136
19137;; Conditional move instructions.
19138
19139(define_expand "movdicc"
19140  [(set (match_operand:DI 0 "register_operand" "")
19141	(if_then_else:DI (match_operand 1 "comparison_operator" "")
19142			 (match_operand:DI 2 "general_operand" "")
19143			 (match_operand:DI 3 "general_operand" "")))]
19144  "TARGET_64BIT"
19145  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19146
19147(define_insn "x86_movdicc_0_m1_rex64"
19148  [(set (match_operand:DI 0 "register_operand" "=r")
19149	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19150	  (const_int -1)
19151	  (const_int 0)))
19152   (clobber (reg:CC FLAGS_REG))]
19153  "TARGET_64BIT"
19154  "sbb{q}\t%0, %0"
19155  ; Since we don't have the proper number of operands for an alu insn,
19156  ; fill in all the blanks.
19157  [(set_attr "type" "alu")
19158   (set_attr "pent_pair" "pu")
19159   (set_attr "memory" "none")
19160   (set_attr "imm_disp" "false")
19161   (set_attr "mode" "DI")
19162   (set_attr "length_immediate" "0")])
19163
19164(define_insn "*movdicc_c_rex64"
19165  [(set (match_operand:DI 0 "register_operand" "=r,r")
19166	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
19167				[(reg FLAGS_REG) (const_int 0)])
19168		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19169		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19170  "TARGET_64BIT && TARGET_CMOVE
19171   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19172  "@
19173   cmov%O2%C1\t{%2, %0|%0, %2}
19174   cmov%O2%c1\t{%3, %0|%0, %3}"
19175  [(set_attr "type" "icmov")
19176   (set_attr "mode" "DI")])
19177
19178(define_expand "movsicc"
19179  [(set (match_operand:SI 0 "register_operand" "")
19180	(if_then_else:SI (match_operand 1 "comparison_operator" "")
19181			 (match_operand:SI 2 "general_operand" "")
19182			 (match_operand:SI 3 "general_operand" "")))]
19183  ""
19184  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19185
19186;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19187;; the register first winds up with `sbbl $0,reg', which is also weird.
19188;; So just document what we're doing explicitly.
19189
19190(define_insn "x86_movsicc_0_m1"
19191  [(set (match_operand:SI 0 "register_operand" "=r")
19192	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19193	  (const_int -1)
19194	  (const_int 0)))
19195   (clobber (reg:CC FLAGS_REG))]
19196  ""
19197  "sbb{l}\t%0, %0"
19198  ; Since we don't have the proper number of operands for an alu insn,
19199  ; fill in all the blanks.
19200  [(set_attr "type" "alu")
19201   (set_attr "pent_pair" "pu")
19202   (set_attr "memory" "none")
19203   (set_attr "imm_disp" "false")
19204   (set_attr "mode" "SI")
19205   (set_attr "length_immediate" "0")])
19206
19207(define_insn "*movsicc_noc"
19208  [(set (match_operand:SI 0 "register_operand" "=r,r")
19209	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
19210				[(reg FLAGS_REG) (const_int 0)])
19211		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19212		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19213  "TARGET_CMOVE
19214   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19215  "@
19216   cmov%O2%C1\t{%2, %0|%0, %2}
19217   cmov%O2%c1\t{%3, %0|%0, %3}"
19218  [(set_attr "type" "icmov")
19219   (set_attr "mode" "SI")])
19220
19221(define_expand "movhicc"
19222  [(set (match_operand:HI 0 "register_operand" "")
19223	(if_then_else:HI (match_operand 1 "comparison_operator" "")
19224			 (match_operand:HI 2 "general_operand" "")
19225			 (match_operand:HI 3 "general_operand" "")))]
19226  "TARGET_HIMODE_MATH"
19227  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19228
19229(define_insn "*movhicc_noc"
19230  [(set (match_operand:HI 0 "register_operand" "=r,r")
19231	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
19232				[(reg FLAGS_REG) (const_int 0)])
19233		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19234		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19235  "TARGET_CMOVE
19236   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19237  "@
19238   cmov%O2%C1\t{%2, %0|%0, %2}
19239   cmov%O2%c1\t{%3, %0|%0, %3}"
19240  [(set_attr "type" "icmov")
19241   (set_attr "mode" "HI")])
19242
19243(define_expand "movqicc"
19244  [(set (match_operand:QI 0 "register_operand" "")
19245	(if_then_else:QI (match_operand 1 "comparison_operator" "")
19246			 (match_operand:QI 2 "general_operand" "")
19247			 (match_operand:QI 3 "general_operand" "")))]
19248  "TARGET_QIMODE_MATH"
19249  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19250
19251(define_insn_and_split "*movqicc_noc"
19252  [(set (match_operand:QI 0 "register_operand" "=r,r")
19253	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
19254				[(match_operand 4 "flags_reg_operand" "")
19255				 (const_int 0)])
19256		      (match_operand:QI 2 "register_operand" "r,0")
19257		      (match_operand:QI 3 "register_operand" "0,r")))]
19258  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19259  "#"
19260  "&& reload_completed"
19261  [(set (match_dup 0)
19262	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19263		      (match_dup 2)
19264		      (match_dup 3)))]
19265  "operands[0] = gen_lowpart (SImode, operands[0]);
19266   operands[2] = gen_lowpart (SImode, operands[2]);
19267   operands[3] = gen_lowpart (SImode, operands[3]);"
19268  [(set_attr "type" "icmov")
19269   (set_attr "mode" "SI")])
19270
19271(define_expand "movsfcc"
19272  [(set (match_operand:SF 0 "register_operand" "")
19273	(if_then_else:SF (match_operand 1 "comparison_operator" "")
19274			 (match_operand:SF 2 "register_operand" "")
19275			 (match_operand:SF 3 "register_operand" "")))]
19276  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19277  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19278
19279(define_insn "*movsfcc_1_387"
19280  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19281	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19282				[(reg FLAGS_REG) (const_int 0)])
19283		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19284		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19285  "TARGET_80387 && TARGET_CMOVE
19286   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19287  "@
19288   fcmov%F1\t{%2, %0|%0, %2}
19289   fcmov%f1\t{%3, %0|%0, %3}
19290   cmov%O2%C1\t{%2, %0|%0, %2}
19291   cmov%O2%c1\t{%3, %0|%0, %3}"
19292  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19293   (set_attr "mode" "SF,SF,SI,SI")])
19294
19295(define_expand "movdfcc"
19296  [(set (match_operand:DF 0 "register_operand" "")
19297	(if_then_else:DF (match_operand 1 "comparison_operator" "")
19298			 (match_operand:DF 2 "register_operand" "")
19299			 (match_operand:DF 3 "register_operand" "")))]
19300  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19301  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19302
19303(define_insn "*movdfcc_1"
19304  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19305	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19306				[(reg FLAGS_REG) (const_int 0)])
19307		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19308		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19309  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19310   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19311  "@
19312   fcmov%F1\t{%2, %0|%0, %2}
19313   fcmov%f1\t{%3, %0|%0, %3}
19314   #
19315   #"
19316  [(set_attr "type" "fcmov,fcmov,multi,multi")
19317   (set_attr "mode" "DF")])
19318
19319(define_insn "*movdfcc_1_rex64"
19320  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19321	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19322				[(reg FLAGS_REG) (const_int 0)])
19323		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19324		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19325  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19326   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19327  "@
19328   fcmov%F1\t{%2, %0|%0, %2}
19329   fcmov%f1\t{%3, %0|%0, %3}
19330   cmov%O2%C1\t{%2, %0|%0, %2}
19331   cmov%O2%c1\t{%3, %0|%0, %3}"
19332  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19333   (set_attr "mode" "DF")])
19334
19335(define_split
19336  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19337	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19338				[(match_operand 4 "flags_reg_operand" "")
19339				 (const_int 0)])
19340		      (match_operand:DF 2 "nonimmediate_operand" "")
19341		      (match_operand:DF 3 "nonimmediate_operand" "")))]
19342  "!TARGET_64BIT && reload_completed"
19343  [(set (match_dup 2)
19344	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19345		      (match_dup 5)
19346		      (match_dup 7)))
19347   (set (match_dup 3)
19348	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19349		      (match_dup 6)
19350		      (match_dup 8)))]
19351  "split_di (operands+2, 1, operands+5, operands+6);
19352   split_di (operands+3, 1, operands+7, operands+8);
19353   split_di (operands, 1, operands+2, operands+3);")
19354
19355(define_expand "movxfcc"
19356  [(set (match_operand:XF 0 "register_operand" "")
19357	(if_then_else:XF (match_operand 1 "comparison_operator" "")
19358			 (match_operand:XF 2 "register_operand" "")
19359			 (match_operand:XF 3 "register_operand" "")))]
19360  "TARGET_80387 && TARGET_CMOVE"
19361  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19362
19363(define_insn "*movxfcc_1"
19364  [(set (match_operand:XF 0 "register_operand" "=f,f")
19365	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19366				[(reg FLAGS_REG) (const_int 0)])
19367		      (match_operand:XF 2 "register_operand" "f,0")
19368		      (match_operand:XF 3 "register_operand" "0,f")))]
19369  "TARGET_80387 && TARGET_CMOVE"
19370  "@
19371   fcmov%F1\t{%2, %0|%0, %2}
19372   fcmov%f1\t{%3, %0|%0, %3}"
19373  [(set_attr "type" "fcmov")
19374   (set_attr "mode" "XF")])
19375
19376;; These versions of the min/max patterns are intentionally ignorant of
19377;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19378;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19379;; are undefined in this condition, we're certain this is correct.
19380
19381(define_insn "sminsf3"
19382  [(set (match_operand:SF 0 "register_operand" "=x")
19383	(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19384		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19385  "TARGET_SSE_MATH"
19386  "minss\t{%2, %0|%0, %2}"
19387  [(set_attr "type" "sseadd")
19388   (set_attr "mode" "SF")])
19389
19390(define_insn "smaxsf3"
19391  [(set (match_operand:SF 0 "register_operand" "=x")
19392	(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19393		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19394  "TARGET_SSE_MATH"
19395  "maxss\t{%2, %0|%0, %2}"
19396  [(set_attr "type" "sseadd")
19397   (set_attr "mode" "SF")])
19398
19399(define_insn "smindf3"
19400  [(set (match_operand:DF 0 "register_operand" "=x")
19401	(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19402		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19403  "TARGET_SSE2 && TARGET_SSE_MATH"
19404  "minsd\t{%2, %0|%0, %2}"
19405  [(set_attr "type" "sseadd")
19406   (set_attr "mode" "DF")])
19407
19408(define_insn "smaxdf3"
19409  [(set (match_operand:DF 0 "register_operand" "=x")
19410	(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19411		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19412  "TARGET_SSE2 && TARGET_SSE_MATH"
19413  "maxsd\t{%2, %0|%0, %2}"
19414  [(set_attr "type" "sseadd")
19415   (set_attr "mode" "DF")])
19416
19417;; These versions of the min/max patterns implement exactly the operations
19418;;   min = (op1 < op2 ? op1 : op2)
19419;;   max = (!(op1 < op2) ? op1 : op2)
19420;; Their operands are not commutative, and thus they may be used in the
19421;; presence of -0.0 and NaN.
19422
19423(define_insn "*ieee_sminsf3"
19424  [(set (match_operand:SF 0 "register_operand" "=x")
19425	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19426		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19427		   UNSPEC_IEEE_MIN))]
19428  "TARGET_SSE_MATH"
19429  "minss\t{%2, %0|%0, %2}"
19430  [(set_attr "type" "sseadd")
19431   (set_attr "mode" "SF")])
19432
19433(define_insn "*ieee_smaxsf3"
19434  [(set (match_operand:SF 0 "register_operand" "=x")
19435	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19436		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19437		   UNSPEC_IEEE_MAX))]
19438  "TARGET_SSE_MATH"
19439  "maxss\t{%2, %0|%0, %2}"
19440  [(set_attr "type" "sseadd")
19441   (set_attr "mode" "SF")])
19442
19443(define_insn "*ieee_smindf3"
19444  [(set (match_operand:DF 0 "register_operand" "=x")
19445	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19446		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19447		   UNSPEC_IEEE_MIN))]
19448  "TARGET_SSE2 && TARGET_SSE_MATH"
19449  "minsd\t{%2, %0|%0, %2}"
19450  [(set_attr "type" "sseadd")
19451   (set_attr "mode" "DF")])
19452
19453(define_insn "*ieee_smaxdf3"
19454  [(set (match_operand:DF 0 "register_operand" "=x")
19455	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19456		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19457		   UNSPEC_IEEE_MAX))]
19458  "TARGET_SSE2 && TARGET_SSE_MATH"
19459  "maxsd\t{%2, %0|%0, %2}"
19460  [(set_attr "type" "sseadd")
19461   (set_attr "mode" "DF")])
19462
19463;; Make two stack loads independent:
19464;;   fld aa              fld aa
19465;;   fld %st(0)     ->   fld bb
19466;;   fmul bb             fmul %st(1), %st
19467;;
19468;; Actually we only match the last two instructions for simplicity.
19469(define_peephole2
19470  [(set (match_operand 0 "fp_register_operand" "")
19471	(match_operand 1 "fp_register_operand" ""))
19472   (set (match_dup 0)
19473	(match_operator 2 "binary_fp_operator"
19474	   [(match_dup 0)
19475	    (match_operand 3 "memory_operand" "")]))]
19476  "REGNO (operands[0]) != REGNO (operands[1])"
19477  [(set (match_dup 0) (match_dup 3))
19478   (set (match_dup 0) (match_dup 4))]
19479
19480  ;; The % modifier is not operational anymore in peephole2's, so we have to
19481  ;; swap the operands manually in the case of addition and multiplication.
19482  "if (COMMUTATIVE_ARITH_P (operands[2]))
19483     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19484				 operands[0], operands[1]);
19485   else
19486     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19487				 operands[1], operands[0]);")
19488
19489;; Conditional addition patterns
19490(define_expand "addqicc"
19491  [(match_operand:QI 0 "register_operand" "")
19492   (match_operand 1 "comparison_operator" "")
19493   (match_operand:QI 2 "register_operand" "")
19494   (match_operand:QI 3 "const_int_operand" "")]
19495  ""
19496  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19497
19498(define_expand "addhicc"
19499  [(match_operand:HI 0 "register_operand" "")
19500   (match_operand 1 "comparison_operator" "")
19501   (match_operand:HI 2 "register_operand" "")
19502   (match_operand:HI 3 "const_int_operand" "")]
19503  ""
19504  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19505
19506(define_expand "addsicc"
19507  [(match_operand:SI 0 "register_operand" "")
19508   (match_operand 1 "comparison_operator" "")
19509   (match_operand:SI 2 "register_operand" "")
19510   (match_operand:SI 3 "const_int_operand" "")]
19511  ""
19512  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19513
19514(define_expand "adddicc"
19515  [(match_operand:DI 0 "register_operand" "")
19516   (match_operand 1 "comparison_operator" "")
19517   (match_operand:DI 2 "register_operand" "")
19518   (match_operand:DI 3 "const_int_operand" "")]
19519  "TARGET_64BIT"
19520  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19521
19522
19523;; Misc patterns (?)
19524
19525;; This pattern exists to put a dependency on all ebp-based memory accesses.
19526;; Otherwise there will be nothing to keep
19527;; 
19528;; [(set (reg ebp) (reg esp))]
19529;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19530;;  (clobber (eflags)]
19531;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19532;;
19533;; in proper program order.
19534(define_insn "pro_epilogue_adjust_stack_1"
19535  [(set (match_operand:SI 0 "register_operand" "=r,r")
19536	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
19537	         (match_operand:SI 2 "immediate_operand" "i,i")))
19538   (clobber (reg:CC FLAGS_REG))
19539   (clobber (mem:BLK (scratch)))]
19540  "!TARGET_64BIT"
19541{
19542  switch (get_attr_type (insn))
19543    {
19544    case TYPE_IMOV:
19545      return "mov{l}\t{%1, %0|%0, %1}";
19546
19547    case TYPE_ALU:
19548      if (GET_CODE (operands[2]) == CONST_INT
19549          && (INTVAL (operands[2]) == 128
19550	      || (INTVAL (operands[2]) < 0
19551	          && INTVAL (operands[2]) != -128)))
19552	{
19553	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19554	  return "sub{l}\t{%2, %0|%0, %2}";
19555	}
19556      return "add{l}\t{%2, %0|%0, %2}";
19557
19558    case TYPE_LEA:
19559      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19560      return "lea{l}\t{%a2, %0|%0, %a2}";
19561
19562    default:
19563      gcc_unreachable ();
19564    }
19565}
19566  [(set (attr "type")
19567	(cond [(eq_attr "alternative" "0")
19568		 (const_string "alu")
19569	       (match_operand:SI 2 "const0_operand" "")
19570		 (const_string "imov")
19571	      ]
19572	      (const_string "lea")))
19573   (set_attr "mode" "SI")])
19574
19575(define_insn "pro_epilogue_adjust_stack_rex64"
19576  [(set (match_operand:DI 0 "register_operand" "=r,r")
19577	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19578		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19579   (clobber (reg:CC FLAGS_REG))
19580   (clobber (mem:BLK (scratch)))]
19581  "TARGET_64BIT"
19582{
19583  switch (get_attr_type (insn))
19584    {
19585    case TYPE_IMOV:
19586      return "mov{q}\t{%1, %0|%0, %1}";
19587
19588    case TYPE_ALU:
19589      if (GET_CODE (operands[2]) == CONST_INT
19590	  /* Avoid overflows.  */
19591	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19592          && (INTVAL (operands[2]) == 128
19593	      || (INTVAL (operands[2]) < 0
19594	          && INTVAL (operands[2]) != -128)))
19595	{
19596	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19597	  return "sub{q}\t{%2, %0|%0, %2}";
19598	}
19599      return "add{q}\t{%2, %0|%0, %2}";
19600
19601    case TYPE_LEA:
19602      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19603      return "lea{q}\t{%a2, %0|%0, %a2}";
19604
19605    default:
19606      gcc_unreachable ();
19607    }
19608}
19609  [(set (attr "type")
19610	(cond [(eq_attr "alternative" "0")
19611		 (const_string "alu")
19612	       (match_operand:DI 2 "const0_operand" "")
19613		 (const_string "imov")
19614	      ]
19615	      (const_string "lea")))
19616   (set_attr "mode" "DI")])
19617
19618(define_insn "pro_epilogue_adjust_stack_rex64_2"
19619  [(set (match_operand:DI 0 "register_operand" "=r,r")
19620	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19621		 (match_operand:DI 3 "immediate_operand" "i,i")))
19622   (use (match_operand:DI 2 "register_operand" "r,r"))
19623   (clobber (reg:CC FLAGS_REG))
19624   (clobber (mem:BLK (scratch)))]
19625  "TARGET_64BIT"
19626{
19627  switch (get_attr_type (insn))
19628    {
19629    case TYPE_ALU:
19630      return "add{q}\t{%2, %0|%0, %2}";
19631
19632    case TYPE_LEA:
19633      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19634      return "lea{q}\t{%a2, %0|%0, %a2}";
19635
19636    default:
19637      gcc_unreachable ();
19638    }
19639}
19640  [(set_attr "type" "alu,lea")
19641   (set_attr "mode" "DI")])
19642
19643(define_expand "allocate_stack_worker"
19644  [(match_operand:SI 0 "register_operand" "")]
19645  "TARGET_STACK_PROBE"
19646{
19647  if (reload_completed)
19648    {
19649      if (TARGET_64BIT)
19650	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19651      else
19652	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19653    }
19654  else
19655    {
19656      if (TARGET_64BIT)
19657	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19658      else
19659	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19660    }
19661  DONE;
19662})
19663
19664(define_insn "allocate_stack_worker_1"
19665  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19666    UNSPECV_STACK_PROBE)
19667   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19668   (clobber (match_scratch:SI 1 "=0"))
19669   (clobber (reg:CC FLAGS_REG))]
19670  "!TARGET_64BIT && TARGET_STACK_PROBE"
19671  "call\t__alloca"
19672  [(set_attr "type" "multi")
19673   (set_attr "length" "5")])
19674
19675(define_expand "allocate_stack_worker_postreload"
19676  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19677				    UNSPECV_STACK_PROBE)
19678	      (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19679	      (clobber (match_dup 0))
19680	      (clobber (reg:CC FLAGS_REG))])]
19681  ""
19682  "")
19683
19684(define_insn "allocate_stack_worker_rex64"
19685  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19686    UNSPECV_STACK_PROBE)
19687   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19688   (clobber (match_scratch:DI 1 "=0"))
19689   (clobber (reg:CC FLAGS_REG))]
19690  "TARGET_64BIT && TARGET_STACK_PROBE"
19691  "call\t__alloca"
19692  [(set_attr "type" "multi")
19693   (set_attr "length" "5")])
19694
19695(define_expand "allocate_stack_worker_rex64_postreload"
19696  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19697				    UNSPECV_STACK_PROBE)
19698	      (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19699	      (clobber (match_dup 0))
19700	      (clobber (reg:CC FLAGS_REG))])]
19701  ""
19702  "")
19703
19704(define_expand "allocate_stack"
19705  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19706		   (minus:SI (reg:SI SP_REG)
19707			     (match_operand:SI 1 "general_operand" "")))
19708	      (clobber (reg:CC FLAGS_REG))])
19709   (parallel [(set (reg:SI SP_REG)
19710		   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19711	      (clobber (reg:CC FLAGS_REG))])]
19712  "TARGET_STACK_PROBE"
19713{
19714#ifdef CHECK_STACK_LIMIT
19715  if (GET_CODE (operands[1]) == CONST_INT
19716      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19717    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19718			   operands[1]));
19719  else 
19720#endif
19721    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19722							    operands[1])));
19723
19724  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19725  DONE;
19726})
19727
19728(define_expand "builtin_setjmp_receiver"
19729  [(label_ref (match_operand 0 "" ""))]
19730  "!TARGET_64BIT && flag_pic"
19731{
19732  if (TARGET_MACHO)
19733    {
19734      rtx xops[3];
19735      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19736      rtx label_rtx = gen_label_rtx ();
19737      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19738      xops[0] = xops[1] = picreg;
19739      xops[2] = gen_rtx_CONST (SImode,
19740	          gen_rtx_MINUS (SImode,
19741		    gen_rtx_LABEL_REF (SImode, label_rtx),
19742		    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19743      ix86_expand_binary_operator (MINUS, SImode, xops);
19744    }
19745  else
19746    emit_insn (gen_set_got (pic_offset_table_rtx));
19747  DONE;
19748})
19749
19750;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19751
19752(define_split
19753  [(set (match_operand 0 "register_operand" "")
19754	(match_operator 3 "promotable_binary_operator"
19755	   [(match_operand 1 "register_operand" "")
19756	    (match_operand 2 "aligned_operand" "")]))
19757   (clobber (reg:CC FLAGS_REG))]
19758  "! TARGET_PARTIAL_REG_STALL && reload_completed
19759   && ((GET_MODE (operands[0]) == HImode 
19760	&& ((!optimize_size && !TARGET_FAST_PREFIX)
19761            /* ??? next two lines just !satisfies_constraint_K (...) */
19762	    || GET_CODE (operands[2]) != CONST_INT
19763	    || satisfies_constraint_K (operands[2])))
19764       || (GET_MODE (operands[0]) == QImode 
19765	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19766  [(parallel [(set (match_dup 0)
19767		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19768	      (clobber (reg:CC FLAGS_REG))])]
19769  "operands[0] = gen_lowpart (SImode, operands[0]);
19770   operands[1] = gen_lowpart (SImode, operands[1]);
19771   if (GET_CODE (operands[3]) != ASHIFT)
19772     operands[2] = gen_lowpart (SImode, operands[2]);
19773   PUT_MODE (operands[3], SImode);")
19774
19775; Promote the QImode tests, as i386 has encoding of the AND
19776; instruction with 32-bit sign-extended immediate and thus the
19777; instruction size is unchanged, except in the %eax case for
19778; which it is increased by one byte, hence the ! optimize_size.
19779(define_split
19780  [(set (match_operand 0 "flags_reg_operand" "")
19781	(match_operator 2 "compare_operator"
19782	  [(and (match_operand 3 "aligned_operand" "")
19783		(match_operand 4 "const_int_operand" ""))
19784	   (const_int 0)]))
19785   (set (match_operand 1 "register_operand" "")
19786	(and (match_dup 3) (match_dup 4)))]
19787  "! TARGET_PARTIAL_REG_STALL && reload_completed
19788   /* Ensure that the operand will remain sign-extended immediate.  */
19789   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19790   && ! optimize_size
19791   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19792       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19793  [(parallel [(set (match_dup 0)
19794		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19795			            (const_int 0)]))
19796	      (set (match_dup 1)
19797		   (and:SI (match_dup 3) (match_dup 4)))])]
19798{
19799  operands[4]
19800    = gen_int_mode (INTVAL (operands[4])
19801		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19802  operands[1] = gen_lowpart (SImode, operands[1]);
19803  operands[3] = gen_lowpart (SImode, operands[3]);
19804})
19805
19806; Don't promote the QImode tests, as i386 doesn't have encoding of
19807; the TEST instruction with 32-bit sign-extended immediate and thus
19808; the instruction size would at least double, which is not what we
19809; want even with ! optimize_size.
19810(define_split
19811  [(set (match_operand 0 "flags_reg_operand" "")
19812	(match_operator 1 "compare_operator"
19813	  [(and (match_operand:HI 2 "aligned_operand" "")
19814		(match_operand:HI 3 "const_int_operand" ""))
19815	   (const_int 0)]))]
19816  "! TARGET_PARTIAL_REG_STALL && reload_completed
19817   /* Ensure that the operand will remain sign-extended immediate.  */
19818   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19819   && ! TARGET_FAST_PREFIX
19820   && ! optimize_size"
19821  [(set (match_dup 0)
19822	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19823		         (const_int 0)]))]
19824{
19825  operands[3]
19826    = gen_int_mode (INTVAL (operands[3])
19827		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19828  operands[2] = gen_lowpart (SImode, operands[2]);
19829})
19830
19831(define_split
19832  [(set (match_operand 0 "register_operand" "")
19833	(neg (match_operand 1 "register_operand" "")))
19834   (clobber (reg:CC FLAGS_REG))]
19835  "! TARGET_PARTIAL_REG_STALL && reload_completed
19836   && (GET_MODE (operands[0]) == HImode
19837       || (GET_MODE (operands[0]) == QImode 
19838	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19839  [(parallel [(set (match_dup 0)
19840		   (neg:SI (match_dup 1)))
19841	      (clobber (reg:CC FLAGS_REG))])]
19842  "operands[0] = gen_lowpart (SImode, operands[0]);
19843   operands[1] = gen_lowpart (SImode, operands[1]);")
19844
19845(define_split
19846  [(set (match_operand 0 "register_operand" "")
19847	(not (match_operand 1 "register_operand" "")))]
19848  "! TARGET_PARTIAL_REG_STALL && reload_completed
19849   && (GET_MODE (operands[0]) == HImode
19850       || (GET_MODE (operands[0]) == QImode 
19851	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19852  [(set (match_dup 0)
19853	(not:SI (match_dup 1)))]
19854  "operands[0] = gen_lowpart (SImode, operands[0]);
19855   operands[1] = gen_lowpart (SImode, operands[1]);")
19856
19857(define_split 
19858  [(set (match_operand 0 "register_operand" "")
19859	(if_then_else (match_operator 1 "comparison_operator" 
19860				[(reg FLAGS_REG) (const_int 0)])
19861		      (match_operand 2 "register_operand" "")
19862		      (match_operand 3 "register_operand" "")))]
19863  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19864   && (GET_MODE (operands[0]) == HImode
19865       || (GET_MODE (operands[0]) == QImode 
19866	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19867  [(set (match_dup 0)
19868	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19869  "operands[0] = gen_lowpart (SImode, operands[0]);
19870   operands[2] = gen_lowpart (SImode, operands[2]);
19871   operands[3] = gen_lowpart (SImode, operands[3]);")
19872			
19873
19874;; RTL Peephole optimizations, run before sched2.  These primarily look to
19875;; transform a complex memory operation into two memory to register operations.
19876
19877;; Don't push memory operands
19878(define_peephole2
19879  [(set (match_operand:SI 0 "push_operand" "")
19880	(match_operand:SI 1 "memory_operand" ""))
19881   (match_scratch:SI 2 "r")]
19882  "!optimize_size && !TARGET_PUSH_MEMORY
19883   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19884  [(set (match_dup 2) (match_dup 1))
19885   (set (match_dup 0) (match_dup 2))]
19886  "")
19887
19888(define_peephole2
19889  [(set (match_operand:DI 0 "push_operand" "")
19890	(match_operand:DI 1 "memory_operand" ""))
19891   (match_scratch:DI 2 "r")]
19892  "!optimize_size && !TARGET_PUSH_MEMORY
19893   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19894  [(set (match_dup 2) (match_dup 1))
19895   (set (match_dup 0) (match_dup 2))]
19896  "")
19897
19898;; We need to handle SFmode only, because DFmode and XFmode is split to
19899;; SImode pushes.
19900(define_peephole2
19901  [(set (match_operand:SF 0 "push_operand" "")
19902	(match_operand:SF 1 "memory_operand" ""))
19903   (match_scratch:SF 2 "r")]
19904  "!optimize_size && !TARGET_PUSH_MEMORY
19905   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19906  [(set (match_dup 2) (match_dup 1))
19907   (set (match_dup 0) (match_dup 2))]
19908  "")
19909
19910(define_peephole2
19911  [(set (match_operand:HI 0 "push_operand" "")
19912	(match_operand:HI 1 "memory_operand" ""))
19913   (match_scratch:HI 2 "r")]
19914  "!optimize_size && !TARGET_PUSH_MEMORY
19915   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19916  [(set (match_dup 2) (match_dup 1))
19917   (set (match_dup 0) (match_dup 2))]
19918  "")
19919
19920(define_peephole2
19921  [(set (match_operand:QI 0 "push_operand" "")
19922	(match_operand:QI 1 "memory_operand" ""))
19923   (match_scratch:QI 2 "q")]
19924  "!optimize_size && !TARGET_PUSH_MEMORY
19925   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19926  [(set (match_dup 2) (match_dup 1))
19927   (set (match_dup 0) (match_dup 2))]
19928  "")
19929
19930;; Don't move an immediate directly to memory when the instruction
19931;; gets too big.
19932(define_peephole2
19933  [(match_scratch:SI 1 "r")
19934   (set (match_operand:SI 0 "memory_operand" "")
19935        (const_int 0))]
19936  "! optimize_size
19937   && ! TARGET_USE_MOV0
19938   && TARGET_SPLIT_LONG_MOVES
19939   && get_attr_length (insn) >= ix86_cost->large_insn
19940   && peep2_regno_dead_p (0, FLAGS_REG)"
19941  [(parallel [(set (match_dup 1) (const_int 0))
19942	      (clobber (reg:CC FLAGS_REG))])
19943   (set (match_dup 0) (match_dup 1))]
19944  "")
19945
19946(define_peephole2
19947  [(match_scratch:HI 1 "r")
19948   (set (match_operand:HI 0 "memory_operand" "")
19949        (const_int 0))]
19950  "! optimize_size
19951   && ! TARGET_USE_MOV0
19952   && TARGET_SPLIT_LONG_MOVES
19953   && get_attr_length (insn) >= ix86_cost->large_insn
19954   && peep2_regno_dead_p (0, FLAGS_REG)"
19955  [(parallel [(set (match_dup 2) (const_int 0))
19956	      (clobber (reg:CC FLAGS_REG))])
19957   (set (match_dup 0) (match_dup 1))]
19958  "operands[2] = gen_lowpart (SImode, operands[1]);")
19959
19960(define_peephole2
19961  [(match_scratch:QI 1 "q")
19962   (set (match_operand:QI 0 "memory_operand" "")
19963        (const_int 0))]
19964  "! optimize_size
19965   && ! TARGET_USE_MOV0
19966   && TARGET_SPLIT_LONG_MOVES
19967   && get_attr_length (insn) >= ix86_cost->large_insn
19968   && peep2_regno_dead_p (0, FLAGS_REG)"
19969  [(parallel [(set (match_dup 2) (const_int 0))
19970	      (clobber (reg:CC FLAGS_REG))])
19971   (set (match_dup 0) (match_dup 1))]
19972  "operands[2] = gen_lowpart (SImode, operands[1]);")
19973
19974(define_peephole2
19975  [(match_scratch:SI 2 "r")
19976   (set (match_operand:SI 0 "memory_operand" "")
19977        (match_operand:SI 1 "immediate_operand" ""))]
19978  "! optimize_size
19979   && get_attr_length (insn) >= ix86_cost->large_insn
19980   && TARGET_SPLIT_LONG_MOVES"
19981  [(set (match_dup 2) (match_dup 1))
19982   (set (match_dup 0) (match_dup 2))]
19983  "")
19984
19985(define_peephole2
19986  [(match_scratch:HI 2 "r")
19987   (set (match_operand:HI 0 "memory_operand" "")
19988        (match_operand:HI 1 "immediate_operand" ""))]
19989  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19990  && TARGET_SPLIT_LONG_MOVES"
19991  [(set (match_dup 2) (match_dup 1))
19992   (set (match_dup 0) (match_dup 2))]
19993  "")
19994
19995(define_peephole2
19996  [(match_scratch:QI 2 "q")
19997   (set (match_operand:QI 0 "memory_operand" "")
19998        (match_operand:QI 1 "immediate_operand" ""))]
19999  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20000  && TARGET_SPLIT_LONG_MOVES"
20001  [(set (match_dup 2) (match_dup 1))
20002   (set (match_dup 0) (match_dup 2))]
20003  "")
20004
20005;; Don't compare memory with zero, load and use a test instead.
20006(define_peephole2
20007  [(set (match_operand 0 "flags_reg_operand" "")
20008 	(match_operator 1 "compare_operator"
20009	  [(match_operand:SI 2 "memory_operand" "")
20010	   (const_int 0)]))
20011   (match_scratch:SI 3 "r")]
20012  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20013  [(set (match_dup 3) (match_dup 2))
20014   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20015  "")
20016
20017;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
20018;; Don't split NOTs with a displacement operand, because resulting XOR
20019;; will not be pairable anyway.
20020;;
20021;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20022;; represented using a modRM byte.  The XOR replacement is long decoded,
20023;; so this split helps here as well.
20024;;
20025;; Note: Can't do this as a regular split because we can't get proper
20026;; lifetime information then.
20027
20028(define_peephole2
20029  [(set (match_operand:SI 0 "nonimmediate_operand" "")
20030	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20031  "!optimize_size
20032   && peep2_regno_dead_p (0, FLAGS_REG)
20033   && ((TARGET_PENTIUM 
20034        && (GET_CODE (operands[0]) != MEM
20035            || !memory_displacement_operand (operands[0], SImode)))
20036       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20037  [(parallel [(set (match_dup 0)
20038		   (xor:SI (match_dup 1) (const_int -1)))
20039	      (clobber (reg:CC FLAGS_REG))])]
20040  "")
20041
20042(define_peephole2
20043  [(set (match_operand:HI 0 "nonimmediate_operand" "")
20044	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20045  "!optimize_size
20046   && peep2_regno_dead_p (0, FLAGS_REG)
20047   && ((TARGET_PENTIUM 
20048        && (GET_CODE (operands[0]) != MEM
20049            || !memory_displacement_operand (operands[0], HImode)))
20050       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20051  [(parallel [(set (match_dup 0)
20052		   (xor:HI (match_dup 1) (const_int -1)))
20053	      (clobber (reg:CC FLAGS_REG))])]
20054  "")
20055
20056(define_peephole2
20057  [(set (match_operand:QI 0 "nonimmediate_operand" "")
20058	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20059  "!optimize_size
20060   && peep2_regno_dead_p (0, FLAGS_REG)
20061   && ((TARGET_PENTIUM 
20062        && (GET_CODE (operands[0]) != MEM
20063            || !memory_displacement_operand (operands[0], QImode)))
20064       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20065  [(parallel [(set (match_dup 0)
20066		   (xor:QI (match_dup 1) (const_int -1)))
20067	      (clobber (reg:CC FLAGS_REG))])]
20068  "")
20069
20070;; Non pairable "test imm, reg" instructions can be translated to
20071;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20072;; byte opcode instead of two, have a short form for byte operands),
20073;; so do it for other CPUs as well.  Given that the value was dead,
20074;; this should not create any new dependencies.  Pass on the sub-word
20075;; versions if we're concerned about partial register stalls.
20076
20077(define_peephole2
20078  [(set (match_operand 0 "flags_reg_operand" "")
20079	(match_operator 1 "compare_operator"
20080	  [(and:SI (match_operand:SI 2 "register_operand" "")
20081		   (match_operand:SI 3 "immediate_operand" ""))
20082	   (const_int 0)]))]
20083  "ix86_match_ccmode (insn, CCNOmode)
20084   && (true_regnum (operands[2]) != 0
20085       || satisfies_constraint_K (operands[3]))
20086   && peep2_reg_dead_p (1, operands[2])"
20087  [(parallel
20088     [(set (match_dup 0)
20089	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20090		            (const_int 0)]))
20091      (set (match_dup 2)
20092	   (and:SI (match_dup 2) (match_dup 3)))])]
20093  "")
20094
20095;; We don't need to handle HImode case, because it will be promoted to SImode
20096;; on ! TARGET_PARTIAL_REG_STALL
20097
20098(define_peephole2
20099  [(set (match_operand 0 "flags_reg_operand" "")
20100	(match_operator 1 "compare_operator"
20101	  [(and:QI (match_operand:QI 2 "register_operand" "")
20102		   (match_operand:QI 3 "immediate_operand" ""))
20103	   (const_int 0)]))]
20104  "! TARGET_PARTIAL_REG_STALL
20105   && ix86_match_ccmode (insn, CCNOmode)
20106   && true_regnum (operands[2]) != 0
20107   && peep2_reg_dead_p (1, operands[2])"
20108  [(parallel
20109     [(set (match_dup 0)
20110	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20111		            (const_int 0)]))
20112      (set (match_dup 2)
20113	   (and:QI (match_dup 2) (match_dup 3)))])]
20114  "")
20115
20116(define_peephole2
20117  [(set (match_operand 0 "flags_reg_operand" "")
20118	(match_operator 1 "compare_operator"
20119	  [(and:SI
20120	     (zero_extract:SI
20121	       (match_operand 2 "ext_register_operand" "")
20122	       (const_int 8)
20123	       (const_int 8))
20124	     (match_operand 3 "const_int_operand" ""))
20125	   (const_int 0)]))]
20126  "! TARGET_PARTIAL_REG_STALL
20127   && ix86_match_ccmode (insn, CCNOmode)
20128   && true_regnum (operands[2]) != 0
20129   && peep2_reg_dead_p (1, operands[2])"
20130  [(parallel [(set (match_dup 0)
20131		   (match_op_dup 1
20132		     [(and:SI
20133			(zero_extract:SI
20134			  (match_dup 2)
20135			  (const_int 8)
20136			  (const_int 8))
20137			(match_dup 3))
20138		      (const_int 0)]))
20139	      (set (zero_extract:SI (match_dup 2)
20140				    (const_int 8)
20141				    (const_int 8))
20142		   (and:SI 
20143		     (zero_extract:SI
20144		       (match_dup 2)
20145		       (const_int 8)
20146		       (const_int 8))
20147		     (match_dup 3)))])]
20148  "")
20149
20150;; Don't do logical operations with memory inputs.
20151(define_peephole2
20152  [(match_scratch:SI 2 "r")
20153   (parallel [(set (match_operand:SI 0 "register_operand" "")
20154                   (match_operator:SI 3 "arith_or_logical_operator"
20155                     [(match_dup 0)
20156                      (match_operand:SI 1 "memory_operand" "")]))
20157              (clobber (reg:CC FLAGS_REG))])]
20158  "! optimize_size && ! TARGET_READ_MODIFY"
20159  [(set (match_dup 2) (match_dup 1))
20160   (parallel [(set (match_dup 0)
20161                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20162              (clobber (reg:CC FLAGS_REG))])]
20163  "")
20164
20165(define_peephole2
20166  [(match_scratch:SI 2 "r")
20167   (parallel [(set (match_operand:SI 0 "register_operand" "")
20168                   (match_operator:SI 3 "arith_or_logical_operator"
20169                     [(match_operand:SI 1 "memory_operand" "")
20170                      (match_dup 0)]))
20171              (clobber (reg:CC FLAGS_REG))])]
20172  "! optimize_size && ! TARGET_READ_MODIFY"
20173  [(set (match_dup 2) (match_dup 1))
20174   (parallel [(set (match_dup 0)
20175                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20176              (clobber (reg:CC FLAGS_REG))])]
20177  "")
20178
20179; Don't do logical operations with memory outputs
20180;
20181; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20182; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20183; the same decoder scheduling characteristics as the original.
20184
20185(define_peephole2
20186  [(match_scratch:SI 2 "r")
20187   (parallel [(set (match_operand:SI 0 "memory_operand" "")
20188                   (match_operator:SI 3 "arith_or_logical_operator"
20189                     [(match_dup 0)
20190                      (match_operand:SI 1 "nonmemory_operand" "")]))
20191              (clobber (reg:CC FLAGS_REG))])]
20192  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20193  [(set (match_dup 2) (match_dup 0))
20194   (parallel [(set (match_dup 2)
20195                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20196              (clobber (reg:CC FLAGS_REG))])
20197   (set (match_dup 0) (match_dup 2))]
20198  "")
20199
20200(define_peephole2
20201  [(match_scratch:SI 2 "r")
20202   (parallel [(set (match_operand:SI 0 "memory_operand" "")
20203                   (match_operator:SI 3 "arith_or_logical_operator"
20204                     [(match_operand:SI 1 "nonmemory_operand" "")
20205                      (match_dup 0)]))
20206              (clobber (reg:CC FLAGS_REG))])]
20207  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20208  [(set (match_dup 2) (match_dup 0))
20209   (parallel [(set (match_dup 2)
20210                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20211              (clobber (reg:CC FLAGS_REG))])
20212   (set (match_dup 0) (match_dup 2))]
20213  "")
20214
20215;; Attempt to always use XOR for zeroing registers.
20216(define_peephole2
20217  [(set (match_operand 0 "register_operand" "")
20218	(match_operand 1 "const0_operand" ""))]
20219  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20220   && (! TARGET_USE_MOV0 || optimize_size)
20221   && GENERAL_REG_P (operands[0])
20222   && peep2_regno_dead_p (0, FLAGS_REG)"
20223  [(parallel [(set (match_dup 0) (const_int 0))
20224	      (clobber (reg:CC FLAGS_REG))])]
20225{
20226  operands[0] = gen_lowpart (word_mode, operands[0]);
20227})
20228
20229(define_peephole2
20230  [(set (strict_low_part (match_operand 0 "register_operand" ""))
20231	(const_int 0))]
20232  "(GET_MODE (operands[0]) == QImode
20233    || GET_MODE (operands[0]) == HImode)
20234   && (! TARGET_USE_MOV0 || optimize_size)
20235   && peep2_regno_dead_p (0, FLAGS_REG)"
20236  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20237	      (clobber (reg:CC FLAGS_REG))])])
20238
20239;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20240(define_peephole2
20241  [(set (match_operand 0 "register_operand" "")
20242	(const_int -1))]
20243  "(GET_MODE (operands[0]) == HImode
20244    || GET_MODE (operands[0]) == SImode 
20245    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20246   && (optimize_size || TARGET_PENTIUM)
20247   && peep2_regno_dead_p (0, FLAGS_REG)"
20248  [(parallel [(set (match_dup 0) (const_int -1))
20249	      (clobber (reg:CC FLAGS_REG))])]
20250  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20251			      operands[0]);")
20252
20253;; Attempt to convert simple leas to adds. These can be created by
20254;; move expanders.
20255(define_peephole2
20256  [(set (match_operand:SI 0 "register_operand" "")
20257  	(plus:SI (match_dup 0)
20258		 (match_operand:SI 1 "nonmemory_operand" "")))]
20259  "peep2_regno_dead_p (0, FLAGS_REG)"
20260  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20261	      (clobber (reg:CC FLAGS_REG))])]
20262  "")
20263
20264(define_peephole2
20265  [(set (match_operand:SI 0 "register_operand" "")
20266  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20267			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20268  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20269  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20270	      (clobber (reg:CC FLAGS_REG))])]
20271  "operands[2] = gen_lowpart (SImode, operands[2]);")
20272
20273(define_peephole2
20274  [(set (match_operand:DI 0 "register_operand" "")
20275  	(plus:DI (match_dup 0)
20276		 (match_operand:DI 1 "x86_64_general_operand" "")))]
20277  "peep2_regno_dead_p (0, FLAGS_REG)"
20278  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20279	      (clobber (reg:CC FLAGS_REG))])]
20280  "")
20281
20282(define_peephole2
20283  [(set (match_operand:SI 0 "register_operand" "")
20284  	(mult:SI (match_dup 0)
20285		 (match_operand:SI 1 "const_int_operand" "")))]
20286  "exact_log2 (INTVAL (operands[1])) >= 0
20287   && peep2_regno_dead_p (0, FLAGS_REG)"
20288  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20289	      (clobber (reg:CC FLAGS_REG))])]
20290  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20291
20292(define_peephole2
20293  [(set (match_operand:DI 0 "register_operand" "")
20294  	(mult:DI (match_dup 0)
20295		 (match_operand:DI 1 "const_int_operand" "")))]
20296  "exact_log2 (INTVAL (operands[1])) >= 0
20297   && peep2_regno_dead_p (0, FLAGS_REG)"
20298  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20299	      (clobber (reg:CC FLAGS_REG))])]
20300  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20301
20302(define_peephole2
20303  [(set (match_operand:SI 0 "register_operand" "")
20304  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20305		   (match_operand:DI 2 "const_int_operand" "")) 0))]
20306  "exact_log2 (INTVAL (operands[2])) >= 0
20307   && REGNO (operands[0]) == REGNO (operands[1])
20308   && peep2_regno_dead_p (0, FLAGS_REG)"
20309  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20310	      (clobber (reg:CC FLAGS_REG))])]
20311  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20312
20313;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20314;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20315;; many CPUs it is also faster, since special hardware to avoid esp
20316;; dependencies is present.
20317
20318;; While some of these conversions may be done using splitters, we use peepholes
20319;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20320
20321;; Convert prologue esp subtractions to push.
20322;; We need register to push.  In order to keep verify_flow_info happy we have
20323;; two choices
20324;; - use scratch and clobber it in order to avoid dependencies
20325;; - use already live register
20326;; We can't use the second way right now, since there is no reliable way how to
20327;; verify that given register is live.  First choice will also most likely in
20328;; fewer dependencies.  On the place of esp adjustments it is very likely that
20329;; call clobbered registers are dead.  We may want to use base pointer as an
20330;; alternative when no register is available later.
20331
20332(define_peephole2
20333  [(match_scratch:SI 0 "r")
20334   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20335	      (clobber (reg:CC FLAGS_REG))
20336	      (clobber (mem:BLK (scratch)))])]
20337  "optimize_size || !TARGET_SUB_ESP_4"
20338  [(clobber (match_dup 0))
20339   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20340	      (clobber (mem:BLK (scratch)))])])
20341
20342(define_peephole2
20343  [(match_scratch:SI 0 "r")
20344   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20345	      (clobber (reg:CC FLAGS_REG))
20346	      (clobber (mem:BLK (scratch)))])]
20347  "optimize_size || !TARGET_SUB_ESP_8"
20348  [(clobber (match_dup 0))
20349   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20350   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20351	      (clobber (mem:BLK (scratch)))])])
20352
20353;; Convert esp subtractions to push.
20354(define_peephole2
20355  [(match_scratch:SI 0 "r")
20356   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20357	      (clobber (reg:CC FLAGS_REG))])]
20358  "optimize_size || !TARGET_SUB_ESP_4"
20359  [(clobber (match_dup 0))
20360   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20361
20362(define_peephole2
20363  [(match_scratch:SI 0 "r")
20364   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20365	      (clobber (reg:CC FLAGS_REG))])]
20366  "optimize_size || !TARGET_SUB_ESP_8"
20367  [(clobber (match_dup 0))
20368   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20369   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20370
20371;; Convert epilogue deallocator to pop.
20372(define_peephole2
20373  [(match_scratch:SI 0 "r")
20374   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20375	      (clobber (reg:CC FLAGS_REG))
20376	      (clobber (mem:BLK (scratch)))])]
20377  "optimize_size || !TARGET_ADD_ESP_4"
20378  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20379	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20380	      (clobber (mem:BLK (scratch)))])]
20381  "")
20382
20383;; Two pops case is tricky, since pop causes dependency on destination register.
20384;; We use two registers if available.
20385(define_peephole2
20386  [(match_scratch:SI 0 "r")
20387   (match_scratch:SI 1 "r")
20388   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20389	      (clobber (reg:CC FLAGS_REG))
20390	      (clobber (mem:BLK (scratch)))])]
20391  "optimize_size || !TARGET_ADD_ESP_8"
20392  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20393	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20394	      (clobber (mem:BLK (scratch)))])
20395   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20396	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20397  "")
20398
20399(define_peephole2
20400  [(match_scratch:SI 0 "r")
20401   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20402	      (clobber (reg:CC FLAGS_REG))
20403	      (clobber (mem:BLK (scratch)))])]
20404  "optimize_size"
20405  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20406	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20407	      (clobber (mem:BLK (scratch)))])
20408   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20409	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20410  "")
20411
20412;; Convert esp additions to pop.
20413(define_peephole2
20414  [(match_scratch:SI 0 "r")
20415   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20416	      (clobber (reg:CC FLAGS_REG))])]
20417  ""
20418  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20419	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20420  "")
20421
20422;; Two pops case is tricky, since pop causes dependency on destination register.
20423;; We use two registers if available.
20424(define_peephole2
20425  [(match_scratch:SI 0 "r")
20426   (match_scratch:SI 1 "r")
20427   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20428	      (clobber (reg:CC FLAGS_REG))])]
20429  ""
20430  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20431	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20432   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20433	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20434  "")
20435
20436(define_peephole2
20437  [(match_scratch:SI 0 "r")
20438   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20439	      (clobber (reg:CC FLAGS_REG))])]
20440  "optimize_size"
20441  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20442	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20443   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20444	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20445  "")
20446
20447;; Convert compares with 1 to shorter inc/dec operations when CF is not
20448;; required and register dies.  Similarly for 128 to plus -128.
20449(define_peephole2
20450  [(set (match_operand 0 "flags_reg_operand" "")
20451	(match_operator 1 "compare_operator"
20452	  [(match_operand 2 "register_operand" "")
20453	   (match_operand 3 "const_int_operand" "")]))]
20454  "(INTVAL (operands[3]) == -1
20455    || INTVAL (operands[3]) == 1
20456    || INTVAL (operands[3]) == 128)
20457   && ix86_match_ccmode (insn, CCGCmode)
20458   && peep2_reg_dead_p (1, operands[2])"
20459  [(parallel [(set (match_dup 0)
20460		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20461	      (clobber (match_dup 2))])]
20462  "")
20463
20464(define_peephole2
20465  [(match_scratch:DI 0 "r")
20466   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20467	      (clobber (reg:CC FLAGS_REG))
20468	      (clobber (mem:BLK (scratch)))])]
20469  "optimize_size || !TARGET_SUB_ESP_4"
20470  [(clobber (match_dup 0))
20471   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20472	      (clobber (mem:BLK (scratch)))])])
20473
20474(define_peephole2
20475  [(match_scratch:DI 0 "r")
20476   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20477	      (clobber (reg:CC FLAGS_REG))
20478	      (clobber (mem:BLK (scratch)))])]
20479  "optimize_size || !TARGET_SUB_ESP_8"
20480  [(clobber (match_dup 0))
20481   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20482   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20483	      (clobber (mem:BLK (scratch)))])])
20484
20485;; Convert esp subtractions to push.
20486(define_peephole2
20487  [(match_scratch:DI 0 "r")
20488   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20489	      (clobber (reg:CC FLAGS_REG))])]
20490  "optimize_size || !TARGET_SUB_ESP_4"
20491  [(clobber (match_dup 0))
20492   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20493
20494(define_peephole2
20495  [(match_scratch:DI 0 "r")
20496   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20497	      (clobber (reg:CC FLAGS_REG))])]
20498  "optimize_size || !TARGET_SUB_ESP_8"
20499  [(clobber (match_dup 0))
20500   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20501   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20502
20503;; Convert epilogue deallocator to pop.
20504(define_peephole2
20505  [(match_scratch:DI 0 "r")
20506   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20507	      (clobber (reg:CC FLAGS_REG))
20508	      (clobber (mem:BLK (scratch)))])]
20509  "optimize_size || !TARGET_ADD_ESP_4"
20510  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20511	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20512	      (clobber (mem:BLK (scratch)))])]
20513  "")
20514
20515;; Two pops case is tricky, since pop causes dependency on destination register.
20516;; We use two registers if available.
20517(define_peephole2
20518  [(match_scratch:DI 0 "r")
20519   (match_scratch:DI 1 "r")
20520   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20521	      (clobber (reg:CC FLAGS_REG))
20522	      (clobber (mem:BLK (scratch)))])]
20523  "optimize_size || !TARGET_ADD_ESP_8"
20524  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20525	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20526	      (clobber (mem:BLK (scratch)))])
20527   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20528	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20529  "")
20530
20531(define_peephole2
20532  [(match_scratch:DI 0 "r")
20533   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20534	      (clobber (reg:CC FLAGS_REG))
20535	      (clobber (mem:BLK (scratch)))])]
20536  "optimize_size"
20537  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20538	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20539	      (clobber (mem:BLK (scratch)))])
20540   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20541	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20542  "")
20543
20544;; Convert esp additions to pop.
20545(define_peephole2
20546  [(match_scratch:DI 0 "r")
20547   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20548	      (clobber (reg:CC FLAGS_REG))])]
20549  ""
20550  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20551	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20552  "")
20553
20554;; Two pops case is tricky, since pop causes dependency on destination register.
20555;; We use two registers if available.
20556(define_peephole2
20557  [(match_scratch:DI 0 "r")
20558   (match_scratch:DI 1 "r")
20559   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20560	      (clobber (reg:CC FLAGS_REG))])]
20561  ""
20562  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20563	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20564   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20565	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20566  "")
20567
20568(define_peephole2
20569  [(match_scratch:DI 0 "r")
20570   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20571	      (clobber (reg:CC FLAGS_REG))])]
20572  "optimize_size"
20573  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20574	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20575   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20576	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20577  "")
20578
20579;; Convert imul by three, five and nine into lea
20580(define_peephole2
20581  [(parallel
20582    [(set (match_operand:SI 0 "register_operand" "")
20583	  (mult:SI (match_operand:SI 1 "register_operand" "")
20584		   (match_operand:SI 2 "const_int_operand" "")))
20585     (clobber (reg:CC FLAGS_REG))])]
20586  "INTVAL (operands[2]) == 3
20587   || INTVAL (operands[2]) == 5
20588   || INTVAL (operands[2]) == 9"
20589  [(set (match_dup 0)
20590        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20591                 (match_dup 1)))]
20592  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20593
20594(define_peephole2
20595  [(parallel
20596    [(set (match_operand:SI 0 "register_operand" "")
20597          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20598                   (match_operand:SI 2 "const_int_operand" "")))
20599     (clobber (reg:CC FLAGS_REG))])]
20600  "!optimize_size 
20601   && (INTVAL (operands[2]) == 3
20602       || INTVAL (operands[2]) == 5
20603       || INTVAL (operands[2]) == 9)"
20604  [(set (match_dup 0) (match_dup 1))
20605   (set (match_dup 0)
20606        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20607                 (match_dup 0)))]
20608  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20609
20610(define_peephole2
20611  [(parallel
20612    [(set (match_operand:DI 0 "register_operand" "")
20613	  (mult:DI (match_operand:DI 1 "register_operand" "")
20614		   (match_operand:DI 2 "const_int_operand" "")))
20615     (clobber (reg:CC FLAGS_REG))])]
20616  "TARGET_64BIT
20617   && (INTVAL (operands[2]) == 3
20618       || INTVAL (operands[2]) == 5
20619       || INTVAL (operands[2]) == 9)"
20620  [(set (match_dup 0)
20621        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20622                 (match_dup 1)))]
20623  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20624
20625(define_peephole2
20626  [(parallel
20627    [(set (match_operand:DI 0 "register_operand" "")
20628          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20629                   (match_operand:DI 2 "const_int_operand" "")))
20630     (clobber (reg:CC FLAGS_REG))])]
20631  "TARGET_64BIT
20632   && !optimize_size 
20633   && (INTVAL (operands[2]) == 3
20634       || INTVAL (operands[2]) == 5
20635       || INTVAL (operands[2]) == 9)"
20636  [(set (match_dup 0) (match_dup 1))
20637   (set (match_dup 0)
20638        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20639                 (match_dup 0)))]
20640  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20641
20642;; Imul $32bit_imm, mem, reg is vector decoded, while
20643;; imul $32bit_imm, reg, reg is direct decoded.
20644(define_peephole2
20645  [(match_scratch:DI 3 "r")
20646   (parallel [(set (match_operand:DI 0 "register_operand" "")
20647		   (mult:DI (match_operand:DI 1 "memory_operand" "")
20648			    (match_operand:DI 2 "immediate_operand" "")))
20649	      (clobber (reg:CC FLAGS_REG))])]
20650  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20651   && !satisfies_constraint_K (operands[2])"
20652  [(set (match_dup 3) (match_dup 1))
20653   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20654	      (clobber (reg:CC FLAGS_REG))])]
20655"")
20656
20657(define_peephole2
20658  [(match_scratch:SI 3 "r")
20659   (parallel [(set (match_operand:SI 0 "register_operand" "")
20660		   (mult:SI (match_operand:SI 1 "memory_operand" "")
20661			    (match_operand:SI 2 "immediate_operand" "")))
20662	      (clobber (reg:CC FLAGS_REG))])]
20663  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20664   && !satisfies_constraint_K (operands[2])"
20665  [(set (match_dup 3) (match_dup 1))
20666   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20667	      (clobber (reg:CC FLAGS_REG))])]
20668"")
20669
20670(define_peephole2
20671  [(match_scratch:SI 3 "r")
20672   (parallel [(set (match_operand:DI 0 "register_operand" "")
20673		   (zero_extend:DI
20674		     (mult:SI (match_operand:SI 1 "memory_operand" "")
20675			      (match_operand:SI 2 "immediate_operand" ""))))
20676	      (clobber (reg:CC FLAGS_REG))])]
20677  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20678   && !satisfies_constraint_K (operands[2])"
20679  [(set (match_dup 3) (match_dup 1))
20680   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20681	      (clobber (reg:CC FLAGS_REG))])]
20682"")
20683
20684;; imul $8/16bit_imm, regmem, reg is vector decoded.
20685;; Convert it into imul reg, reg
20686;; It would be better to force assembler to encode instruction using long
20687;; immediate, but there is apparently no way to do so.
20688(define_peephole2
20689  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20690		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20691			    (match_operand:DI 2 "const_int_operand" "")))
20692	      (clobber (reg:CC FLAGS_REG))])
20693   (match_scratch:DI 3 "r")]
20694  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20695   && satisfies_constraint_K (operands[2])"
20696  [(set (match_dup 3) (match_dup 2))
20697   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20698	      (clobber (reg:CC FLAGS_REG))])]
20699{
20700  if (!rtx_equal_p (operands[0], operands[1]))
20701    emit_move_insn (operands[0], operands[1]);
20702})
20703
20704(define_peephole2
20705  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20706		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20707			    (match_operand:SI 2 "const_int_operand" "")))
20708	      (clobber (reg:CC FLAGS_REG))])
20709   (match_scratch:SI 3 "r")]
20710  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20711   && satisfies_constraint_K (operands[2])"
20712  [(set (match_dup 3) (match_dup 2))
20713   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20714	      (clobber (reg:CC FLAGS_REG))])]
20715{
20716  if (!rtx_equal_p (operands[0], operands[1]))
20717    emit_move_insn (operands[0], operands[1]);
20718})
20719
20720(define_peephole2
20721  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20722		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20723			    (match_operand:HI 2 "immediate_operand" "")))
20724	      (clobber (reg:CC FLAGS_REG))])
20725   (match_scratch:HI 3 "r")]
20726  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20727  [(set (match_dup 3) (match_dup 2))
20728   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20729	      (clobber (reg:CC FLAGS_REG))])]
20730{
20731  if (!rtx_equal_p (operands[0], operands[1]))
20732    emit_move_insn (operands[0], operands[1]);
20733})
20734
20735;; After splitting up read-modify operations, array accesses with memory
20736;; operands might end up in form:
20737;;  sall    $2, %eax
20738;;  movl    4(%esp), %edx
20739;;  addl    %edx, %eax
20740;; instead of pre-splitting:
20741;;  sall    $2, %eax
20742;;  addl    4(%esp), %eax
20743;; Turn it into:
20744;;  movl    4(%esp), %edx
20745;;  leal    (%edx,%eax,4), %eax
20746
20747(define_peephole2
20748  [(parallel [(set (match_operand 0 "register_operand" "")
20749		   (ashift (match_operand 1 "register_operand" "")
20750			   (match_operand 2 "const_int_operand" "")))
20751	       (clobber (reg:CC FLAGS_REG))])
20752   (set (match_operand 3 "register_operand")
20753        (match_operand 4 "x86_64_general_operand" ""))
20754   (parallel [(set (match_operand 5 "register_operand" "")
20755		   (plus (match_operand 6 "register_operand" "")
20756			 (match_operand 7 "register_operand" "")))
20757		   (clobber (reg:CC FLAGS_REG))])]
20758  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20759   /* Validate MODE for lea.  */
20760   && ((!TARGET_PARTIAL_REG_STALL
20761	&& (GET_MODE (operands[0]) == QImode
20762	    || GET_MODE (operands[0]) == HImode))
20763       || GET_MODE (operands[0]) == SImode 
20764       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20765   /* We reorder load and the shift.  */
20766   && !rtx_equal_p (operands[1], operands[3])
20767   && !reg_overlap_mentioned_p (operands[0], operands[4])
20768   /* Last PLUS must consist of operand 0 and 3.  */
20769   && !rtx_equal_p (operands[0], operands[3])
20770   && (rtx_equal_p (operands[3], operands[6])
20771       || rtx_equal_p (operands[3], operands[7]))
20772   && (rtx_equal_p (operands[0], operands[6])
20773       || rtx_equal_p (operands[0], operands[7]))
20774   /* The intermediate operand 0 must die or be same as output.  */
20775   && (rtx_equal_p (operands[0], operands[5])
20776       || peep2_reg_dead_p (3, operands[0]))"
20777  [(set (match_dup 3) (match_dup 4))
20778   (set (match_dup 0) (match_dup 1))]
20779{
20780  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20781  int scale = 1 << INTVAL (operands[2]);
20782  rtx index = gen_lowpart (Pmode, operands[1]);
20783  rtx base = gen_lowpart (Pmode, operands[3]);
20784  rtx dest = gen_lowpart (mode, operands[5]);
20785
20786  operands[1] = gen_rtx_PLUS (Pmode, base,
20787  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20788  if (mode != Pmode)
20789    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20790  operands[0] = dest;
20791})
20792
20793;; Call-value patterns last so that the wildcard operand does not
20794;; disrupt insn-recog's switch tables.
20795
20796(define_insn "*call_value_pop_0"
20797  [(set (match_operand 0 "" "")
20798	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20799	      (match_operand:SI 2 "" "")))
20800   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20801			    (match_operand:SI 3 "immediate_operand" "")))]
20802  "!TARGET_64BIT"
20803{
20804  if (SIBLING_CALL_P (insn))
20805    return "jmp\t%P1";
20806  else
20807    return "call\t%P1";
20808}
20809  [(set_attr "type" "callv")])
20810
20811(define_insn "*call_value_pop_1"
20812  [(set (match_operand 0 "" "")
20813	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20814	      (match_operand:SI 2 "" "")))
20815   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20816			    (match_operand:SI 3 "immediate_operand" "i")))]
20817  "!TARGET_64BIT"
20818{
20819  if (constant_call_address_operand (operands[1], Pmode))
20820    {
20821      if (SIBLING_CALL_P (insn))
20822	return "jmp\t%P1";
20823      else
20824	return "call\t%P1";
20825    }
20826  if (SIBLING_CALL_P (insn))
20827    return "jmp\t%A1";
20828  else
20829    return "call\t%A1";
20830}
20831  [(set_attr "type" "callv")])
20832
20833(define_insn "*call_value_0"
20834  [(set (match_operand 0 "" "")
20835	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20836	      (match_operand:SI 2 "" "")))]
20837  "!TARGET_64BIT"
20838{
20839  if (SIBLING_CALL_P (insn))
20840    return "jmp\t%P1";
20841  else
20842    return "call\t%P1";
20843}
20844  [(set_attr "type" "callv")])
20845
20846(define_insn "*call_value_0_rex64"
20847  [(set (match_operand 0 "" "")
20848	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20849	      (match_operand:DI 2 "const_int_operand" "")))]
20850  "TARGET_64BIT"
20851{
20852  if (SIBLING_CALL_P (insn))
20853    return "jmp\t%P1";
20854  else
20855    return "call\t%P1";
20856}
20857  [(set_attr "type" "callv")])
20858
20859(define_insn "*call_value_1"
20860  [(set (match_operand 0 "" "")
20861	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20862	      (match_operand:SI 2 "" "")))]
20863  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20864{
20865  if (constant_call_address_operand (operands[1], Pmode))
20866    return "call\t%P1";
20867  return "call\t%A1";
20868}
20869  [(set_attr "type" "callv")])
20870
20871(define_insn "*sibcall_value_1"
20872  [(set (match_operand 0 "" "")
20873	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20874	      (match_operand:SI 2 "" "")))]
20875  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20876{
20877  if (constant_call_address_operand (operands[1], Pmode))
20878    return "jmp\t%P1";
20879  return "jmp\t%A1";
20880}
20881  [(set_attr "type" "callv")])
20882
20883(define_insn "*call_value_1_rex64"
20884  [(set (match_operand 0 "" "")
20885	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20886	      (match_operand:DI 2 "" "")))]
20887  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20888{
20889  if (constant_call_address_operand (operands[1], Pmode))
20890    return "call\t%P1";
20891  return "call\t%A1";
20892}
20893  [(set_attr "type" "callv")])
20894
20895(define_insn "*sibcall_value_1_rex64"
20896  [(set (match_operand 0 "" "")
20897	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20898	      (match_operand:DI 2 "" "")))]
20899  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20900  "jmp\t%P1"
20901  [(set_attr "type" "callv")])
20902
20903(define_insn "*sibcall_value_1_rex64_v"
20904  [(set (match_operand 0 "" "")
20905	(call (mem:QI (reg:DI R11_REG))
20906	      (match_operand:DI 1 "" "")))]
20907  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20908  "jmp\t*%%r11"
20909  [(set_attr "type" "callv")])
20910
20911;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20912;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20913;; caught for use by garbage collectors and the like.  Using an insn that
20914;; maps to SIGILL makes it more likely the program will rightfully die.
20915;; Keeping with tradition, "6" is in honor of #UD.
20916(define_insn "trap"
20917  [(trap_if (const_int 1) (const_int 6))]
20918  ""
20919  { return ASM_SHORT "0x0b0f"; }
20920  [(set_attr "length" "2")])
20921
20922(define_expand "sse_prologue_save"
20923  [(parallel [(set (match_operand:BLK 0 "" "")
20924		   (unspec:BLK [(reg:DI 22)
20925				(reg:DI 23)
20926				(reg:DI 24)
20927				(reg:DI 25)
20928				(reg:DI 26)
20929				(reg:DI 27)
20930				(reg:DI 28)
20931				(reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20932	      (use (match_operand:DI 1 "register_operand" ""))
20933	      (use (match_operand:DI 2 "immediate_operand" ""))
20934	      (use (label_ref:DI (match_operand 3 "" "")))])]
20935  "TARGET_64BIT"
20936  "")
20937
20938(define_insn "*sse_prologue_save_insn"
20939  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20940			  (match_operand:DI 4 "const_int_operand" "n")))
20941	(unspec:BLK [(reg:DI 22)
20942		     (reg:DI 23)
20943		     (reg:DI 24)
20944		     (reg:DI 25)
20945		     (reg:DI 26)
20946		     (reg:DI 27)
20947		     (reg:DI 28)
20948		     (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20949   (use (match_operand:DI 1 "register_operand" "r"))
20950   (use (match_operand:DI 2 "const_int_operand" "i"))
20951   (use (label_ref:DI (match_operand 3 "" "X")))]
20952  "TARGET_64BIT
20953   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20954   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20955  "*
20956{
20957  int i;
20958  operands[0] = gen_rtx_MEM (Pmode,
20959			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20960  output_asm_insn (\"jmp\\t%A1\", operands);
20961  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20962    {
20963      operands[4] = adjust_address (operands[0], DImode, i*16);
20964      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20965      PUT_MODE (operands[4], TImode);
20966      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20967        output_asm_insn (\"rex\", operands);
20968      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20969    }
20970  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20971			     CODE_LABEL_NUMBER (operands[3]));
20972  RET;
20973}
20974  "
20975  [(set_attr "type" "other")
20976   (set_attr "length_immediate" "0")
20977   (set_attr "length_address" "0")
20978   (set_attr "length" "135")
20979   (set_attr "memory" "store")
20980   (set_attr "modrm" "0")
20981   (set_attr "mode" "DI")])
20982
20983(define_expand "prefetch"
20984  [(prefetch (match_operand 0 "address_operand" "")
20985	     (match_operand:SI 1 "const_int_operand" "")
20986	     (match_operand:SI 2 "const_int_operand" ""))]
20987  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20988{
20989  int rw = INTVAL (operands[1]);
20990  int locality = INTVAL (operands[2]);
20991
20992  gcc_assert (rw == 0 || rw == 1);
20993  gcc_assert (locality >= 0 && locality <= 3);
20994  gcc_assert (GET_MODE (operands[0]) == Pmode
20995	      || GET_MODE (operands[0]) == VOIDmode);
20996
20997  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20998     supported by SSE counterpart or the SSE prefetch is not available
20999     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21000     of locality.  */
21001  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21002    operands[2] = GEN_INT (3);
21003  else
21004    operands[1] = const0_rtx;
21005})
21006
21007(define_insn "*prefetch_sse"
21008  [(prefetch (match_operand:SI 0 "address_operand" "p")
21009	     (const_int 0)
21010	     (match_operand:SI 1 "const_int_operand" ""))]
21011  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21012{
21013  static const char * const patterns[4] = {
21014   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21015  };
21016
21017  int locality = INTVAL (operands[1]);
21018  gcc_assert (locality >= 0 && locality <= 3);
21019
21020  return patterns[locality];  
21021}
21022  [(set_attr "type" "sse")
21023   (set_attr "memory" "none")])
21024
21025(define_insn "*prefetch_sse_rex"
21026  [(prefetch (match_operand:DI 0 "address_operand" "p")
21027	     (const_int 0)
21028	     (match_operand:SI 1 "const_int_operand" ""))]
21029  "TARGET_PREFETCH_SSE && TARGET_64BIT"
21030{
21031  static const char * const patterns[4] = {
21032   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21033  };
21034
21035  int locality = INTVAL (operands[1]);
21036  gcc_assert (locality >= 0 && locality <= 3);
21037
21038  return patterns[locality];  
21039}
21040  [(set_attr "type" "sse")
21041   (set_attr "memory" "none")])
21042
21043(define_insn "*prefetch_3dnow"
21044  [(prefetch (match_operand:SI 0 "address_operand" "p")
21045	     (match_operand:SI 1 "const_int_operand" "n")
21046	     (const_int 3))]
21047  "TARGET_3DNOW && !TARGET_64BIT"
21048{
21049  if (INTVAL (operands[1]) == 0)
21050    return "prefetch\t%a0";
21051  else
21052    return "prefetchw\t%a0";
21053}
21054  [(set_attr "type" "mmx")
21055   (set_attr "memory" "none")])
21056
21057(define_insn "*prefetch_3dnow_rex"
21058  [(prefetch (match_operand:DI 0 "address_operand" "p")
21059	     (match_operand:SI 1 "const_int_operand" "n")
21060	     (const_int 3))]
21061  "TARGET_3DNOW && TARGET_64BIT"
21062{
21063  if (INTVAL (operands[1]) == 0)
21064    return "prefetch\t%a0";
21065  else
21066    return "prefetchw\t%a0";
21067}
21068  [(set_attr "type" "mmx")
21069   (set_attr "memory" "none")])
21070
21071(define_expand "stack_protect_set"
21072  [(match_operand 0 "memory_operand" "")
21073   (match_operand 1 "memory_operand" "")]
21074  ""
21075{
21076#ifdef TARGET_THREAD_SSP_OFFSET
21077  if (TARGET_64BIT)
21078    emit_insn (gen_stack_tls_protect_set_di (operands[0],
21079					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21080  else
21081    emit_insn (gen_stack_tls_protect_set_si (operands[0],
21082					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21083#else
21084  if (TARGET_64BIT)
21085    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21086  else
21087    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21088#endif
21089  DONE;
21090})
21091
21092(define_insn "stack_protect_set_si"
21093  [(set (match_operand:SI 0 "memory_operand" "=m")
21094	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21095   (set (match_scratch:SI 2 "=&r") (const_int 0))
21096   (clobber (reg:CC FLAGS_REG))]
21097  ""
21098  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21099  [(set_attr "type" "multi")])
21100
21101(define_insn "stack_protect_set_di"
21102  [(set (match_operand:DI 0 "memory_operand" "=m")
21103	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21104   (set (match_scratch:DI 2 "=&r") (const_int 0))
21105   (clobber (reg:CC FLAGS_REG))]
21106  "TARGET_64BIT"
21107  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21108  [(set_attr "type" "multi")])
21109
21110(define_insn "stack_tls_protect_set_si"
21111  [(set (match_operand:SI 0 "memory_operand" "=m")
21112	(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21113   (set (match_scratch:SI 2 "=&r") (const_int 0))
21114   (clobber (reg:CC FLAGS_REG))]
21115  ""
21116  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21117  [(set_attr "type" "multi")])
21118
21119(define_insn "stack_tls_protect_set_di"
21120  [(set (match_operand:DI 0 "memory_operand" "=m")
21121	(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21122   (set (match_scratch:DI 2 "=&r") (const_int 0))
21123   (clobber (reg:CC FLAGS_REG))]
21124  "TARGET_64BIT"
21125  {
21126     /* The kernel uses a different segment register for performance reasons; a
21127        system call would not have to trash the userspace segment register,
21128        which would be expensive */
21129     if (ix86_cmodel != CM_KERNEL)
21130        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21131     else
21132        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21133  }
21134  [(set_attr "type" "multi")])
21135
21136(define_expand "stack_protect_test"
21137  [(match_operand 0 "memory_operand" "")
21138   (match_operand 1 "memory_operand" "")
21139   (match_operand 2 "" "")]
21140  ""
21141{
21142  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21143  ix86_compare_op0 = operands[0];
21144  ix86_compare_op1 = operands[1];
21145  ix86_compare_emitted = flags;
21146
21147#ifdef TARGET_THREAD_SSP_OFFSET
21148  if (TARGET_64BIT)
21149    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21150					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21151  else
21152    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21153					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21154#else
21155  if (TARGET_64BIT)
21156    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21157  else
21158    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21159#endif
21160  emit_jump_insn (gen_beq (operands[2]));
21161  DONE;
21162})
21163
21164(define_insn "stack_protect_test_si"
21165  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21166	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21167		     (match_operand:SI 2 "memory_operand" "m")]
21168		    UNSPEC_SP_TEST))
21169   (clobber (match_scratch:SI 3 "=&r"))]
21170  ""
21171  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21172  [(set_attr "type" "multi")])
21173
21174(define_insn "stack_protect_test_di"
21175  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21176	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21177		     (match_operand:DI 2 "memory_operand" "m")]
21178		    UNSPEC_SP_TEST))
21179   (clobber (match_scratch:DI 3 "=&r"))]
21180  "TARGET_64BIT"
21181  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21182  [(set_attr "type" "multi")])
21183
21184(define_insn "stack_tls_protect_test_si"
21185  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21186	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21187		     (match_operand:SI 2 "const_int_operand" "i")]
21188		    UNSPEC_SP_TLS_TEST))
21189   (clobber (match_scratch:SI 3 "=r"))]
21190  ""
21191  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21192  [(set_attr "type" "multi")])
21193
21194(define_insn "stack_tls_protect_test_di"
21195  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21196	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21197		     (match_operand:DI 2 "const_int_operand" "i")]
21198		    UNSPEC_SP_TLS_TEST))
21199   (clobber (match_scratch:DI 3 "=r"))]
21200  "TARGET_64BIT"
21201  {
21202     /* The kernel uses a different segment register for performance reasons; a
21203        system call would not have to trash the userspace segment register,
21204        which would be expensive */
21205     if (ix86_cmodel != CM_KERNEL)
21206        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21207     else
21208        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21209  }
21210  [(set_attr "type" "multi")])
21211
21212(include "mmx.md")
21213(include "sse.md")
21214(include "sync.md")
21215