i386.md revision 219374
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_LDQQU		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
153(define_constants
154  [(UNSPECV_BLOCKAGE		0)
155   (UNSPECV_STACK_PROBE		1)
156   (UNSPECV_EMMS		2)
157   (UNSPECV_LDMXCSR		3)
158   (UNSPECV_STMXCSR		4)
159   (UNSPECV_FEMMS		5)
160   (UNSPECV_CLFLUSH		6)
161   (UNSPECV_ALIGN		7)
162   (UNSPECV_MONITOR		8)
163   (UNSPECV_MWAIT		9)
164   (UNSPECV_CMPXCHG_1		10)
165   (UNSPECV_CMPXCHG_2		11)
166   (UNSPECV_XCHG		12)
167   (UNSPECV_LOCK		13)
168  ])
169
170;; Registers by name.
171(define_constants
172  [(BP_REG			 6)
173   (SP_REG			 7)
174   (FLAGS_REG			17)
175   (FPSR_REG			18)
176   (DIRFLAG_REG			19)
177  ])
178
179;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180;; from i386.c.
181
182;; In C guard expressions, put expressions which may be compile-time
183;; constants first.  This allows for better optimization.  For
184;; example, write "TARGET_64BIT && reload_completed", not
185;; "reload_completed && TARGET_64BIT".
186
187
188;; Processor type.  This attribute must exactly match the processor_type
189;; enumeration in i386.h.
190(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
191  (const (symbol_ref "ix86_tune")))
192
193;; A basic instruction type.  Refinements due to arguments to be
194;; provided in other attributes.
195(define_attr "type"
196  "other,multi,
197   alu,alu1,negnot,imov,imovx,lea,
198   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199   icmp,test,ibr,setcc,icmov,
200   push,pop,call,callv,leave,
201   str,cld,
202   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203   sselog,sselog1,sseiadd,sseishft,sseimul,
204   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206  (const_string "other"))
207
208;; Main data type used by the insn
209(define_attr "mode"
210  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211  (const_string "unknown"))
212
213;; The CPU unit operations uses.
214(define_attr "unit" "integer,i387,sse,mmx,unknown"
215  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216	   (const_string "i387")
217	 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219	   (const_string "sse")
220	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221	   (const_string "mmx")
222	 (eq_attr "type" "other")
223	   (const_string "unknown")]
224	 (const_string "integer")))
225
226;; The (bounding maximum) length of an instruction immediate.
227(define_attr "length_immediate" ""
228  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229	   (const_int 0)
230	 (eq_attr "unit" "i387,sse,mmx")
231	   (const_int 0)
232	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233			  imul,icmp,push,pop")
234	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235	 (eq_attr "type" "imov,test")
236	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237	 (eq_attr "type" "call")
238	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
239	     (const_int 4)
240	     (const_int 0))
241	 (eq_attr "type" "callv")
242	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
243	     (const_int 4)
244	     (const_int 0))
245	 ;; We don't know the size before shorten_branches.  Expect
246	 ;; the instruction to fit for better scheduling.
247	 (eq_attr "type" "ibr")
248	   (const_int 1)
249	 ]
250	 (symbol_ref "/* Update immediate_length and other attributes! */
251		      gcc_unreachable (),1")))
252
253;; The (bounding maximum) length of an instruction address.
254(define_attr "length_address" ""
255  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256	   (const_int 0)
257	 (and (eq_attr "type" "call")
258	      (match_operand 0 "constant_call_address_operand" ""))
259	     (const_int 0)
260	 (and (eq_attr "type" "callv")
261	      (match_operand 1 "constant_call_address_operand" ""))
262	     (const_int 0)
263	 ]
264	 (symbol_ref "ix86_attr_length_address_default (insn)")))
265
266;; Set when length prefix is used.
267(define_attr "prefix_data16" ""
268  (if_then_else (ior (eq_attr "mode" "HI")
269		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270    (const_int 1)
271    (const_int 0)))
272
273;; Set when string REP prefix is used.
274(define_attr "prefix_rep" "" 
275  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276    (const_int 1)
277    (const_int 0)))
278
279;; Set when 0f opcode prefix is used.
280(define_attr "prefix_0f" ""
281  (if_then_else 
282    (ior (eq_attr "type" "imovx,setcc,icmov")
283	 (eq_attr "unit" "sse,mmx"))
284    (const_int 1)
285    (const_int 0)))
286
287;; Set when REX opcode prefix is used.
288(define_attr "prefix_rex" ""
289  (cond [(and (eq_attr "mode" "DI")
290  	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291	   (const_int 1)
292	 (and (eq_attr "mode" "QI")
293	      (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294		  (const_int 0)))
295	   (const_int 1)
296	 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297	     (const_int 0))
298	   (const_int 1)
299	]
300	(const_int 0)))
301
302;; Set when modrm byte is used.
303(define_attr "modrm" ""
304  (cond [(eq_attr "type" "str,cld,leave")
305	   (const_int 0)
306	 (eq_attr "unit" "i387")
307	   (const_int 0)
308         (and (eq_attr "type" "incdec")
309	      (ior (match_operand:SI 1 "register_operand" "")
310		   (match_operand:HI 1 "register_operand" "")))
311	   (const_int 0)
312	 (and (eq_attr "type" "push")
313	      (not (match_operand 1 "memory_operand" "")))
314	   (const_int 0)
315	 (and (eq_attr "type" "pop")
316	      (not (match_operand 0 "memory_operand" "")))
317	   (const_int 0)
318	 (and (eq_attr "type" "imov")
319	      (ior (and (match_operand 0 "register_operand" "")
320			(match_operand 1 "immediate_operand" ""))
321		   (ior (and (match_operand 0 "ax_reg_operand" "")
322			     (match_operand 1 "memory_displacement_only_operand" ""))
323			(and (match_operand 0 "memory_displacement_only_operand" "")
324			     (match_operand 1 "ax_reg_operand" "")))))
325	   (const_int 0)
326	 (and (eq_attr "type" "call")
327	      (match_operand 0 "constant_call_address_operand" ""))
328	     (const_int 0)
329	 (and (eq_attr "type" "callv")
330	      (match_operand 1 "constant_call_address_operand" ""))
331	     (const_int 0)
332	 ]
333	 (const_int 1)))
334
335;; The (bounding maximum) length of an instruction in bytes.
336;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337;; Later we may want to split them and compute proper length as for
338;; other insns.
339(define_attr "length" ""
340  (cond [(eq_attr "type" "other,multi,fistp,frndint")
341	   (const_int 16)
342	 (eq_attr "type" "fcmp")
343	   (const_int 4)
344	 (eq_attr "unit" "i387")
345	   (plus (const_int 2)
346		 (plus (attr "prefix_data16")
347		       (attr "length_address")))]
348	 (plus (plus (attr "modrm")
349		     (plus (attr "prefix_0f")
350			   (plus (attr "prefix_rex")
351				 (const_int 1))))
352	       (plus (attr "prefix_rep")
353		     (plus (attr "prefix_data16")
354			   (plus (attr "length_immediate")
355				 (attr "length_address")))))))
356
357;; The `memory' attribute is `none' if no memory is referenced, `load' or
358;; `store' if there is a simple memory reference therein, or `unknown'
359;; if the instruction is complex.
360
361(define_attr "memory" "none,load,store,both,unknown"
362  (cond [(eq_attr "type" "other,multi,str")
363	   (const_string "unknown")
364	 (eq_attr "type" "lea,fcmov,fpspc,cld")
365	   (const_string "none")
366	 (eq_attr "type" "fistp,leave")
367	   (const_string "both")
368	 (eq_attr "type" "frndint")
369	   (const_string "load")
370	 (eq_attr "type" "push")
371	   (if_then_else (match_operand 1 "memory_operand" "")
372	     (const_string "both")
373	     (const_string "store"))
374	 (eq_attr "type" "pop")
375	   (if_then_else (match_operand 0 "memory_operand" "")
376	     (const_string "both")
377	     (const_string "load"))
378	 (eq_attr "type" "setcc")
379	   (if_then_else (match_operand 0 "memory_operand" "")
380	     (const_string "store")
381	     (const_string "none"))
382	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383	   (if_then_else (ior (match_operand 0 "memory_operand" "")
384			      (match_operand 1 "memory_operand" ""))
385	     (const_string "load")
386	     (const_string "none"))
387	 (eq_attr "type" "ibr")
388	   (if_then_else (match_operand 0 "memory_operand" "")
389	     (const_string "load")
390	     (const_string "none"))
391	 (eq_attr "type" "call")
392	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
393	     (const_string "none")
394	     (const_string "load"))
395	 (eq_attr "type" "callv")
396	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
397	     (const_string "none")
398	     (const_string "load"))
399	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400	      (match_operand 1 "memory_operand" ""))
401	   (const_string "both")
402	 (and (match_operand 0 "memory_operand" "")
403	      (match_operand 1 "memory_operand" ""))
404	   (const_string "both")
405	 (match_operand 0 "memory_operand" "")
406	   (const_string "store")
407	 (match_operand 1 "memory_operand" "")
408	   (const_string "load")
409	 (and (eq_attr "type"
410		 "!alu1,negnot,ishift1,
411		   imov,imovx,icmp,test,
412		   fmov,fcmp,fsgn,
413		   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414		   mmx,mmxmov,mmxcmp,mmxcvt")
415	      (match_operand 2 "memory_operand" ""))
416	   (const_string "load")
417	 (and (eq_attr "type" "icmov")
418	      (match_operand 3 "memory_operand" ""))
419	   (const_string "load")
420	]
421	(const_string "none")))
422
423;; Indicates if an instruction has both an immediate and a displacement.
424
425(define_attr "imm_disp" "false,true,unknown"
426  (cond [(eq_attr "type" "other,multi")
427	   (const_string "unknown")
428	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429	      (and (match_operand 0 "memory_displacement_operand" "")
430		   (match_operand 1 "immediate_operand" "")))
431	   (const_string "true")
432	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433	      (and (match_operand 0 "memory_displacement_operand" "")
434		   (match_operand 2 "immediate_operand" "")))
435	   (const_string "true")
436	]
437	(const_string "false")))
438
439;; Indicates if an FP operation has an integer source.
440
441(define_attr "fp_int_src" "false,true"
442  (const_string "false"))
443
444;; Defines rounding mode of an FP operation.
445
446(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447  (const_string "any"))
448
449;; Describe a user's asm statement.
450(define_asm_attributes
451  [(set_attr "length" "128")
452   (set_attr "type" "multi")])
453
454;; All x87 floating point modes
455(define_mode_macro X87MODEF [SF DF XF])
456 
457;; All integer modes handled by x87 fisttp operator.
458(define_mode_macro X87MODEI [HI SI DI])
459
460;; All integer modes handled by integer x87 operators.
461(define_mode_macro X87MODEI12 [HI SI])
462
463;; All SSE floating point modes
464(define_mode_macro SSEMODEF [SF DF])
465 
466;; All integer modes handled by SSE cvtts?2si* operators.
467(define_mode_macro SSEMODEI24 [SI DI])
468
469
470;; Scheduling descriptions
471
472(include "pentium.md")
473(include "ppro.md")
474(include "k6.md")
475(include "athlon.md")
476(include "geode.md")
477
478
479;; Operand and operator predicates and constraints
480
481(include "predicates.md")
482(include "constraints.md")
483
484
485;; Compare instructions.
486
487;; All compare insns have expanders that save the operands away without
488;; actually generating RTL.  The bCOND or sCOND (emitted immediately
489;; after the cmp) will actually emit the cmpM.
490
491(define_expand "cmpti"
492  [(set (reg:CC FLAGS_REG)
493	(compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
494		    (match_operand:TI 1 "x86_64_general_operand" "")))]
495  "TARGET_64BIT"
496{
497  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
498    operands[0] = force_reg (TImode, operands[0]);
499  ix86_compare_op0 = operands[0];
500  ix86_compare_op1 = operands[1];
501  DONE;
502})
503
504(define_expand "cmpdi"
505  [(set (reg:CC FLAGS_REG)
506	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
507		    (match_operand:DI 1 "x86_64_general_operand" "")))]
508  ""
509{
510  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
511    operands[0] = force_reg (DImode, operands[0]);
512  ix86_compare_op0 = operands[0];
513  ix86_compare_op1 = operands[1];
514  DONE;
515})
516
517(define_expand "cmpsi"
518  [(set (reg:CC FLAGS_REG)
519	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
520		    (match_operand:SI 1 "general_operand" "")))]
521  ""
522{
523  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
524    operands[0] = force_reg (SImode, operands[0]);
525  ix86_compare_op0 = operands[0];
526  ix86_compare_op1 = operands[1];
527  DONE;
528})
529
530(define_expand "cmphi"
531  [(set (reg:CC FLAGS_REG)
532	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
533		    (match_operand:HI 1 "general_operand" "")))]
534  ""
535{
536  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
537    operands[0] = force_reg (HImode, operands[0]);
538  ix86_compare_op0 = operands[0];
539  ix86_compare_op1 = operands[1];
540  DONE;
541})
542
543(define_expand "cmpqi"
544  [(set (reg:CC FLAGS_REG)
545	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
546		    (match_operand:QI 1 "general_operand" "")))]
547  "TARGET_QIMODE_MATH"
548{
549  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
550    operands[0] = force_reg (QImode, operands[0]);
551  ix86_compare_op0 = operands[0];
552  ix86_compare_op1 = operands[1];
553  DONE;
554})
555
556(define_insn "cmpdi_ccno_1_rex64"
557  [(set (reg FLAGS_REG)
558	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
559		 (match_operand:DI 1 "const0_operand" "n,n")))]
560  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
561  "@
562   test{q}\t{%0, %0|%0, %0}
563   cmp{q}\t{%1, %0|%0, %1}"
564  [(set_attr "type" "test,icmp")
565   (set_attr "length_immediate" "0,1")
566   (set_attr "mode" "DI")])
567
568(define_insn "*cmpdi_minus_1_rex64"
569  [(set (reg FLAGS_REG)
570	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
571			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
572		 (const_int 0)))]
573  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
574  "cmp{q}\t{%1, %0|%0, %1}"
575  [(set_attr "type" "icmp")
576   (set_attr "mode" "DI")])
577
578(define_expand "cmpdi_1_rex64"
579  [(set (reg:CC FLAGS_REG)
580	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
581		    (match_operand:DI 1 "general_operand" "")))]
582  "TARGET_64BIT"
583  "")
584
585(define_insn "cmpdi_1_insn_rex64"
586  [(set (reg FLAGS_REG)
587	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
588		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
589  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
590  "cmp{q}\t{%1, %0|%0, %1}"
591  [(set_attr "type" "icmp")
592   (set_attr "mode" "DI")])
593
594
595(define_insn "*cmpsi_ccno_1"
596  [(set (reg FLAGS_REG)
597	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
598		 (match_operand:SI 1 "const0_operand" "n,n")))]
599  "ix86_match_ccmode (insn, CCNOmode)"
600  "@
601   test{l}\t{%0, %0|%0, %0}
602   cmp{l}\t{%1, %0|%0, %1}"
603  [(set_attr "type" "test,icmp")
604   (set_attr "length_immediate" "0,1")
605   (set_attr "mode" "SI")])
606
607(define_insn "*cmpsi_minus_1"
608  [(set (reg FLAGS_REG)
609	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
610			   (match_operand:SI 1 "general_operand" "ri,mr"))
611		 (const_int 0)))]
612  "ix86_match_ccmode (insn, CCGOCmode)"
613  "cmp{l}\t{%1, %0|%0, %1}"
614  [(set_attr "type" "icmp")
615   (set_attr "mode" "SI")])
616
617(define_expand "cmpsi_1"
618  [(set (reg:CC FLAGS_REG)
619	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
620		    (match_operand:SI 1 "general_operand" "ri,mr")))]
621  ""
622  "")
623
624(define_insn "*cmpsi_1_insn"
625  [(set (reg FLAGS_REG)
626	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
627		 (match_operand:SI 1 "general_operand" "ri,mr")))]
628  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
629    && ix86_match_ccmode (insn, CCmode)"
630  "cmp{l}\t{%1, %0|%0, %1}"
631  [(set_attr "type" "icmp")
632   (set_attr "mode" "SI")])
633
634(define_insn "*cmphi_ccno_1"
635  [(set (reg FLAGS_REG)
636	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
637		 (match_operand:HI 1 "const0_operand" "n,n")))]
638  "ix86_match_ccmode (insn, CCNOmode)"
639  "@
640   test{w}\t{%0, %0|%0, %0}
641   cmp{w}\t{%1, %0|%0, %1}"
642  [(set_attr "type" "test,icmp")
643   (set_attr "length_immediate" "0,1")
644   (set_attr "mode" "HI")])
645
646(define_insn "*cmphi_minus_1"
647  [(set (reg FLAGS_REG)
648	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
649			   (match_operand:HI 1 "general_operand" "ri,mr"))
650		 (const_int 0)))]
651  "ix86_match_ccmode (insn, CCGOCmode)"
652  "cmp{w}\t{%1, %0|%0, %1}"
653  [(set_attr "type" "icmp")
654   (set_attr "mode" "HI")])
655
656(define_insn "*cmphi_1"
657  [(set (reg FLAGS_REG)
658	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
659		 (match_operand:HI 1 "general_operand" "ri,mr")))]
660  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
661   && ix86_match_ccmode (insn, CCmode)"
662  "cmp{w}\t{%1, %0|%0, %1}"
663  [(set_attr "type" "icmp")
664   (set_attr "mode" "HI")])
665
666(define_insn "*cmpqi_ccno_1"
667  [(set (reg FLAGS_REG)
668	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
669		 (match_operand:QI 1 "const0_operand" "n,n")))]
670  "ix86_match_ccmode (insn, CCNOmode)"
671  "@
672   test{b}\t{%0, %0|%0, %0}
673   cmp{b}\t{$0, %0|%0, 0}"
674  [(set_attr "type" "test,icmp")
675   (set_attr "length_immediate" "0,1")
676   (set_attr "mode" "QI")])
677
678(define_insn "*cmpqi_1"
679  [(set (reg FLAGS_REG)
680	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
681		 (match_operand:QI 1 "general_operand" "qi,mq")))]
682  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
683    && ix86_match_ccmode (insn, CCmode)"
684  "cmp{b}\t{%1, %0|%0, %1}"
685  [(set_attr "type" "icmp")
686   (set_attr "mode" "QI")])
687
688(define_insn "*cmpqi_minus_1"
689  [(set (reg FLAGS_REG)
690	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
691			   (match_operand:QI 1 "general_operand" "qi,mq"))
692		 (const_int 0)))]
693  "ix86_match_ccmode (insn, CCGOCmode)"
694  "cmp{b}\t{%1, %0|%0, %1}"
695  [(set_attr "type" "icmp")
696   (set_attr "mode" "QI")])
697
698(define_insn "*cmpqi_ext_1"
699  [(set (reg FLAGS_REG)
700	(compare
701	  (match_operand:QI 0 "general_operand" "Qm")
702	  (subreg:QI
703	    (zero_extract:SI
704	      (match_operand 1 "ext_register_operand" "Q")
705	      (const_int 8)
706	      (const_int 8)) 0)))]
707  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
708  "cmp{b}\t{%h1, %0|%0, %h1}"
709  [(set_attr "type" "icmp")
710   (set_attr "mode" "QI")])
711
712(define_insn "*cmpqi_ext_1_rex64"
713  [(set (reg FLAGS_REG)
714	(compare
715	  (match_operand:QI 0 "register_operand" "Q")
716	  (subreg:QI
717	    (zero_extract:SI
718	      (match_operand 1 "ext_register_operand" "Q")
719	      (const_int 8)
720	      (const_int 8)) 0)))]
721  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
722  "cmp{b}\t{%h1, %0|%0, %h1}"
723  [(set_attr "type" "icmp")
724   (set_attr "mode" "QI")])
725
726(define_insn "*cmpqi_ext_2"
727  [(set (reg FLAGS_REG)
728	(compare
729	  (subreg:QI
730	    (zero_extract:SI
731	      (match_operand 0 "ext_register_operand" "Q")
732	      (const_int 8)
733	      (const_int 8)) 0)
734	  (match_operand:QI 1 "const0_operand" "n")))]
735  "ix86_match_ccmode (insn, CCNOmode)"
736  "test{b}\t%h0, %h0"
737  [(set_attr "type" "test")
738   (set_attr "length_immediate" "0")
739   (set_attr "mode" "QI")])
740
741(define_expand "cmpqi_ext_3"
742  [(set (reg:CC FLAGS_REG)
743	(compare:CC
744	  (subreg:QI
745	    (zero_extract:SI
746	      (match_operand 0 "ext_register_operand" "")
747	      (const_int 8)
748	      (const_int 8)) 0)
749	  (match_operand:QI 1 "general_operand" "")))]
750  ""
751  "")
752
753(define_insn "cmpqi_ext_3_insn"
754  [(set (reg FLAGS_REG)
755	(compare
756	  (subreg:QI
757	    (zero_extract:SI
758	      (match_operand 0 "ext_register_operand" "Q")
759	      (const_int 8)
760	      (const_int 8)) 0)
761	  (match_operand:QI 1 "general_operand" "Qmn")))]
762  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
763  "cmp{b}\t{%1, %h0|%h0, %1}"
764  [(set_attr "type" "icmp")
765   (set_attr "mode" "QI")])
766
767(define_insn "cmpqi_ext_3_insn_rex64"
768  [(set (reg FLAGS_REG)
769	(compare
770	  (subreg:QI
771	    (zero_extract:SI
772	      (match_operand 0 "ext_register_operand" "Q")
773	      (const_int 8)
774	      (const_int 8)) 0)
775	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
776  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
777  "cmp{b}\t{%1, %h0|%h0, %1}"
778  [(set_attr "type" "icmp")
779   (set_attr "mode" "QI")])
780
781(define_insn "*cmpqi_ext_4"
782  [(set (reg FLAGS_REG)
783	(compare
784	  (subreg:QI
785	    (zero_extract:SI
786	      (match_operand 0 "ext_register_operand" "Q")
787	      (const_int 8)
788	      (const_int 8)) 0)
789	  (subreg:QI
790	    (zero_extract:SI
791	      (match_operand 1 "ext_register_operand" "Q")
792	      (const_int 8)
793	      (const_int 8)) 0)))]
794  "ix86_match_ccmode (insn, CCmode)"
795  "cmp{b}\t{%h1, %h0|%h0, %h1}"
796  [(set_attr "type" "icmp")
797   (set_attr "mode" "QI")])
798
799;; These implement float point compares.
800;; %%% See if we can get away with VOIDmode operands on the actual insns,
801;; which would allow mix and match FP modes on the compares.  Which is what
802;; the old patterns did, but with many more of them.
803
804(define_expand "cmpxf"
805  [(set (reg:CC FLAGS_REG)
806	(compare:CC (match_operand:XF 0 "nonmemory_operand" "")
807		    (match_operand:XF 1 "nonmemory_operand" "")))]
808  "TARGET_80387"
809{
810  ix86_compare_op0 = operands[0];
811  ix86_compare_op1 = operands[1];
812  DONE;
813})
814
815(define_expand "cmpdf"
816  [(set (reg:CC FLAGS_REG)
817	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
818		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
819  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
820{
821  ix86_compare_op0 = operands[0];
822  ix86_compare_op1 = operands[1];
823  DONE;
824})
825
826(define_expand "cmpsf"
827  [(set (reg:CC FLAGS_REG)
828	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
829		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
830  "TARGET_80387 || TARGET_SSE_MATH"
831{
832  ix86_compare_op0 = operands[0];
833  ix86_compare_op1 = operands[1];
834  DONE;
835})
836
837;; FP compares, step 1:
838;; Set the FP condition codes.
839;;
840;; CCFPmode	compare with exceptions
841;; CCFPUmode	compare with no exceptions
842
843;; We may not use "#" to split and emit these, since the REG_DEAD notes
844;; used to manage the reg stack popping would not be preserved.
845
846(define_insn "*cmpfp_0"
847  [(set (match_operand:HI 0 "register_operand" "=a")
848	(unspec:HI
849	  [(compare:CCFP
850	     (match_operand 1 "register_operand" "f")
851	     (match_operand 2 "const0_operand" "X"))]
852	UNSPEC_FNSTSW))]
853  "TARGET_80387
854   && FLOAT_MODE_P (GET_MODE (operands[1]))
855   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
856  "* return output_fp_compare (insn, operands, 0, 0);"
857  [(set_attr "type" "multi")
858   (set_attr "unit" "i387")
859   (set (attr "mode")
860     (cond [(match_operand:SF 1 "" "")
861	      (const_string "SF")
862	    (match_operand:DF 1 "" "")
863	      (const_string "DF")
864	   ]
865	   (const_string "XF")))])
866
867(define_insn "*cmpfp_sf"
868  [(set (match_operand:HI 0 "register_operand" "=a")
869	(unspec:HI
870	  [(compare:CCFP
871	     (match_operand:SF 1 "register_operand" "f")
872	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
873	  UNSPEC_FNSTSW))]
874  "TARGET_80387"
875  "* return output_fp_compare (insn, operands, 0, 0);"
876  [(set_attr "type" "multi")
877   (set_attr "unit" "i387")
878   (set_attr "mode" "SF")])
879
880(define_insn "*cmpfp_df"
881  [(set (match_operand:HI 0 "register_operand" "=a")
882	(unspec:HI
883	  [(compare:CCFP
884	     (match_operand:DF 1 "register_operand" "f")
885	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
886	  UNSPEC_FNSTSW))]
887  "TARGET_80387"
888  "* return output_fp_compare (insn, operands, 0, 0);"
889  [(set_attr "type" "multi")
890   (set_attr "unit" "i387")
891   (set_attr "mode" "DF")])
892
893(define_insn "*cmpfp_xf"
894  [(set (match_operand:HI 0 "register_operand" "=a")
895	(unspec:HI
896	  [(compare:CCFP
897	     (match_operand:XF 1 "register_operand" "f")
898	     (match_operand:XF 2 "register_operand" "f"))]
899	  UNSPEC_FNSTSW))]
900  "TARGET_80387"
901  "* return output_fp_compare (insn, operands, 0, 0);"
902  [(set_attr "type" "multi")
903   (set_attr "unit" "i387")
904   (set_attr "mode" "XF")])
905
906(define_insn "*cmpfp_u"
907  [(set (match_operand:HI 0 "register_operand" "=a")
908	(unspec:HI
909	  [(compare:CCFPU
910	     (match_operand 1 "register_operand" "f")
911	     (match_operand 2 "register_operand" "f"))]
912	  UNSPEC_FNSTSW))]
913  "TARGET_80387
914   && FLOAT_MODE_P (GET_MODE (operands[1]))
915   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
916  "* return output_fp_compare (insn, operands, 0, 1);"
917  [(set_attr "type" "multi")
918   (set_attr "unit" "i387")
919   (set (attr "mode")
920     (cond [(match_operand:SF 1 "" "")
921	      (const_string "SF")
922	    (match_operand:DF 1 "" "")
923	      (const_string "DF")
924	   ]
925	   (const_string "XF")))])
926
927(define_insn "*cmpfp_<mode>"
928  [(set (match_operand:HI 0 "register_operand" "=a")
929	(unspec:HI
930	  [(compare:CCFP
931	     (match_operand 1 "register_operand" "f")
932	     (match_operator 3 "float_operator"
933	       [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
934	  UNSPEC_FNSTSW))]
935  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
936   && FLOAT_MODE_P (GET_MODE (operands[1]))
937   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
938  "* return output_fp_compare (insn, operands, 0, 0);"
939  [(set_attr "type" "multi")
940   (set_attr "unit" "i387")
941   (set_attr "fp_int_src" "true")
942   (set_attr "mode" "<MODE>")])
943
944;; FP compares, step 2
945;; Move the fpsw to ax.
946
947(define_insn "x86_fnstsw_1"
948  [(set (match_operand:HI 0 "register_operand" "=a")
949	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
950  "TARGET_80387"
951  "fnstsw\t%0"
952  [(set_attr "length" "2")
953   (set_attr "mode" "SI")
954   (set_attr "unit" "i387")])
955
956;; FP compares, step 3
957;; Get ax into flags, general case.
958
959(define_insn "x86_sahf_1"
960  [(set (reg:CC FLAGS_REG)
961	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
962  "!TARGET_64BIT"
963  "sahf"
964  [(set_attr "length" "1")
965   (set_attr "athlon_decode" "vector")
966   (set_attr "mode" "SI")])
967
968;; Pentium Pro can do steps 1 through 3 in one go.
969
970(define_insn "*cmpfp_i_mixed"
971  [(set (reg:CCFP FLAGS_REG)
972	(compare:CCFP (match_operand 0 "register_operand" "f,x")
973		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
974  "TARGET_MIX_SSE_I387
975   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977  "* return output_fp_compare (insn, operands, 1, 0);"
978  [(set_attr "type" "fcmp,ssecomi")
979   (set (attr "mode")
980     (if_then_else (match_operand:SF 1 "" "")
981        (const_string "SF")
982        (const_string "DF")))
983   (set_attr "athlon_decode" "vector")])
984
985(define_insn "*cmpfp_i_sse"
986  [(set (reg:CCFP FLAGS_REG)
987	(compare:CCFP (match_operand 0 "register_operand" "x")
988		      (match_operand 1 "nonimmediate_operand" "xm")))]
989  "TARGET_SSE_MATH
990   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
992  "* return output_fp_compare (insn, operands, 1, 0);"
993  [(set_attr "type" "ssecomi")
994   (set (attr "mode")
995     (if_then_else (match_operand:SF 1 "" "")
996        (const_string "SF")
997        (const_string "DF")))
998   (set_attr "athlon_decode" "vector")])
999
1000(define_insn "*cmpfp_i_i387"
1001  [(set (reg:CCFP FLAGS_REG)
1002	(compare:CCFP (match_operand 0 "register_operand" "f")
1003		      (match_operand 1 "register_operand" "f")))]
1004  "TARGET_80387 && TARGET_CMOVE
1005   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1006   && FLOAT_MODE_P (GET_MODE (operands[0]))
1007   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1008  "* return output_fp_compare (insn, operands, 1, 0);"
1009  [(set_attr "type" "fcmp")
1010   (set (attr "mode")
1011     (cond [(match_operand:SF 1 "" "")
1012	      (const_string "SF")
1013	    (match_operand:DF 1 "" "")
1014	      (const_string "DF")
1015	   ]
1016	   (const_string "XF")))
1017   (set_attr "athlon_decode" "vector")])
1018
1019(define_insn "*cmpfp_iu_mixed"
1020  [(set (reg:CCFPU FLAGS_REG)
1021	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
1022		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1023  "TARGET_MIX_SSE_I387
1024   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1025   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1026  "* return output_fp_compare (insn, operands, 1, 1);"
1027  [(set_attr "type" "fcmp,ssecomi")
1028   (set (attr "mode")
1029     (if_then_else (match_operand:SF 1 "" "")
1030        (const_string "SF")
1031        (const_string "DF")))
1032   (set_attr "athlon_decode" "vector")])
1033
1034(define_insn "*cmpfp_iu_sse"
1035  [(set (reg:CCFPU FLAGS_REG)
1036	(compare:CCFPU (match_operand 0 "register_operand" "x")
1037		       (match_operand 1 "nonimmediate_operand" "xm")))]
1038  "TARGET_SSE_MATH
1039   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1040   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1041  "* return output_fp_compare (insn, operands, 1, 1);"
1042  [(set_attr "type" "ssecomi")
1043   (set (attr "mode")
1044     (if_then_else (match_operand:SF 1 "" "")
1045        (const_string "SF")
1046        (const_string "DF")))
1047   (set_attr "athlon_decode" "vector")])
1048
1049(define_insn "*cmpfp_iu_387"
1050  [(set (reg:CCFPU FLAGS_REG)
1051	(compare:CCFPU (match_operand 0 "register_operand" "f")
1052		       (match_operand 1 "register_operand" "f")))]
1053  "TARGET_80387 && TARGET_CMOVE
1054   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1055   && FLOAT_MODE_P (GET_MODE (operands[0]))
1056   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1057  "* return output_fp_compare (insn, operands, 1, 1);"
1058  [(set_attr "type" "fcmp")
1059   (set (attr "mode")
1060     (cond [(match_operand:SF 1 "" "")
1061	      (const_string "SF")
1062	    (match_operand:DF 1 "" "")
1063	      (const_string "DF")
1064	   ]
1065	   (const_string "XF")))
1066   (set_attr "athlon_decode" "vector")])
1067
1068;; Move instructions.
1069
1070;; General case of fullword move.
1071
1072(define_expand "movsi"
1073  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1074	(match_operand:SI 1 "general_operand" ""))]
1075  ""
1076  "ix86_expand_move (SImode, operands); DONE;")
1077
1078;; Push/pop instructions.  They are separate since autoinc/dec is not a
1079;; general_operand.
1080;;
1081;; %%% We don't use a post-inc memory reference because x86 is not a 
1082;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1083;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1084;; targets without our curiosities, and it is just as easy to represent
1085;; this differently.
1086
1087(define_insn "*pushsi2"
1088  [(set (match_operand:SI 0 "push_operand" "=<")
1089	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1090  "!TARGET_64BIT"
1091  "push{l}\t%1"
1092  [(set_attr "type" "push")
1093   (set_attr "mode" "SI")])
1094
1095;; For 64BIT abi we always round up to 8 bytes.
1096(define_insn "*pushsi2_rex64"
1097  [(set (match_operand:SI 0 "push_operand" "=X")
1098	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1099  "TARGET_64BIT"
1100  "push{q}\t%q1"
1101  [(set_attr "type" "push")
1102   (set_attr "mode" "SI")])
1103
1104(define_insn "*pushsi2_prologue"
1105  [(set (match_operand:SI 0 "push_operand" "=<")
1106	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1107   (clobber (mem:BLK (scratch)))]
1108  "!TARGET_64BIT"
1109  "push{l}\t%1"
1110  [(set_attr "type" "push")
1111   (set_attr "mode" "SI")])
1112
1113(define_insn "*popsi1_epilogue"
1114  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1115	(mem:SI (reg:SI SP_REG)))
1116   (set (reg:SI SP_REG)
1117	(plus:SI (reg:SI SP_REG) (const_int 4)))
1118   (clobber (mem:BLK (scratch)))]
1119  "!TARGET_64BIT"
1120  "pop{l}\t%0"
1121  [(set_attr "type" "pop")
1122   (set_attr "mode" "SI")])
1123
1124(define_insn "popsi1"
1125  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1126	(mem:SI (reg:SI SP_REG)))
1127   (set (reg:SI SP_REG)
1128	(plus:SI (reg:SI SP_REG) (const_int 4)))]
1129  "!TARGET_64BIT"
1130  "pop{l}\t%0"
1131  [(set_attr "type" "pop")
1132   (set_attr "mode" "SI")])
1133
1134(define_insn "*movsi_xor"
1135  [(set (match_operand:SI 0 "register_operand" "=r")
1136	(match_operand:SI 1 "const0_operand" "i"))
1137   (clobber (reg:CC FLAGS_REG))]
1138  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1139  "xor{l}\t{%0, %0|%0, %0}"
1140  [(set_attr "type" "alu1")
1141   (set_attr "mode" "SI")
1142   (set_attr "length_immediate" "0")])
1143 
1144(define_insn "*movsi_or"
1145  [(set (match_operand:SI 0 "register_operand" "=r")
1146	(match_operand:SI 1 "immediate_operand" "i"))
1147   (clobber (reg:CC FLAGS_REG))]
1148  "reload_completed
1149   && operands[1] == constm1_rtx
1150   && (TARGET_PENTIUM || optimize_size)"
1151{
1152  operands[1] = constm1_rtx;
1153  return "or{l}\t{%1, %0|%0, %1}";
1154}
1155  [(set_attr "type" "alu1")
1156   (set_attr "mode" "SI")
1157   (set_attr "length_immediate" "1")])
1158
1159(define_insn "*movsi_1"
1160  [(set (match_operand:SI 0 "nonimmediate_operand"
1161			"=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1162	(match_operand:SI 1 "general_operand"
1163			"rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1164  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1165{
1166  switch (get_attr_type (insn))
1167    {
1168    case TYPE_SSELOG1:
1169      if (get_attr_mode (insn) == MODE_TI)
1170        return "pxor\t%0, %0";
1171      return "xorps\t%0, %0";
1172
1173    case TYPE_SSEMOV:
1174      switch (get_attr_mode (insn))
1175	{
1176	case MODE_TI:
1177	  return "movdqa\t{%1, %0|%0, %1}";
1178	case MODE_V4SF:
1179	  return "movaps\t{%1, %0|%0, %1}";
1180	case MODE_SI:
1181          return "movd\t{%1, %0|%0, %1}";
1182	case MODE_SF:
1183          return "movss\t{%1, %0|%0, %1}";
1184	default:
1185	  gcc_unreachable ();
1186	}
1187
1188    case TYPE_MMXADD:
1189      return "pxor\t%0, %0";
1190
1191    case TYPE_MMXMOV:
1192      if (get_attr_mode (insn) == MODE_DI)
1193	return "movq\t{%1, %0|%0, %1}";
1194      return "movd\t{%1, %0|%0, %1}";
1195
1196    case TYPE_LEA:
1197      return "lea{l}\t{%1, %0|%0, %1}";
1198
1199    default:
1200      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1201      return "mov{l}\t{%1, %0|%0, %1}";
1202    }
1203}
1204  [(set (attr "type")
1205     (cond [(eq_attr "alternative" "2")
1206	      (const_string "mmxadd")
1207	    (eq_attr "alternative" "3,4,5")
1208	      (const_string "mmxmov")
1209	    (eq_attr "alternative" "6")
1210	      (const_string "sselog1")
1211	    (eq_attr "alternative" "7,8,9,10,11")
1212	      (const_string "ssemov")
1213 	    (match_operand:DI 1 "pic_32bit_operand" "")
1214	      (const_string "lea")
1215	   ]
1216	   (const_string "imov")))
1217   (set (attr "mode")
1218     (cond [(eq_attr "alternative" "2,3")
1219	      (const_string "DI")
1220	    (eq_attr "alternative" "6,7")
1221	      (if_then_else
1222	        (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1223	        (const_string "V4SF")
1224	        (const_string "TI"))
1225	    (and (eq_attr "alternative" "8,9,10,11")
1226	         (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1227	      (const_string "SF")
1228	   ]
1229	   (const_string "SI")))])
1230
1231;; Stores and loads of ax to arbitrary constant address.
1232;; We fake an second form of instruction to force reload to load address
1233;; into register when rax is not available
1234(define_insn "*movabssi_1_rex64"
1235  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1236	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1237  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1238  "@
1239   movabs{l}\t{%1, %P0|%P0, %1}
1240   mov{l}\t{%1, %a0|%a0, %1}"
1241  [(set_attr "type" "imov")
1242   (set_attr "modrm" "0,*")
1243   (set_attr "length_address" "8,0")
1244   (set_attr "length_immediate" "0,*")
1245   (set_attr "memory" "store")
1246   (set_attr "mode" "SI")])
1247
1248(define_insn "*movabssi_2_rex64"
1249  [(set (match_operand:SI 0 "register_operand" "=a,r")
1250        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1251  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1252  "@
1253   movabs{l}\t{%P1, %0|%0, %P1}
1254   mov{l}\t{%a1, %0|%0, %a1}"
1255  [(set_attr "type" "imov")
1256   (set_attr "modrm" "0,*")
1257   (set_attr "length_address" "8,0")
1258   (set_attr "length_immediate" "0")
1259   (set_attr "memory" "load")
1260   (set_attr "mode" "SI")])
1261
1262(define_insn "*swapsi"
1263  [(set (match_operand:SI 0 "register_operand" "+r")
1264	(match_operand:SI 1 "register_operand" "+r"))
1265   (set (match_dup 1)
1266	(match_dup 0))]
1267  ""
1268  "xchg{l}\t%1, %0"
1269  [(set_attr "type" "imov")
1270   (set_attr "mode" "SI")
1271   (set_attr "pent_pair" "np")
1272   (set_attr "athlon_decode" "vector")])
1273
1274(define_expand "movhi"
1275  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1276        (match_operand:HI 1 "general_operand" ""))]
1277  ""
1278  "ix86_expand_move (HImode, operands); DONE;")
1279
1280(define_insn "*pushhi2"
1281  [(set (match_operand:HI 0 "push_operand" "=X")
1282	(match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1283  "!TARGET_64BIT"
1284  "push{l}\t%k1"
1285  [(set_attr "type" "push")
1286   (set_attr "mode" "SI")])
1287
1288;; For 64BIT abi we always round up to 8 bytes.
1289(define_insn "*pushhi2_rex64"
1290  [(set (match_operand:HI 0 "push_operand" "=X")
1291	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1292  "TARGET_64BIT"
1293  "push{q}\t%q1"
1294  [(set_attr "type" "push")
1295   (set_attr "mode" "DI")])
1296
1297(define_insn "*movhi_1"
1298  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1299	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1300  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1301{
1302  switch (get_attr_type (insn))
1303    {
1304    case TYPE_IMOVX:
1305      /* movzwl is faster than movw on p2 due to partial word stalls,
1306	 though not as fast as an aligned movl.  */
1307      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1308    default:
1309      if (get_attr_mode (insn) == MODE_SI)
1310        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1311      else
1312        return "mov{w}\t{%1, %0|%0, %1}";
1313    }
1314}
1315  [(set (attr "type")
1316     (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1317	      (const_string "imov")
1318	    (and (eq_attr "alternative" "0")
1319		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1320			  (const_int 0))
1321		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1322			  (const_int 0))))
1323	      (const_string "imov")
1324	    (and (eq_attr "alternative" "1,2")
1325		 (match_operand:HI 1 "aligned_operand" ""))
1326	      (const_string "imov")
1327	    (and (ne (symbol_ref "TARGET_MOVX")
1328		     (const_int 0))
1329		 (eq_attr "alternative" "0,2"))
1330	      (const_string "imovx")
1331	   ]
1332	   (const_string "imov")))
1333    (set (attr "mode")
1334      (cond [(eq_attr "type" "imovx")
1335	       (const_string "SI")
1336	     (and (eq_attr "alternative" "1,2")
1337		  (match_operand:HI 1 "aligned_operand" ""))
1338	       (const_string "SI")
1339	     (and (eq_attr "alternative" "0")
1340		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341			   (const_int 0))
1342		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1343			   (const_int 0))))
1344	       (const_string "SI")
1345	    ]
1346	    (const_string "HI")))])
1347
1348;; Stores and loads of ax to arbitrary constant address.
1349;; We fake an second form of instruction to force reload to load address
1350;; into register when rax is not available
1351(define_insn "*movabshi_1_rex64"
1352  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1353	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1354  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1355  "@
1356   movabs{w}\t{%1, %P0|%P0, %1}
1357   mov{w}\t{%1, %a0|%a0, %1}"
1358  [(set_attr "type" "imov")
1359   (set_attr "modrm" "0,*")
1360   (set_attr "length_address" "8,0")
1361   (set_attr "length_immediate" "0,*")
1362   (set_attr "memory" "store")
1363   (set_attr "mode" "HI")])
1364
1365(define_insn "*movabshi_2_rex64"
1366  [(set (match_operand:HI 0 "register_operand" "=a,r")
1367        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1368  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1369  "@
1370   movabs{w}\t{%P1, %0|%0, %P1}
1371   mov{w}\t{%a1, %0|%0, %a1}"
1372  [(set_attr "type" "imov")
1373   (set_attr "modrm" "0,*")
1374   (set_attr "length_address" "8,0")
1375   (set_attr "length_immediate" "0")
1376   (set_attr "memory" "load")
1377   (set_attr "mode" "HI")])
1378
1379(define_insn "*swaphi_1"
1380  [(set (match_operand:HI 0 "register_operand" "+r")
1381	(match_operand:HI 1 "register_operand" "+r"))
1382   (set (match_dup 1)
1383	(match_dup 0))]
1384  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1385  "xchg{l}\t%k1, %k0"
1386  [(set_attr "type" "imov")
1387   (set_attr "mode" "SI")
1388   (set_attr "pent_pair" "np")
1389   (set_attr "athlon_decode" "vector")])
1390
1391(define_insn "*swaphi_2"
1392  [(set (match_operand:HI 0 "register_operand" "+r")
1393	(match_operand:HI 1 "register_operand" "+r"))
1394   (set (match_dup 1)
1395	(match_dup 0))]
1396  "TARGET_PARTIAL_REG_STALL"
1397  "xchg{w}\t%1, %0"
1398  [(set_attr "type" "imov")
1399   (set_attr "mode" "HI")
1400   (set_attr "pent_pair" "np")
1401   (set_attr "athlon_decode" "vector")])
1402
1403(define_expand "movstricthi"
1404  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1405	(match_operand:HI 1 "general_operand" ""))]
1406  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407{
1408  /* Don't generate memory->memory moves, go through a register */
1409  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1410    operands[1] = force_reg (HImode, operands[1]);
1411})
1412
1413(define_insn "*movstricthi_1"
1414  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1415	(match_operand:HI 1 "general_operand" "rn,m"))]
1416  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1417   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1418  "mov{w}\t{%1, %0|%0, %1}"
1419  [(set_attr "type" "imov")
1420   (set_attr "mode" "HI")])
1421
1422(define_insn "*movstricthi_xor"
1423  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1424	(match_operand:HI 1 "const0_operand" "i"))
1425   (clobber (reg:CC FLAGS_REG))]
1426  "reload_completed
1427   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1428  "xor{w}\t{%0, %0|%0, %0}"
1429  [(set_attr "type" "alu1")
1430   (set_attr "mode" "HI")
1431   (set_attr "length_immediate" "0")])
1432
1433(define_expand "movqi"
1434  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1435	(match_operand:QI 1 "general_operand" ""))]
1436  ""
1437  "ix86_expand_move (QImode, operands); DONE;")
1438
1439;; emit_push_insn when it calls move_by_pieces requires an insn to
1440;; "push a byte".  But actually we use pushl, which has the effect
1441;; of rounding the amount pushed up to a word.
1442
1443(define_insn "*pushqi2"
1444  [(set (match_operand:QI 0 "push_operand" "=X")
1445	(match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1446  "!TARGET_64BIT"
1447  "push{l}\t%k1"
1448  [(set_attr "type" "push")
1449   (set_attr "mode" "SI")])
1450
1451;; For 64BIT abi we always round up to 8 bytes.
1452(define_insn "*pushqi2_rex64"
1453  [(set (match_operand:QI 0 "push_operand" "=X")
1454	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455  "TARGET_64BIT"
1456  "push{q}\t%q1"
1457  [(set_attr "type" "push")
1458   (set_attr "mode" "DI")])
1459
1460;; Situation is quite tricky about when to choose full sized (SImode) move
1461;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1462;; partial register dependency machines (such as AMD Athlon), where QImode
1463;; moves issue extra dependency and for partial register stalls machines
1464;; that don't use QImode patterns (and QImode move cause stall on the next
1465;; instruction).
1466;;
1467;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468;; register stall machines with, where we use QImode instructions, since
1469;; partial register stall can be caused there.  Then we use movzx.
1470(define_insn "*movqi_1"
1471  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1473  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474{
1475  switch (get_attr_type (insn))
1476    {
1477    case TYPE_IMOVX:
1478      gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1479      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480    default:
1481      if (get_attr_mode (insn) == MODE_SI)
1482        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483      else
1484        return "mov{b}\t{%1, %0|%0, %1}";
1485    }
1486}
1487  [(set (attr "type")
1488     (cond [(and (eq_attr "alternative" "5")
1489		 (not (match_operand:QI 1 "aligned_operand" "")))
1490	      (const_string "imovx")
1491	    (ne (symbol_ref "optimize_size") (const_int 0))
1492	      (const_string "imov")
1493	    (and (eq_attr "alternative" "3")
1494		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495			  (const_int 0))
1496		      (eq (symbol_ref "TARGET_QIMODE_MATH")
1497			  (const_int 0))))
1498	      (const_string "imov")
1499	    (eq_attr "alternative" "3,5")
1500	      (const_string "imovx")
1501	    (and (ne (symbol_ref "TARGET_MOVX")
1502		     (const_int 0))
1503		 (eq_attr "alternative" "2"))
1504	      (const_string "imovx")
1505	   ]
1506	   (const_string "imov")))
1507   (set (attr "mode")
1508      (cond [(eq_attr "alternative" "3,4,5")
1509	       (const_string "SI")
1510	     (eq_attr "alternative" "6")
1511	       (const_string "QI")
1512	     (eq_attr "type" "imovx")
1513	       (const_string "SI")
1514	     (and (eq_attr "type" "imov")
1515		  (and (eq_attr "alternative" "0,1")
1516		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517				(const_int 0))
1518			    (and (eq (symbol_ref "optimize_size")
1519				     (const_int 0))
1520			    	 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1521				     (const_int 0))))))
1522	       (const_string "SI")
1523	     ;; Avoid partial register stalls when not using QImode arithmetic
1524	     (and (eq_attr "type" "imov")
1525		  (and (eq_attr "alternative" "0,1")
1526		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527				(const_int 0))
1528			    (eq (symbol_ref "TARGET_QIMODE_MATH")
1529				(const_int 0)))))
1530	       (const_string "SI")
1531	   ]
1532	   (const_string "QI")))])
1533
1534(define_expand "reload_outqi"
1535  [(parallel [(match_operand:QI 0 "" "=m")
1536              (match_operand:QI 1 "register_operand" "r")
1537              (match_operand:QI 2 "register_operand" "=&q")])]
1538  ""
1539{
1540  rtx op0, op1, op2;
1541  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542
1543  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1544  if (! q_regs_operand (op1, QImode))
1545    {
1546      emit_insn (gen_movqi (op2, op1));
1547      op1 = op2;
1548    }
1549  emit_insn (gen_movqi (op0, op1));
1550  DONE;
1551})
1552
1553(define_insn "*swapqi_1"
1554  [(set (match_operand:QI 0 "register_operand" "+r")
1555	(match_operand:QI 1 "register_operand" "+r"))
1556   (set (match_dup 1)
1557	(match_dup 0))]
1558  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1559  "xchg{l}\t%k1, %k0"
1560  [(set_attr "type" "imov")
1561   (set_attr "mode" "SI")
1562   (set_attr "pent_pair" "np")
1563   (set_attr "athlon_decode" "vector")])
1564
1565(define_insn "*swapqi_2"
1566  [(set (match_operand:QI 0 "register_operand" "+q")
1567	(match_operand:QI 1 "register_operand" "+q"))
1568   (set (match_dup 1)
1569	(match_dup 0))]
1570  "TARGET_PARTIAL_REG_STALL"
1571  "xchg{b}\t%1, %0"
1572  [(set_attr "type" "imov")
1573   (set_attr "mode" "QI")
1574   (set_attr "pent_pair" "np")
1575   (set_attr "athlon_decode" "vector")])
1576
1577(define_expand "movstrictqi"
1578  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1579	(match_operand:QI 1 "general_operand" ""))]
1580  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1581{
1582  /* Don't generate memory->memory moves, go through a register.  */
1583  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1584    operands[1] = force_reg (QImode, operands[1]);
1585})
1586
1587(define_insn "*movstrictqi_1"
1588  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1589	(match_operand:QI 1 "general_operand" "*qn,m"))]
1590  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1591   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1592  "mov{b}\t{%1, %0|%0, %1}"
1593  [(set_attr "type" "imov")
1594   (set_attr "mode" "QI")])
1595
1596(define_insn "*movstrictqi_xor"
1597  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1598	(match_operand:QI 1 "const0_operand" "i"))
1599   (clobber (reg:CC FLAGS_REG))]
1600  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1601  "xor{b}\t{%0, %0|%0, %0}"
1602  [(set_attr "type" "alu1")
1603   (set_attr "mode" "QI")
1604   (set_attr "length_immediate" "0")])
1605
1606(define_insn "*movsi_extv_1"
1607  [(set (match_operand:SI 0 "register_operand" "=R")
1608	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1609			 (const_int 8)
1610			 (const_int 8)))]
1611  ""
1612  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1613  [(set_attr "type" "imovx")
1614   (set_attr "mode" "SI")])
1615
1616(define_insn "*movhi_extv_1"
1617  [(set (match_operand:HI 0 "register_operand" "=R")
1618	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1619			 (const_int 8)
1620			 (const_int 8)))]
1621  ""
1622  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1623  [(set_attr "type" "imovx")
1624   (set_attr "mode" "SI")])
1625
1626(define_insn "*movqi_extv_1"
1627  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1628        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1629                         (const_int 8)
1630                         (const_int 8)))]
1631  "!TARGET_64BIT"
1632{
1633  switch (get_attr_type (insn))
1634    {
1635    case TYPE_IMOVX:
1636      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1637    default:
1638      return "mov{b}\t{%h1, %0|%0, %h1}";
1639    }
1640}
1641  [(set (attr "type")
1642     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1643			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1644			     (ne (symbol_ref "TARGET_MOVX")
1645				 (const_int 0))))
1646	(const_string "imovx")
1647	(const_string "imov")))
1648   (set (attr "mode")
1649     (if_then_else (eq_attr "type" "imovx")
1650	(const_string "SI")
1651	(const_string "QI")))])
1652
1653(define_insn "*movqi_extv_1_rex64"
1654  [(set (match_operand:QI 0 "register_operand" "=Q,?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;; Stores and loads of ax to arbitrary constant address.
1681;; We fake an second form of instruction to force reload to load address
1682;; into register when rax is not available
1683(define_insn "*movabsqi_1_rex64"
1684  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1685	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1686  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1687  "@
1688   movabs{b}\t{%1, %P0|%P0, %1}
1689   mov{b}\t{%1, %a0|%a0, %1}"
1690  [(set_attr "type" "imov")
1691   (set_attr "modrm" "0,*")
1692   (set_attr "length_address" "8,0")
1693   (set_attr "length_immediate" "0,*")
1694   (set_attr "memory" "store")
1695   (set_attr "mode" "QI")])
1696
1697(define_insn "*movabsqi_2_rex64"
1698  [(set (match_operand:QI 0 "register_operand" "=a,r")
1699        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1700  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1701  "@
1702   movabs{b}\t{%P1, %0|%0, %P1}
1703   mov{b}\t{%a1, %0|%0, %a1}"
1704  [(set_attr "type" "imov")
1705   (set_attr "modrm" "0,*")
1706   (set_attr "length_address" "8,0")
1707   (set_attr "length_immediate" "0")
1708   (set_attr "memory" "load")
1709   (set_attr "mode" "QI")])
1710
1711(define_insn "*movdi_extzv_1"
1712  [(set (match_operand:DI 0 "register_operand" "=R")
1713	(zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1714			 (const_int 8)
1715			 (const_int 8)))]
1716  "TARGET_64BIT"
1717  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1718  [(set_attr "type" "imovx")
1719   (set_attr "mode" "DI")])
1720
1721(define_insn "*movsi_extzv_1"
1722  [(set (match_operand:SI 0 "register_operand" "=R")
1723	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1724			 (const_int 8)
1725			 (const_int 8)))]
1726  ""
1727  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1728  [(set_attr "type" "imovx")
1729   (set_attr "mode" "SI")])
1730
1731(define_insn "*movqi_extzv_2"
1732  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1733        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1734				    (const_int 8)
1735				    (const_int 8)) 0))]
1736  "!TARGET_64BIT"
1737{
1738  switch (get_attr_type (insn))
1739    {
1740    case TYPE_IMOVX:
1741      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1742    default:
1743      return "mov{b}\t{%h1, %0|%0, %h1}";
1744    }
1745}
1746  [(set (attr "type")
1747     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1748			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1749			     (ne (symbol_ref "TARGET_MOVX")
1750				 (const_int 0))))
1751	(const_string "imovx")
1752	(const_string "imov")))
1753   (set (attr "mode")
1754     (if_then_else (eq_attr "type" "imovx")
1755	(const_string "SI")
1756	(const_string "QI")))])
1757
1758(define_insn "*movqi_extzv_2_rex64"
1759  [(set (match_operand:QI 0 "register_operand" "=Q,?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 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1775			(ne (symbol_ref "TARGET_MOVX")
1776			    (const_int 0)))
1777	(const_string "imovx")
1778	(const_string "imov")))
1779   (set (attr "mode")
1780     (if_then_else (eq_attr "type" "imovx")
1781	(const_string "SI")
1782	(const_string "QI")))])
1783
1784(define_insn "movsi_insv_1"
1785  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1786			 (const_int 8)
1787			 (const_int 8))
1788	(match_operand:SI 1 "general_operand" "Qmn"))]
1789  "!TARGET_64BIT"
1790  "mov{b}\t{%b1, %h0|%h0, %b1}"
1791  [(set_attr "type" "imov")
1792   (set_attr "mode" "QI")])
1793
1794(define_insn "movdi_insv_1_rex64"
1795  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1796			 (const_int 8)
1797			 (const_int 8))
1798	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
1799  "TARGET_64BIT"
1800  "mov{b}\t{%b1, %h0|%h0, %b1}"
1801  [(set_attr "type" "imov")
1802   (set_attr "mode" "QI")])
1803
1804(define_insn "*movqi_insv_2"
1805  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1806			 (const_int 8)
1807			 (const_int 8))
1808	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1809		     (const_int 8)))]
1810  ""
1811  "mov{b}\t{%h1, %h0|%h0, %h1}"
1812  [(set_attr "type" "imov")
1813   (set_attr "mode" "QI")])
1814
1815(define_expand "movdi"
1816  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1817	(match_operand:DI 1 "general_operand" ""))]
1818  ""
1819  "ix86_expand_move (DImode, operands); DONE;")
1820
1821(define_insn "*pushdi"
1822  [(set (match_operand:DI 0 "push_operand" "=<")
1823	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1824  "!TARGET_64BIT"
1825  "#")
1826
1827(define_insn "*pushdi2_rex64"
1828  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1829	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1830  "TARGET_64BIT"
1831  "@
1832   push{q}\t%1
1833   #"
1834  [(set_attr "type" "push,multi")
1835   (set_attr "mode" "DI")])
1836
1837;; Convert impossible pushes of immediate to existing instructions.
1838;; First try to get scratch register and go through it.  In case this
1839;; fails, push sign extended lower part first and then overwrite
1840;; upper part by 32bit move.
1841(define_peephole2
1842  [(match_scratch:DI 2 "r")
1843   (set (match_operand:DI 0 "push_operand" "")
1844        (match_operand:DI 1 "immediate_operand" ""))]
1845  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1846   && !x86_64_immediate_operand (operands[1], DImode)"
1847  [(set (match_dup 2) (match_dup 1))
1848   (set (match_dup 0) (match_dup 2))]
1849  "")
1850
1851;; We need to define this as both peepholer and splitter for case
1852;; peephole2 pass is not run.
1853;; "&& 1" is needed to keep it from matching the previous pattern.
1854(define_peephole2
1855  [(set (match_operand:DI 0 "push_operand" "")
1856        (match_operand:DI 1 "immediate_operand" ""))]
1857  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1858   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1859  [(set (match_dup 0) (match_dup 1))
1860   (set (match_dup 2) (match_dup 3))]
1861  "split_di (operands + 1, 1, operands + 2, operands + 3);
1862   operands[1] = gen_lowpart (DImode, operands[2]);
1863   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1864						    GEN_INT (4)));
1865  ")
1866
1867(define_split
1868  [(set (match_operand:DI 0 "push_operand" "")
1869        (match_operand:DI 1 "immediate_operand" ""))]
1870  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1871		    ? flow2_completed : reload_completed)
1872   && !symbolic_operand (operands[1], DImode)
1873   && !x86_64_immediate_operand (operands[1], DImode)"
1874  [(set (match_dup 0) (match_dup 1))
1875   (set (match_dup 2) (match_dup 3))]
1876  "split_di (operands + 1, 1, operands + 2, operands + 3);
1877   operands[1] = gen_lowpart (DImode, operands[2]);
1878   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1879						    GEN_INT (4)));
1880  ")
1881
1882(define_insn "*pushdi2_prologue_rex64"
1883  [(set (match_operand:DI 0 "push_operand" "=<")
1884	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
1885   (clobber (mem:BLK (scratch)))]
1886  "TARGET_64BIT"
1887  "push{q}\t%1"
1888  [(set_attr "type" "push")
1889   (set_attr "mode" "DI")])
1890
1891(define_insn "*popdi1_epilogue_rex64"
1892  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1893	(mem:DI (reg:DI SP_REG)))
1894   (set (reg:DI SP_REG)
1895	(plus:DI (reg:DI SP_REG) (const_int 8)))
1896   (clobber (mem:BLK (scratch)))]
1897  "TARGET_64BIT"
1898  "pop{q}\t%0"
1899  [(set_attr "type" "pop")
1900   (set_attr "mode" "DI")])
1901
1902(define_insn "popdi1"
1903  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1904	(mem:DI (reg:DI SP_REG)))
1905   (set (reg:DI SP_REG)
1906	(plus:DI (reg:DI SP_REG) (const_int 8)))]
1907  "TARGET_64BIT"
1908  "pop{q}\t%0"
1909  [(set_attr "type" "pop")
1910   (set_attr "mode" "DI")])
1911
1912(define_insn "*movdi_xor_rex64"
1913  [(set (match_operand:DI 0 "register_operand" "=r")
1914	(match_operand:DI 1 "const0_operand" "i"))
1915   (clobber (reg:CC FLAGS_REG))]
1916  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1917   && reload_completed"
1918  "xor{l}\t{%k0, %k0|%k0, %k0}"
1919  [(set_attr "type" "alu1")
1920   (set_attr "mode" "SI")
1921   (set_attr "length_immediate" "0")])
1922
1923(define_insn "*movdi_or_rex64"
1924  [(set (match_operand:DI 0 "register_operand" "=r")
1925	(match_operand:DI 1 "const_int_operand" "i"))
1926   (clobber (reg:CC FLAGS_REG))]
1927  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1928   && reload_completed
1929   && operands[1] == constm1_rtx"
1930{
1931  operands[1] = constm1_rtx;
1932  return "or{q}\t{%1, %0|%0, %1}";
1933}
1934  [(set_attr "type" "alu1")
1935   (set_attr "mode" "DI")
1936   (set_attr "length_immediate" "1")])
1937
1938(define_insn "*movdi_2"
1939  [(set (match_operand:DI 0 "nonimmediate_operand"
1940				"=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1941	(match_operand:DI 1 "general_operand"
1942				"riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1943  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1944  "@
1945   #
1946   #
1947   pxor\t%0, %0
1948   movq\t{%1, %0|%0, %1}
1949   movq\t{%1, %0|%0, %1}
1950   pxor\t%0, %0
1951   movq\t{%1, %0|%0, %1}
1952   movdqa\t{%1, %0|%0, %1}
1953   movq\t{%1, %0|%0, %1}
1954   xorps\t%0, %0
1955   movlps\t{%1, %0|%0, %1}
1956   movaps\t{%1, %0|%0, %1}
1957   movlps\t{%1, %0|%0, %1}"
1958  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1959   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1960
1961(define_split
1962  [(set (match_operand:DI 0 "push_operand" "")
1963        (match_operand:DI 1 "general_operand" ""))]
1964  "!TARGET_64BIT && reload_completed
1965   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1966  [(const_int 0)]
1967  "ix86_split_long_move (operands); DONE;")
1968
1969;; %%% This multiword shite has got to go.
1970(define_split
1971  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1972        (match_operand:DI 1 "general_operand" ""))]
1973  "!TARGET_64BIT && reload_completed
1974   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1975   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1976  [(const_int 0)]
1977  "ix86_split_long_move (operands); DONE;")
1978
1979(define_insn "*movdi_1_rex64"
1980  [(set (match_operand:DI 0 "nonimmediate_operand"
1981		"=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1982	(match_operand:DI 1 "general_operand"
1983		"Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1984  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1985{
1986  switch (get_attr_type (insn))
1987    {
1988    case TYPE_SSECVT:
1989      if (which_alternative == 13)
1990	return "movq2dq\t{%1, %0|%0, %1}";
1991      else
1992	return "movdq2q\t{%1, %0|%0, %1}";
1993    case TYPE_SSEMOV:
1994      if (get_attr_mode (insn) == MODE_TI)
1995	  return "movdqa\t{%1, %0|%0, %1}";
1996      /* FALLTHRU */
1997    case TYPE_MMXMOV:
1998      /* Moves from and into integer register is done using movd opcode with
1999 	 REX prefix.  */
2000      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2001	  return "movd\t{%1, %0|%0, %1}";
2002      return "movq\t{%1, %0|%0, %1}";
2003    case TYPE_SSELOG1:
2004    case TYPE_MMXADD:
2005      return "pxor\t%0, %0";
2006    case TYPE_MULTI:
2007      return "#";
2008    case TYPE_LEA:
2009      return "lea{q}\t{%a1, %0|%0, %a1}";
2010    default:
2011      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2012      if (get_attr_mode (insn) == MODE_SI)
2013	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014      else if (which_alternative == 2)
2015	return "movabs{q}\t{%1, %0|%0, %1}";
2016      else
2017	return "mov{q}\t{%1, %0|%0, %1}";
2018    }
2019}
2020  [(set (attr "type")
2021     (cond [(eq_attr "alternative" "5")
2022	      (const_string "mmxadd")
2023	    (eq_attr "alternative" "6,7,8")
2024	      (const_string "mmxmov")
2025	    (eq_attr "alternative" "9")
2026	      (const_string "sselog1")
2027	    (eq_attr "alternative" "10,11,12")
2028	      (const_string "ssemov")
2029	    (eq_attr "alternative" "13,14")
2030	      (const_string "ssecvt")
2031	    (eq_attr "alternative" "4")
2032	      (const_string "multi")
2033 	    (match_operand:DI 1 "pic_32bit_operand" "")
2034	      (const_string "lea")
2035	   ]
2036	   (const_string "imov")))
2037   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2038   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2039   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2040
2041;; Stores and loads of ax to arbitrary constant address.
2042;; We fake an second form of instruction to force reload to load address
2043;; into register when rax is not available
2044(define_insn "*movabsdi_1_rex64"
2045  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2046	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2047  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2048  "@
2049   movabs{q}\t{%1, %P0|%P0, %1}
2050   mov{q}\t{%1, %a0|%a0, %1}"
2051  [(set_attr "type" "imov")
2052   (set_attr "modrm" "0,*")
2053   (set_attr "length_address" "8,0")
2054   (set_attr "length_immediate" "0,*")
2055   (set_attr "memory" "store")
2056   (set_attr "mode" "DI")])
2057
2058(define_insn "*movabsdi_2_rex64"
2059  [(set (match_operand:DI 0 "register_operand" "=a,r")
2060        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2061  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2062  "@
2063   movabs{q}\t{%P1, %0|%0, %P1}
2064   mov{q}\t{%a1, %0|%0, %a1}"
2065  [(set_attr "type" "imov")
2066   (set_attr "modrm" "0,*")
2067   (set_attr "length_address" "8,0")
2068   (set_attr "length_immediate" "0")
2069   (set_attr "memory" "load")
2070   (set_attr "mode" "DI")])
2071
2072;; Convert impossible stores of immediate to existing instructions.
2073;; First try to get scratch register and go through it.  In case this
2074;; fails, move by 32bit parts.
2075(define_peephole2
2076  [(match_scratch:DI 2 "r")
2077   (set (match_operand:DI 0 "memory_operand" "")
2078        (match_operand:DI 1 "immediate_operand" ""))]
2079  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080   && !x86_64_immediate_operand (operands[1], DImode)"
2081  [(set (match_dup 2) (match_dup 1))
2082   (set (match_dup 0) (match_dup 2))]
2083  "")
2084
2085;; We need to define this as both peepholer and splitter for case
2086;; peephole2 pass is not run.
2087;; "&& 1" is needed to keep it from matching the previous pattern.
2088(define_peephole2
2089  [(set (match_operand:DI 0 "memory_operand" "")
2090        (match_operand:DI 1 "immediate_operand" ""))]
2091  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2092   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2093  [(set (match_dup 2) (match_dup 3))
2094   (set (match_dup 4) (match_dup 5))]
2095  "split_di (operands, 2, operands + 2, operands + 4);")
2096
2097(define_split
2098  [(set (match_operand:DI 0 "memory_operand" "")
2099        (match_operand:DI 1 "immediate_operand" ""))]
2100  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2101		    ? flow2_completed : reload_completed)
2102   && !symbolic_operand (operands[1], DImode)
2103   && !x86_64_immediate_operand (operands[1], DImode)"
2104  [(set (match_dup 2) (match_dup 3))
2105   (set (match_dup 4) (match_dup 5))]
2106  "split_di (operands, 2, operands + 2, operands + 4);")
2107
2108(define_insn "*swapdi_rex64"
2109  [(set (match_operand:DI 0 "register_operand" "+r")
2110	(match_operand:DI 1 "register_operand" "+r"))
2111   (set (match_dup 1)
2112	(match_dup 0))]
2113  "TARGET_64BIT"
2114  "xchg{q}\t%1, %0"
2115  [(set_attr "type" "imov")
2116   (set_attr "mode" "DI")
2117   (set_attr "pent_pair" "np")
2118   (set_attr "athlon_decode" "vector")])
2119
2120(define_expand "movti"
2121  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2122	(match_operand:TI 1 "nonimmediate_operand" ""))]
2123  "TARGET_SSE || TARGET_64BIT"
2124{
2125  if (TARGET_64BIT)
2126    ix86_expand_move (TImode, operands);
2127  else
2128    ix86_expand_vector_move (TImode, operands);
2129  DONE;
2130})
2131
2132(define_insn "*movti_internal"
2133  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2134	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2135  "TARGET_SSE && !TARGET_64BIT
2136   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2137{
2138  switch (which_alternative)
2139    {
2140    case 0:
2141      if (get_attr_mode (insn) == MODE_V4SF)
2142	return "xorps\t%0, %0";
2143      else
2144	return "pxor\t%0, %0";
2145    case 1:
2146    case 2:
2147      if (get_attr_mode (insn) == MODE_V4SF)
2148	return "movaps\t{%1, %0|%0, %1}";
2149      else
2150	return "movdqa\t{%1, %0|%0, %1}";
2151    default:
2152      gcc_unreachable ();
2153    }
2154}
2155  [(set_attr "type" "sselog1,ssemov,ssemov")
2156   (set (attr "mode")
2157	(cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2158		    (ne (symbol_ref "optimize_size") (const_int 0)))
2159		 (const_string "V4SF")
2160	       (and (eq_attr "alternative" "2")
2161		    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2162			(const_int 0)))
2163		 (const_string "V4SF")]
2164	      (const_string "TI")))])
2165
2166(define_insn "*movti_rex64"
2167  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2168	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2169  "TARGET_64BIT
2170   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2171{
2172  switch (which_alternative)
2173    {
2174    case 0:
2175    case 1:
2176      return "#";
2177    case 2:
2178      if (get_attr_mode (insn) == MODE_V4SF)
2179	return "xorps\t%0, %0";
2180      else
2181	return "pxor\t%0, %0";
2182    case 3:
2183    case 4:
2184      if (get_attr_mode (insn) == MODE_V4SF)
2185	return "movaps\t{%1, %0|%0, %1}";
2186      else
2187	return "movdqa\t{%1, %0|%0, %1}";
2188    default:
2189      gcc_unreachable ();
2190    }
2191}
2192  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2193   (set (attr "mode")
2194        (cond [(eq_attr "alternative" "2,3")
2195		 (if_then_else
2196		   (ne (symbol_ref "optimize_size")
2197		       (const_int 0))
2198		   (const_string "V4SF")
2199		   (const_string "TI"))
2200	       (eq_attr "alternative" "4")
2201		 (if_then_else
2202		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2203			    (const_int 0))
2204			(ne (symbol_ref "optimize_size")
2205			    (const_int 0)))
2206		   (const_string "V4SF")
2207		   (const_string "TI"))]
2208	       (const_string "DI")))])
2209
2210(define_split
2211  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2212        (match_operand:TI 1 "general_operand" ""))]
2213  "reload_completed && !SSE_REG_P (operands[0])
2214   && !SSE_REG_P (operands[1])"
2215  [(const_int 0)]
2216  "ix86_split_long_move (operands); DONE;")
2217
2218(define_expand "movsf"
2219  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2220	(match_operand:SF 1 "general_operand" ""))]
2221  ""
2222  "ix86_expand_move (SFmode, operands); DONE;")
2223
2224(define_insn "*pushsf"
2225  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2226	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2227  "!TARGET_64BIT"
2228{
2229  /* Anything else should be already split before reg-stack.  */
2230  gcc_assert (which_alternative == 1);
2231  return "push{l}\t%1";
2232}
2233  [(set_attr "type" "multi,push,multi")
2234   (set_attr "unit" "i387,*,*")
2235   (set_attr "mode" "SF,SI,SF")])
2236
2237(define_insn "*pushsf_rex64"
2238  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2239	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2240  "TARGET_64BIT"
2241{
2242  /* Anything else should be already split before reg-stack.  */
2243  gcc_assert (which_alternative == 1);
2244  return "push{q}\t%q1";
2245}
2246  [(set_attr "type" "multi,push,multi")
2247   (set_attr "unit" "i387,*,*")
2248   (set_attr "mode" "SF,DI,SF")])
2249
2250(define_split
2251  [(set (match_operand:SF 0 "push_operand" "")
2252	(match_operand:SF 1 "memory_operand" ""))]
2253  "reload_completed
2254   && GET_CODE (operands[1]) == MEM
2255   && constant_pool_reference_p (operands[1])"
2256  [(set (match_dup 0)
2257	(match_dup 1))]
2258  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2259
2260
2261;; %%% Kill this when call knows how to work this out.
2262(define_split
2263  [(set (match_operand:SF 0 "push_operand" "")
2264	(match_operand:SF 1 "any_fp_register_operand" ""))]
2265  "!TARGET_64BIT"
2266  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2267   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2268
2269(define_split
2270  [(set (match_operand:SF 0 "push_operand" "")
2271	(match_operand:SF 1 "any_fp_register_operand" ""))]
2272  "TARGET_64BIT"
2273  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2274   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2275
2276(define_insn "*movsf_1"
2277  [(set (match_operand:SF 0 "nonimmediate_operand"
2278	  "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2279	(match_operand:SF 1 "general_operand"
2280	  "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2281  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2282   && (reload_in_progress || reload_completed
2283       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2284       || GET_CODE (operands[1]) != CONST_DOUBLE
2285       || memory_operand (operands[0], SFmode))" 
2286{
2287  switch (which_alternative)
2288    {
2289    case 0:
2290      return output_387_reg_move (insn, operands);
2291
2292    case 1:
2293      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2294        return "fstp%z0\t%y0";
2295      else
2296        return "fst%z0\t%y0";
2297
2298    case 2:
2299      return standard_80387_constant_opcode (operands[1]);
2300
2301    case 3:
2302    case 4:
2303      return "mov{l}\t{%1, %0|%0, %1}";
2304    case 5:
2305      if (get_attr_mode (insn) == MODE_TI)
2306	return "pxor\t%0, %0";
2307      else
2308	return "xorps\t%0, %0";
2309    case 6:
2310      if (get_attr_mode (insn) == MODE_V4SF)
2311	return "movaps\t{%1, %0|%0, %1}";
2312      else
2313	return "movss\t{%1, %0|%0, %1}";
2314    case 7:
2315    case 8:
2316      return "movss\t{%1, %0|%0, %1}";
2317
2318    case 9:
2319    case 10:
2320      return "movd\t{%1, %0|%0, %1}";
2321
2322    case 11:
2323      return "movq\t{%1, %0|%0, %1}";
2324
2325    default:
2326      gcc_unreachable ();
2327    }
2328}
2329  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2330   (set (attr "mode")
2331        (cond [(eq_attr "alternative" "3,4,9,10")
2332		 (const_string "SI")
2333	       (eq_attr "alternative" "5")
2334		 (if_then_else
2335		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2336			    	 (const_int 0))
2337			     (ne (symbol_ref "TARGET_SSE2")
2338				 (const_int 0)))
2339			(eq (symbol_ref "optimize_size")
2340			    (const_int 0)))
2341		   (const_string "TI")
2342		   (const_string "V4SF"))
2343	       /* For architectures resolving dependencies on
2344		  whole SSE registers use APS move to break dependency
2345		  chains, otherwise use short move to avoid extra work. 
2346
2347		  Do the same for architectures resolving dependencies on
2348		  the parts.  While in DF mode it is better to always handle
2349		  just register parts, the SF mode is different due to lack
2350		  of instructions to load just part of the register.  It is
2351		  better to maintain the whole registers in single format
2352		  to avoid problems on using packed logical operations.  */
2353	       (eq_attr "alternative" "6")
2354		 (if_then_else
2355		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2356			    (const_int 0))
2357			(ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2358			    (const_int 0)))
2359		   (const_string "V4SF")
2360		   (const_string "SF"))
2361	       (eq_attr "alternative" "11")
2362		 (const_string "DI")]
2363	       (const_string "SF")))])
2364
2365(define_insn "*swapsf"
2366  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2367	(match_operand:SF 1 "fp_register_operand" "+f"))
2368   (set (match_dup 1)
2369	(match_dup 0))]
2370  "reload_completed || TARGET_80387"
2371{
2372  if (STACK_TOP_P (operands[0]))
2373    return "fxch\t%1";
2374  else
2375    return "fxch\t%0";
2376}
2377  [(set_attr "type" "fxch")
2378   (set_attr "mode" "SF")])
2379
2380(define_expand "movdf"
2381  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2382	(match_operand:DF 1 "general_operand" ""))]
2383  ""
2384  "ix86_expand_move (DFmode, operands); DONE;")
2385
2386;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2387;; Size of pushdf using integer instructions is 2+2*memory operand size
2388;; On the average, pushdf using integers can be still shorter.  Allow this
2389;; pattern for optimize_size too.
2390
2391(define_insn "*pushdf_nointeger"
2392  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2393	(match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2394  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2395{
2396  /* This insn should be already split before reg-stack.  */
2397  gcc_unreachable ();
2398}
2399  [(set_attr "type" "multi")
2400   (set_attr "unit" "i387,*,*,*")
2401   (set_attr "mode" "DF,SI,SI,DF")])
2402
2403(define_insn "*pushdf_integer"
2404  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2405	(match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2406  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2407{
2408  /* This insn should be already split before reg-stack.  */
2409  gcc_unreachable ();
2410}
2411  [(set_attr "type" "multi")
2412   (set_attr "unit" "i387,*,*")
2413   (set_attr "mode" "DF,SI,DF")])
2414
2415;; %%% Kill this when call knows how to work this out.
2416(define_split
2417  [(set (match_operand:DF 0 "push_operand" "")
2418	(match_operand:DF 1 "any_fp_register_operand" ""))]
2419  "!TARGET_64BIT && reload_completed"
2420  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2421   (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2422  "")
2423
2424(define_split
2425  [(set (match_operand:DF 0 "push_operand" "")
2426	(match_operand:DF 1 "any_fp_register_operand" ""))]
2427  "TARGET_64BIT && reload_completed"
2428  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2429   (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2430  "")
2431
2432(define_split
2433  [(set (match_operand:DF 0 "push_operand" "")
2434	(match_operand:DF 1 "general_operand" ""))]
2435  "reload_completed"
2436  [(const_int 0)]
2437  "ix86_split_long_move (operands); DONE;")
2438
2439;; Moving is usually shorter when only FP registers are used. This separate
2440;; movdf pattern avoids the use of integer registers for FP operations
2441;; when optimizing for size.
2442
2443(define_insn "*movdf_nointeger"
2444  [(set (match_operand:DF 0 "nonimmediate_operand"
2445			"=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2446	(match_operand:DF 1 "general_operand"
2447			"fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2448  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2449   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2450   && (reload_in_progress || reload_completed
2451       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2452       || GET_CODE (operands[1]) != CONST_DOUBLE
2453       || memory_operand (operands[0], DFmode))" 
2454{
2455  switch (which_alternative)
2456    {
2457    case 0:
2458      return output_387_reg_move (insn, operands);
2459
2460    case 1:
2461      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2462        return "fstp%z0\t%y0";
2463      else
2464        return "fst%z0\t%y0";
2465
2466    case 2:
2467      return standard_80387_constant_opcode (operands[1]);
2468
2469    case 3:
2470    case 4:
2471      return "#";
2472    case 5:
2473      switch (get_attr_mode (insn))
2474	{
2475	case MODE_V4SF:
2476	  return "xorps\t%0, %0";
2477	case MODE_V2DF:
2478	  return "xorpd\t%0, %0";
2479	case MODE_TI:
2480	  return "pxor\t%0, %0";
2481	default:
2482	  gcc_unreachable ();
2483	}
2484    case 6:
2485    case 7:
2486    case 8:
2487      switch (get_attr_mode (insn))
2488	{
2489	case MODE_V4SF:
2490	  return "movaps\t{%1, %0|%0, %1}";
2491	case MODE_V2DF:
2492	  return "movapd\t{%1, %0|%0, %1}";
2493	case MODE_TI:
2494	  return "movdqa\t{%1, %0|%0, %1}";
2495	case MODE_DI:
2496	  return "movq\t{%1, %0|%0, %1}";
2497	case MODE_DF:
2498	  return "movsd\t{%1, %0|%0, %1}";
2499	case MODE_V1DF:
2500	  return "movlpd\t{%1, %0|%0, %1}";
2501	case MODE_V2SF:
2502	  return "movlps\t{%1, %0|%0, %1}";
2503	default:
2504	  gcc_unreachable ();
2505	}
2506
2507    default:
2508      gcc_unreachable ();
2509    }
2510}
2511  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2512   (set (attr "mode")
2513        (cond [(eq_attr "alternative" "0,1,2")
2514		 (const_string "DF")
2515	       (eq_attr "alternative" "3,4")
2516		 (const_string "SI")
2517
2518	       /* For SSE1, we have many fewer alternatives.  */
2519	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2520		 (cond [(eq_attr "alternative" "5,6")
2521			  (const_string "V4SF")
2522		       ]
2523		   (const_string "V2SF"))
2524
2525	       /* xorps is one byte shorter.  */
2526	       (eq_attr "alternative" "5")
2527		 (cond [(ne (symbol_ref "optimize_size")
2528			    (const_int 0))
2529			  (const_string "V4SF")
2530			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2531			    (const_int 0))
2532			  (const_string "TI")
2533		       ]
2534		       (const_string "V2DF"))
2535
2536	       /* For architectures resolving dependencies on
2537		  whole SSE registers use APD move to break dependency
2538		  chains, otherwise use short move to avoid extra work.
2539
2540		  movaps encodes one byte shorter.  */
2541	       (eq_attr "alternative" "6")
2542		 (cond
2543		   [(ne (symbol_ref "optimize_size")
2544		        (const_int 0))
2545		      (const_string "V4SF")
2546		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2547		        (const_int 0))
2548		      (const_string "V2DF")
2549		   ]
2550		   (const_string "DF"))
2551	       /* For architectures resolving dependencies on register
2552		  parts we may avoid extra work to zero out upper part
2553		  of register.  */
2554	       (eq_attr "alternative" "7")
2555		 (if_then_else
2556		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2557		       (const_int 0))
2558		   (const_string "V1DF")
2559		   (const_string "DF"))
2560	      ]
2561	      (const_string "DF")))])
2562
2563(define_insn "*movdf_integer"
2564  [(set (match_operand:DF 0 "nonimmediate_operand"
2565		"=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2566	(match_operand:DF 1 "general_operand"
2567		"fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2568  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2569   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2570   && (reload_in_progress || reload_completed
2571       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2572       || GET_CODE (operands[1]) != CONST_DOUBLE
2573       || memory_operand (operands[0], DFmode))" 
2574{
2575  switch (which_alternative)
2576    {
2577    case 0:
2578      return output_387_reg_move (insn, operands);
2579
2580    case 1:
2581      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2582        return "fstp%z0\t%y0";
2583      else
2584        return "fst%z0\t%y0";
2585
2586    case 2:
2587      return standard_80387_constant_opcode (operands[1]);
2588
2589    case 3:
2590    case 4:
2591      return "#";
2592
2593    case 5:
2594      switch (get_attr_mode (insn))
2595	{
2596	case MODE_V4SF:
2597	  return "xorps\t%0, %0";
2598	case MODE_V2DF:
2599	  return "xorpd\t%0, %0";
2600	case MODE_TI:
2601	  return "pxor\t%0, %0";
2602	default:
2603	  gcc_unreachable ();
2604	}
2605    case 6:
2606    case 7:
2607    case 8:
2608      switch (get_attr_mode (insn))
2609	{
2610	case MODE_V4SF:
2611	  return "movaps\t{%1, %0|%0, %1}";
2612	case MODE_V2DF:
2613	  return "movapd\t{%1, %0|%0, %1}";
2614	case MODE_TI:
2615	  return "movdqa\t{%1, %0|%0, %1}";
2616	case MODE_DI:
2617	  return "movq\t{%1, %0|%0, %1}";
2618	case MODE_DF:
2619	  return "movsd\t{%1, %0|%0, %1}";
2620	case MODE_V1DF:
2621	  return "movlpd\t{%1, %0|%0, %1}";
2622	case MODE_V2SF:
2623	  return "movlps\t{%1, %0|%0, %1}";
2624	default:
2625	  gcc_unreachable ();
2626	}
2627
2628    default:
2629      gcc_unreachable();
2630    }
2631}
2632  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2633   (set (attr "mode")
2634        (cond [(eq_attr "alternative" "0,1,2")
2635		 (const_string "DF")
2636	       (eq_attr "alternative" "3,4")
2637		 (const_string "SI")
2638
2639	       /* For SSE1, we have many fewer alternatives.  */
2640	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2641		 (cond [(eq_attr "alternative" "5,6")
2642			  (const_string "V4SF")
2643		       ]
2644		   (const_string "V2SF"))
2645
2646	       /* xorps is one byte shorter.  */
2647	       (eq_attr "alternative" "5")
2648		 (cond [(ne (symbol_ref "optimize_size")
2649			    (const_int 0))
2650			  (const_string "V4SF")
2651			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652			    (const_int 0))
2653			  (const_string "TI")
2654		       ]
2655		       (const_string "V2DF"))
2656
2657	       /* For architectures resolving dependencies on
2658		  whole SSE registers use APD move to break dependency
2659		  chains, otherwise use short move to avoid extra work.
2660
2661		  movaps encodes one byte shorter.  */
2662	       (eq_attr "alternative" "6")
2663		 (cond
2664		   [(ne (symbol_ref "optimize_size")
2665		        (const_int 0))
2666		      (const_string "V4SF")
2667		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668		        (const_int 0))
2669		      (const_string "V2DF")
2670		   ]
2671		   (const_string "DF"))
2672	       /* For architectures resolving dependencies on register
2673		  parts we may avoid extra work to zero out upper part
2674		  of register.  */
2675	       (eq_attr "alternative" "7")
2676		 (if_then_else
2677		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678		       (const_int 0))
2679		   (const_string "V1DF")
2680		   (const_string "DF"))
2681	      ]
2682	      (const_string "DF")))])
2683
2684(define_split
2685  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2686	(match_operand:DF 1 "general_operand" ""))]
2687  "reload_completed
2688   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2689   && ! (ANY_FP_REG_P (operands[0]) || 
2690	 (GET_CODE (operands[0]) == SUBREG
2691	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2692   && ! (ANY_FP_REG_P (operands[1]) || 
2693	 (GET_CODE (operands[1]) == SUBREG
2694	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695  [(const_int 0)]
2696  "ix86_split_long_move (operands); DONE;")
2697
2698(define_insn "*swapdf"
2699  [(set (match_operand:DF 0 "fp_register_operand" "+f")
2700	(match_operand:DF 1 "fp_register_operand" "+f"))
2701   (set (match_dup 1)
2702	(match_dup 0))]
2703  "reload_completed || TARGET_80387"
2704{
2705  if (STACK_TOP_P (operands[0]))
2706    return "fxch\t%1";
2707  else
2708    return "fxch\t%0";
2709}
2710  [(set_attr "type" "fxch")
2711   (set_attr "mode" "DF")])
2712
2713(define_expand "movxf"
2714  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2715	(match_operand:XF 1 "general_operand" ""))]
2716  ""
2717  "ix86_expand_move (XFmode, operands); DONE;")
2718
2719;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2720;; Size of pushdf using integer instructions is 3+3*memory operand size
2721;; Pushing using integer instructions is longer except for constants
2722;; and direct memory references.
2723;; (assuming that any given constant is pushed only once, but this ought to be
2724;;  handled elsewhere).
2725
2726(define_insn "*pushxf_nointeger"
2727  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2728	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729  "optimize_size"
2730{
2731  /* This insn should be already split before reg-stack.  */
2732  gcc_unreachable ();
2733}
2734  [(set_attr "type" "multi")
2735   (set_attr "unit" "i387,*,*")
2736   (set_attr "mode" "XF,SI,SI")])
2737
2738(define_insn "*pushxf_integer"
2739  [(set (match_operand:XF 0 "push_operand" "=<,<")
2740	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2741  "!optimize_size"
2742{
2743  /* This insn should be already split before reg-stack.  */
2744  gcc_unreachable ();
2745}
2746  [(set_attr "type" "multi")
2747   (set_attr "unit" "i387,*")
2748   (set_attr "mode" "XF,SI")])
2749
2750(define_split
2751  [(set (match_operand 0 "push_operand" "")
2752	(match_operand 1 "general_operand" ""))]
2753  "reload_completed
2754   && (GET_MODE (operands[0]) == XFmode
2755       || GET_MODE (operands[0]) == DFmode)
2756   && !ANY_FP_REG_P (operands[1])"
2757  [(const_int 0)]
2758  "ix86_split_long_move (operands); DONE;")
2759
2760(define_split
2761  [(set (match_operand:XF 0 "push_operand" "")
2762	(match_operand:XF 1 "any_fp_register_operand" ""))]
2763  "!TARGET_64BIT"
2764  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2765   (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2766  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767
2768(define_split
2769  [(set (match_operand:XF 0 "push_operand" "")
2770	(match_operand:XF 1 "any_fp_register_operand" ""))]
2771  "TARGET_64BIT"
2772  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2773   (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2774  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775
2776;; Do not use integer registers when optimizing for size
2777(define_insn "*movxf_nointeger"
2778  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2779	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2780  "optimize_size
2781   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2782   && (reload_in_progress || reload_completed
2783       || GET_CODE (operands[1]) != CONST_DOUBLE
2784       || memory_operand (operands[0], XFmode))" 
2785{
2786  switch (which_alternative)
2787    {
2788    case 0:
2789      return output_387_reg_move (insn, operands);
2790
2791    case 1:
2792      /* There is no non-popping store to memory for XFmode.  So if
2793	 we need one, follow the store with a load.  */
2794      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2795        return "fstp%z0\t%y0\;fld%z0\t%y0";
2796      else
2797        return "fstp%z0\t%y0";
2798
2799    case 2:
2800      return standard_80387_constant_opcode (operands[1]);
2801
2802    case 3: case 4:
2803      return "#";
2804    default:
2805      gcc_unreachable ();
2806    }
2807}
2808  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2809   (set_attr "mode" "XF,XF,XF,SI,SI")])
2810
2811(define_insn "*movxf_integer"
2812  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2813	(match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2814  "!optimize_size
2815   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2816   && (reload_in_progress || reload_completed
2817       || GET_CODE (operands[1]) != CONST_DOUBLE
2818       || memory_operand (operands[0], XFmode))" 
2819{
2820  switch (which_alternative)
2821    {
2822    case 0:
2823      return output_387_reg_move (insn, operands);
2824
2825    case 1:
2826      /* There is no non-popping store to memory for XFmode.  So if
2827	 we need one, follow the store with a load.  */
2828      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2829        return "fstp%z0\t%y0\;fld%z0\t%y0";
2830      else
2831        return "fstp%z0\t%y0";
2832
2833    case 2:
2834      return standard_80387_constant_opcode (operands[1]);
2835
2836    case 3: case 4:
2837      return "#";
2838
2839    default:
2840      gcc_unreachable ();
2841    }
2842}
2843  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2844   (set_attr "mode" "XF,XF,XF,SI,SI")])
2845
2846(define_split
2847  [(set (match_operand 0 "nonimmediate_operand" "")
2848	(match_operand 1 "general_operand" ""))]
2849  "reload_completed
2850   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2851   && GET_MODE (operands[0]) == XFmode
2852   && ! (ANY_FP_REG_P (operands[0]) || 
2853	 (GET_CODE (operands[0]) == SUBREG
2854	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2855   && ! (ANY_FP_REG_P (operands[1]) || 
2856	 (GET_CODE (operands[1]) == SUBREG
2857	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2858  [(const_int 0)]
2859  "ix86_split_long_move (operands); DONE;")
2860
2861(define_split
2862  [(set (match_operand 0 "register_operand" "")
2863	(match_operand 1 "memory_operand" ""))]
2864  "reload_completed
2865   && GET_CODE (operands[1]) == MEM
2866   && (GET_MODE (operands[0]) == XFmode
2867       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2868   && constant_pool_reference_p (operands[1])"
2869  [(set (match_dup 0) (match_dup 1))]
2870{
2871  rtx c = avoid_constant_pool_reference (operands[1]);
2872  rtx r = operands[0];
2873
2874  if (GET_CODE (r) == SUBREG)
2875    r = SUBREG_REG (r);
2876
2877  if (SSE_REG_P (r))
2878    {
2879      if (!standard_sse_constant_p (c))
2880	FAIL;
2881    }
2882  else if (FP_REG_P (r))
2883    {
2884      if (!standard_80387_constant_p (c))
2885	FAIL;
2886    }
2887  else if (MMX_REG_P (r))
2888    FAIL;
2889
2890  operands[1] = c;
2891})
2892
2893(define_insn "swapxf"
2894  [(set (match_operand:XF 0 "register_operand" "+f")
2895	(match_operand:XF 1 "register_operand" "+f"))
2896   (set (match_dup 1)
2897	(match_dup 0))]
2898  "TARGET_80387"
2899{
2900  if (STACK_TOP_P (operands[0]))
2901    return "fxch\t%1";
2902  else
2903    return "fxch\t%0";
2904}
2905  [(set_attr "type" "fxch")
2906   (set_attr "mode" "XF")])
2907
2908(define_expand "movtf"
2909  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2910	(match_operand:TF 1 "nonimmediate_operand" ""))]
2911  "TARGET_64BIT"
2912{
2913  ix86_expand_move (TFmode, operands);
2914  DONE;
2915})
2916
2917(define_insn "*movtf_internal"
2918  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2919	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2920  "TARGET_64BIT
2921   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922{
2923  switch (which_alternative)
2924    {
2925    case 0:
2926    case 1:
2927      return "#";
2928    case 2:
2929      if (get_attr_mode (insn) == MODE_V4SF)
2930	return "xorps\t%0, %0";
2931      else
2932	return "pxor\t%0, %0";
2933    case 3:
2934    case 4:
2935      if (get_attr_mode (insn) == MODE_V4SF)
2936	return "movaps\t{%1, %0|%0, %1}";
2937      else
2938	return "movdqa\t{%1, %0|%0, %1}";
2939    default:
2940      gcc_unreachable ();
2941    }
2942}
2943  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2944   (set (attr "mode")
2945        (cond [(eq_attr "alternative" "2,3")
2946		 (if_then_else
2947		   (ne (symbol_ref "optimize_size")
2948		       (const_int 0))
2949		   (const_string "V4SF")
2950		   (const_string "TI"))
2951	       (eq_attr "alternative" "4")
2952		 (if_then_else
2953		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2954			    (const_int 0))
2955			(ne (symbol_ref "optimize_size")
2956			    (const_int 0)))
2957		   (const_string "V4SF")
2958		   (const_string "TI"))]
2959	       (const_string "DI")))])
2960
2961(define_split
2962  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2963        (match_operand:TF 1 "general_operand" ""))]
2964  "reload_completed && !SSE_REG_P (operands[0])
2965   && !SSE_REG_P (operands[1])"
2966  [(const_int 0)]
2967  "ix86_split_long_move (operands); DONE;")
2968
2969;; Zero extension instructions
2970
2971(define_expand "zero_extendhisi2"
2972  [(set (match_operand:SI 0 "register_operand" "")
2973     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2974  ""
2975{
2976  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2977    {
2978      operands[1] = force_reg (HImode, operands[1]);
2979      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2980      DONE;
2981    }
2982})
2983
2984(define_insn "zero_extendhisi2_and"
2985  [(set (match_operand:SI 0 "register_operand" "=r")
2986     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2987   (clobber (reg:CC FLAGS_REG))]
2988  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2989  "#"
2990  [(set_attr "type" "alu1")
2991   (set_attr "mode" "SI")])
2992
2993(define_split
2994  [(set (match_operand:SI 0 "register_operand" "")
2995	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2996   (clobber (reg:CC FLAGS_REG))]
2997  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2998  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2999	      (clobber (reg:CC FLAGS_REG))])]
3000  "")
3001
3002(define_insn "*zero_extendhisi2_movzwl"
3003  [(set (match_operand:SI 0 "register_operand" "=r")
3004     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3005  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3006  "movz{wl|x}\t{%1, %0|%0, %1}"
3007  [(set_attr "type" "imovx")
3008   (set_attr "mode" "SI")])
3009
3010(define_expand "zero_extendqihi2"
3011  [(parallel
3012    [(set (match_operand:HI 0 "register_operand" "")
3013       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3014     (clobber (reg:CC FLAGS_REG))])]
3015  ""
3016  "")
3017
3018(define_insn "*zero_extendqihi2_and"
3019  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3020     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3021   (clobber (reg:CC FLAGS_REG))]
3022  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3023  "#"
3024  [(set_attr "type" "alu1")
3025   (set_attr "mode" "HI")])
3026
3027(define_insn "*zero_extendqihi2_movzbw_and"
3028  [(set (match_operand:HI 0 "register_operand" "=r,r")
3029     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3030   (clobber (reg:CC FLAGS_REG))]
3031  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032  "#"
3033  [(set_attr "type" "imovx,alu1")
3034   (set_attr "mode" "HI")])
3035
3036; zero extend to SImode here to avoid partial register stalls
3037(define_insn "*zero_extendqihi2_movzbl"
3038  [(set (match_operand:HI 0 "register_operand" "=r")
3039     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3040  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3041  "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3042  [(set_attr "type" "imovx")
3043   (set_attr "mode" "SI")])
3044
3045;; For the movzbw case strip only the clobber
3046(define_split
3047  [(set (match_operand:HI 0 "register_operand" "")
3048	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3049   (clobber (reg:CC FLAGS_REG))]
3050  "reload_completed 
3051   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3052   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3053  [(set (match_operand:HI 0 "register_operand" "")
3054	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3055
3056;; When source and destination does not overlap, clear destination
3057;; first and then do the movb
3058(define_split
3059  [(set (match_operand:HI 0 "register_operand" "")
3060	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3061   (clobber (reg:CC FLAGS_REG))]
3062  "reload_completed
3063   && ANY_QI_REG_P (operands[0])
3064   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3065   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3066  [(set (match_dup 0) (const_int 0))
3067   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3068  "operands[2] = gen_lowpart (QImode, operands[0]);")
3069
3070;; Rest is handled by single and.
3071(define_split
3072  [(set (match_operand:HI 0 "register_operand" "")
3073	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3074   (clobber (reg:CC FLAGS_REG))]
3075  "reload_completed
3076   && true_regnum (operands[0]) == true_regnum (operands[1])"
3077  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3078	      (clobber (reg:CC FLAGS_REG))])]
3079  "")
3080
3081(define_expand "zero_extendqisi2"
3082  [(parallel
3083    [(set (match_operand:SI 0 "register_operand" "")
3084       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3085     (clobber (reg:CC FLAGS_REG))])]
3086  ""
3087  "")
3088
3089(define_insn "*zero_extendqisi2_and"
3090  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3091     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3092   (clobber (reg:CC FLAGS_REG))]
3093  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3094  "#"
3095  [(set_attr "type" "alu1")
3096   (set_attr "mode" "SI")])
3097
3098(define_insn "*zero_extendqisi2_movzbw_and"
3099  [(set (match_operand:SI 0 "register_operand" "=r,r")
3100     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3101   (clobber (reg:CC FLAGS_REG))]
3102  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3103  "#"
3104  [(set_attr "type" "imovx,alu1")
3105   (set_attr "mode" "SI")])
3106
3107(define_insn "*zero_extendqisi2_movzbw"
3108  [(set (match_operand:SI 0 "register_operand" "=r")
3109     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3110  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3111  "movz{bl|x}\t{%1, %0|%0, %1}"
3112  [(set_attr "type" "imovx")
3113   (set_attr "mode" "SI")])
3114
3115;; For the movzbl case strip only the clobber
3116(define_split
3117  [(set (match_operand:SI 0 "register_operand" "")
3118	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3119   (clobber (reg:CC FLAGS_REG))]
3120  "reload_completed 
3121   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3122   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3123  [(set (match_dup 0)
3124	(zero_extend:SI (match_dup 1)))])
3125
3126;; When source and destination does not overlap, clear destination
3127;; first and then do the movb
3128(define_split
3129  [(set (match_operand:SI 0 "register_operand" "")
3130	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3131   (clobber (reg:CC FLAGS_REG))]
3132  "reload_completed
3133   && ANY_QI_REG_P (operands[0])
3134   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3135   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3136   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3137  [(set (match_dup 0) (const_int 0))
3138   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3139  "operands[2] = gen_lowpart (QImode, operands[0]);")
3140
3141;; Rest is handled by single and.
3142(define_split
3143  [(set (match_operand:SI 0 "register_operand" "")
3144	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3145   (clobber (reg:CC FLAGS_REG))]
3146  "reload_completed
3147   && true_regnum (operands[0]) == true_regnum (operands[1])"
3148  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3149	      (clobber (reg:CC FLAGS_REG))])]
3150  "")
3151
3152;; %%% Kill me once multi-word ops are sane.
3153(define_expand "zero_extendsidi2"
3154  [(set (match_operand:DI 0 "register_operand" "=r")
3155     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3156  ""
3157  "if (!TARGET_64BIT)
3158     {
3159       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3160       DONE;
3161     }
3162  ")
3163
3164(define_insn "zero_extendsidi2_32"
3165  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3166	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3167   (clobber (reg:CC FLAGS_REG))]
3168  "!TARGET_64BIT"
3169  "@
3170   #
3171   #
3172   #
3173   movd\t{%1, %0|%0, %1}
3174   movd\t{%1, %0|%0, %1}"
3175  [(set_attr "mode" "SI,SI,SI,DI,TI")
3176   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3177
3178(define_insn "zero_extendsidi2_rex64"
3179  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3180     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3181  "TARGET_64BIT"
3182  "@
3183   mov\t{%k1, %k0|%k0, %k1}
3184   #
3185   movd\t{%1, %0|%0, %1}
3186   movd\t{%1, %0|%0, %1}"
3187  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3188   (set_attr "mode" "SI,DI,SI,SI")])
3189
3190(define_split
3191  [(set (match_operand:DI 0 "memory_operand" "")
3192     (zero_extend:DI (match_dup 0)))]
3193  "TARGET_64BIT"
3194  [(set (match_dup 4) (const_int 0))]
3195  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196
3197(define_split 
3198  [(set (match_operand:DI 0 "register_operand" "")
3199	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3200   (clobber (reg:CC FLAGS_REG))]
3201  "!TARGET_64BIT && reload_completed
3202   && true_regnum (operands[0]) == true_regnum (operands[1])"
3203  [(set (match_dup 4) (const_int 0))]
3204  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206(define_split 
3207  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3208	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3209   (clobber (reg:CC FLAGS_REG))]
3210  "!TARGET_64BIT && reload_completed
3211   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3212  [(set (match_dup 3) (match_dup 1))
3213   (set (match_dup 4) (const_int 0))]
3214  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3215
3216(define_insn "zero_extendhidi2"
3217  [(set (match_operand:DI 0 "register_operand" "=r")
3218     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3219  "TARGET_64BIT"
3220  "movz{wl|x}\t{%1, %k0|%k0, %1}"
3221  [(set_attr "type" "imovx")
3222   (set_attr "mode" "DI")])
3223
3224(define_insn "zero_extendqidi2"
3225  [(set (match_operand:DI 0 "register_operand" "=r")
3226     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3227  "TARGET_64BIT"
3228  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3229  [(set_attr "type" "imovx")
3230   (set_attr "mode" "DI")])
3231
3232;; Sign extension instructions
3233
3234(define_expand "extendsidi2"
3235  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3236		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3237	      (clobber (reg:CC FLAGS_REG))
3238	      (clobber (match_scratch:SI 2 ""))])]
3239  ""
3240{
3241  if (TARGET_64BIT)
3242    {
3243      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3244      DONE;
3245    }
3246})
3247
3248(define_insn "*extendsidi2_1"
3249  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3250	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3251   (clobber (reg:CC FLAGS_REG))
3252   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3253  "!TARGET_64BIT"
3254  "#")
3255
3256(define_insn "extendsidi2_rex64"
3257  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3258	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3259  "TARGET_64BIT"
3260  "@
3261   {cltq|cdqe}
3262   movs{lq|x}\t{%1,%0|%0, %1}"
3263  [(set_attr "type" "imovx")
3264   (set_attr "mode" "DI")
3265   (set_attr "prefix_0f" "0")
3266   (set_attr "modrm" "0,1")])
3267
3268(define_insn "extendhidi2"
3269  [(set (match_operand:DI 0 "register_operand" "=r")
3270	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3271  "TARGET_64BIT"
3272  "movs{wq|x}\t{%1,%0|%0, %1}"
3273  [(set_attr "type" "imovx")
3274   (set_attr "mode" "DI")])
3275
3276(define_insn "extendqidi2"
3277  [(set (match_operand:DI 0 "register_operand" "=r")
3278	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3279  "TARGET_64BIT"
3280  "movs{bq|x}\t{%1,%0|%0, %1}"
3281   [(set_attr "type" "imovx")
3282    (set_attr "mode" "DI")])
3283
3284;; Extend to memory case when source register does die.
3285(define_split 
3286  [(set (match_operand:DI 0 "memory_operand" "")
3287	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3288   (clobber (reg:CC FLAGS_REG))
3289   (clobber (match_operand:SI 2 "register_operand" ""))]
3290  "(reload_completed
3291    && dead_or_set_p (insn, operands[1])
3292    && !reg_mentioned_p (operands[1], operands[0]))"
3293  [(set (match_dup 3) (match_dup 1))
3294   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3295	      (clobber (reg:CC FLAGS_REG))])
3296   (set (match_dup 4) (match_dup 1))]
3297  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3298
3299;; Extend to memory case when source register does not die.
3300(define_split 
3301  [(set (match_operand:DI 0 "memory_operand" "")
3302	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3303   (clobber (reg:CC FLAGS_REG))
3304   (clobber (match_operand:SI 2 "register_operand" ""))]
3305  "reload_completed"
3306  [(const_int 0)]
3307{
3308  split_di (&operands[0], 1, &operands[3], &operands[4]);
3309
3310  emit_move_insn (operands[3], operands[1]);
3311
3312  /* Generate a cltd if possible and doing so it profitable.  */
3313  if (true_regnum (operands[1]) == 0
3314      && true_regnum (operands[2]) == 1
3315      && (optimize_size || TARGET_USE_CLTD))
3316    {
3317      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3318    }
3319  else
3320    {
3321      emit_move_insn (operands[2], operands[1]);
3322      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3323    }
3324  emit_move_insn (operands[4], operands[2]);
3325  DONE;
3326})
3327
3328;; Extend to register case.  Optimize case where source and destination
3329;; registers match and cases where we can use cltd.
3330(define_split 
3331  [(set (match_operand:DI 0 "register_operand" "")
3332	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3333   (clobber (reg:CC FLAGS_REG))
3334   (clobber (match_scratch:SI 2 ""))]
3335  "reload_completed"
3336  [(const_int 0)]
3337{
3338  split_di (&operands[0], 1, &operands[3], &operands[4]);
3339
3340  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3341    emit_move_insn (operands[3], operands[1]);
3342
3343  /* Generate a cltd if possible and doing so it profitable.  */
3344  if (true_regnum (operands[3]) == 0
3345      && (optimize_size || TARGET_USE_CLTD))
3346    {
3347      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3348      DONE;
3349    }
3350
3351  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3352    emit_move_insn (operands[4], operands[1]);
3353
3354  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3355  DONE;
3356})
3357
3358(define_insn "extendhisi2"
3359  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3360	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3361  ""
3362{
3363  switch (get_attr_prefix_0f (insn))
3364    {
3365    case 0:
3366      return "{cwtl|cwde}";
3367    default:
3368      return "movs{wl|x}\t{%1,%0|%0, %1}";
3369    }
3370}
3371  [(set_attr "type" "imovx")
3372   (set_attr "mode" "SI")
3373   (set (attr "prefix_0f")
3374     ;; movsx is short decodable while cwtl is vector decoded.
3375     (if_then_else (and (eq_attr "cpu" "!k6")
3376			(eq_attr "alternative" "0"))
3377	(const_string "0")
3378	(const_string "1")))
3379   (set (attr "modrm")
3380     (if_then_else (eq_attr "prefix_0f" "0")
3381	(const_string "0")
3382	(const_string "1")))])
3383
3384(define_insn "*extendhisi2_zext"
3385  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3386	(zero_extend:DI
3387	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3388  "TARGET_64BIT"
3389{
3390  switch (get_attr_prefix_0f (insn))
3391    {
3392    case 0:
3393      return "{cwtl|cwde}";
3394    default:
3395      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3396    }
3397}
3398  [(set_attr "type" "imovx")
3399   (set_attr "mode" "SI")
3400   (set (attr "prefix_0f")
3401     ;; movsx is short decodable while cwtl is vector decoded.
3402     (if_then_else (and (eq_attr "cpu" "!k6")
3403			(eq_attr "alternative" "0"))
3404	(const_string "0")
3405	(const_string "1")))
3406   (set (attr "modrm")
3407     (if_then_else (eq_attr "prefix_0f" "0")
3408	(const_string "0")
3409	(const_string "1")))])
3410
3411(define_insn "extendqihi2"
3412  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3413	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3414  ""
3415{
3416  switch (get_attr_prefix_0f (insn))
3417    {
3418    case 0:
3419      return "{cbtw|cbw}";
3420    default:
3421      return "movs{bw|x}\t{%1,%0|%0, %1}";
3422    }
3423}
3424  [(set_attr "type" "imovx")
3425   (set_attr "mode" "HI")
3426   (set (attr "prefix_0f")
3427     ;; movsx is short decodable while cwtl is vector decoded.
3428     (if_then_else (and (eq_attr "cpu" "!k6")
3429			(eq_attr "alternative" "0"))
3430	(const_string "0")
3431	(const_string "1")))
3432   (set (attr "modrm")
3433     (if_then_else (eq_attr "prefix_0f" "0")
3434	(const_string "0")
3435	(const_string "1")))])
3436
3437(define_insn "extendqisi2"
3438  [(set (match_operand:SI 0 "register_operand" "=r")
3439	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3440  ""
3441  "movs{bl|x}\t{%1,%0|%0, %1}"
3442   [(set_attr "type" "imovx")
3443    (set_attr "mode" "SI")])
3444
3445(define_insn "*extendqisi2_zext"
3446  [(set (match_operand:DI 0 "register_operand" "=r")
3447	(zero_extend:DI
3448	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3449  "TARGET_64BIT"
3450  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3451   [(set_attr "type" "imovx")
3452    (set_attr "mode" "SI")])
3453
3454;; Conversions between float and double.
3455
3456;; These are all no-ops in the model used for the 80387.  So just
3457;; emit moves.
3458
3459;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3460(define_insn "*dummy_extendsfdf2"
3461  [(set (match_operand:DF 0 "push_operand" "=<")
3462	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3463  "0"
3464  "#")
3465
3466(define_split
3467  [(set (match_operand:DF 0 "push_operand" "")
3468	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469  "!TARGET_64BIT"
3470  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3471   (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3472
3473(define_split
3474  [(set (match_operand:DF 0 "push_operand" "")
3475	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3476  "TARGET_64BIT"
3477  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3478   (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3479
3480(define_insn "*dummy_extendsfxf2"
3481  [(set (match_operand:XF 0 "push_operand" "=<")
3482	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3483  "0"
3484  "#")
3485
3486(define_split
3487  [(set (match_operand:XF 0 "push_operand" "")
3488	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3489  ""
3490  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3491   (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3492  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493
3494(define_split
3495  [(set (match_operand:XF 0 "push_operand" "")
3496	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3497  "TARGET_64BIT"
3498  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3499   (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3500  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501
3502(define_split
3503  [(set (match_operand:XF 0 "push_operand" "")
3504	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3505  ""
3506  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3507   (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3508  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509
3510(define_split
3511  [(set (match_operand:XF 0 "push_operand" "")
3512	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3513  "TARGET_64BIT"
3514  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3515   (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3516  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3517
3518(define_expand "extendsfdf2"
3519  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3520        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3521  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3522{
3523  /* ??? Needed for compress_float_constant since all fp constants
3524     are LEGITIMATE_CONSTANT_P.  */
3525  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3526    {
3527      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3528	  && standard_80387_constant_p (operands[1]) > 0)
3529	{
3530	  operands[1] = simplify_const_unary_operation
3531	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3532	  emit_move_insn_1 (operands[0], operands[1]);
3533	  DONE;
3534	}
3535      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3536    }
3537  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3538    operands[1] = force_reg (SFmode, operands[1]);
3539})
3540
3541(define_insn "*extendsfdf2_mixed"
3542  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3543        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3544  "TARGET_SSE2 && TARGET_MIX_SSE_I387
3545   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3546{
3547  switch (which_alternative)
3548    {
3549    case 0:
3550      return output_387_reg_move (insn, operands);
3551
3552    case 1:
3553      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3554        return "fstp%z0\t%y0";
3555      else
3556        return "fst%z0\t%y0";
3557
3558    case 2:
3559      return "cvtss2sd\t{%1, %0|%0, %1}";
3560
3561    default:
3562      gcc_unreachable ();
3563    }
3564}
3565  [(set_attr "type" "fmov,fmov,ssecvt")
3566   (set_attr "mode" "SF,XF,DF")])
3567
3568(define_insn "*extendsfdf2_sse"
3569  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3570        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3571  "TARGET_SSE2 && TARGET_SSE_MATH
3572   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573  "cvtss2sd\t{%1, %0|%0, %1}"
3574  [(set_attr "type" "ssecvt")
3575   (set_attr "mode" "DF")])
3576
3577(define_insn "*extendsfdf2_i387"
3578  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3579        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3580  "TARGET_80387
3581   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3582{
3583  switch (which_alternative)
3584    {
3585    case 0:
3586      return output_387_reg_move (insn, operands);
3587
3588    case 1:
3589      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590        return "fstp%z0\t%y0";
3591      else
3592        return "fst%z0\t%y0";
3593
3594    default:
3595      gcc_unreachable ();
3596    }
3597}
3598  [(set_attr "type" "fmov")
3599   (set_attr "mode" "SF,XF")])
3600
3601(define_expand "extendsfxf2"
3602  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3603        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3604  "TARGET_80387"
3605{
3606  /* ??? Needed for compress_float_constant since all fp constants
3607     are LEGITIMATE_CONSTANT_P.  */
3608  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609    {
3610      if (standard_80387_constant_p (operands[1]) > 0)
3611	{
3612	  operands[1] = simplify_const_unary_operation
3613	    (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3614	  emit_move_insn_1 (operands[0], operands[1]);
3615	  DONE;
3616	}
3617      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3618    }
3619  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3620    operands[1] = force_reg (SFmode, operands[1]);
3621})
3622
3623(define_insn "*extendsfxf2_i387"
3624  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3625        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3626  "TARGET_80387
3627   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3628{
3629  switch (which_alternative)
3630    {
3631    case 0:
3632      return output_387_reg_move (insn, operands);
3633
3634    case 1:
3635      /* There is no non-popping store to memory for XFmode.  So if
3636	 we need one, follow the store with a load.  */
3637      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3638        return "fstp%z0\t%y0";
3639      else
3640        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3641
3642    default:
3643      gcc_unreachable ();
3644    }
3645}
3646  [(set_attr "type" "fmov")
3647   (set_attr "mode" "SF,XF")])
3648
3649(define_expand "extenddfxf2"
3650  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3651        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3652  "TARGET_80387"
3653{
3654  /* ??? Needed for compress_float_constant since all fp constants
3655     are LEGITIMATE_CONSTANT_P.  */
3656  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3657    {
3658      if (standard_80387_constant_p (operands[1]) > 0)
3659	{
3660	  operands[1] = simplify_const_unary_operation
3661	    (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3662	  emit_move_insn_1 (operands[0], operands[1]);
3663	  DONE;
3664	}
3665      operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3666    }
3667  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3668    operands[1] = force_reg (DFmode, operands[1]);
3669})
3670
3671(define_insn "*extenddfxf2_i387"
3672  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3673        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3674  "TARGET_80387
3675   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3676{
3677  switch (which_alternative)
3678    {
3679    case 0:
3680      return output_387_reg_move (insn, operands);
3681
3682    case 1:
3683      /* There is no non-popping store to memory for XFmode.  So if
3684	 we need one, follow the store with a load.  */
3685      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3686        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3687      else
3688        return "fstp%z0\t%y0";
3689
3690    default:
3691      gcc_unreachable ();
3692    }
3693}
3694  [(set_attr "type" "fmov")
3695   (set_attr "mode" "DF,XF")])
3696
3697;; %%% This seems bad bad news.
3698;; This cannot output into an f-reg because there is no way to be sure
3699;; of truncating in that case.  Otherwise this is just like a simple move
3700;; insn.  So we pretend we can output to a reg in order to get better
3701;; register preferencing, but we really use a stack slot.
3702
3703;; Conversion from DFmode to SFmode.
3704
3705(define_expand "truncdfsf2"
3706  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3707	(float_truncate:SF
3708	  (match_operand:DF 1 "nonimmediate_operand" "")))]
3709  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3710{
3711  if (MEM_P (operands[0]) && MEM_P (operands[1]))
3712    operands[1] = force_reg (DFmode, operands[1]);
3713
3714  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3715    ;
3716  else if (flag_unsafe_math_optimizations)
3717    ;
3718  else
3719    {
3720      rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3721      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3722      DONE;
3723    }
3724})
3725
3726(define_expand "truncdfsf2_with_temp"
3727  [(parallel [(set (match_operand:SF 0 "" "")
3728		   (float_truncate:SF (match_operand:DF 1 "" "")))
3729	      (clobber (match_operand:SF 2 "" ""))])]
3730  "")
3731
3732(define_insn "*truncdfsf_fast_mixed"
3733  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3734        (float_truncate:SF
3735          (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3736  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3737{
3738  switch (which_alternative)
3739    {
3740    case 0:
3741      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3742	return "fstp%z0\t%y0";
3743      else
3744	return "fst%z0\t%y0";
3745    case 1:
3746      return output_387_reg_move (insn, operands);
3747    case 2:
3748      return "cvtsd2ss\t{%1, %0|%0, %1}";
3749    default:
3750      gcc_unreachable ();
3751    }
3752}
3753  [(set_attr "type" "fmov,fmov,ssecvt")
3754   (set_attr "mode" "SF")])
3755
3756;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3757;; because nothing we do here is unsafe.
3758(define_insn "*truncdfsf_fast_sse"
3759  [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3760        (float_truncate:SF
3761          (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3762  "TARGET_SSE2 && TARGET_SSE_MATH"
3763  "cvtsd2ss\t{%1, %0|%0, %1}"
3764  [(set_attr "type" "ssecvt")
3765   (set_attr "mode" "SF")])
3766
3767(define_insn "*truncdfsf_fast_i387"
3768  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3769        (float_truncate:SF
3770          (match_operand:DF 1 "nonimmediate_operand" "f")))]
3771  "TARGET_80387 && flag_unsafe_math_optimizations"
3772  "* return output_387_reg_move (insn, operands);"
3773  [(set_attr "type" "fmov")
3774   (set_attr "mode" "SF")])
3775
3776(define_insn "*truncdfsf_mixed"
3777  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3778	(float_truncate:SF
3779	  (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3780   (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3781  "TARGET_MIX_SSE_I387"
3782{
3783  switch (which_alternative)
3784    {
3785    case 0:
3786      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3787	return "fstp%z0\t%y0";
3788      else
3789	return "fst%z0\t%y0";
3790    case 1:
3791      return "#";
3792    case 2:
3793      return "cvtsd2ss\t{%1, %0|%0, %1}";
3794    default:
3795      gcc_unreachable ();
3796    }
3797}
3798  [(set_attr "type" "fmov,multi,ssecvt")
3799   (set_attr "unit" "*,i387,*")
3800   (set_attr "mode" "SF")])
3801
3802(define_insn "*truncdfsf_i387"
3803  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3804	(float_truncate:SF
3805	  (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3806   (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3807  "TARGET_80387"
3808{
3809  switch (which_alternative)
3810    {
3811    case 0:
3812      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813	return "fstp%z0\t%y0";
3814      else
3815	return "fst%z0\t%y0";
3816    case 1:
3817      return "#";
3818    default:
3819      gcc_unreachable ();
3820    }
3821}
3822  [(set_attr "type" "fmov,multi")
3823   (set_attr "unit" "*,i387")
3824   (set_attr "mode" "SF")])
3825
3826(define_insn "*truncdfsf2_i387_1"
3827  [(set (match_operand:SF 0 "memory_operand" "=m")
3828	(float_truncate:SF
3829	  (match_operand:DF 1 "register_operand" "f")))]
3830  "TARGET_80387
3831   && !(TARGET_SSE2 && TARGET_SSE_MATH)
3832   && !TARGET_MIX_SSE_I387"
3833{
3834  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835    return "fstp%z0\t%y0";
3836  else
3837    return "fst%z0\t%y0";
3838}
3839  [(set_attr "type" "fmov")
3840   (set_attr "mode" "SF")])
3841
3842(define_split
3843  [(set (match_operand:SF 0 "register_operand" "")
3844	(float_truncate:SF
3845	 (match_operand:DF 1 "fp_register_operand" "")))
3846   (clobber (match_operand 2 "" ""))]
3847  "reload_completed"
3848  [(set (match_dup 2) (match_dup 1))
3849   (set (match_dup 0) (match_dup 2))]
3850{
3851  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3852})
3853
3854;; Conversion from XFmode to SFmode.
3855
3856(define_expand "truncxfsf2"
3857  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3858		   (float_truncate:SF
3859		    (match_operand:XF 1 "register_operand" "")))
3860	      (clobber (match_dup 2))])]
3861  "TARGET_80387"
3862{
3863  if (flag_unsafe_math_optimizations)
3864    {
3865      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3866      emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3867      if (reg != operands[0])
3868	emit_move_insn (operands[0], reg);
3869      DONE;
3870    }
3871  else
3872    operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3873})
3874
3875(define_insn "*truncxfsf2_mixed"
3876  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3877	(float_truncate:SF
3878	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3879   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3880  "TARGET_MIX_SSE_I387"
3881{
3882  gcc_assert (!which_alternative);
3883  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3884    return "fstp%z0\t%y0";
3885  else
3886    return "fst%z0\t%y0";
3887}
3888  [(set_attr "type" "fmov,multi,multi,multi")
3889   (set_attr "unit" "*,i387,i387,i387")
3890   (set_attr "mode" "SF")])
3891
3892(define_insn "truncxfsf2_i387_noop"
3893  [(set (match_operand:SF 0 "register_operand" "=f")
3894	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3895  "TARGET_80387 && flag_unsafe_math_optimizations"
3896{
3897  return output_387_reg_move (insn, operands);
3898}
3899  [(set_attr "type" "fmov")
3900   (set_attr "mode" "SF")])
3901
3902(define_insn "*truncxfsf2_i387"
3903  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3904	(float_truncate:SF
3905	 (match_operand:XF 1 "register_operand" "f,f,f")))
3906   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3907  "TARGET_80387"
3908{
3909  gcc_assert (!which_alternative);
3910  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911    return "fstp%z0\t%y0";
3912   else
3913     return "fst%z0\t%y0";
3914}
3915  [(set_attr "type" "fmov,multi,multi")
3916   (set_attr "unit" "*,i387,i387")
3917   (set_attr "mode" "SF")])
3918
3919(define_insn "*truncxfsf2_i387_1"
3920  [(set (match_operand:SF 0 "memory_operand" "=m")
3921	(float_truncate:SF
3922	 (match_operand:XF 1 "register_operand" "f")))]
3923  "TARGET_80387"
3924{
3925  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3926    return "fstp%z0\t%y0";
3927  else
3928    return "fst%z0\t%y0";
3929}
3930  [(set_attr "type" "fmov")
3931   (set_attr "mode" "SF")])
3932
3933(define_split
3934  [(set (match_operand:SF 0 "register_operand" "")
3935	(float_truncate:SF
3936	 (match_operand:XF 1 "register_operand" "")))
3937   (clobber (match_operand:SF 2 "memory_operand" ""))]
3938  "TARGET_80387 && reload_completed"
3939  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3940   (set (match_dup 0) (match_dup 2))]
3941  "")
3942
3943(define_split
3944  [(set (match_operand:SF 0 "memory_operand" "")
3945	(float_truncate:SF
3946	 (match_operand:XF 1 "register_operand" "")))
3947   (clobber (match_operand:SF 2 "memory_operand" ""))]
3948  "TARGET_80387"
3949  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3950  "")
3951
3952;; Conversion from XFmode to DFmode.
3953
3954(define_expand "truncxfdf2"
3955  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3956		   (float_truncate:DF
3957		    (match_operand:XF 1 "register_operand" "")))
3958	      (clobber (match_dup 2))])]
3959  "TARGET_80387"
3960{
3961  if (flag_unsafe_math_optimizations)
3962    {
3963      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3964      emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3965      if (reg != operands[0])
3966	emit_move_insn (operands[0], reg);
3967      DONE;
3968    }
3969  else
3970    operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3971})
3972
3973(define_insn "*truncxfdf2_mixed"
3974  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3975	(float_truncate:DF
3976	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3977   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3978  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3979{
3980  gcc_assert (!which_alternative);
3981  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3982    return "fstp%z0\t%y0";
3983  else
3984    return "fst%z0\t%y0";
3985}
3986  [(set_attr "type" "fmov,multi,multi,multi")
3987   (set_attr "unit" "*,i387,i387,i387")
3988   (set_attr "mode" "DF")])
3989
3990(define_insn "truncxfdf2_i387_noop"
3991  [(set (match_operand:DF 0 "register_operand" "=f")
3992	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3993  "TARGET_80387 && flag_unsafe_math_optimizations"
3994{
3995  return output_387_reg_move (insn, operands);
3996}
3997  [(set_attr "type" "fmov")
3998   (set_attr "mode" "DF")])
3999
4000(define_insn "*truncxfdf2_i387"
4001  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4002	(float_truncate:DF
4003	 (match_operand:XF 1 "register_operand" "f,f,f")))
4004   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4005  "TARGET_80387"
4006{
4007  gcc_assert (!which_alternative);
4008  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4009    return "fstp%z0\t%y0";
4010  else
4011    return "fst%z0\t%y0";
4012}
4013  [(set_attr "type" "fmov,multi,multi")
4014   (set_attr "unit" "*,i387,i387")
4015   (set_attr "mode" "DF")])
4016
4017(define_insn "*truncxfdf2_i387_1"
4018  [(set (match_operand:DF 0 "memory_operand" "=m")
4019	(float_truncate:DF
4020	  (match_operand:XF 1 "register_operand" "f")))]
4021  "TARGET_80387"
4022{
4023  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4024    return "fstp%z0\t%y0";
4025  else
4026    return "fst%z0\t%y0";
4027}
4028  [(set_attr "type" "fmov")
4029   (set_attr "mode" "DF")])
4030
4031(define_split
4032  [(set (match_operand:DF 0 "register_operand" "")
4033	(float_truncate:DF
4034	 (match_operand:XF 1 "register_operand" "")))
4035   (clobber (match_operand:DF 2 "memory_operand" ""))]
4036  "TARGET_80387 && reload_completed"
4037  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4038   (set (match_dup 0) (match_dup 2))]
4039  "")
4040
4041(define_split
4042  [(set (match_operand:DF 0 "memory_operand" "")
4043	(float_truncate:DF
4044	 (match_operand:XF 1 "register_operand" "")))
4045   (clobber (match_operand:DF 2 "memory_operand" ""))]
4046  "TARGET_80387"
4047  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4048  "")
4049
4050;; Signed conversion to DImode.
4051
4052(define_expand "fix_truncxfdi2"
4053  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4054                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4055	      (clobber (reg:CC FLAGS_REG))])]
4056  "TARGET_80387"
4057{
4058  if (TARGET_FISTTP)
4059   {
4060     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4061     DONE;
4062   }
4063})
4064
4065(define_expand "fix_trunc<mode>di2"
4066  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4067                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4068              (clobber (reg:CC FLAGS_REG))])]
4069  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4070{
4071  if (TARGET_FISTTP
4072      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4073   {
4074     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4075     DONE;
4076   }
4077  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4078   {
4079     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4080     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4081     if (out != operands[0])
4082	emit_move_insn (operands[0], out);
4083     DONE;
4084   }
4085})
4086
4087;; Signed conversion to SImode.
4088
4089(define_expand "fix_truncxfsi2"
4090  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4091                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4092	      (clobber (reg:CC FLAGS_REG))])]
4093  "TARGET_80387"
4094{
4095  if (TARGET_FISTTP)
4096   {
4097     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4098     DONE;
4099   }
4100})
4101
4102(define_expand "fix_trunc<mode>si2"
4103  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4104	           (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4105	      (clobber (reg:CC FLAGS_REG))])]
4106  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4107{
4108  if (TARGET_FISTTP
4109      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4110   {
4111     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4112     DONE;
4113   }
4114  if (SSE_FLOAT_MODE_P (<MODE>mode))
4115   {
4116     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4117     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4118     if (out != operands[0])
4119	emit_move_insn (operands[0], out);
4120     DONE;
4121   }
4122})
4123
4124;; Signed conversion to HImode.
4125
4126(define_expand "fix_trunc<mode>hi2"
4127  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4128	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4129              (clobber (reg:CC FLAGS_REG))])]
4130  "TARGET_80387
4131   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4132{
4133  if (TARGET_FISTTP)
4134   {
4135     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4136     DONE;
4137   }
4138})
4139
4140;; When SSE is available, it is always faster to use it!
4141(define_insn "fix_truncsfdi_sse"
4142  [(set (match_operand:DI 0 "register_operand" "=r,r")
4143	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4144  "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4145  "cvttss2si{q}\t{%1, %0|%0, %1}"
4146  [(set_attr "type" "sseicvt")
4147   (set_attr "mode" "SF")
4148   (set_attr "athlon_decode" "double,vector")])
4149
4150(define_insn "fix_truncdfdi_sse"
4151  [(set (match_operand:DI 0 "register_operand" "=r,r")
4152	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4153  "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4154  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4155  [(set_attr "type" "sseicvt")
4156   (set_attr "mode" "DF")
4157   (set_attr "athlon_decode" "double,vector")])
4158
4159(define_insn "fix_truncsfsi_sse"
4160  [(set (match_operand:SI 0 "register_operand" "=r,r")
4161	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4162  "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4163  "cvttss2si\t{%1, %0|%0, %1}"
4164  [(set_attr "type" "sseicvt")
4165   (set_attr "mode" "DF")
4166   (set_attr "athlon_decode" "double,vector")])
4167
4168(define_insn "fix_truncdfsi_sse"
4169  [(set (match_operand:SI 0 "register_operand" "=r,r")
4170	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4171  "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4172  "cvttsd2si\t{%1, %0|%0, %1}"
4173  [(set_attr "type" "sseicvt")
4174   (set_attr "mode" "DF")
4175   (set_attr "athlon_decode" "double,vector")])
4176
4177;; Avoid vector decoded forms of the instruction.
4178(define_peephole2
4179  [(match_scratch:DF 2 "Y")
4180   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4181	(fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4182  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4183  [(set (match_dup 2) (match_dup 1))
4184   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4185  "")
4186
4187(define_peephole2
4188  [(match_scratch:SF 2 "x")
4189   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4190	(fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4191  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4192  [(set (match_dup 2) (match_dup 1))
4193   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4194  "")
4195
4196(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4197  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4198	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4199  "TARGET_FISTTP
4200   && FLOAT_MODE_P (GET_MODE (operands[1]))
4201   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4202	 && (TARGET_64BIT || <MODE>mode != DImode))
4203	&& TARGET_SSE_MATH)
4204   && !(reload_completed || reload_in_progress)"
4205  "#"
4206  "&& 1"
4207  [(const_int 0)]
4208{
4209  if (memory_operand (operands[0], VOIDmode))
4210    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4211  else
4212    {
4213      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4214      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4215							    operands[1],
4216							    operands[2]));
4217    }
4218  DONE;
4219}
4220  [(set_attr "type" "fisttp")
4221   (set_attr "mode" "<MODE>")])
4222
4223(define_insn "fix_trunc<mode>_i387_fisttp"
4224  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4225	(fix:X87MODEI (match_operand 1 "register_operand" "f")))
4226   (clobber (match_scratch:XF 2 "=&1f"))]
4227  "TARGET_FISTTP
4228   && FLOAT_MODE_P (GET_MODE (operands[1]))
4229   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4230	 && (TARGET_64BIT || <MODE>mode != DImode))
4231	&& TARGET_SSE_MATH)"
4232  "* return output_fix_trunc (insn, operands, 1);"
4233  [(set_attr "type" "fisttp")
4234   (set_attr "mode" "<MODE>")])
4235
4236(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4237  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4238	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4239   (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4240   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4241  "TARGET_FISTTP
4242   && FLOAT_MODE_P (GET_MODE (operands[1]))
4243   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4244	&& (TARGET_64BIT || <MODE>mode != DImode))
4245	&& TARGET_SSE_MATH)"
4246  "#"
4247  [(set_attr "type" "fisttp")
4248   (set_attr "mode" "<MODE>")])
4249
4250(define_split
4251  [(set (match_operand:X87MODEI 0 "register_operand" "")
4252	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4253   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4254   (clobber (match_scratch 3 ""))]
4255  "reload_completed"
4256  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4257	      (clobber (match_dup 3))])
4258   (set (match_dup 0) (match_dup 2))]
4259  "")
4260
4261(define_split
4262  [(set (match_operand:X87MODEI 0 "memory_operand" "")
4263	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4264   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4265   (clobber (match_scratch 3 ""))]
4266  "reload_completed"
4267  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4268	      (clobber (match_dup 3))])]
4269  "")
4270
4271;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4272;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4273;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4274;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4275;; function in i386.c.
4276(define_insn_and_split "*fix_trunc<mode>_i387_1"
4277  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4278	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4279   (clobber (reg:CC FLAGS_REG))]
4280  "TARGET_80387 && !TARGET_FISTTP
4281   && FLOAT_MODE_P (GET_MODE (operands[1]))
4282   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4283	 && (TARGET_64BIT || <MODE>mode != DImode))
4284   && !(reload_completed || reload_in_progress)"
4285  "#"
4286  "&& 1"
4287  [(const_int 0)]
4288{
4289  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4290
4291  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4292  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4293  if (memory_operand (operands[0], VOIDmode))
4294    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4295					 operands[2], operands[3]));
4296  else
4297    {
4298      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4299      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4300						     operands[2], operands[3],
4301						     operands[4]));
4302    }
4303  DONE;
4304}
4305  [(set_attr "type" "fistp")
4306   (set_attr "i387_cw" "trunc")
4307   (set_attr "mode" "<MODE>")])
4308
4309(define_insn "fix_truncdi_i387"
4310  [(set (match_operand:DI 0 "memory_operand" "=m")
4311	(fix:DI (match_operand 1 "register_operand" "f")))
4312   (use (match_operand:HI 2 "memory_operand" "m"))
4313   (use (match_operand:HI 3 "memory_operand" "m"))
4314   (clobber (match_scratch:XF 4 "=&1f"))]
4315  "TARGET_80387 && !TARGET_FISTTP
4316   && FLOAT_MODE_P (GET_MODE (operands[1]))
4317   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4318  "* return output_fix_trunc (insn, operands, 0);"
4319  [(set_attr "type" "fistp")
4320   (set_attr "i387_cw" "trunc")
4321   (set_attr "mode" "DI")])
4322
4323(define_insn "fix_truncdi_i387_with_temp"
4324  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4325	(fix:DI (match_operand 1 "register_operand" "f,f")))
4326   (use (match_operand:HI 2 "memory_operand" "m,m"))
4327   (use (match_operand:HI 3 "memory_operand" "m,m"))
4328   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4329   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4330  "TARGET_80387 && !TARGET_FISTTP
4331   && FLOAT_MODE_P (GET_MODE (operands[1]))
4332   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4333  "#"
4334  [(set_attr "type" "fistp")
4335   (set_attr "i387_cw" "trunc")
4336   (set_attr "mode" "DI")])
4337
4338(define_split 
4339  [(set (match_operand:DI 0 "register_operand" "")
4340	(fix:DI (match_operand 1 "register_operand" "")))
4341   (use (match_operand:HI 2 "memory_operand" ""))
4342   (use (match_operand:HI 3 "memory_operand" ""))
4343   (clobber (match_operand:DI 4 "memory_operand" ""))
4344   (clobber (match_scratch 5 ""))]
4345  "reload_completed"
4346  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4347	      (use (match_dup 2))
4348	      (use (match_dup 3))
4349	      (clobber (match_dup 5))])
4350   (set (match_dup 0) (match_dup 4))]
4351  "")
4352
4353(define_split 
4354  [(set (match_operand:DI 0 "memory_operand" "")
4355	(fix:DI (match_operand 1 "register_operand" "")))
4356   (use (match_operand:HI 2 "memory_operand" ""))
4357   (use (match_operand:HI 3 "memory_operand" ""))
4358   (clobber (match_operand:DI 4 "memory_operand" ""))
4359   (clobber (match_scratch 5 ""))]
4360  "reload_completed"
4361  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4362	      (use (match_dup 2))
4363	      (use (match_dup 3))
4364	      (clobber (match_dup 5))])]
4365  "")
4366
4367(define_insn "fix_trunc<mode>_i387"
4368  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4369	(fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4370   (use (match_operand:HI 2 "memory_operand" "m"))
4371   (use (match_operand:HI 3 "memory_operand" "m"))]
4372  "TARGET_80387 && !TARGET_FISTTP
4373   && FLOAT_MODE_P (GET_MODE (operands[1]))
4374   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4375  "* return output_fix_trunc (insn, operands, 0);"
4376  [(set_attr "type" "fistp")
4377   (set_attr "i387_cw" "trunc")
4378   (set_attr "mode" "<MODE>")])
4379
4380(define_insn "fix_trunc<mode>_i387_with_temp"
4381  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4382	(fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4383   (use (match_operand:HI 2 "memory_operand" "m,m"))
4384   (use (match_operand:HI 3 "memory_operand" "m,m"))
4385   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4386  "TARGET_80387 && !TARGET_FISTTP
4387   && FLOAT_MODE_P (GET_MODE (operands[1]))
4388   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4389  "#"
4390  [(set_attr "type" "fistp")
4391   (set_attr "i387_cw" "trunc")
4392   (set_attr "mode" "<MODE>")])
4393
4394(define_split 
4395  [(set (match_operand:X87MODEI12 0 "register_operand" "")
4396	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4397   (use (match_operand:HI 2 "memory_operand" ""))
4398   (use (match_operand:HI 3 "memory_operand" ""))
4399   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4400  "reload_completed"
4401  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4402	      (use (match_dup 2))
4403	      (use (match_dup 3))])
4404   (set (match_dup 0) (match_dup 4))]
4405  "")
4406
4407(define_split 
4408  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4409	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4410   (use (match_operand:HI 2 "memory_operand" ""))
4411   (use (match_operand:HI 3 "memory_operand" ""))
4412   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4413  "reload_completed"
4414  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4415	      (use (match_dup 2))
4416	      (use (match_dup 3))])]
4417  "")
4418
4419(define_insn "x86_fnstcw_1"
4420  [(set (match_operand:HI 0 "memory_operand" "=m")
4421	(unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4422  "TARGET_80387"
4423  "fnstcw\t%0"
4424  [(set_attr "length" "2")
4425   (set_attr "mode" "HI")
4426   (set_attr "unit" "i387")])
4427
4428(define_insn "x86_fldcw_1"
4429  [(set (reg:HI FPSR_REG)
4430	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4431  "TARGET_80387"
4432  "fldcw\t%0"
4433  [(set_attr "length" "2")
4434   (set_attr "mode" "HI")
4435   (set_attr "unit" "i387")
4436   (set_attr "athlon_decode" "vector")])
4437
4438;; Conversion between fixed point and floating point.
4439
4440;; Even though we only accept memory inputs, the backend _really_
4441;; wants to be able to do this between registers.
4442
4443(define_expand "floathisf2"
4444  [(set (match_operand:SF 0 "register_operand" "")
4445	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4446  "TARGET_80387 || TARGET_SSE_MATH"
4447{
4448  if (TARGET_SSE_MATH)
4449    {
4450      emit_insn (gen_floatsisf2 (operands[0],
4451				 convert_to_mode (SImode, operands[1], 0)));
4452      DONE;
4453    }
4454})
4455
4456(define_insn "*floathisf2_i387"
4457  [(set (match_operand:SF 0 "register_operand" "=f,f")
4458	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4459  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4460  "@
4461   fild%z1\t%1
4462   #"
4463  [(set_attr "type" "fmov,multi")
4464   (set_attr "mode" "SF")
4465   (set_attr "unit" "*,i387")
4466   (set_attr "fp_int_src" "true")])
4467
4468(define_expand "floatsisf2"
4469  [(set (match_operand:SF 0 "register_operand" "")
4470	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4471  "TARGET_80387 || TARGET_SSE_MATH"
4472  "")
4473
4474(define_insn "*floatsisf2_mixed"
4475  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4476	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4477  "TARGET_MIX_SSE_I387"
4478  "@
4479   fild%z1\t%1
4480   #
4481   cvtsi2ss\t{%1, %0|%0, %1}
4482   cvtsi2ss\t{%1, %0|%0, %1}"
4483  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4484   (set_attr "mode" "SF")
4485   (set_attr "unit" "*,i387,*,*")
4486   (set_attr "athlon_decode" "*,*,vector,double")
4487   (set_attr "fp_int_src" "true")])
4488
4489(define_insn "*floatsisf2_sse"
4490  [(set (match_operand:SF 0 "register_operand" "=x,x")
4491	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4492  "TARGET_SSE_MATH"
4493  "cvtsi2ss\t{%1, %0|%0, %1}"
4494  [(set_attr "type" "sseicvt")
4495   (set_attr "mode" "SF")
4496   (set_attr "athlon_decode" "vector,double")
4497   (set_attr "fp_int_src" "true")])
4498
4499(define_insn "*floatsisf2_i387"
4500  [(set (match_operand:SF 0 "register_operand" "=f,f")
4501	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4502  "TARGET_80387"
4503  "@
4504   fild%z1\t%1
4505   #"
4506  [(set_attr "type" "fmov,multi")
4507   (set_attr "mode" "SF")
4508   (set_attr "unit" "*,i387")
4509   (set_attr "fp_int_src" "true")])
4510
4511(define_expand "floatdisf2"
4512  [(set (match_operand:SF 0 "register_operand" "")
4513	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4514  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4515  "")
4516
4517(define_insn "*floatdisf2_mixed"
4518  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4519	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4520  "TARGET_64BIT && TARGET_MIX_SSE_I387"
4521  "@
4522   fild%z1\t%1
4523   #
4524   cvtsi2ss{q}\t{%1, %0|%0, %1}
4525   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4526  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4527   (set_attr "mode" "SF")
4528   (set_attr "unit" "*,i387,*,*")
4529   (set_attr "athlon_decode" "*,*,vector,double")
4530   (set_attr "fp_int_src" "true")])
4531
4532(define_insn "*floatdisf2_sse"
4533  [(set (match_operand:SF 0 "register_operand" "=x,x")
4534	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4535  "TARGET_64BIT && TARGET_SSE_MATH"
4536  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537  [(set_attr "type" "sseicvt")
4538   (set_attr "mode" "SF")
4539   (set_attr "athlon_decode" "vector,double")
4540   (set_attr "fp_int_src" "true")])
4541
4542(define_insn "*floatdisf2_i387"
4543  [(set (match_operand:SF 0 "register_operand" "=f,f")
4544	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4545  "TARGET_80387"
4546  "@
4547   fild%z1\t%1
4548   #"
4549  [(set_attr "type" "fmov,multi")
4550   (set_attr "mode" "SF")
4551   (set_attr "unit" "*,i387")
4552   (set_attr "fp_int_src" "true")])
4553
4554(define_expand "floathidf2"
4555  [(set (match_operand:DF 0 "register_operand" "")
4556	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4557  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4558{
4559  if (TARGET_SSE2 && TARGET_SSE_MATH)
4560    {
4561      emit_insn (gen_floatsidf2 (operands[0],
4562				 convert_to_mode (SImode, operands[1], 0)));
4563      DONE;
4564    }
4565})
4566
4567(define_insn "*floathidf2_i387"
4568  [(set (match_operand:DF 0 "register_operand" "=f,f")
4569	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4570  "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4571  "@
4572   fild%z1\t%1
4573   #"
4574  [(set_attr "type" "fmov,multi")
4575   (set_attr "mode" "DF")
4576   (set_attr "unit" "*,i387")
4577   (set_attr "fp_int_src" "true")])
4578
4579(define_expand "floatsidf2"
4580  [(set (match_operand:DF 0 "register_operand" "")
4581	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4582  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4583  "")
4584
4585(define_insn "*floatsidf2_mixed"
4586  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4587	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4588  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4589  "@
4590   fild%z1\t%1
4591   #
4592   cvtsi2sd\t{%1, %0|%0, %1}
4593   cvtsi2sd\t{%1, %0|%0, %1}"
4594  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4595   (set_attr "mode" "DF")
4596   (set_attr "unit" "*,i387,*,*")
4597   (set_attr "athlon_decode" "*,*,double,direct")
4598   (set_attr "fp_int_src" "true")])
4599
4600(define_insn "*floatsidf2_sse"
4601  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4602	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4603  "TARGET_SSE2 && TARGET_SSE_MATH"
4604  "cvtsi2sd\t{%1, %0|%0, %1}"
4605  [(set_attr "type" "sseicvt")
4606   (set_attr "mode" "DF")
4607   (set_attr "athlon_decode" "double,direct")
4608   (set_attr "fp_int_src" "true")])
4609
4610(define_insn "*floatsidf2_i387"
4611  [(set (match_operand:DF 0 "register_operand" "=f,f")
4612	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4613  "TARGET_80387"
4614  "@
4615   fild%z1\t%1
4616   #"
4617  [(set_attr "type" "fmov,multi")
4618   (set_attr "mode" "DF")
4619   (set_attr "unit" "*,i387")
4620   (set_attr "fp_int_src" "true")])
4621
4622(define_expand "floatdidf2"
4623  [(set (match_operand:DF 0 "register_operand" "")
4624	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4625  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4626  "")
4627
4628(define_insn "*floatdidf2_mixed"
4629  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4630	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4631  "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4632  "@
4633   fild%z1\t%1
4634   #
4635   cvtsi2sd{q}\t{%1, %0|%0, %1}
4636   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4637  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4638   (set_attr "mode" "DF")
4639   (set_attr "unit" "*,i387,*,*")
4640   (set_attr "athlon_decode" "*,*,double,direct")
4641   (set_attr "fp_int_src" "true")])
4642
4643(define_insn "*floatdidf2_sse"
4644  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4645	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4646  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4647  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4648  [(set_attr "type" "sseicvt")
4649   (set_attr "mode" "DF")
4650   (set_attr "athlon_decode" "double,direct")
4651   (set_attr "fp_int_src" "true")])
4652
4653(define_insn "*floatdidf2_i387"
4654  [(set (match_operand:DF 0 "register_operand" "=f,f")
4655	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4656  "TARGET_80387"
4657  "@
4658   fild%z1\t%1
4659   #"
4660  [(set_attr "type" "fmov,multi")
4661   (set_attr "mode" "DF")
4662   (set_attr "unit" "*,i387")
4663   (set_attr "fp_int_src" "true")])
4664
4665(define_insn "floathixf2"
4666  [(set (match_operand:XF 0 "register_operand" "=f,f")
4667	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4668  "TARGET_80387"
4669  "@
4670   fild%z1\t%1
4671   #"
4672  [(set_attr "type" "fmov,multi")
4673   (set_attr "mode" "XF")
4674   (set_attr "unit" "*,i387")
4675   (set_attr "fp_int_src" "true")])
4676
4677(define_insn "floatsixf2"
4678  [(set (match_operand:XF 0 "register_operand" "=f,f")
4679	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4680  "TARGET_80387"
4681  "@
4682   fild%z1\t%1
4683   #"
4684  [(set_attr "type" "fmov,multi")
4685   (set_attr "mode" "XF")
4686   (set_attr "unit" "*,i387")
4687   (set_attr "fp_int_src" "true")])
4688
4689(define_insn "floatdixf2"
4690  [(set (match_operand:XF 0 "register_operand" "=f,f")
4691	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4692  "TARGET_80387"
4693  "@
4694   fild%z1\t%1
4695   #"
4696  [(set_attr "type" "fmov,multi")
4697   (set_attr "mode" "XF")
4698   (set_attr "unit" "*,i387")
4699   (set_attr "fp_int_src" "true")])
4700
4701;; %%% Kill these when reload knows how to do it.
4702(define_split
4703  [(set (match_operand 0 "fp_register_operand" "")
4704	(float (match_operand 1 "register_operand" "")))]
4705  "reload_completed
4706   && TARGET_80387
4707   && FLOAT_MODE_P (GET_MODE (operands[0]))"
4708  [(const_int 0)]
4709{
4710  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4711  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4712  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4713  ix86_free_from_memory (GET_MODE (operands[1]));
4714  DONE;
4715})
4716
4717(define_expand "floatunssisf2"
4718  [(use (match_operand:SF 0 "register_operand" ""))
4719   (use (match_operand:SI 1 "register_operand" ""))]
4720  "!TARGET_64BIT && TARGET_SSE_MATH"
4721  "x86_emit_floatuns (operands); DONE;")
4722
4723(define_expand "floatunsdisf2"
4724  [(use (match_operand:SF 0 "register_operand" ""))
4725   (use (match_operand:DI 1 "register_operand" ""))]
4726  "TARGET_64BIT && TARGET_SSE_MATH"
4727  "x86_emit_floatuns (operands); DONE;")
4728
4729(define_expand "floatunsdidf2"
4730  [(use (match_operand:DF 0 "register_operand" ""))
4731   (use (match_operand:DI 1 "register_operand" ""))]
4732  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4733  "x86_emit_floatuns (operands); DONE;")
4734
4735;; SSE extract/set expanders
4736
4737
4738;; Add instructions
4739
4740;; %%% splits for addditi3
4741
4742(define_expand "addti3"
4743  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4744	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4745		 (match_operand:TI 2 "x86_64_general_operand" "")))
4746   (clobber (reg:CC FLAGS_REG))]
4747  "TARGET_64BIT"
4748  "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4749
4750(define_insn "*addti3_1"
4751  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4752	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4753		 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4754   (clobber (reg:CC FLAGS_REG))]
4755  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4756  "#")
4757
4758(define_split
4759  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4760	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4761		 (match_operand:TI 2 "x86_64_general_operand" "")))
4762   (clobber (reg:CC FLAGS_REG))]
4763  "TARGET_64BIT && reload_completed"
4764  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4765					  UNSPEC_ADD_CARRY))
4766	      (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4767   (parallel [(set (match_dup 3)
4768		   (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4769				     (match_dup 4))
4770			    (match_dup 5)))
4771	      (clobber (reg:CC FLAGS_REG))])]
4772  "split_ti (operands+0, 1, operands+0, operands+3);
4773   split_ti (operands+1, 1, operands+1, operands+4);
4774   split_ti (operands+2, 1, operands+2, operands+5);")
4775
4776;; %%% splits for addsidi3
4777;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4778;	(plus:DI (match_operand:DI 1 "general_operand" "")
4779;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4780
4781(define_expand "adddi3"
4782  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4783	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4784		 (match_operand:DI 2 "x86_64_general_operand" "")))
4785   (clobber (reg:CC FLAGS_REG))]
4786  ""
4787  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4788
4789(define_insn "*adddi3_1"
4790  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4791	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4792		 (match_operand:DI 2 "general_operand" "roiF,riF")))
4793   (clobber (reg:CC FLAGS_REG))]
4794  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4795  "#")
4796
4797(define_split
4798  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4799	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4800		 (match_operand:DI 2 "general_operand" "")))
4801   (clobber (reg:CC FLAGS_REG))]
4802  "!TARGET_64BIT && reload_completed"
4803  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4804					  UNSPEC_ADD_CARRY))
4805	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4806   (parallel [(set (match_dup 3)
4807		   (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4808				     (match_dup 4))
4809			    (match_dup 5)))
4810	      (clobber (reg:CC FLAGS_REG))])]
4811  "split_di (operands+0, 1, operands+0, operands+3);
4812   split_di (operands+1, 1, operands+1, operands+4);
4813   split_di (operands+2, 1, operands+2, operands+5);")
4814
4815(define_insn "adddi3_carry_rex64"
4816  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4817	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4818			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4819		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4820   (clobber (reg:CC FLAGS_REG))]
4821  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4822  "adc{q}\t{%2, %0|%0, %2}"
4823  [(set_attr "type" "alu")
4824   (set_attr "pent_pair" "pu")
4825   (set_attr "mode" "DI")])
4826
4827(define_insn "*adddi3_cc_rex64"
4828  [(set (reg:CC FLAGS_REG)
4829	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4830		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4831		   UNSPEC_ADD_CARRY))
4832   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4833	(plus:DI (match_dup 1) (match_dup 2)))]
4834  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4835  "add{q}\t{%2, %0|%0, %2}"
4836  [(set_attr "type" "alu")
4837   (set_attr "mode" "DI")])
4838
4839(define_insn "addqi3_carry"
4840  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4841	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4842			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4843		   (match_operand:QI 2 "general_operand" "qi,qm")))
4844   (clobber (reg:CC FLAGS_REG))]
4845  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4846  "adc{b}\t{%2, %0|%0, %2}"
4847  [(set_attr "type" "alu")
4848   (set_attr "pent_pair" "pu")
4849   (set_attr "mode" "QI")])
4850
4851(define_insn "addhi3_carry"
4852  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4853	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4854			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4855		   (match_operand:HI 2 "general_operand" "ri,rm")))
4856   (clobber (reg:CC FLAGS_REG))]
4857  "ix86_binary_operator_ok (PLUS, HImode, operands)"
4858  "adc{w}\t{%2, %0|%0, %2}"
4859  [(set_attr "type" "alu")
4860   (set_attr "pent_pair" "pu")
4861   (set_attr "mode" "HI")])
4862
4863(define_insn "addsi3_carry"
4864  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4865	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4866			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4867		   (match_operand:SI 2 "general_operand" "ri,rm")))
4868   (clobber (reg:CC FLAGS_REG))]
4869  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4870  "adc{l}\t{%2, %0|%0, %2}"
4871  [(set_attr "type" "alu")
4872   (set_attr "pent_pair" "pu")
4873   (set_attr "mode" "SI")])
4874
4875(define_insn "*addsi3_carry_zext"
4876  [(set (match_operand:DI 0 "register_operand" "=r")
4877	  (zero_extend:DI 
4878	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4879			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
4880		     (match_operand:SI 2 "general_operand" "rim"))))
4881   (clobber (reg:CC FLAGS_REG))]
4882  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4883  "adc{l}\t{%2, %k0|%k0, %2}"
4884  [(set_attr "type" "alu")
4885   (set_attr "pent_pair" "pu")
4886   (set_attr "mode" "SI")])
4887
4888(define_insn "*addsi3_cc"
4889  [(set (reg:CC FLAGS_REG)
4890	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4891		    (match_operand:SI 2 "general_operand" "ri,rm")]
4892		   UNSPEC_ADD_CARRY))
4893   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4894	(plus:SI (match_dup 1) (match_dup 2)))]
4895  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4896  "add{l}\t{%2, %0|%0, %2}"
4897  [(set_attr "type" "alu")
4898   (set_attr "mode" "SI")])
4899
4900(define_insn "addqi3_cc"
4901  [(set (reg:CC FLAGS_REG)
4902	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4903		    (match_operand:QI 2 "general_operand" "qi,qm")]
4904		   UNSPEC_ADD_CARRY))
4905   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4906	(plus:QI (match_dup 1) (match_dup 2)))]
4907  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4908  "add{b}\t{%2, %0|%0, %2}"
4909  [(set_attr "type" "alu")
4910   (set_attr "mode" "QI")])
4911
4912(define_expand "addsi3"
4913  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4914		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4915			    (match_operand:SI 2 "general_operand" "")))
4916	      (clobber (reg:CC FLAGS_REG))])]
4917  ""
4918  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4919
4920(define_insn "*lea_1"
4921  [(set (match_operand:SI 0 "register_operand" "=r")
4922	(match_operand:SI 1 "no_seg_address_operand" "p"))]
4923  "!TARGET_64BIT"
4924  "lea{l}\t{%a1, %0|%0, %a1}"
4925  [(set_attr "type" "lea")
4926   (set_attr "mode" "SI")])
4927
4928(define_insn "*lea_1_rex64"
4929  [(set (match_operand:SI 0 "register_operand" "=r")
4930	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4931  "TARGET_64BIT"
4932  "lea{l}\t{%a1, %0|%0, %a1}"
4933  [(set_attr "type" "lea")
4934   (set_attr "mode" "SI")])
4935
4936(define_insn "*lea_1_zext"
4937  [(set (match_operand:DI 0 "register_operand" "=r")
4938	(zero_extend:DI
4939	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4940  "TARGET_64BIT"
4941  "lea{l}\t{%a1, %k0|%k0, %a1}"
4942  [(set_attr "type" "lea")
4943   (set_attr "mode" "SI")])
4944
4945(define_insn "*lea_2_rex64"
4946  [(set (match_operand:DI 0 "register_operand" "=r")
4947	(match_operand:DI 1 "no_seg_address_operand" "p"))]
4948  "TARGET_64BIT"
4949  "lea{q}\t{%a1, %0|%0, %a1}"
4950  [(set_attr "type" "lea")
4951   (set_attr "mode" "DI")])
4952
4953;; The lea patterns for non-Pmodes needs to be matched by several
4954;; insns converted to real lea by splitters.
4955
4956(define_insn_and_split "*lea_general_1"
4957  [(set (match_operand 0 "register_operand" "=r")
4958	(plus (plus (match_operand 1 "index_register_operand" "l")
4959		    (match_operand 2 "register_operand" "r"))
4960	      (match_operand 3 "immediate_operand" "i")))]
4961  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4962    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4963   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4964   && GET_MODE (operands[0]) == GET_MODE (operands[1])
4965   && GET_MODE (operands[0]) == GET_MODE (operands[2])
4966   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4967       || GET_MODE (operands[3]) == VOIDmode)"
4968  "#"
4969  "&& reload_completed"
4970  [(const_int 0)]
4971{
4972  rtx pat;
4973  operands[0] = gen_lowpart (SImode, operands[0]);
4974  operands[1] = gen_lowpart (Pmode, operands[1]);
4975  operands[2] = gen_lowpart (Pmode, operands[2]);
4976  operands[3] = gen_lowpart (Pmode, operands[3]);
4977  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4978  		      operands[3]);
4979  if (Pmode != SImode)
4980    pat = gen_rtx_SUBREG (SImode, pat, 0);
4981  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4982  DONE;
4983}
4984  [(set_attr "type" "lea")
4985   (set_attr "mode" "SI")])
4986
4987(define_insn_and_split "*lea_general_1_zext"
4988  [(set (match_operand:DI 0 "register_operand" "=r")
4989	(zero_extend:DI
4990	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4991			    (match_operand:SI 2 "register_operand" "r"))
4992		   (match_operand:SI 3 "immediate_operand" "i"))))]
4993  "TARGET_64BIT"
4994  "#"
4995  "&& reload_completed"
4996  [(set (match_dup 0)
4997	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4998						     (match_dup 2))
4999					    (match_dup 3)) 0)))]
5000{
5001  operands[1] = gen_lowpart (Pmode, operands[1]);
5002  operands[2] = gen_lowpart (Pmode, operands[2]);
5003  operands[3] = gen_lowpart (Pmode, operands[3]);
5004}
5005  [(set_attr "type" "lea")
5006   (set_attr "mode" "SI")])
5007
5008(define_insn_and_split "*lea_general_2"
5009  [(set (match_operand 0 "register_operand" "=r")
5010	(plus (mult (match_operand 1 "index_register_operand" "l")
5011		    (match_operand 2 "const248_operand" "i"))
5012	      (match_operand 3 "nonmemory_operand" "ri")))]
5013  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5014    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5015   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5016   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5017   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5018       || GET_MODE (operands[3]) == VOIDmode)"
5019  "#"
5020  "&& reload_completed"
5021  [(const_int 0)]
5022{
5023  rtx pat;
5024  operands[0] = gen_lowpart (SImode, operands[0]);
5025  operands[1] = gen_lowpart (Pmode, operands[1]);
5026  operands[3] = gen_lowpart (Pmode, operands[3]);
5027  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5028  		      operands[3]);
5029  if (Pmode != SImode)
5030    pat = gen_rtx_SUBREG (SImode, pat, 0);
5031  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5032  DONE;
5033}
5034  [(set_attr "type" "lea")
5035   (set_attr "mode" "SI")])
5036
5037(define_insn_and_split "*lea_general_2_zext"
5038  [(set (match_operand:DI 0 "register_operand" "=r")
5039	(zero_extend:DI
5040	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5041			    (match_operand:SI 2 "const248_operand" "n"))
5042		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5043  "TARGET_64BIT"
5044  "#"
5045  "&& reload_completed"
5046  [(set (match_dup 0)
5047	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5048						     (match_dup 2))
5049					    (match_dup 3)) 0)))]
5050{
5051  operands[1] = gen_lowpart (Pmode, operands[1]);
5052  operands[3] = gen_lowpart (Pmode, operands[3]);
5053}
5054  [(set_attr "type" "lea")
5055   (set_attr "mode" "SI")])
5056
5057(define_insn_and_split "*lea_general_3"
5058  [(set (match_operand 0 "register_operand" "=r")
5059	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
5060			  (match_operand 2 "const248_operand" "i"))
5061		    (match_operand 3 "register_operand" "r"))
5062	      (match_operand 4 "immediate_operand" "i")))]
5063  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5064    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5065   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5066   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5067   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5068  "#"
5069  "&& reload_completed"
5070  [(const_int 0)]
5071{
5072  rtx pat;
5073  operands[0] = gen_lowpart (SImode, operands[0]);
5074  operands[1] = gen_lowpart (Pmode, operands[1]);
5075  operands[3] = gen_lowpart (Pmode, operands[3]);
5076  operands[4] = gen_lowpart (Pmode, operands[4]);
5077  pat = gen_rtx_PLUS (Pmode,
5078  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5079		      					 operands[2]),
5080				    operands[3]),
5081  		      operands[4]);
5082  if (Pmode != SImode)
5083    pat = gen_rtx_SUBREG (SImode, pat, 0);
5084  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5085  DONE;
5086}
5087  [(set_attr "type" "lea")
5088   (set_attr "mode" "SI")])
5089
5090(define_insn_and_split "*lea_general_3_zext"
5091  [(set (match_operand:DI 0 "register_operand" "=r")
5092	(zero_extend:DI
5093	  (plus:SI (plus:SI (mult:SI
5094			      (match_operand:SI 1 "index_register_operand" "l")
5095			      (match_operand:SI 2 "const248_operand" "n"))
5096			    (match_operand:SI 3 "register_operand" "r"))
5097		   (match_operand:SI 4 "immediate_operand" "i"))))]
5098  "TARGET_64BIT"
5099  "#"
5100  "&& reload_completed"
5101  [(set (match_dup 0)
5102	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5103							      (match_dup 2))
5104						     (match_dup 3))
5105					    (match_dup 4)) 0)))]
5106{
5107  operands[1] = gen_lowpart (Pmode, operands[1]);
5108  operands[3] = gen_lowpart (Pmode, operands[3]);
5109  operands[4] = gen_lowpart (Pmode, operands[4]);
5110}
5111  [(set_attr "type" "lea")
5112   (set_attr "mode" "SI")])
5113
5114(define_insn "*adddi_1_rex64"
5115  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5116	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5117		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5118   (clobber (reg:CC FLAGS_REG))]
5119  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120{
5121  switch (get_attr_type (insn))
5122    {
5123    case TYPE_LEA:
5124      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5125      return "lea{q}\t{%a2, %0|%0, %a2}";
5126
5127    case TYPE_INCDEC:
5128      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5129      if (operands[2] == const1_rtx)
5130        return "inc{q}\t%0";
5131      else
5132        {
5133	  gcc_assert (operands[2] == constm1_rtx);
5134          return "dec{q}\t%0";
5135	}
5136
5137    default:
5138      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5139
5140      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5141	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5142      if (GET_CODE (operands[2]) == CONST_INT
5143	  /* Avoid overflows.  */
5144	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5145          && (INTVAL (operands[2]) == 128
5146	      || (INTVAL (operands[2]) < 0
5147		  && INTVAL (operands[2]) != -128)))
5148        {
5149          operands[2] = GEN_INT (-INTVAL (operands[2]));
5150          return "sub{q}\t{%2, %0|%0, %2}";
5151        }
5152      return "add{q}\t{%2, %0|%0, %2}";
5153    }
5154}
5155  [(set (attr "type")
5156     (cond [(eq_attr "alternative" "2")
5157	      (const_string "lea")
5158	    ; Current assemblers are broken and do not allow @GOTOFF in
5159	    ; ought but a memory context.
5160	    (match_operand:DI 2 "pic_symbolic_operand" "")
5161	      (const_string "lea")
5162	    (match_operand:DI 2 "incdec_operand" "")
5163	      (const_string "incdec")
5164	   ]
5165	   (const_string "alu")))
5166   (set_attr "mode" "DI")])
5167
5168;; Convert lea to the lea pattern to avoid flags dependency.
5169(define_split
5170  [(set (match_operand:DI 0 "register_operand" "")
5171	(plus:DI (match_operand:DI 1 "register_operand" "")
5172		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5173   (clobber (reg:CC FLAGS_REG))]
5174  "TARGET_64BIT && reload_completed
5175   && true_regnum (operands[0]) != true_regnum (operands[1])"
5176  [(set (match_dup 0)
5177	(plus:DI (match_dup 1)
5178		 (match_dup 2)))]
5179  "")
5180
5181(define_insn "*adddi_2_rex64"
5182  [(set (reg FLAGS_REG)
5183	(compare
5184	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5185		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5186	  (const_int 0)))			
5187   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5188	(plus:DI (match_dup 1) (match_dup 2)))]
5189  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5190   && ix86_binary_operator_ok (PLUS, DImode, operands)
5191   /* Current assemblers are broken and do not allow @GOTOFF in
5192      ought but a memory context.  */
5193   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5194{
5195  switch (get_attr_type (insn))
5196    {
5197    case TYPE_INCDEC:
5198      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5199      if (operands[2] == const1_rtx)
5200        return "inc{q}\t%0";
5201      else
5202        {
5203	  gcc_assert (operands[2] == constm1_rtx);
5204          return "dec{q}\t%0";
5205	}
5206
5207    default:
5208      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5209      /* ???? We ought to handle there the 32bit case too
5210	 - do we need new constraint?  */
5211      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5212	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5213      if (GET_CODE (operands[2]) == CONST_INT
5214	  /* Avoid overflows.  */
5215	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5216          && (INTVAL (operands[2]) == 128
5217	      || (INTVAL (operands[2]) < 0
5218		  && INTVAL (operands[2]) != -128)))
5219        {
5220          operands[2] = GEN_INT (-INTVAL (operands[2]));
5221          return "sub{q}\t{%2, %0|%0, %2}";
5222        }
5223      return "add{q}\t{%2, %0|%0, %2}";
5224    }
5225}
5226  [(set (attr "type")
5227     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5228	(const_string "incdec")
5229	(const_string "alu")))
5230   (set_attr "mode" "DI")])
5231
5232(define_insn "*adddi_3_rex64"
5233  [(set (reg FLAGS_REG)
5234	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5235		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5236   (clobber (match_scratch:DI 0 "=r"))]
5237  "TARGET_64BIT
5238   && ix86_match_ccmode (insn, CCZmode)
5239   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5240   /* Current assemblers are broken and do not allow @GOTOFF in
5241      ought but a memory context.  */
5242   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5243{
5244  switch (get_attr_type (insn))
5245    {
5246    case TYPE_INCDEC:
5247      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248      if (operands[2] == const1_rtx)
5249        return "inc{q}\t%0";
5250      else
5251        {
5252	  gcc_assert (operands[2] == constm1_rtx);
5253          return "dec{q}\t%0";
5254	}
5255
5256    default:
5257      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5258      /* ???? We ought to handle there the 32bit case too
5259	 - do we need new constraint?  */
5260      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5261	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5262      if (GET_CODE (operands[2]) == CONST_INT
5263	  /* Avoid overflows.  */
5264	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5265          && (INTVAL (operands[2]) == 128
5266	      || (INTVAL (operands[2]) < 0
5267		  && INTVAL (operands[2]) != -128)))
5268        {
5269          operands[2] = GEN_INT (-INTVAL (operands[2]));
5270          return "sub{q}\t{%2, %0|%0, %2}";
5271        }
5272      return "add{q}\t{%2, %0|%0, %2}";
5273    }
5274}
5275  [(set (attr "type")
5276     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5277	(const_string "incdec")
5278	(const_string "alu")))
5279   (set_attr "mode" "DI")])
5280
5281; For comparisons against 1, -1 and 128, we may generate better code
5282; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5283; is matched then.  We can't accept general immediate, because for
5284; case of overflows,  the result is messed up.
5285; This pattern also don't hold of 0x8000000000000000, since the value overflows
5286; when negated.
5287; Also carry flag is reversed compared to cmp, so this conversion is valid
5288; only for comparisons not depending on it.
5289(define_insn "*adddi_4_rex64"
5290  [(set (reg FLAGS_REG)
5291	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5292		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5293   (clobber (match_scratch:DI 0 "=rm"))]
5294  "TARGET_64BIT
5295   &&  ix86_match_ccmode (insn, CCGCmode)"
5296{
5297  switch (get_attr_type (insn))
5298    {
5299    case TYPE_INCDEC:
5300      if (operands[2] == constm1_rtx)
5301        return "inc{q}\t%0";
5302      else
5303        {
5304	  gcc_assert (operands[2] == const1_rtx);
5305          return "dec{q}\t%0";
5306	}
5307
5308    default:
5309      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5310      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5311	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5312      if ((INTVAL (operands[2]) == -128
5313	   || (INTVAL (operands[2]) > 0
5314	       && INTVAL (operands[2]) != 128))
5315	  /* Avoid overflows.  */
5316	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5317	return "sub{q}\t{%2, %0|%0, %2}";
5318      operands[2] = GEN_INT (-INTVAL (operands[2]));
5319      return "add{q}\t{%2, %0|%0, %2}";
5320    }
5321}
5322  [(set (attr "type")
5323     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5324	(const_string "incdec")
5325	(const_string "alu")))
5326   (set_attr "mode" "DI")])
5327
5328(define_insn "*adddi_5_rex64"
5329  [(set (reg FLAGS_REG)
5330	(compare
5331	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5332		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5333	  (const_int 0)))			
5334   (clobber (match_scratch:DI 0 "=r"))]
5335  "TARGET_64BIT
5336   && ix86_match_ccmode (insn, CCGOCmode)
5337   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5338   /* Current assemblers are broken and do not allow @GOTOFF in
5339      ought but a memory context.  */
5340   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5341{
5342  switch (get_attr_type (insn))
5343    {
5344    case TYPE_INCDEC:
5345      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5346      if (operands[2] == const1_rtx)
5347        return "inc{q}\t%0";
5348      else
5349        {
5350          gcc_assert (operands[2] == constm1_rtx);
5351          return "dec{q}\t%0";
5352	}
5353
5354    default:
5355      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5356      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5357	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5358      if (GET_CODE (operands[2]) == CONST_INT
5359	  /* Avoid overflows.  */
5360	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5361          && (INTVAL (operands[2]) == 128
5362	      || (INTVAL (operands[2]) < 0
5363		  && INTVAL (operands[2]) != -128)))
5364        {
5365          operands[2] = GEN_INT (-INTVAL (operands[2]));
5366          return "sub{q}\t{%2, %0|%0, %2}";
5367        }
5368      return "add{q}\t{%2, %0|%0, %2}";
5369    }
5370}
5371  [(set (attr "type")
5372     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5373	(const_string "incdec")
5374	(const_string "alu")))
5375   (set_attr "mode" "DI")])
5376
5377
5378(define_insn "*addsi_1"
5379  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5380	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5381		 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5382   (clobber (reg:CC FLAGS_REG))]
5383  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5384{
5385  switch (get_attr_type (insn))
5386    {
5387    case TYPE_LEA:
5388      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5389      return "lea{l}\t{%a2, %0|%0, %a2}";
5390
5391    case TYPE_INCDEC:
5392      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5393      if (operands[2] == const1_rtx)
5394        return "inc{l}\t%0";
5395      else
5396	{
5397  	  gcc_assert (operands[2] == constm1_rtx);
5398          return "dec{l}\t%0";
5399	}
5400
5401    default:
5402      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5403
5404      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5405	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5406      if (GET_CODE (operands[2]) == CONST_INT
5407          && (INTVAL (operands[2]) == 128
5408	      || (INTVAL (operands[2]) < 0
5409		  && INTVAL (operands[2]) != -128)))
5410        {
5411          operands[2] = GEN_INT (-INTVAL (operands[2]));
5412          return "sub{l}\t{%2, %0|%0, %2}";
5413        }
5414      return "add{l}\t{%2, %0|%0, %2}";
5415    }
5416}
5417  [(set (attr "type")
5418     (cond [(eq_attr "alternative" "2")
5419	      (const_string "lea")
5420	    ; Current assemblers are broken and do not allow @GOTOFF in
5421	    ; ought but a memory context.
5422	    (match_operand:SI 2 "pic_symbolic_operand" "")
5423	      (const_string "lea")
5424	    (match_operand:SI 2 "incdec_operand" "")
5425	      (const_string "incdec")
5426	   ]
5427	   (const_string "alu")))
5428   (set_attr "mode" "SI")])
5429
5430;; Convert lea to the lea pattern to avoid flags dependency.
5431(define_split
5432  [(set (match_operand 0 "register_operand" "")
5433	(plus (match_operand 1 "register_operand" "")
5434              (match_operand 2 "nonmemory_operand" "")))
5435   (clobber (reg:CC FLAGS_REG))]
5436  "reload_completed
5437   && true_regnum (operands[0]) != true_regnum (operands[1])"
5438  [(const_int 0)]
5439{
5440  rtx pat;
5441  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5442     may confuse gen_lowpart.  */
5443  if (GET_MODE (operands[0]) != Pmode)
5444    {
5445      operands[1] = gen_lowpart (Pmode, operands[1]);
5446      operands[2] = gen_lowpart (Pmode, operands[2]);
5447    }
5448  operands[0] = gen_lowpart (SImode, operands[0]);
5449  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5450  if (Pmode != SImode)
5451    pat = gen_rtx_SUBREG (SImode, pat, 0);
5452  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5453  DONE;
5454})
5455
5456;; It may seem that nonimmediate operand is proper one for operand 1.
5457;; The addsi_1 pattern allows nonimmediate operand at that place and
5458;; we take care in ix86_binary_operator_ok to not allow two memory
5459;; operands so proper swapping will be done in reload.  This allow
5460;; patterns constructed from addsi_1 to match.
5461(define_insn "addsi_1_zext"
5462  [(set (match_operand:DI 0 "register_operand" "=r,r")
5463	(zero_extend:DI
5464	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5465		   (match_operand:SI 2 "general_operand" "rmni,lni"))))
5466   (clobber (reg:CC FLAGS_REG))]
5467  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5468{
5469  switch (get_attr_type (insn))
5470    {
5471    case TYPE_LEA:
5472      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5473      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5474
5475    case TYPE_INCDEC:
5476      if (operands[2] == const1_rtx)
5477        return "inc{l}\t%k0";
5478      else
5479        {
5480	  gcc_assert (operands[2] == constm1_rtx);
5481          return "dec{l}\t%k0";
5482	}
5483
5484    default:
5485      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5486	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5487      if (GET_CODE (operands[2]) == CONST_INT
5488          && (INTVAL (operands[2]) == 128
5489	      || (INTVAL (operands[2]) < 0
5490		  && INTVAL (operands[2]) != -128)))
5491        {
5492          operands[2] = GEN_INT (-INTVAL (operands[2]));
5493          return "sub{l}\t{%2, %k0|%k0, %2}";
5494        }
5495      return "add{l}\t{%2, %k0|%k0, %2}";
5496    }
5497}
5498  [(set (attr "type")
5499     (cond [(eq_attr "alternative" "1")
5500	      (const_string "lea")
5501	    ; Current assemblers are broken and do not allow @GOTOFF in
5502	    ; ought but a memory context.
5503	    (match_operand:SI 2 "pic_symbolic_operand" "")
5504	      (const_string "lea")
5505	    (match_operand:SI 2 "incdec_operand" "")
5506	      (const_string "incdec")
5507	   ]
5508	   (const_string "alu")))
5509   (set_attr "mode" "SI")])
5510
5511;; Convert lea to the lea pattern to avoid flags dependency.
5512(define_split
5513  [(set (match_operand:DI 0 "register_operand" "")
5514	(zero_extend:DI
5515	  (plus:SI (match_operand:SI 1 "register_operand" "")
5516		   (match_operand:SI 2 "nonmemory_operand" ""))))
5517   (clobber (reg:CC FLAGS_REG))]
5518  "TARGET_64BIT && reload_completed
5519   && true_regnum (operands[0]) != true_regnum (operands[1])"
5520  [(set (match_dup 0)
5521	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5522{
5523  operands[1] = gen_lowpart (Pmode, operands[1]);
5524  operands[2] = gen_lowpart (Pmode, operands[2]);
5525})
5526
5527(define_insn "*addsi_2"
5528  [(set (reg FLAGS_REG)
5529	(compare
5530	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5531		   (match_operand:SI 2 "general_operand" "rmni,rni"))
5532	  (const_int 0)))			
5533   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5534	(plus:SI (match_dup 1) (match_dup 2)))]
5535  "ix86_match_ccmode (insn, CCGOCmode)
5536   && ix86_binary_operator_ok (PLUS, SImode, operands)
5537   /* Current assemblers are broken and do not allow @GOTOFF in
5538      ought but a memory context.  */
5539   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5540{
5541  switch (get_attr_type (insn))
5542    {
5543    case TYPE_INCDEC:
5544      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5545      if (operands[2] == const1_rtx)
5546        return "inc{l}\t%0";
5547      else
5548        {
5549	  gcc_assert (operands[2] == constm1_rtx);
5550          return "dec{l}\t%0";
5551	}
5552
5553    default:
5554      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5555      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5556	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5557      if (GET_CODE (operands[2]) == CONST_INT
5558          && (INTVAL (operands[2]) == 128
5559	      || (INTVAL (operands[2]) < 0
5560		  && INTVAL (operands[2]) != -128)))
5561        {
5562          operands[2] = GEN_INT (-INTVAL (operands[2]));
5563          return "sub{l}\t{%2, %0|%0, %2}";
5564        }
5565      return "add{l}\t{%2, %0|%0, %2}";
5566    }
5567}
5568  [(set (attr "type")
5569     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5570	(const_string "incdec")
5571	(const_string "alu")))
5572   (set_attr "mode" "SI")])
5573
5574;; See comment for addsi_1_zext why we do use nonimmediate_operand
5575(define_insn "*addsi_2_zext"
5576  [(set (reg FLAGS_REG)
5577	(compare
5578	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5579		   (match_operand:SI 2 "general_operand" "rmni"))
5580	  (const_int 0)))			
5581   (set (match_operand:DI 0 "register_operand" "=r")
5582	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5583  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5584   && ix86_binary_operator_ok (PLUS, SImode, operands)
5585   /* Current assemblers are broken and do not allow @GOTOFF in
5586      ought but a memory context.  */
5587   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5588{
5589  switch (get_attr_type (insn))
5590    {
5591    case TYPE_INCDEC:
5592      if (operands[2] == const1_rtx)
5593        return "inc{l}\t%k0";
5594      else
5595	{
5596	  gcc_assert (operands[2] == constm1_rtx);
5597          return "dec{l}\t%k0";
5598	}
5599
5600    default:
5601      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5602	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5603      if (GET_CODE (operands[2]) == CONST_INT
5604          && (INTVAL (operands[2]) == 128
5605	      || (INTVAL (operands[2]) < 0
5606		  && INTVAL (operands[2]) != -128)))
5607        {
5608          operands[2] = GEN_INT (-INTVAL (operands[2]));
5609          return "sub{l}\t{%2, %k0|%k0, %2}";
5610        }
5611      return "add{l}\t{%2, %k0|%k0, %2}";
5612    }
5613}
5614  [(set (attr "type")
5615     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5616	(const_string "incdec")
5617	(const_string "alu")))
5618   (set_attr "mode" "SI")])
5619
5620(define_insn "*addsi_3"
5621  [(set (reg FLAGS_REG)
5622	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5623		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5624   (clobber (match_scratch:SI 0 "=r"))]
5625  "ix86_match_ccmode (insn, CCZmode)
5626   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5627   /* Current assemblers are broken and do not allow @GOTOFF in
5628      ought but a memory context.  */
5629   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5630{
5631  switch (get_attr_type (insn))
5632    {
5633    case TYPE_INCDEC:
5634      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5635      if (operands[2] == const1_rtx)
5636        return "inc{l}\t%0";
5637      else
5638        {
5639	  gcc_assert (operands[2] == constm1_rtx);
5640          return "dec{l}\t%0";
5641	}
5642
5643    default:
5644      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5645      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5646	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5647      if (GET_CODE (operands[2]) == CONST_INT
5648          && (INTVAL (operands[2]) == 128
5649	      || (INTVAL (operands[2]) < 0
5650		  && INTVAL (operands[2]) != -128)))
5651        {
5652          operands[2] = GEN_INT (-INTVAL (operands[2]));
5653          return "sub{l}\t{%2, %0|%0, %2}";
5654        }
5655      return "add{l}\t{%2, %0|%0, %2}";
5656    }
5657}
5658  [(set (attr "type")
5659     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5660	(const_string "incdec")
5661	(const_string "alu")))
5662   (set_attr "mode" "SI")])
5663
5664;; See comment for addsi_1_zext why we do use nonimmediate_operand
5665(define_insn "*addsi_3_zext"
5666  [(set (reg FLAGS_REG)
5667	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5668		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5669   (set (match_operand:DI 0 "register_operand" "=r")
5670	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5671  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5672   && ix86_binary_operator_ok (PLUS, SImode, operands)
5673   /* Current assemblers are broken and do not allow @GOTOFF in
5674      ought but a memory context.  */
5675   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5676{
5677  switch (get_attr_type (insn))
5678    {
5679    case TYPE_INCDEC:
5680      if (operands[2] == const1_rtx)
5681        return "inc{l}\t%k0";
5682      else
5683        {
5684	  gcc_assert (operands[2] == constm1_rtx);
5685          return "dec{l}\t%k0";
5686	}
5687
5688    default:
5689      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5691      if (GET_CODE (operands[2]) == CONST_INT
5692          && (INTVAL (operands[2]) == 128
5693	      || (INTVAL (operands[2]) < 0
5694		  && INTVAL (operands[2]) != -128)))
5695        {
5696          operands[2] = GEN_INT (-INTVAL (operands[2]));
5697          return "sub{l}\t{%2, %k0|%k0, %2}";
5698        }
5699      return "add{l}\t{%2, %k0|%k0, %2}";
5700    }
5701}
5702  [(set (attr "type")
5703     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5704	(const_string "incdec")
5705	(const_string "alu")))
5706   (set_attr "mode" "SI")])
5707
5708; For comparisons against 1, -1 and 128, we may generate better code
5709; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5710; is matched then.  We can't accept general immediate, because for
5711; case of overflows,  the result is messed up.
5712; This pattern also don't hold of 0x80000000, since the value overflows
5713; when negated.
5714; Also carry flag is reversed compared to cmp, so this conversion is valid
5715; only for comparisons not depending on it.
5716(define_insn "*addsi_4"
5717  [(set (reg FLAGS_REG)
5718	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
5719		 (match_operand:SI 2 "const_int_operand" "n")))
5720   (clobber (match_scratch:SI 0 "=rm"))]
5721  "ix86_match_ccmode (insn, CCGCmode)
5722   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5723{
5724  switch (get_attr_type (insn))
5725    {
5726    case TYPE_INCDEC:
5727      if (operands[2] == constm1_rtx)
5728        return "inc{l}\t%0";
5729      else
5730        {
5731	  gcc_assert (operands[2] == const1_rtx);
5732          return "dec{l}\t%0";
5733	}
5734
5735    default:
5736      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5737      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5738	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5739      if ((INTVAL (operands[2]) == -128
5740	   || (INTVAL (operands[2]) > 0
5741	       && INTVAL (operands[2]) != 128)))
5742	return "sub{l}\t{%2, %0|%0, %2}";
5743      operands[2] = GEN_INT (-INTVAL (operands[2]));
5744      return "add{l}\t{%2, %0|%0, %2}";
5745    }
5746}
5747  [(set (attr "type")
5748     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5749	(const_string "incdec")
5750	(const_string "alu")))
5751   (set_attr "mode" "SI")])
5752
5753(define_insn "*addsi_5"
5754  [(set (reg FLAGS_REG)
5755	(compare
5756	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5757		   (match_operand:SI 2 "general_operand" "rmni"))
5758	  (const_int 0)))			
5759   (clobber (match_scratch:SI 0 "=r"))]
5760  "ix86_match_ccmode (insn, CCGOCmode)
5761   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5762   /* Current assemblers are broken and do not allow @GOTOFF in
5763      ought but a memory context.  */
5764   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5765{
5766  switch (get_attr_type (insn))
5767    {
5768    case TYPE_INCDEC:
5769      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5770      if (operands[2] == const1_rtx)
5771        return "inc{l}\t%0";
5772      else
5773        {
5774	  gcc_assert (operands[2] == constm1_rtx);
5775          return "dec{l}\t%0";
5776	}
5777
5778    default:
5779      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5780      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5782      if (GET_CODE (operands[2]) == CONST_INT
5783          && (INTVAL (operands[2]) == 128
5784	      || (INTVAL (operands[2]) < 0
5785		  && INTVAL (operands[2]) != -128)))
5786        {
5787          operands[2] = GEN_INT (-INTVAL (operands[2]));
5788          return "sub{l}\t{%2, %0|%0, %2}";
5789        }
5790      return "add{l}\t{%2, %0|%0, %2}";
5791    }
5792}
5793  [(set (attr "type")
5794     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5795	(const_string "incdec")
5796	(const_string "alu")))
5797   (set_attr "mode" "SI")])
5798
5799(define_expand "addhi3"
5800  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5801		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5802			    (match_operand:HI 2 "general_operand" "")))
5803	      (clobber (reg:CC FLAGS_REG))])]
5804  "TARGET_HIMODE_MATH"
5805  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5806
5807;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5808;; type optimizations enabled by define-splits.  This is not important
5809;; for PII, and in fact harmful because of partial register stalls.
5810
5811(define_insn "*addhi_1_lea"
5812  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5813	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5814		 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5815   (clobber (reg:CC FLAGS_REG))]
5816  "!TARGET_PARTIAL_REG_STALL
5817   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5818{
5819  switch (get_attr_type (insn))
5820    {
5821    case TYPE_LEA:
5822      return "#";
5823    case TYPE_INCDEC:
5824      if (operands[2] == const1_rtx)
5825	return "inc{w}\t%0";
5826      else
5827	{
5828	  gcc_assert (operands[2] == constm1_rtx);
5829	  return "dec{w}\t%0";
5830	}
5831
5832    default:
5833      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5834	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5835      if (GET_CODE (operands[2]) == CONST_INT
5836          && (INTVAL (operands[2]) == 128
5837	      || (INTVAL (operands[2]) < 0
5838		  && INTVAL (operands[2]) != -128)))
5839	{
5840	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5841	  return "sub{w}\t{%2, %0|%0, %2}";
5842	}
5843      return "add{w}\t{%2, %0|%0, %2}";
5844    }
5845}
5846  [(set (attr "type")
5847     (if_then_else (eq_attr "alternative" "2")
5848	(const_string "lea")
5849	(if_then_else (match_operand:HI 2 "incdec_operand" "")
5850	   (const_string "incdec")
5851	   (const_string "alu"))))
5852   (set_attr "mode" "HI,HI,SI")])
5853
5854(define_insn "*addhi_1"
5855  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5856	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5857		 (match_operand:HI 2 "general_operand" "ri,rm")))
5858   (clobber (reg:CC FLAGS_REG))]
5859  "TARGET_PARTIAL_REG_STALL
5860   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5861{
5862  switch (get_attr_type (insn))
5863    {
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 (match_operand:HI 2 "incdec_operand" "")
5889	(const_string "incdec")
5890	(const_string "alu")))
5891   (set_attr "mode" "HI")])
5892
5893(define_insn "*addhi_2"
5894  [(set (reg FLAGS_REG)
5895	(compare
5896	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5897		   (match_operand:HI 2 "general_operand" "rmni,rni"))
5898	  (const_int 0)))			
5899   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5900	(plus:HI (match_dup 1) (match_dup 2)))]
5901  "ix86_match_ccmode (insn, CCGOCmode)
5902   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5903{
5904  switch (get_attr_type (insn))
5905    {
5906    case TYPE_INCDEC:
5907      if (operands[2] == const1_rtx)
5908	return "inc{w}\t%0";
5909      else
5910        {
5911	  gcc_assert (operands[2] == constm1_rtx);
5912	  return "dec{w}\t%0";
5913	}
5914
5915    default:
5916      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5917	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5918      if (GET_CODE (operands[2]) == CONST_INT
5919          && (INTVAL (operands[2]) == 128
5920	      || (INTVAL (operands[2]) < 0
5921		  && INTVAL (operands[2]) != -128)))
5922	{
5923	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5924	  return "sub{w}\t{%2, %0|%0, %2}";
5925	}
5926      return "add{w}\t{%2, %0|%0, %2}";
5927    }
5928}
5929  [(set (attr "type")
5930     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5931	(const_string "incdec")
5932	(const_string "alu")))
5933   (set_attr "mode" "HI")])
5934
5935(define_insn "*addhi_3"
5936  [(set (reg FLAGS_REG)
5937	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5938		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5939   (clobber (match_scratch:HI 0 "=r"))]
5940  "ix86_match_ccmode (insn, CCZmode)
5941   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5942{
5943  switch (get_attr_type (insn))
5944    {
5945    case TYPE_INCDEC:
5946      if (operands[2] == const1_rtx)
5947	return "inc{w}\t%0";
5948      else
5949        {
5950	  gcc_assert (operands[2] == constm1_rtx);
5951	  return "dec{w}\t%0";
5952	}
5953
5954    default:
5955      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5957      if (GET_CODE (operands[2]) == CONST_INT
5958          && (INTVAL (operands[2]) == 128
5959	      || (INTVAL (operands[2]) < 0
5960		  && INTVAL (operands[2]) != -128)))
5961	{
5962	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5963	  return "sub{w}\t{%2, %0|%0, %2}";
5964	}
5965      return "add{w}\t{%2, %0|%0, %2}";
5966    }
5967}
5968  [(set (attr "type")
5969     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5970	(const_string "incdec")
5971	(const_string "alu")))
5972   (set_attr "mode" "HI")])
5973
5974; See comments above addsi_4 for details.
5975(define_insn "*addhi_4"
5976  [(set (reg FLAGS_REG)
5977	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
5978		 (match_operand:HI 2 "const_int_operand" "n")))
5979   (clobber (match_scratch:HI 0 "=rm"))]
5980  "ix86_match_ccmode (insn, CCGCmode)
5981   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5982{
5983  switch (get_attr_type (insn))
5984    {
5985    case TYPE_INCDEC:
5986      if (operands[2] == constm1_rtx)
5987        return "inc{w}\t%0";
5988      else
5989	{
5990	  gcc_assert (operands[2] == const1_rtx);
5991          return "dec{w}\t%0";
5992	}
5993
5994    default:
5995      gcc_assert (rtx_equal_p (operands[0], operands[1]));
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 ((INTVAL (operands[2]) == -128
5999	   || (INTVAL (operands[2]) > 0
6000	       && INTVAL (operands[2]) != 128)))
6001	return "sub{w}\t{%2, %0|%0, %2}";
6002      operands[2] = GEN_INT (-INTVAL (operands[2]));
6003      return "add{w}\t{%2, %0|%0, %2}";
6004    }
6005}
6006  [(set (attr "type")
6007     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6008	(const_string "incdec")
6009	(const_string "alu")))
6010   (set_attr "mode" "SI")])
6011
6012
6013(define_insn "*addhi_5"
6014  [(set (reg FLAGS_REG)
6015	(compare
6016	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6017		   (match_operand:HI 2 "general_operand" "rmni"))
6018	  (const_int 0)))			
6019   (clobber (match_scratch:HI 0 "=r"))]
6020  "ix86_match_ccmode (insn, CCGOCmode)
6021   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6022{
6023  switch (get_attr_type (insn))
6024    {
6025    case TYPE_INCDEC:
6026      if (operands[2] == const1_rtx)
6027	return "inc{w}\t%0";
6028      else
6029	{
6030	  gcc_assert (operands[2] == constm1_rtx);
6031	  return "dec{w}\t%0";
6032	}
6033
6034    default:
6035      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6037      if (GET_CODE (operands[2]) == CONST_INT
6038          && (INTVAL (operands[2]) == 128
6039	      || (INTVAL (operands[2]) < 0
6040		  && INTVAL (operands[2]) != -128)))
6041	{
6042	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6043	  return "sub{w}\t{%2, %0|%0, %2}";
6044	}
6045      return "add{w}\t{%2, %0|%0, %2}";
6046    }
6047}
6048  [(set (attr "type")
6049     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6050	(const_string "incdec")
6051	(const_string "alu")))
6052   (set_attr "mode" "HI")])
6053
6054(define_expand "addqi3"
6055  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6056		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6057			    (match_operand:QI 2 "general_operand" "")))
6058	      (clobber (reg:CC FLAGS_REG))])]
6059  "TARGET_QIMODE_MATH"
6060  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6061
6062;; %%% Potential partial reg stall on alternative 2.  What to do?
6063(define_insn "*addqi_1_lea"
6064  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6065	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6066		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6067   (clobber (reg:CC FLAGS_REG))]
6068  "!TARGET_PARTIAL_REG_STALL
6069   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6070{
6071  int widen = (which_alternative == 2);
6072  switch (get_attr_type (insn))
6073    {
6074    case TYPE_LEA:
6075      return "#";
6076    case TYPE_INCDEC:
6077      if (operands[2] == const1_rtx)
6078	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6079      else
6080	{
6081	  gcc_assert (operands[2] == constm1_rtx);
6082	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6083	}
6084
6085    default:
6086      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6087	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6088      if (GET_CODE (operands[2]) == CONST_INT
6089          && (INTVAL (operands[2]) == 128
6090	      || (INTVAL (operands[2]) < 0
6091		  && INTVAL (operands[2]) != -128)))
6092	{
6093	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6094	  if (widen)
6095	    return "sub{l}\t{%2, %k0|%k0, %2}";
6096	  else
6097	    return "sub{b}\t{%2, %0|%0, %2}";
6098	}
6099      if (widen)
6100        return "add{l}\t{%k2, %k0|%k0, %k2}";
6101      else
6102        return "add{b}\t{%2, %0|%0, %2}";
6103    }
6104}
6105  [(set (attr "type")
6106     (if_then_else (eq_attr "alternative" "3")
6107	(const_string "lea")
6108	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6109	   (const_string "incdec")
6110	   (const_string "alu"))))
6111   (set_attr "mode" "QI,QI,SI,SI")])
6112
6113(define_insn "*addqi_1"
6114  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6115	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6116		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6117   (clobber (reg:CC FLAGS_REG))]
6118  "TARGET_PARTIAL_REG_STALL
6119   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6120{
6121  int widen = (which_alternative == 2);
6122  switch (get_attr_type (insn))
6123    {
6124    case TYPE_INCDEC:
6125      if (operands[2] == const1_rtx)
6126	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6127      else
6128	{
6129	  gcc_assert (operands[2] == constm1_rtx);
6130	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6131	}
6132
6133    default:
6134      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6135	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6136      if (GET_CODE (operands[2]) == CONST_INT
6137          && (INTVAL (operands[2]) == 128
6138	      || (INTVAL (operands[2]) < 0
6139		  && INTVAL (operands[2]) != -128)))
6140	{
6141	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6142	  if (widen)
6143	    return "sub{l}\t{%2, %k0|%k0, %2}";
6144	  else
6145	    return "sub{b}\t{%2, %0|%0, %2}";
6146	}
6147      if (widen)
6148        return "add{l}\t{%k2, %k0|%k0, %k2}";
6149      else
6150        return "add{b}\t{%2, %0|%0, %2}";
6151    }
6152}
6153  [(set (attr "type")
6154     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6155	(const_string "incdec")
6156	(const_string "alu")))
6157   (set_attr "mode" "QI,QI,SI")])
6158
6159(define_insn "*addqi_1_slp"
6160  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6161	(plus:QI (match_dup 0)
6162		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6163   (clobber (reg:CC FLAGS_REG))]
6164  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6165   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6166{
6167  switch (get_attr_type (insn))
6168    {
6169    case TYPE_INCDEC:
6170      if (operands[1] == const1_rtx)
6171	return "inc{b}\t%0";
6172      else
6173	{
6174	  gcc_assert (operands[1] == constm1_rtx);
6175	  return "dec{b}\t%0";
6176	}
6177
6178    default:
6179      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6180      if (GET_CODE (operands[1]) == CONST_INT
6181	  && INTVAL (operands[1]) < 0)
6182	{
6183	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6184	  return "sub{b}\t{%1, %0|%0, %1}";
6185	}
6186      return "add{b}\t{%1, %0|%0, %1}";
6187    }
6188}
6189  [(set (attr "type")
6190     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6191	(const_string "incdec")
6192	(const_string "alu1")))
6193   (set (attr "memory")
6194     (if_then_else (match_operand 1 "memory_operand" "")
6195        (const_string "load")
6196        (const_string "none")))
6197   (set_attr "mode" "QI")])
6198
6199(define_insn "*addqi_2"
6200  [(set (reg FLAGS_REG)
6201	(compare
6202	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6203		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6204	  (const_int 0)))
6205   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6206	(plus:QI (match_dup 1) (match_dup 2)))]
6207  "ix86_match_ccmode (insn, CCGOCmode)
6208   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6209{
6210  switch (get_attr_type (insn))
6211    {
6212    case TYPE_INCDEC:
6213      if (operands[2] == const1_rtx)
6214	return "inc{b}\t%0";
6215      else
6216        {
6217	  gcc_assert (operands[2] == constm1_rtx
6218		      || (GET_CODE (operands[2]) == CONST_INT
6219		          && INTVAL (operands[2]) == 255));
6220	  return "dec{b}\t%0";
6221	}
6222
6223    default:
6224      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6225      if (GET_CODE (operands[2]) == CONST_INT
6226          && INTVAL (operands[2]) < 0)
6227	{
6228	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6229	  return "sub{b}\t{%2, %0|%0, %2}";
6230	}
6231      return "add{b}\t{%2, %0|%0, %2}";
6232    }
6233}
6234  [(set (attr "type")
6235     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6236	(const_string "incdec")
6237	(const_string "alu")))
6238   (set_attr "mode" "QI")])
6239
6240(define_insn "*addqi_3"
6241  [(set (reg FLAGS_REG)
6242	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6243		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6244   (clobber (match_scratch:QI 0 "=q"))]
6245  "ix86_match_ccmode (insn, CCZmode)
6246   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6247{
6248  switch (get_attr_type (insn))
6249    {
6250    case TYPE_INCDEC:
6251      if (operands[2] == const1_rtx)
6252	return "inc{b}\t%0";
6253      else
6254        {
6255	  gcc_assert (operands[2] == constm1_rtx
6256		      || (GET_CODE (operands[2]) == CONST_INT
6257			  && INTVAL (operands[2]) == 255));
6258	  return "dec{b}\t%0";
6259	}
6260
6261    default:
6262      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6263      if (GET_CODE (operands[2]) == CONST_INT
6264          && INTVAL (operands[2]) < 0)
6265	{
6266	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6267	  return "sub{b}\t{%2, %0|%0, %2}";
6268	}
6269      return "add{b}\t{%2, %0|%0, %2}";
6270    }
6271}
6272  [(set (attr "type")
6273     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6274	(const_string "incdec")
6275	(const_string "alu")))
6276   (set_attr "mode" "QI")])
6277
6278; See comments above addsi_4 for details.
6279(define_insn "*addqi_4"
6280  [(set (reg FLAGS_REG)
6281	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6282		 (match_operand:QI 2 "const_int_operand" "n")))
6283   (clobber (match_scratch:QI 0 "=qm"))]
6284  "ix86_match_ccmode (insn, CCGCmode)
6285   && (INTVAL (operands[2]) & 0xff) != 0x80"
6286{
6287  switch (get_attr_type (insn))
6288    {
6289    case TYPE_INCDEC:
6290      if (operands[2] == constm1_rtx
6291	  || (GET_CODE (operands[2]) == CONST_INT
6292	      && INTVAL (operands[2]) == 255))
6293        return "inc{b}\t%0";
6294      else
6295	{
6296	  gcc_assert (operands[2] == const1_rtx);
6297          return "dec{b}\t%0";
6298	}
6299
6300    default:
6301      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6302      if (INTVAL (operands[2]) < 0)
6303        {
6304          operands[2] = GEN_INT (-INTVAL (operands[2]));
6305          return "add{b}\t{%2, %0|%0, %2}";
6306        }
6307      return "sub{b}\t{%2, %0|%0, %2}";
6308    }
6309}
6310  [(set (attr "type")
6311     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6312	(const_string "incdec")
6313	(const_string "alu")))
6314   (set_attr "mode" "QI")])
6315
6316
6317(define_insn "*addqi_5"
6318  [(set (reg FLAGS_REG)
6319	(compare
6320	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6321		   (match_operand:QI 2 "general_operand" "qmni"))
6322	  (const_int 0)))
6323   (clobber (match_scratch:QI 0 "=q"))]
6324  "ix86_match_ccmode (insn, CCGOCmode)
6325   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6326{
6327  switch (get_attr_type (insn))
6328    {
6329    case TYPE_INCDEC:
6330      if (operands[2] == const1_rtx)
6331	return "inc{b}\t%0";
6332      else
6333        {
6334	  gcc_assert (operands[2] == constm1_rtx
6335		      || (GET_CODE (operands[2]) == CONST_INT
6336			  && INTVAL (operands[2]) == 255));
6337	  return "dec{b}\t%0";
6338	}
6339
6340    default:
6341      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6342      if (GET_CODE (operands[2]) == CONST_INT
6343          && INTVAL (operands[2]) < 0)
6344	{
6345	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6346	  return "sub{b}\t{%2, %0|%0, %2}";
6347	}
6348      return "add{b}\t{%2, %0|%0, %2}";
6349    }
6350}
6351  [(set (attr "type")
6352     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6353	(const_string "incdec")
6354	(const_string "alu")))
6355   (set_attr "mode" "QI")])
6356
6357
6358(define_insn "addqi_ext_1"
6359  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6360			 (const_int 8)
6361			 (const_int 8))
6362	(plus:SI
6363	  (zero_extract:SI
6364	    (match_operand 1 "ext_register_operand" "0")
6365	    (const_int 8)
6366	    (const_int 8))
6367	  (match_operand:QI 2 "general_operand" "Qmn")))
6368   (clobber (reg:CC FLAGS_REG))]
6369  "!TARGET_64BIT"
6370{
6371  switch (get_attr_type (insn))
6372    {
6373    case TYPE_INCDEC:
6374      if (operands[2] == const1_rtx)
6375	return "inc{b}\t%h0";
6376      else
6377        {
6378	  gcc_assert (operands[2] == constm1_rtx
6379		      || (GET_CODE (operands[2]) == CONST_INT
6380			  && INTVAL (operands[2]) == 255));
6381          return "dec{b}\t%h0";
6382	}
6383
6384    default:
6385      return "add{b}\t{%2, %h0|%h0, %2}";
6386    }
6387}
6388  [(set (attr "type")
6389     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390	(const_string "incdec")
6391	(const_string "alu")))
6392   (set_attr "mode" "QI")])
6393
6394(define_insn "*addqi_ext_1_rex64"
6395  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6396			 (const_int 8)
6397			 (const_int 8))
6398	(plus:SI
6399	  (zero_extract:SI
6400	    (match_operand 1 "ext_register_operand" "0")
6401	    (const_int 8)
6402	    (const_int 8))
6403	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6404   (clobber (reg:CC FLAGS_REG))]
6405  "TARGET_64BIT"
6406{
6407  switch (get_attr_type (insn))
6408    {
6409    case TYPE_INCDEC:
6410      if (operands[2] == const1_rtx)
6411	return "inc{b}\t%h0";
6412      else
6413        {
6414	  gcc_assert (operands[2] == constm1_rtx
6415		      || (GET_CODE (operands[2]) == CONST_INT
6416			  && INTVAL (operands[2]) == 255));
6417          return "dec{b}\t%h0";
6418        }
6419
6420    default:
6421      return "add{b}\t{%2, %h0|%h0, %2}";
6422    }
6423}
6424  [(set (attr "type")
6425     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6426	(const_string "incdec")
6427	(const_string "alu")))
6428   (set_attr "mode" "QI")])
6429
6430(define_insn "*addqi_ext_2"
6431  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6432			 (const_int 8)
6433			 (const_int 8))
6434	(plus:SI
6435	  (zero_extract:SI
6436	    (match_operand 1 "ext_register_operand" "%0")
6437	    (const_int 8)
6438	    (const_int 8))
6439	  (zero_extract:SI
6440	    (match_operand 2 "ext_register_operand" "Q")
6441	    (const_int 8)
6442	    (const_int 8))))
6443   (clobber (reg:CC FLAGS_REG))]
6444  ""
6445  "add{b}\t{%h2, %h0|%h0, %h2}"
6446  [(set_attr "type" "alu")
6447   (set_attr "mode" "QI")])
6448
6449;; The patterns that match these are at the end of this file.
6450
6451(define_expand "addxf3"
6452  [(set (match_operand:XF 0 "register_operand" "")
6453	(plus:XF (match_operand:XF 1 "register_operand" "")
6454		 (match_operand:XF 2 "register_operand" "")))]
6455  "TARGET_80387"
6456  "")
6457
6458(define_expand "adddf3"
6459  [(set (match_operand:DF 0 "register_operand" "")
6460	(plus:DF (match_operand:DF 1 "register_operand" "")
6461		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6462  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6463  "")
6464
6465(define_expand "addsf3"
6466  [(set (match_operand:SF 0 "register_operand" "")
6467	(plus:SF (match_operand:SF 1 "register_operand" "")
6468		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6469  "TARGET_80387 || TARGET_SSE_MATH"
6470  "")
6471
6472;; Subtract instructions
6473
6474;; %%% splits for subditi3
6475
6476(define_expand "subti3"
6477  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6478		   (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6479			     (match_operand:TI 2 "x86_64_general_operand" "")))
6480	      (clobber (reg:CC FLAGS_REG))])]
6481  "TARGET_64BIT"
6482  "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6483
6484(define_insn "*subti3_1"
6485  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6486	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6487		  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6488   (clobber (reg:CC FLAGS_REG))]
6489  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6490  "#")
6491
6492(define_split
6493  [(set (match_operand:TI 0 "nonimmediate_operand" "")
6494	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6495		  (match_operand:TI 2 "x86_64_general_operand" "")))
6496   (clobber (reg:CC FLAGS_REG))]
6497  "TARGET_64BIT && reload_completed"
6498  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6499	      (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6500   (parallel [(set (match_dup 3)
6501		   (minus:DI (match_dup 4)
6502			     (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6503				      (match_dup 5))))
6504	      (clobber (reg:CC FLAGS_REG))])]
6505  "split_ti (operands+0, 1, operands+0, operands+3);
6506   split_ti (operands+1, 1, operands+1, operands+4);
6507   split_ti (operands+2, 1, operands+2, operands+5);")
6508
6509;; %%% splits for subsidi3
6510
6511(define_expand "subdi3"
6512  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6513		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6514			     (match_operand:DI 2 "x86_64_general_operand" "")))
6515	      (clobber (reg:CC FLAGS_REG))])]
6516  ""
6517  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6518
6519(define_insn "*subdi3_1"
6520  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6521	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6522		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6523   (clobber (reg:CC FLAGS_REG))]
6524  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6525  "#")
6526
6527(define_split
6528  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6529	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6530		  (match_operand:DI 2 "general_operand" "")))
6531   (clobber (reg:CC FLAGS_REG))]
6532  "!TARGET_64BIT && reload_completed"
6533  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6534	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6535   (parallel [(set (match_dup 3)
6536		   (minus:SI (match_dup 4)
6537			     (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6538				      (match_dup 5))))
6539	      (clobber (reg:CC FLAGS_REG))])]
6540  "split_di (operands+0, 1, operands+0, operands+3);
6541   split_di (operands+1, 1, operands+1, operands+4);
6542   split_di (operands+2, 1, operands+2, operands+5);")
6543
6544(define_insn "subdi3_carry_rex64"
6545  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6546	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6547	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6548	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6549   (clobber (reg:CC FLAGS_REG))]
6550  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6551  "sbb{q}\t{%2, %0|%0, %2}"
6552  [(set_attr "type" "alu")
6553   (set_attr "pent_pair" "pu")
6554   (set_attr "mode" "DI")])
6555
6556(define_insn "*subdi_1_rex64"
6557  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6558	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6559		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6560   (clobber (reg:CC FLAGS_REG))]
6561  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6562  "sub{q}\t{%2, %0|%0, %2}"
6563  [(set_attr "type" "alu")
6564   (set_attr "mode" "DI")])
6565
6566(define_insn "*subdi_2_rex64"
6567  [(set (reg FLAGS_REG)
6568	(compare
6569	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6570		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6571	  (const_int 0)))
6572   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6573	(minus:DI (match_dup 1) (match_dup 2)))]
6574  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6575   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6576  "sub{q}\t{%2, %0|%0, %2}"
6577  [(set_attr "type" "alu")
6578   (set_attr "mode" "DI")])
6579
6580(define_insn "*subdi_3_rex63"
6581  [(set (reg FLAGS_REG)
6582	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6584   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6585	(minus:DI (match_dup 1) (match_dup 2)))]
6586  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6587   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6588  "sub{q}\t{%2, %0|%0, %2}"
6589  [(set_attr "type" "alu")
6590   (set_attr "mode" "DI")])
6591
6592(define_insn "subqi3_carry"
6593  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6594	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6595	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6596	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6597   (clobber (reg:CC FLAGS_REG))]
6598  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6599  "sbb{b}\t{%2, %0|%0, %2}"
6600  [(set_attr "type" "alu")
6601   (set_attr "pent_pair" "pu")
6602   (set_attr "mode" "QI")])
6603
6604(define_insn "subhi3_carry"
6605  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6606	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6607	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6608	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6609   (clobber (reg:CC FLAGS_REG))]
6610  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6611  "sbb{w}\t{%2, %0|%0, %2}"
6612  [(set_attr "type" "alu")
6613   (set_attr "pent_pair" "pu")
6614   (set_attr "mode" "HI")])
6615
6616(define_insn "subsi3_carry"
6617  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6618	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6619	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6620	       (match_operand:SI 2 "general_operand" "ri,rm"))))
6621   (clobber (reg:CC FLAGS_REG))]
6622  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6623  "sbb{l}\t{%2, %0|%0, %2}"
6624  [(set_attr "type" "alu")
6625   (set_attr "pent_pair" "pu")
6626   (set_attr "mode" "SI")])
6627
6628(define_insn "subsi3_carry_zext"
6629  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6630	  (zero_extend:DI
6631	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6632	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6633		 (match_operand:SI 2 "general_operand" "ri,rm")))))
6634   (clobber (reg:CC FLAGS_REG))]
6635  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636  "sbb{l}\t{%2, %k0|%k0, %2}"
6637  [(set_attr "type" "alu")
6638   (set_attr "pent_pair" "pu")
6639   (set_attr "mode" "SI")])
6640
6641(define_expand "subsi3"
6642  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6643		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6644			     (match_operand:SI 2 "general_operand" "")))
6645	      (clobber (reg:CC FLAGS_REG))])]
6646  ""
6647  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6648
6649(define_insn "*subsi_1"
6650  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6651	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6652		  (match_operand:SI 2 "general_operand" "ri,rm")))
6653   (clobber (reg:CC FLAGS_REG))]
6654  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6655  "sub{l}\t{%2, %0|%0, %2}"
6656  [(set_attr "type" "alu")
6657   (set_attr "mode" "SI")])
6658
6659(define_insn "*subsi_1_zext"
6660  [(set (match_operand:DI 0 "register_operand" "=r")
6661	(zero_extend:DI
6662	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6663		    (match_operand:SI 2 "general_operand" "rim"))))
6664   (clobber (reg:CC FLAGS_REG))]
6665  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666  "sub{l}\t{%2, %k0|%k0, %2}"
6667  [(set_attr "type" "alu")
6668   (set_attr "mode" "SI")])
6669
6670(define_insn "*subsi_2"
6671  [(set (reg FLAGS_REG)
6672	(compare
6673	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6674		    (match_operand:SI 2 "general_operand" "ri,rm"))
6675	  (const_int 0)))
6676   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6677	(minus:SI (match_dup 1) (match_dup 2)))]
6678  "ix86_match_ccmode (insn, CCGOCmode)
6679   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6680  "sub{l}\t{%2, %0|%0, %2}"
6681  [(set_attr "type" "alu")
6682   (set_attr "mode" "SI")])
6683
6684(define_insn "*subsi_2_zext"
6685  [(set (reg FLAGS_REG)
6686	(compare
6687	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6688		    (match_operand:SI 2 "general_operand" "rim"))
6689	  (const_int 0)))
6690   (set (match_operand:DI 0 "register_operand" "=r")
6691	(zero_extend:DI
6692	  (minus:SI (match_dup 1)
6693		    (match_dup 2))))]
6694  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6695   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6696  "sub{l}\t{%2, %k0|%k0, %2}"
6697  [(set_attr "type" "alu")
6698   (set_attr "mode" "SI")])
6699
6700(define_insn "*subsi_3"
6701  [(set (reg FLAGS_REG)
6702	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6703		 (match_operand:SI 2 "general_operand" "ri,rm")))
6704   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6705	(minus:SI (match_dup 1) (match_dup 2)))]
6706  "ix86_match_ccmode (insn, CCmode)
6707   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6708  "sub{l}\t{%2, %0|%0, %2}"
6709  [(set_attr "type" "alu")
6710   (set_attr "mode" "SI")])
6711
6712(define_insn "*subsi_3_zext"
6713  [(set (reg FLAGS_REG)
6714	(compare (match_operand:SI 1 "register_operand" "0")
6715		 (match_operand:SI 2 "general_operand" "rim")))
6716   (set (match_operand:DI 0 "register_operand" "=r")
6717	(zero_extend:DI
6718	  (minus:SI (match_dup 1)
6719		    (match_dup 2))))]
6720  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6721   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722  "sub{l}\t{%2, %1|%1, %2}"
6723  [(set_attr "type" "alu")
6724   (set_attr "mode" "DI")])
6725
6726(define_expand "subhi3"
6727  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6728		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6729			     (match_operand:HI 2 "general_operand" "")))
6730	      (clobber (reg:CC FLAGS_REG))])]
6731  "TARGET_HIMODE_MATH"
6732  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6733
6734(define_insn "*subhi_1"
6735  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6736	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6737		  (match_operand:HI 2 "general_operand" "ri,rm")))
6738   (clobber (reg:CC FLAGS_REG))]
6739  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6740  "sub{w}\t{%2, %0|%0, %2}"
6741  [(set_attr "type" "alu")
6742   (set_attr "mode" "HI")])
6743
6744(define_insn "*subhi_2"
6745  [(set (reg FLAGS_REG)
6746	(compare
6747	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6748		    (match_operand:HI 2 "general_operand" "ri,rm"))
6749	  (const_int 0)))
6750   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6751	(minus:HI (match_dup 1) (match_dup 2)))]
6752  "ix86_match_ccmode (insn, CCGOCmode)
6753   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6754  "sub{w}\t{%2, %0|%0, %2}"
6755  [(set_attr "type" "alu")
6756   (set_attr "mode" "HI")])
6757
6758(define_insn "*subhi_3"
6759  [(set (reg FLAGS_REG)
6760	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6761		 (match_operand:HI 2 "general_operand" "ri,rm")))
6762   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6763	(minus:HI (match_dup 1) (match_dup 2)))]
6764  "ix86_match_ccmode (insn, CCmode)
6765   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6766  "sub{w}\t{%2, %0|%0, %2}"
6767  [(set_attr "type" "alu")
6768   (set_attr "mode" "HI")])
6769
6770(define_expand "subqi3"
6771  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6772		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6773			     (match_operand:QI 2 "general_operand" "")))
6774	      (clobber (reg:CC FLAGS_REG))])]
6775  "TARGET_QIMODE_MATH"
6776  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6777
6778(define_insn "*subqi_1"
6779  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6780	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6781		  (match_operand:QI 2 "general_operand" "qn,qmn")))
6782   (clobber (reg:CC FLAGS_REG))]
6783  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6784  "sub{b}\t{%2, %0|%0, %2}"
6785  [(set_attr "type" "alu")
6786   (set_attr "mode" "QI")])
6787
6788(define_insn "*subqi_1_slp"
6789  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6790	(minus:QI (match_dup 0)
6791		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6792   (clobber (reg:CC FLAGS_REG))]
6793  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6794   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6795  "sub{b}\t{%1, %0|%0, %1}"
6796  [(set_attr "type" "alu1")
6797   (set_attr "mode" "QI")])
6798
6799(define_insn "*subqi_2"
6800  [(set (reg FLAGS_REG)
6801	(compare
6802	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6803		    (match_operand:QI 2 "general_operand" "qi,qm"))
6804	  (const_int 0)))
6805   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6806	(minus:HI (match_dup 1) (match_dup 2)))]
6807  "ix86_match_ccmode (insn, CCGOCmode)
6808   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6809  "sub{b}\t{%2, %0|%0, %2}"
6810  [(set_attr "type" "alu")
6811   (set_attr "mode" "QI")])
6812
6813(define_insn "*subqi_3"
6814  [(set (reg FLAGS_REG)
6815	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6816		 (match_operand:QI 2 "general_operand" "qi,qm")))
6817   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6818	(minus:HI (match_dup 1) (match_dup 2)))]
6819  "ix86_match_ccmode (insn, CCmode)
6820   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6821  "sub{b}\t{%2, %0|%0, %2}"
6822  [(set_attr "type" "alu")
6823   (set_attr "mode" "QI")])
6824
6825;; The patterns that match these are at the end of this file.
6826
6827(define_expand "subxf3"
6828  [(set (match_operand:XF 0 "register_operand" "")
6829	(minus:XF (match_operand:XF 1 "register_operand" "")
6830		  (match_operand:XF 2 "register_operand" "")))]
6831  "TARGET_80387"
6832  "")
6833
6834(define_expand "subdf3"
6835  [(set (match_operand:DF 0 "register_operand" "")
6836	(minus:DF (match_operand:DF 1 "register_operand" "")
6837		  (match_operand:DF 2 "nonimmediate_operand" "")))]
6838  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6839  "")
6840
6841(define_expand "subsf3"
6842  [(set (match_operand:SF 0 "register_operand" "")
6843	(minus:SF (match_operand:SF 1 "register_operand" "")
6844		  (match_operand:SF 2 "nonimmediate_operand" "")))]
6845  "TARGET_80387 || TARGET_SSE_MATH"
6846  "")
6847
6848;; Multiply instructions
6849
6850(define_expand "muldi3"
6851  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6852		   (mult:DI (match_operand:DI 1 "register_operand" "")
6853			    (match_operand:DI 2 "x86_64_general_operand" "")))
6854	      (clobber (reg:CC FLAGS_REG))])]
6855  "TARGET_64BIT"
6856  "")
6857
6858(define_insn "*muldi3_1_rex64"
6859  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6860	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6861		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6862   (clobber (reg:CC FLAGS_REG))]
6863  "TARGET_64BIT
6864   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6865  "@
6866   imul{q}\t{%2, %1, %0|%0, %1, %2}
6867   imul{q}\t{%2, %1, %0|%0, %1, %2}
6868   imul{q}\t{%2, %0|%0, %2}"
6869  [(set_attr "type" "imul")
6870   (set_attr "prefix_0f" "0,0,1")
6871   (set (attr "athlon_decode")
6872	(cond [(eq_attr "cpu" "athlon")
6873		  (const_string "vector")
6874	       (eq_attr "alternative" "1")
6875		  (const_string "vector")
6876	       (and (eq_attr "alternative" "2")
6877		    (match_operand 1 "memory_operand" ""))
6878		  (const_string "vector")]
6879	      (const_string "direct")))
6880   (set_attr "mode" "DI")])
6881
6882(define_expand "mulsi3"
6883  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6884		   (mult:SI (match_operand:SI 1 "register_operand" "")
6885			    (match_operand:SI 2 "general_operand" "")))
6886	      (clobber (reg:CC FLAGS_REG))])]
6887  ""
6888  "")
6889
6890(define_insn "*mulsi3_1"
6891  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6892	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6893		 (match_operand:SI 2 "general_operand" "K,i,mr")))
6894   (clobber (reg:CC FLAGS_REG))]
6895  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6896  "@
6897   imul{l}\t{%2, %1, %0|%0, %1, %2}
6898   imul{l}\t{%2, %1, %0|%0, %1, %2}
6899   imul{l}\t{%2, %0|%0, %2}"
6900  [(set_attr "type" "imul")
6901   (set_attr "prefix_0f" "0,0,1")
6902   (set (attr "athlon_decode")
6903	(cond [(eq_attr "cpu" "athlon")
6904		  (const_string "vector")
6905	       (eq_attr "alternative" "1")
6906		  (const_string "vector")
6907	       (and (eq_attr "alternative" "2")
6908		    (match_operand 1 "memory_operand" ""))
6909		  (const_string "vector")]
6910	      (const_string "direct")))
6911   (set_attr "mode" "SI")])
6912
6913(define_insn "*mulsi3_1_zext"
6914  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6915	(zero_extend:DI
6916	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6917		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
6918   (clobber (reg:CC FLAGS_REG))]
6919  "TARGET_64BIT
6920   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6921  "@
6922   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6924   imul{l}\t{%2, %k0|%k0, %2}"
6925  [(set_attr "type" "imul")
6926   (set_attr "prefix_0f" "0,0,1")
6927   (set (attr "athlon_decode")
6928	(cond [(eq_attr "cpu" "athlon")
6929		  (const_string "vector")
6930	       (eq_attr "alternative" "1")
6931		  (const_string "vector")
6932	       (and (eq_attr "alternative" "2")
6933		    (match_operand 1 "memory_operand" ""))
6934		  (const_string "vector")]
6935	      (const_string "direct")))
6936   (set_attr "mode" "SI")])
6937
6938(define_expand "mulhi3"
6939  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6940		   (mult:HI (match_operand:HI 1 "register_operand" "")
6941			    (match_operand:HI 2 "general_operand" "")))
6942	      (clobber (reg:CC FLAGS_REG))])]
6943  "TARGET_HIMODE_MATH"
6944  "")
6945
6946(define_insn "*mulhi3_1"
6947  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6948	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6949		 (match_operand:HI 2 "general_operand" "K,i,mr")))
6950   (clobber (reg:CC FLAGS_REG))]
6951  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6952  "@
6953   imul{w}\t{%2, %1, %0|%0, %1, %2}
6954   imul{w}\t{%2, %1, %0|%0, %1, %2}
6955   imul{w}\t{%2, %0|%0, %2}"
6956  [(set_attr "type" "imul")
6957   (set_attr "prefix_0f" "0,0,1")
6958   (set (attr "athlon_decode")
6959	(cond [(eq_attr "cpu" "athlon")
6960		  (const_string "vector")
6961	       (eq_attr "alternative" "1,2")
6962		  (const_string "vector")]
6963	      (const_string "direct")))
6964   (set_attr "mode" "HI")])
6965
6966(define_expand "mulqi3"
6967  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6968		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6969			    (match_operand:QI 2 "register_operand" "")))
6970	      (clobber (reg:CC FLAGS_REG))])]
6971  "TARGET_QIMODE_MATH"
6972  "")
6973
6974(define_insn "*mulqi3_1"
6975  [(set (match_operand:QI 0 "register_operand" "=a")
6976	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6977		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6978   (clobber (reg:CC FLAGS_REG))]
6979  "TARGET_QIMODE_MATH
6980   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6981  "mul{b}\t%2"
6982  [(set_attr "type" "imul")
6983   (set_attr "length_immediate" "0")
6984   (set (attr "athlon_decode")
6985     (if_then_else (eq_attr "cpu" "athlon")
6986        (const_string "vector")
6987        (const_string "direct")))
6988   (set_attr "mode" "QI")])
6989
6990(define_expand "umulqihi3"
6991  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6992		   (mult:HI (zero_extend:HI
6993			      (match_operand:QI 1 "nonimmediate_operand" ""))
6994			    (zero_extend:HI
6995			      (match_operand:QI 2 "register_operand" ""))))
6996	      (clobber (reg:CC FLAGS_REG))])]
6997  "TARGET_QIMODE_MATH"
6998  "")
6999
7000(define_insn "*umulqihi3_1"
7001  [(set (match_operand:HI 0 "register_operand" "=a")
7002	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7003		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7004   (clobber (reg:CC FLAGS_REG))]
7005  "TARGET_QIMODE_MATH
7006   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7007  "mul{b}\t%2"
7008  [(set_attr "type" "imul")
7009   (set_attr "length_immediate" "0")
7010   (set (attr "athlon_decode")
7011     (if_then_else (eq_attr "cpu" "athlon")
7012        (const_string "vector")
7013        (const_string "direct")))
7014   (set_attr "mode" "QI")])
7015
7016(define_expand "mulqihi3"
7017  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7018		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7019			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7020	      (clobber (reg:CC FLAGS_REG))])]
7021  "TARGET_QIMODE_MATH"
7022  "")
7023
7024(define_insn "*mulqihi3_insn"
7025  [(set (match_operand:HI 0 "register_operand" "=a")
7026	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7027		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7028   (clobber (reg:CC FLAGS_REG))]
7029  "TARGET_QIMODE_MATH
7030   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7031  "imul{b}\t%2"
7032  [(set_attr "type" "imul")
7033   (set_attr "length_immediate" "0")
7034   (set (attr "athlon_decode")
7035     (if_then_else (eq_attr "cpu" "athlon")
7036        (const_string "vector")
7037        (const_string "direct")))
7038   (set_attr "mode" "QI")])
7039
7040(define_expand "umulditi3"
7041  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7042		   (mult:TI (zero_extend:TI
7043			      (match_operand:DI 1 "nonimmediate_operand" ""))
7044			    (zero_extend:TI
7045			      (match_operand:DI 2 "register_operand" ""))))
7046	      (clobber (reg:CC FLAGS_REG))])]
7047  "TARGET_64BIT"
7048  "")
7049
7050(define_insn "*umulditi3_insn"
7051  [(set (match_operand:TI 0 "register_operand" "=A")
7052	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7053		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7054   (clobber (reg:CC FLAGS_REG))]
7055  "TARGET_64BIT
7056   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7057  "mul{q}\t%2"
7058  [(set_attr "type" "imul")
7059   (set_attr "length_immediate" "0")
7060   (set (attr "athlon_decode")
7061     (if_then_else (eq_attr "cpu" "athlon")
7062        (const_string "vector")
7063        (const_string "double")))
7064   (set_attr "mode" "DI")])
7065
7066;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7067(define_expand "umulsidi3"
7068  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7069		   (mult:DI (zero_extend:DI
7070			      (match_operand:SI 1 "nonimmediate_operand" ""))
7071			    (zero_extend:DI
7072			      (match_operand:SI 2 "register_operand" ""))))
7073	      (clobber (reg:CC FLAGS_REG))])]
7074  "!TARGET_64BIT"
7075  "")
7076
7077(define_insn "*umulsidi3_insn"
7078  [(set (match_operand:DI 0 "register_operand" "=A")
7079	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7080		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7081   (clobber (reg:CC FLAGS_REG))]
7082  "!TARGET_64BIT
7083   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084  "mul{l}\t%2"
7085  [(set_attr "type" "imul")
7086   (set_attr "length_immediate" "0")
7087   (set (attr "athlon_decode")
7088     (if_then_else (eq_attr "cpu" "athlon")
7089        (const_string "vector")
7090        (const_string "double")))
7091   (set_attr "mode" "SI")])
7092
7093(define_expand "mulditi3"
7094  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7095		   (mult:TI (sign_extend:TI
7096			      (match_operand:DI 1 "nonimmediate_operand" ""))
7097			    (sign_extend:TI
7098			      (match_operand:DI 2 "register_operand" ""))))
7099	      (clobber (reg:CC FLAGS_REG))])]
7100  "TARGET_64BIT"
7101  "")
7102
7103(define_insn "*mulditi3_insn"
7104  [(set (match_operand:TI 0 "register_operand" "=A")
7105	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7106		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7107   (clobber (reg:CC FLAGS_REG))]
7108  "TARGET_64BIT
7109   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7110  "imul{q}\t%2"
7111  [(set_attr "type" "imul")
7112   (set_attr "length_immediate" "0")
7113   (set (attr "athlon_decode")
7114     (if_then_else (eq_attr "cpu" "athlon")
7115        (const_string "vector")
7116        (const_string "double")))
7117   (set_attr "mode" "DI")])
7118
7119(define_expand "mulsidi3"
7120  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7121		   (mult:DI (sign_extend:DI
7122			      (match_operand:SI 1 "nonimmediate_operand" ""))
7123			    (sign_extend:DI
7124			      (match_operand:SI 2 "register_operand" ""))))
7125	      (clobber (reg:CC FLAGS_REG))])]
7126  "!TARGET_64BIT"
7127  "")
7128
7129(define_insn "*mulsidi3_insn"
7130  [(set (match_operand:DI 0 "register_operand" "=A")
7131	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7132		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7133   (clobber (reg:CC FLAGS_REG))]
7134  "!TARGET_64BIT
7135   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7136  "imul{l}\t%2"
7137  [(set_attr "type" "imul")
7138   (set_attr "length_immediate" "0")
7139   (set (attr "athlon_decode")
7140     (if_then_else (eq_attr "cpu" "athlon")
7141        (const_string "vector")
7142        (const_string "double")))
7143   (set_attr "mode" "SI")])
7144
7145(define_expand "umuldi3_highpart"
7146  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7147		   (truncate:DI
7148		     (lshiftrt:TI
7149		       (mult:TI (zero_extend:TI
7150				  (match_operand:DI 1 "nonimmediate_operand" ""))
7151				(zero_extend:TI
7152				  (match_operand:DI 2 "register_operand" "")))
7153		       (const_int 64))))
7154	      (clobber (match_scratch:DI 3 ""))
7155	      (clobber (reg:CC FLAGS_REG))])]
7156  "TARGET_64BIT"
7157  "")
7158
7159(define_insn "*umuldi3_highpart_rex64"
7160  [(set (match_operand:DI 0 "register_operand" "=d")
7161	(truncate:DI
7162	  (lshiftrt:TI
7163	    (mult:TI (zero_extend:TI
7164		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7165		     (zero_extend:TI
7166		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7167	    (const_int 64))))
7168   (clobber (match_scratch:DI 3 "=1"))
7169   (clobber (reg:CC FLAGS_REG))]
7170  "TARGET_64BIT
7171   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172  "mul{q}\t%2"
7173  [(set_attr "type" "imul")
7174   (set_attr "length_immediate" "0")
7175   (set (attr "athlon_decode")
7176     (if_then_else (eq_attr "cpu" "athlon")
7177        (const_string "vector")
7178        (const_string "double")))
7179   (set_attr "mode" "DI")])
7180
7181(define_expand "umulsi3_highpart"
7182  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7183		   (truncate:SI
7184		     (lshiftrt:DI
7185		       (mult:DI (zero_extend:DI
7186				  (match_operand:SI 1 "nonimmediate_operand" ""))
7187				(zero_extend:DI
7188				  (match_operand:SI 2 "register_operand" "")))
7189		       (const_int 32))))
7190	      (clobber (match_scratch:SI 3 ""))
7191	      (clobber (reg:CC FLAGS_REG))])]
7192  ""
7193  "")
7194
7195(define_insn "*umulsi3_highpart_insn"
7196  [(set (match_operand:SI 0 "register_operand" "=d")
7197	(truncate:SI
7198	  (lshiftrt:DI
7199	    (mult:DI (zero_extend:DI
7200		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7201		     (zero_extend:DI
7202		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7203	    (const_int 32))))
7204   (clobber (match_scratch:SI 3 "=1"))
7205   (clobber (reg:CC FLAGS_REG))]
7206  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7207  "mul{l}\t%2"
7208  [(set_attr "type" "imul")
7209   (set_attr "length_immediate" "0")
7210   (set (attr "athlon_decode")
7211     (if_then_else (eq_attr "cpu" "athlon")
7212        (const_string "vector")
7213        (const_string "double")))
7214   (set_attr "mode" "SI")])
7215
7216(define_insn "*umulsi3_highpart_zext"
7217  [(set (match_operand:DI 0 "register_operand" "=d")
7218	(zero_extend:DI (truncate:SI
7219	  (lshiftrt:DI
7220	    (mult:DI (zero_extend:DI
7221		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7222		     (zero_extend:DI
7223		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7224	    (const_int 32)))))
7225   (clobber (match_scratch:SI 3 "=1"))
7226   (clobber (reg:CC FLAGS_REG))]
7227  "TARGET_64BIT
7228   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7229  "mul{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 "mode" "SI")])
7237
7238(define_expand "smuldi3_highpart"
7239  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7240		   (truncate:DI
7241		     (lshiftrt:TI
7242		       (mult:TI (sign_extend:TI
7243				  (match_operand:DI 1 "nonimmediate_operand" ""))
7244				(sign_extend:TI
7245				  (match_operand:DI 2 "register_operand" "")))
7246		       (const_int 64))))
7247	      (clobber (match_scratch:DI 3 ""))
7248	      (clobber (reg:CC FLAGS_REG))])]
7249  "TARGET_64BIT"
7250  "")
7251
7252(define_insn "*smuldi3_highpart_rex64"
7253  [(set (match_operand:DI 0 "register_operand" "=d")
7254	(truncate:DI
7255	  (lshiftrt:TI
7256	    (mult:TI (sign_extend:TI
7257		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7258		     (sign_extend:TI
7259		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7260	    (const_int 64))))
7261   (clobber (match_scratch:DI 3 "=1"))
7262   (clobber (reg:CC FLAGS_REG))]
7263  "TARGET_64BIT
7264   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7265  "imul{q}\t%2"
7266  [(set_attr "type" "imul")
7267   (set (attr "athlon_decode")
7268     (if_then_else (eq_attr "cpu" "athlon")
7269        (const_string "vector")
7270        (const_string "double")))
7271   (set_attr "mode" "DI")])
7272
7273(define_expand "smulsi3_highpart"
7274  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7275		   (truncate:SI
7276		     (lshiftrt:DI
7277		       (mult:DI (sign_extend:DI
7278				  (match_operand:SI 1 "nonimmediate_operand" ""))
7279				(sign_extend:DI
7280				  (match_operand:SI 2 "register_operand" "")))
7281		       (const_int 32))))
7282	      (clobber (match_scratch:SI 3 ""))
7283	      (clobber (reg:CC FLAGS_REG))])]
7284  ""
7285  "")
7286
7287(define_insn "*smulsi3_highpart_insn"
7288  [(set (match_operand:SI 0 "register_operand" "=d")
7289	(truncate:SI
7290	  (lshiftrt:DI
7291	    (mult:DI (sign_extend:DI
7292		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7293		     (sign_extend:DI
7294		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7295	    (const_int 32))))
7296   (clobber (match_scratch:SI 3 "=1"))
7297   (clobber (reg:CC FLAGS_REG))]
7298  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7299  "imul{l}\t%2"
7300  [(set_attr "type" "imul")
7301   (set (attr "athlon_decode")
7302     (if_then_else (eq_attr "cpu" "athlon")
7303        (const_string "vector")
7304        (const_string "double")))
7305   (set_attr "mode" "SI")])
7306
7307(define_insn "*smulsi3_highpart_zext"
7308  [(set (match_operand:DI 0 "register_operand" "=d")
7309	(zero_extend:DI (truncate:SI
7310	  (lshiftrt:DI
7311	    (mult:DI (sign_extend:DI
7312		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7313		     (sign_extend:DI
7314		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7315	    (const_int 32)))))
7316   (clobber (match_scratch:SI 3 "=1"))
7317   (clobber (reg:CC FLAGS_REG))]
7318  "TARGET_64BIT
7319   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7320  "imul{l}\t%2"
7321  [(set_attr "type" "imul")
7322   (set (attr "athlon_decode")
7323     (if_then_else (eq_attr "cpu" "athlon")
7324        (const_string "vector")
7325        (const_string "double")))
7326   (set_attr "mode" "SI")])
7327
7328;; The patterns that match these are at the end of this file.
7329
7330(define_expand "mulxf3"
7331  [(set (match_operand:XF 0 "register_operand" "")
7332	(mult:XF (match_operand:XF 1 "register_operand" "")
7333		 (match_operand:XF 2 "register_operand" "")))]
7334  "TARGET_80387"
7335  "")
7336
7337(define_expand "muldf3"
7338  [(set (match_operand:DF 0 "register_operand" "")
7339	(mult:DF (match_operand:DF 1 "register_operand" "")
7340		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7341  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7342  "")
7343
7344(define_expand "mulsf3"
7345  [(set (match_operand:SF 0 "register_operand" "")
7346	(mult:SF (match_operand:SF 1 "register_operand" "")
7347		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7348  "TARGET_80387 || TARGET_SSE_MATH"
7349  "")
7350
7351;; Divide instructions
7352
7353(define_insn "divqi3"
7354  [(set (match_operand:QI 0 "register_operand" "=a")
7355	(div:QI (match_operand:HI 1 "register_operand" "0")
7356		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7357   (clobber (reg:CC FLAGS_REG))]
7358  "TARGET_QIMODE_MATH"
7359  "idiv{b}\t%2"
7360  [(set_attr "type" "idiv")
7361   (set_attr "mode" "QI")])
7362
7363(define_insn "udivqi3"
7364  [(set (match_operand:QI 0 "register_operand" "=a")
7365	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7366		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7367   (clobber (reg:CC FLAGS_REG))]
7368  "TARGET_QIMODE_MATH"
7369  "div{b}\t%2"
7370  [(set_attr "type" "idiv")
7371   (set_attr "mode" "QI")])
7372
7373;; The patterns that match these are at the end of this file.
7374
7375(define_expand "divxf3"
7376  [(set (match_operand:XF 0 "register_operand" "")
7377	(div:XF (match_operand:XF 1 "register_operand" "")
7378		(match_operand:XF 2 "register_operand" "")))]
7379  "TARGET_80387"
7380  "")
7381
7382(define_expand "divdf3"
7383  [(set (match_operand:DF 0 "register_operand" "")
7384 	(div:DF (match_operand:DF 1 "register_operand" "")
7385 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7386   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7387   "")
7388 
7389(define_expand "divsf3"
7390  [(set (match_operand:SF 0 "register_operand" "")
7391	(div:SF (match_operand:SF 1 "register_operand" "")
7392		(match_operand:SF 2 "nonimmediate_operand" "")))]
7393  "TARGET_80387 || TARGET_SSE_MATH"
7394  "")
7395
7396;; Remainder instructions.
7397
7398(define_expand "divmoddi4"
7399  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7400		   (div:DI (match_operand:DI 1 "register_operand" "")
7401			   (match_operand:DI 2 "nonimmediate_operand" "")))
7402	      (set (match_operand:DI 3 "register_operand" "")
7403		   (mod:DI (match_dup 1) (match_dup 2)))
7404	      (clobber (reg:CC FLAGS_REG))])]
7405  "TARGET_64BIT"
7406  "")
7407
7408;; Allow to come the parameter in eax or edx to avoid extra moves.
7409;; Penalize eax case slightly because it results in worse scheduling
7410;; of code.
7411(define_insn "*divmoddi4_nocltd_rex64"
7412  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7413	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7414		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7415   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7416	(mod:DI (match_dup 2) (match_dup 3)))
7417   (clobber (reg:CC FLAGS_REG))]
7418  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7419  "#"
7420  [(set_attr "type" "multi")])
7421
7422(define_insn "*divmoddi4_cltd_rex64"
7423  [(set (match_operand:DI 0 "register_operand" "=a")
7424	(div:DI (match_operand:DI 2 "register_operand" "a")
7425		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7426   (set (match_operand:DI 1 "register_operand" "=&d")
7427	(mod:DI (match_dup 2) (match_dup 3)))
7428   (clobber (reg:CC FLAGS_REG))]
7429  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7430  "#"
7431  [(set_attr "type" "multi")])
7432
7433(define_insn "*divmoddi_noext_rex64"
7434  [(set (match_operand:DI 0 "register_operand" "=a")
7435	(div:DI (match_operand:DI 1 "register_operand" "0")
7436		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7437   (set (match_operand:DI 3 "register_operand" "=d")
7438	(mod:DI (match_dup 1) (match_dup 2)))
7439   (use (match_operand:DI 4 "register_operand" "3"))
7440   (clobber (reg:CC FLAGS_REG))]
7441  "TARGET_64BIT"
7442  "idiv{q}\t%2"
7443  [(set_attr "type" "idiv")
7444   (set_attr "mode" "DI")])
7445
7446(define_split
7447  [(set (match_operand:DI 0 "register_operand" "")
7448	(div:DI (match_operand:DI 1 "register_operand" "")
7449		(match_operand:DI 2 "nonimmediate_operand" "")))
7450   (set (match_operand:DI 3 "register_operand" "")
7451	(mod:DI (match_dup 1) (match_dup 2)))
7452   (clobber (reg:CC FLAGS_REG))]
7453  "TARGET_64BIT && reload_completed"
7454  [(parallel [(set (match_dup 3)
7455		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7456	      (clobber (reg:CC FLAGS_REG))])
7457   (parallel [(set (match_dup 0)
7458	           (div:DI (reg:DI 0) (match_dup 2)))
7459	      (set (match_dup 3)
7460		   (mod:DI (reg:DI 0) (match_dup 2)))
7461	      (use (match_dup 3))
7462	      (clobber (reg:CC FLAGS_REG))])]
7463{
7464  /* Avoid use of cltd in favor of a mov+shift.  */
7465  if (!TARGET_USE_CLTD && !optimize_size)
7466    {
7467      if (true_regnum (operands[1]))
7468        emit_move_insn (operands[0], operands[1]);
7469      else
7470	emit_move_insn (operands[3], operands[1]);
7471      operands[4] = operands[3];
7472    }
7473  else
7474    {
7475      gcc_assert (!true_regnum (operands[1]));
7476      operands[4] = operands[1];
7477    }
7478})
7479
7480
7481(define_expand "divmodsi4"
7482  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7483		   (div:SI (match_operand:SI 1 "register_operand" "")
7484			   (match_operand:SI 2 "nonimmediate_operand" "")))
7485	      (set (match_operand:SI 3 "register_operand" "")
7486		   (mod:SI (match_dup 1) (match_dup 2)))
7487	      (clobber (reg:CC FLAGS_REG))])]
7488  ""
7489  "")
7490
7491;; Allow to come the parameter in eax or edx to avoid extra moves.
7492;; Penalize eax case slightly because it results in worse scheduling
7493;; of code.
7494(define_insn "*divmodsi4_nocltd"
7495  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7496	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7497		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7498   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7499	(mod:SI (match_dup 2) (match_dup 3)))
7500   (clobber (reg:CC FLAGS_REG))]
7501  "!optimize_size && !TARGET_USE_CLTD"
7502  "#"
7503  [(set_attr "type" "multi")])
7504
7505(define_insn "*divmodsi4_cltd"
7506  [(set (match_operand:SI 0 "register_operand" "=a")
7507	(div:SI (match_operand:SI 2 "register_operand" "a")
7508		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7509   (set (match_operand:SI 1 "register_operand" "=&d")
7510	(mod:SI (match_dup 2) (match_dup 3)))
7511   (clobber (reg:CC FLAGS_REG))]
7512  "optimize_size || TARGET_USE_CLTD"
7513  "#"
7514  [(set_attr "type" "multi")])
7515
7516(define_insn "*divmodsi_noext"
7517  [(set (match_operand:SI 0 "register_operand" "=a")
7518	(div:SI (match_operand:SI 1 "register_operand" "0")
7519		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7520   (set (match_operand:SI 3 "register_operand" "=d")
7521	(mod:SI (match_dup 1) (match_dup 2)))
7522   (use (match_operand:SI 4 "register_operand" "3"))
7523   (clobber (reg:CC FLAGS_REG))]
7524  ""
7525  "idiv{l}\t%2"
7526  [(set_attr "type" "idiv")
7527   (set_attr "mode" "SI")])
7528
7529(define_split
7530  [(set (match_operand:SI 0 "register_operand" "")
7531	(div:SI (match_operand:SI 1 "register_operand" "")
7532		(match_operand:SI 2 "nonimmediate_operand" "")))
7533   (set (match_operand:SI 3 "register_operand" "")
7534	(mod:SI (match_dup 1) (match_dup 2)))
7535   (clobber (reg:CC FLAGS_REG))]
7536  "reload_completed"
7537  [(parallel [(set (match_dup 3)
7538		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7539	      (clobber (reg:CC FLAGS_REG))])
7540   (parallel [(set (match_dup 0)
7541	           (div:SI (reg:SI 0) (match_dup 2)))
7542	      (set (match_dup 3)
7543		   (mod:SI (reg:SI 0) (match_dup 2)))
7544	      (use (match_dup 3))
7545	      (clobber (reg:CC FLAGS_REG))])]
7546{
7547  /* Avoid use of cltd in favor of a mov+shift.  */
7548  if (!TARGET_USE_CLTD && !optimize_size)
7549    {
7550      if (true_regnum (operands[1]))
7551        emit_move_insn (operands[0], operands[1]);
7552      else
7553	emit_move_insn (operands[3], operands[1]);
7554      operands[4] = operands[3];
7555    }
7556  else
7557    {
7558      gcc_assert (!true_regnum (operands[1]));
7559      operands[4] = operands[1];
7560    }
7561})
7562;; %%% Split me.
7563(define_insn "divmodhi4"
7564  [(set (match_operand:HI 0 "register_operand" "=a")
7565	(div:HI (match_operand:HI 1 "register_operand" "0")
7566		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7567   (set (match_operand:HI 3 "register_operand" "=&d")
7568	(mod:HI (match_dup 1) (match_dup 2)))
7569   (clobber (reg:CC FLAGS_REG))]
7570  "TARGET_HIMODE_MATH"
7571  "cwtd\;idiv{w}\t%2"
7572  [(set_attr "type" "multi")
7573   (set_attr "length_immediate" "0")
7574   (set_attr "mode" "SI")])
7575
7576(define_insn "udivmoddi4"
7577  [(set (match_operand:DI 0 "register_operand" "=a")
7578	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7579		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7580   (set (match_operand:DI 3 "register_operand" "=&d")
7581	(umod:DI (match_dup 1) (match_dup 2)))
7582   (clobber (reg:CC FLAGS_REG))]
7583  "TARGET_64BIT"
7584  "xor{q}\t%3, %3\;div{q}\t%2"
7585  [(set_attr "type" "multi")
7586   (set_attr "length_immediate" "0")
7587   (set_attr "mode" "DI")])
7588
7589(define_insn "*udivmoddi4_noext"
7590  [(set (match_operand:DI 0 "register_operand" "=a")
7591	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7592		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7593   (set (match_operand:DI 3 "register_operand" "=d")
7594	(umod:DI (match_dup 1) (match_dup 2)))
7595   (use (match_dup 3))
7596   (clobber (reg:CC FLAGS_REG))]
7597  "TARGET_64BIT"
7598  "div{q}\t%2"
7599  [(set_attr "type" "idiv")
7600   (set_attr "mode" "DI")])
7601
7602(define_split
7603  [(set (match_operand:DI 0 "register_operand" "")
7604	(udiv:DI (match_operand:DI 1 "register_operand" "")
7605		 (match_operand:DI 2 "nonimmediate_operand" "")))
7606   (set (match_operand:DI 3 "register_operand" "")
7607	(umod:DI (match_dup 1) (match_dup 2)))
7608   (clobber (reg:CC FLAGS_REG))]
7609  "TARGET_64BIT && reload_completed"
7610  [(set (match_dup 3) (const_int 0))
7611   (parallel [(set (match_dup 0)
7612		   (udiv:DI (match_dup 1) (match_dup 2)))
7613	      (set (match_dup 3)
7614		   (umod:DI (match_dup 1) (match_dup 2)))
7615	      (use (match_dup 3))
7616	      (clobber (reg:CC FLAGS_REG))])]
7617  "")
7618
7619(define_insn "udivmodsi4"
7620  [(set (match_operand:SI 0 "register_operand" "=a")
7621	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7622		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7623   (set (match_operand:SI 3 "register_operand" "=&d")
7624	(umod:SI (match_dup 1) (match_dup 2)))
7625   (clobber (reg:CC FLAGS_REG))]
7626  ""
7627  "xor{l}\t%3, %3\;div{l}\t%2"
7628  [(set_attr "type" "multi")
7629   (set_attr "length_immediate" "0")
7630   (set_attr "mode" "SI")])
7631
7632(define_insn "*udivmodsi4_noext"
7633  [(set (match_operand:SI 0 "register_operand" "=a")
7634	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7635		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7636   (set (match_operand:SI 3 "register_operand" "=d")
7637	(umod:SI (match_dup 1) (match_dup 2)))
7638   (use (match_dup 3))
7639   (clobber (reg:CC FLAGS_REG))]
7640  ""
7641  "div{l}\t%2"
7642  [(set_attr "type" "idiv")
7643   (set_attr "mode" "SI")])
7644
7645(define_split
7646  [(set (match_operand:SI 0 "register_operand" "")
7647	(udiv:SI (match_operand:SI 1 "register_operand" "")
7648		 (match_operand:SI 2 "nonimmediate_operand" "")))
7649   (set (match_operand:SI 3 "register_operand" "")
7650	(umod:SI (match_dup 1) (match_dup 2)))
7651   (clobber (reg:CC FLAGS_REG))]
7652  "reload_completed"
7653  [(set (match_dup 3) (const_int 0))
7654   (parallel [(set (match_dup 0)
7655		   (udiv:SI (match_dup 1) (match_dup 2)))
7656	      (set (match_dup 3)
7657		   (umod:SI (match_dup 1) (match_dup 2)))
7658	      (use (match_dup 3))
7659	      (clobber (reg:CC FLAGS_REG))])]
7660  "")
7661
7662(define_expand "udivmodhi4"
7663  [(set (match_dup 4) (const_int 0))
7664   (parallel [(set (match_operand:HI 0 "register_operand" "")
7665		   (udiv:HI (match_operand:HI 1 "register_operand" "")
7666		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
7667	      (set (match_operand:HI 3 "register_operand" "")
7668	   	   (umod:HI (match_dup 1) (match_dup 2)))
7669	      (use (match_dup 4))
7670	      (clobber (reg:CC FLAGS_REG))])]
7671  "TARGET_HIMODE_MATH"
7672  "operands[4] = gen_reg_rtx (HImode);")
7673
7674(define_insn "*udivmodhi_noext"
7675  [(set (match_operand:HI 0 "register_operand" "=a")
7676	(udiv:HI (match_operand:HI 1 "register_operand" "0")
7677		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7678   (set (match_operand:HI 3 "register_operand" "=d")
7679	(umod:HI (match_dup 1) (match_dup 2)))
7680   (use (match_operand:HI 4 "register_operand" "3"))
7681   (clobber (reg:CC FLAGS_REG))]
7682  ""
7683  "div{w}\t%2"
7684  [(set_attr "type" "idiv")
7685   (set_attr "mode" "HI")])
7686
7687;; We cannot use div/idiv for double division, because it causes
7688;; "division by zero" on the overflow and that's not what we expect
7689;; from truncate.  Because true (non truncating) double division is
7690;; never generated, we can't create this insn anyway.
7691;
7692;(define_insn ""
7693;  [(set (match_operand:SI 0 "register_operand" "=a")
7694;	(truncate:SI
7695;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7696;		   (zero_extend:DI
7697;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7698;   (set (match_operand:SI 3 "register_operand" "=d")
7699;	(truncate:SI
7700;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7701;   (clobber (reg:CC FLAGS_REG))]
7702;  ""
7703;  "div{l}\t{%2, %0|%0, %2}"
7704;  [(set_attr "type" "idiv")])
7705
7706;;- Logical AND instructions
7707
7708;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7709;; Note that this excludes ah.
7710
7711(define_insn "*testdi_1_rex64"
7712  [(set (reg FLAGS_REG)
7713	(compare
7714	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7715		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7716	  (const_int 0)))]
7717  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7718   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7719  "@
7720   test{l}\t{%k1, %k0|%k0, %k1}
7721   test{l}\t{%k1, %k0|%k0, %k1}
7722   test{q}\t{%1, %0|%0, %1}
7723   test{q}\t{%1, %0|%0, %1}
7724   test{q}\t{%1, %0|%0, %1}"
7725  [(set_attr "type" "test")
7726   (set_attr "modrm" "0,1,0,1,1")
7727   (set_attr "mode" "SI,SI,DI,DI,DI")
7728   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7729
7730(define_insn "testsi_1"
7731  [(set (reg FLAGS_REG)
7732	(compare
7733	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7734		  (match_operand:SI 1 "general_operand" "in,in,rin"))
7735	  (const_int 0)))]
7736  "ix86_match_ccmode (insn, CCNOmode)
7737   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7738  "test{l}\t{%1, %0|%0, %1}"
7739  [(set_attr "type" "test")
7740   (set_attr "modrm" "0,1,1")
7741   (set_attr "mode" "SI")
7742   (set_attr "pent_pair" "uv,np,uv")])
7743
7744(define_expand "testsi_ccno_1"
7745  [(set (reg:CCNO FLAGS_REG)
7746	(compare:CCNO
7747	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7748		  (match_operand:SI 1 "nonmemory_operand" ""))
7749	  (const_int 0)))]
7750  ""
7751  "")
7752
7753(define_insn "*testhi_1"
7754  [(set (reg FLAGS_REG)
7755        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7756			 (match_operand:HI 1 "general_operand" "n,n,rn"))
7757		 (const_int 0)))]
7758  "ix86_match_ccmode (insn, CCNOmode)
7759   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7760  "test{w}\t{%1, %0|%0, %1}"
7761  [(set_attr "type" "test")
7762   (set_attr "modrm" "0,1,1")
7763   (set_attr "mode" "HI")
7764   (set_attr "pent_pair" "uv,np,uv")])
7765
7766(define_expand "testqi_ccz_1"
7767  [(set (reg:CCZ FLAGS_REG)
7768        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7769			     (match_operand:QI 1 "nonmemory_operand" ""))
7770		 (const_int 0)))]
7771  ""
7772  "")
7773
7774(define_insn "*testqi_1_maybe_si"
7775  [(set (reg FLAGS_REG)
7776        (compare
7777	  (and:QI
7778	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7779	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7780	  (const_int 0)))]
7781   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7782    && ix86_match_ccmode (insn,
7783 			 GET_CODE (operands[1]) == CONST_INT
7784 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7785{
7786  if (which_alternative == 3)
7787    {
7788      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7789	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7790      return "test{l}\t{%1, %k0|%k0, %1}";
7791    }
7792  return "test{b}\t{%1, %0|%0, %1}";
7793}
7794  [(set_attr "type" "test")
7795   (set_attr "modrm" "0,1,1,1")
7796   (set_attr "mode" "QI,QI,QI,SI")
7797   (set_attr "pent_pair" "uv,np,uv,np")])
7798
7799(define_insn "*testqi_1"
7800  [(set (reg FLAGS_REG)
7801        (compare
7802	  (and:QI
7803	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7804	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7805	  (const_int 0)))]
7806  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7807   && ix86_match_ccmode (insn, CCNOmode)"
7808  "test{b}\t{%1, %0|%0, %1}"
7809  [(set_attr "type" "test")
7810   (set_attr "modrm" "0,1,1")
7811   (set_attr "mode" "QI")
7812   (set_attr "pent_pair" "uv,np,uv")])
7813
7814(define_expand "testqi_ext_ccno_0"
7815  [(set (reg:CCNO FLAGS_REG)
7816	(compare:CCNO
7817	  (and:SI
7818	    (zero_extract:SI
7819	      (match_operand 0 "ext_register_operand" "")
7820	      (const_int 8)
7821	      (const_int 8))
7822	    (match_operand 1 "const_int_operand" ""))
7823	  (const_int 0)))]
7824  ""
7825  "")
7826
7827(define_insn "*testqi_ext_0"
7828  [(set (reg FLAGS_REG)
7829	(compare
7830	  (and:SI
7831	    (zero_extract:SI
7832	      (match_operand 0 "ext_register_operand" "Q")
7833	      (const_int 8)
7834	      (const_int 8))
7835	    (match_operand 1 "const_int_operand" "n"))
7836	  (const_int 0)))]
7837  "ix86_match_ccmode (insn, CCNOmode)"
7838  "test{b}\t{%1, %h0|%h0, %1}"
7839  [(set_attr "type" "test")
7840   (set_attr "mode" "QI")
7841   (set_attr "length_immediate" "1")
7842   (set_attr "pent_pair" "np")])
7843
7844(define_insn "*testqi_ext_1"
7845  [(set (reg FLAGS_REG)
7846	(compare
7847	  (and:SI
7848	    (zero_extract:SI
7849	      (match_operand 0 "ext_register_operand" "Q")
7850	      (const_int 8)
7851	      (const_int 8))
7852	    (zero_extend:SI
7853	      (match_operand:QI 1 "general_operand" "Qm")))
7854	  (const_int 0)))]
7855  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7856   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7857  "test{b}\t{%1, %h0|%h0, %1}"
7858  [(set_attr "type" "test")
7859   (set_attr "mode" "QI")])
7860
7861(define_insn "*testqi_ext_1_rex64"
7862  [(set (reg FLAGS_REG)
7863	(compare
7864	  (and:SI
7865	    (zero_extract:SI
7866	      (match_operand 0 "ext_register_operand" "Q")
7867	      (const_int 8)
7868	      (const_int 8))
7869	    (zero_extend:SI
7870	      (match_operand:QI 1 "register_operand" "Q")))
7871	  (const_int 0)))]
7872  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7873  "test{b}\t{%1, %h0|%h0, %1}"
7874  [(set_attr "type" "test")
7875   (set_attr "mode" "QI")])
7876
7877(define_insn "*testqi_ext_2"
7878  [(set (reg FLAGS_REG)
7879	(compare
7880	  (and:SI
7881	    (zero_extract:SI
7882	      (match_operand 0 "ext_register_operand" "Q")
7883	      (const_int 8)
7884	      (const_int 8))
7885	    (zero_extract:SI
7886	      (match_operand 1 "ext_register_operand" "Q")
7887	      (const_int 8)
7888	      (const_int 8)))
7889	  (const_int 0)))]
7890  "ix86_match_ccmode (insn, CCNOmode)"
7891  "test{b}\t{%h1, %h0|%h0, %h1}"
7892  [(set_attr "type" "test")
7893   (set_attr "mode" "QI")])
7894
7895;; Combine likes to form bit extractions for some tests.  Humor it.
7896(define_insn "*testqi_ext_3"
7897  [(set (reg FLAGS_REG)
7898        (compare (zero_extract:SI
7899		   (match_operand 0 "nonimmediate_operand" "rm")
7900		   (match_operand:SI 1 "const_int_operand" "")
7901		   (match_operand:SI 2 "const_int_operand" ""))
7902		 (const_int 0)))]
7903  "ix86_match_ccmode (insn, CCNOmode)
7904   && INTVAL (operands[1]) > 0
7905   && INTVAL (operands[2]) >= 0
7906   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7907   && (GET_MODE (operands[0]) == SImode
7908       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7909       || GET_MODE (operands[0]) == HImode
7910       || GET_MODE (operands[0]) == QImode)"
7911  "#")
7912
7913(define_insn "*testqi_ext_3_rex64"
7914  [(set (reg FLAGS_REG)
7915        (compare (zero_extract:DI
7916		   (match_operand 0 "nonimmediate_operand" "rm")
7917		   (match_operand:DI 1 "const_int_operand" "")
7918		   (match_operand:DI 2 "const_int_operand" ""))
7919		 (const_int 0)))]
7920  "TARGET_64BIT
7921   && ix86_match_ccmode (insn, CCNOmode)
7922   && INTVAL (operands[1]) > 0
7923   && INTVAL (operands[2]) >= 0
7924   /* Ensure that resulting mask is zero or sign extended operand.  */
7925   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7926       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7927	   && INTVAL (operands[1]) > 32))
7928   && (GET_MODE (operands[0]) == SImode
7929       || GET_MODE (operands[0]) == DImode
7930       || GET_MODE (operands[0]) == HImode
7931       || GET_MODE (operands[0]) == QImode)"
7932  "#")
7933
7934(define_split
7935  [(set (match_operand 0 "flags_reg_operand" "")
7936        (match_operator 1 "compare_operator"
7937	  [(zero_extract
7938	     (match_operand 2 "nonimmediate_operand" "")
7939	     (match_operand 3 "const_int_operand" "")
7940	     (match_operand 4 "const_int_operand" ""))
7941	   (const_int 0)]))]
7942  "ix86_match_ccmode (insn, CCNOmode)"
7943  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7944{
7945  rtx val = operands[2];
7946  HOST_WIDE_INT len = INTVAL (operands[3]);
7947  HOST_WIDE_INT pos = INTVAL (operands[4]);
7948  HOST_WIDE_INT mask;
7949  enum machine_mode mode, submode;
7950
7951  mode = GET_MODE (val);
7952  if (GET_CODE (val) == MEM)
7953    {
7954      /* ??? Combine likes to put non-volatile mem extractions in QImode
7955	 no matter the size of the test.  So find a mode that works.  */
7956      if (! MEM_VOLATILE_P (val))
7957	{
7958	  mode = smallest_mode_for_size (pos + len, MODE_INT);
7959	  val = adjust_address (val, mode, 0);
7960	}
7961    }
7962  else if (GET_CODE (val) == SUBREG
7963	   && (submode = GET_MODE (SUBREG_REG (val)),
7964	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7965	   && pos + len <= GET_MODE_BITSIZE (submode))
7966    {
7967      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7968      mode = submode;
7969      val = SUBREG_REG (val);
7970    }
7971  else if (mode == HImode && pos + len <= 8)
7972    {
7973      /* Small HImode tests can be converted to QImode.  */
7974      mode = QImode;
7975      val = gen_lowpart (QImode, val);
7976    }
7977
7978  if (len == HOST_BITS_PER_WIDE_INT)
7979    mask = -1;
7980  else
7981    mask = ((HOST_WIDE_INT)1 << len) - 1;
7982  mask <<= pos;
7983
7984  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7985})
7986
7987;; Convert HImode/SImode test instructions with immediate to QImode ones.
7988;; i386 does not allow to encode test with 8bit sign extended immediate, so
7989;; this is relatively important trick.
7990;; Do the conversion only post-reload to avoid limiting of the register class
7991;; to QI regs.
7992(define_split
7993  [(set (match_operand 0 "flags_reg_operand" "")
7994	(match_operator 1 "compare_operator"
7995	  [(and (match_operand 2 "register_operand" "")
7996	        (match_operand 3 "const_int_operand" ""))
7997	   (const_int 0)]))]
7998   "reload_completed
7999    && QI_REG_P (operands[2])
8000    && GET_MODE (operands[2]) != QImode
8001    && ((ix86_match_ccmode (insn, CCZmode)
8002    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8003	|| (ix86_match_ccmode (insn, CCNOmode)
8004	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8005  [(set (match_dup 0)
8006	(match_op_dup 1
8007	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8008		   (match_dup 3))
8009	   (const_int 0)]))]
8010  "operands[2] = gen_lowpart (SImode, operands[2]);
8011   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8012
8013(define_split
8014  [(set (match_operand 0 "flags_reg_operand" "")
8015	(match_operator 1 "compare_operator"
8016	  [(and (match_operand 2 "nonimmediate_operand" "")
8017	        (match_operand 3 "const_int_operand" ""))
8018	   (const_int 0)]))]
8019   "reload_completed
8020    && GET_MODE (operands[2]) != QImode
8021    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8022    && ((ix86_match_ccmode (insn, CCZmode)
8023	 && !(INTVAL (operands[3]) & ~255))
8024	|| (ix86_match_ccmode (insn, CCNOmode)
8025	    && !(INTVAL (operands[3]) & ~127)))"
8026  [(set (match_dup 0)
8027	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8028			 (const_int 0)]))]
8029  "operands[2] = gen_lowpart (QImode, operands[2]);
8030   operands[3] = gen_lowpart (QImode, operands[3]);")
8031
8032
8033;; %%% This used to optimize known byte-wide and operations to memory,
8034;; and sometimes to QImode registers.  If this is considered useful,
8035;; it should be done with splitters.
8036
8037(define_expand "anddi3"
8038  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8039	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8040		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8041   (clobber (reg:CC FLAGS_REG))]
8042  "TARGET_64BIT"
8043  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8044
8045(define_insn "*anddi_1_rex64"
8046  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8047	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8048		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8049   (clobber (reg:CC FLAGS_REG))]
8050  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8051{
8052  switch (get_attr_type (insn))
8053    {
8054    case TYPE_IMOVX:
8055      {
8056	enum machine_mode mode;
8057
8058	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8059        if (INTVAL (operands[2]) == 0xff)
8060	  mode = QImode;
8061	else
8062	  {
8063	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8064	    mode = HImode;
8065	  }
8066	
8067	operands[1] = gen_lowpart (mode, operands[1]);
8068	if (mode == QImode)
8069	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8070	else
8071	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8072      }
8073
8074    default:
8075      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8076      if (get_attr_mode (insn) == MODE_SI)
8077	return "and{l}\t{%k2, %k0|%k0, %k2}";
8078      else
8079	return "and{q}\t{%2, %0|%0, %2}";
8080    }
8081}
8082  [(set_attr "type" "alu,alu,alu,imovx")
8083   (set_attr "length_immediate" "*,*,*,0")
8084   (set_attr "mode" "SI,DI,DI,DI")])
8085
8086(define_insn "*anddi_2"
8087  [(set (reg FLAGS_REG)
8088	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8089			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8090		 (const_int 0)))
8091   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8092	(and:DI (match_dup 1) (match_dup 2)))]
8093  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8094   && ix86_binary_operator_ok (AND, DImode, operands)"
8095  "@
8096   and{l}\t{%k2, %k0|%k0, %k2}
8097   and{q}\t{%2, %0|%0, %2}
8098   and{q}\t{%2, %0|%0, %2}"
8099  [(set_attr "type" "alu")
8100   (set_attr "mode" "SI,DI,DI")])
8101
8102(define_expand "andsi3"
8103  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8104	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8105		(match_operand:SI 2 "general_operand" "")))
8106   (clobber (reg:CC FLAGS_REG))]
8107  ""
8108  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8109
8110(define_insn "*andsi_1"
8111  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8112	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8113		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8114   (clobber (reg:CC FLAGS_REG))]
8115  "ix86_binary_operator_ok (AND, SImode, operands)"
8116{
8117  switch (get_attr_type (insn))
8118    {
8119    case TYPE_IMOVX:
8120      {
8121	enum machine_mode mode;
8122
8123	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8124        if (INTVAL (operands[2]) == 0xff)
8125	  mode = QImode;
8126	else
8127	  {
8128	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8129	    mode = HImode;
8130	  }
8131	
8132	operands[1] = gen_lowpart (mode, operands[1]);
8133	if (mode == QImode)
8134	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8135	else
8136	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8137      }
8138
8139    default:
8140      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8141      return "and{l}\t{%2, %0|%0, %2}";
8142    }
8143}
8144  [(set_attr "type" "alu,alu,imovx")
8145   (set_attr "length_immediate" "*,*,0")
8146   (set_attr "mode" "SI")])
8147
8148(define_split
8149  [(set (match_operand 0 "register_operand" "")
8150	(and (match_dup 0)
8151	     (const_int -65536)))
8152   (clobber (reg:CC FLAGS_REG))]
8153  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8154  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8155  "operands[1] = gen_lowpart (HImode, operands[0]);")
8156
8157(define_split
8158  [(set (match_operand 0 "ext_register_operand" "")
8159	(and (match_dup 0)
8160	     (const_int -256)))
8161   (clobber (reg:CC FLAGS_REG))]
8162  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8163  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8164  "operands[1] = gen_lowpart (QImode, operands[0]);")
8165
8166(define_split
8167  [(set (match_operand 0 "ext_register_operand" "")
8168	(and (match_dup 0)
8169	     (const_int -65281)))
8170   (clobber (reg:CC FLAGS_REG))]
8171  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8172  [(parallel [(set (zero_extract:SI (match_dup 0)
8173				    (const_int 8)
8174				    (const_int 8))
8175		   (xor:SI 
8176		     (zero_extract:SI (match_dup 0)
8177				      (const_int 8)
8178				      (const_int 8))
8179		     (zero_extract:SI (match_dup 0)
8180				      (const_int 8)
8181				      (const_int 8))))
8182	      (clobber (reg:CC FLAGS_REG))])]
8183  "operands[0] = gen_lowpart (SImode, operands[0]);")
8184
8185;; See comment for addsi_1_zext why we do use nonimmediate_operand
8186(define_insn "*andsi_1_zext"
8187  [(set (match_operand:DI 0 "register_operand" "=r")
8188	(zero_extend:DI
8189	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8190		  (match_operand:SI 2 "general_operand" "rim"))))
8191   (clobber (reg:CC FLAGS_REG))]
8192  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8193  "and{l}\t{%2, %k0|%k0, %2}"
8194  [(set_attr "type" "alu")
8195   (set_attr "mode" "SI")])
8196
8197(define_insn "*andsi_2"
8198  [(set (reg FLAGS_REG)
8199	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8200			 (match_operand:SI 2 "general_operand" "rim,ri"))
8201		 (const_int 0)))
8202   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8203	(and:SI (match_dup 1) (match_dup 2)))]
8204  "ix86_match_ccmode (insn, CCNOmode)
8205   && ix86_binary_operator_ok (AND, SImode, operands)"
8206  "and{l}\t{%2, %0|%0, %2}"
8207  [(set_attr "type" "alu")
8208   (set_attr "mode" "SI")])
8209
8210;; See comment for addsi_1_zext why we do use nonimmediate_operand
8211(define_insn "*andsi_2_zext"
8212  [(set (reg FLAGS_REG)
8213	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8214			 (match_operand:SI 2 "general_operand" "rim"))
8215		 (const_int 0)))
8216   (set (match_operand:DI 0 "register_operand" "=r")
8217	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8218  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8219   && ix86_binary_operator_ok (AND, SImode, operands)"
8220  "and{l}\t{%2, %k0|%k0, %2}"
8221  [(set_attr "type" "alu")
8222   (set_attr "mode" "SI")])
8223
8224(define_expand "andhi3"
8225  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8226	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8227		(match_operand:HI 2 "general_operand" "")))
8228   (clobber (reg:CC FLAGS_REG))]
8229  "TARGET_HIMODE_MATH"
8230  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8231
8232(define_insn "*andhi_1"
8233  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8234	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8235		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8236   (clobber (reg:CC FLAGS_REG))]
8237  "ix86_binary_operator_ok (AND, HImode, operands)"
8238{
8239  switch (get_attr_type (insn))
8240    {
8241    case TYPE_IMOVX:
8242      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8243      gcc_assert (INTVAL (operands[2]) == 0xff);
8244      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8245
8246    default:
8247      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8248
8249      return "and{w}\t{%2, %0|%0, %2}";
8250    }
8251}
8252  [(set_attr "type" "alu,alu,imovx")
8253   (set_attr "length_immediate" "*,*,0")
8254   (set_attr "mode" "HI,HI,SI")])
8255
8256(define_insn "*andhi_2"
8257  [(set (reg FLAGS_REG)
8258	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8259			 (match_operand:HI 2 "general_operand" "rim,ri"))
8260		 (const_int 0)))
8261   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8262	(and:HI (match_dup 1) (match_dup 2)))]
8263  "ix86_match_ccmode (insn, CCNOmode)
8264   && ix86_binary_operator_ok (AND, HImode, operands)"
8265  "and{w}\t{%2, %0|%0, %2}"
8266  [(set_attr "type" "alu")
8267   (set_attr "mode" "HI")])
8268
8269(define_expand "andqi3"
8270  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8271	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8272		(match_operand:QI 2 "general_operand" "")))
8273   (clobber (reg:CC FLAGS_REG))]
8274  "TARGET_QIMODE_MATH"
8275  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8276
8277;; %%% Potential partial reg stall on alternative 2.  What to do?
8278(define_insn "*andqi_1"
8279  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8280	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8281		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8282   (clobber (reg:CC FLAGS_REG))]
8283  "ix86_binary_operator_ok (AND, QImode, operands)"
8284  "@
8285   and{b}\t{%2, %0|%0, %2}
8286   and{b}\t{%2, %0|%0, %2}
8287   and{l}\t{%k2, %k0|%k0, %k2}"
8288  [(set_attr "type" "alu")
8289   (set_attr "mode" "QI,QI,SI")])
8290
8291(define_insn "*andqi_1_slp"
8292  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8293	(and:QI (match_dup 0)
8294		(match_operand:QI 1 "general_operand" "qi,qmi")))
8295   (clobber (reg:CC FLAGS_REG))]
8296  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8297   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8298  "and{b}\t{%1, %0|%0, %1}"
8299  [(set_attr "type" "alu1")
8300   (set_attr "mode" "QI")])
8301
8302(define_insn "*andqi_2_maybe_si"
8303  [(set (reg FLAGS_REG)
8304	(compare (and:QI
8305		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8306		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8307		 (const_int 0)))
8308   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8309	(and:QI (match_dup 1) (match_dup 2)))]
8310  "ix86_binary_operator_ok (AND, QImode, operands)
8311   && ix86_match_ccmode (insn,
8312			 GET_CODE (operands[2]) == CONST_INT
8313			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8314{
8315  if (which_alternative == 2)
8316    {
8317      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8318        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8319      return "and{l}\t{%2, %k0|%k0, %2}";
8320    }
8321  return "and{b}\t{%2, %0|%0, %2}";
8322}
8323  [(set_attr "type" "alu")
8324   (set_attr "mode" "QI,QI,SI")])
8325
8326(define_insn "*andqi_2"
8327  [(set (reg FLAGS_REG)
8328	(compare (and:QI
8329		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8330		   (match_operand:QI 2 "general_operand" "qim,qi"))
8331		 (const_int 0)))
8332   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8333	(and:QI (match_dup 1) (match_dup 2)))]
8334  "ix86_match_ccmode (insn, CCNOmode)
8335   && ix86_binary_operator_ok (AND, QImode, operands)"
8336  "and{b}\t{%2, %0|%0, %2}"
8337  [(set_attr "type" "alu")
8338   (set_attr "mode" "QI")])
8339
8340(define_insn "*andqi_2_slp"
8341  [(set (reg FLAGS_REG)
8342	(compare (and:QI
8343		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8344		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8345		 (const_int 0)))
8346   (set (strict_low_part (match_dup 0))
8347	(and:QI (match_dup 0) (match_dup 1)))]
8348  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8349   && ix86_match_ccmode (insn, CCNOmode)
8350   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8351  "and{b}\t{%1, %0|%0, %1}"
8352  [(set_attr "type" "alu1")
8353   (set_attr "mode" "QI")])
8354
8355;; ??? A bug in recog prevents it from recognizing a const_int as an
8356;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8357;; for a QImode operand, which of course failed.
8358
8359(define_insn "andqi_ext_0"
8360  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8361			 (const_int 8)
8362			 (const_int 8))
8363	(and:SI 
8364	  (zero_extract:SI
8365	    (match_operand 1 "ext_register_operand" "0")
8366	    (const_int 8)
8367	    (const_int 8))
8368	  (match_operand 2 "const_int_operand" "n")))
8369   (clobber (reg:CC FLAGS_REG))]
8370  ""
8371  "and{b}\t{%2, %h0|%h0, %2}"
8372  [(set_attr "type" "alu")
8373   (set_attr "length_immediate" "1")
8374   (set_attr "mode" "QI")])
8375
8376;; Generated by peephole translating test to and.  This shows up
8377;; often in fp comparisons.
8378
8379(define_insn "*andqi_ext_0_cc"
8380  [(set (reg FLAGS_REG)
8381	(compare
8382	  (and:SI
8383	    (zero_extract:SI
8384	      (match_operand 1 "ext_register_operand" "0")
8385	      (const_int 8)
8386	      (const_int 8))
8387	    (match_operand 2 "const_int_operand" "n"))
8388	  (const_int 0)))
8389   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8390			 (const_int 8)
8391			 (const_int 8))
8392	(and:SI 
8393	  (zero_extract:SI
8394	    (match_dup 1)
8395	    (const_int 8)
8396	    (const_int 8))
8397	  (match_dup 2)))]
8398  "ix86_match_ccmode (insn, CCNOmode)"
8399  "and{b}\t{%2, %h0|%h0, %2}"
8400  [(set_attr "type" "alu")
8401   (set_attr "length_immediate" "1")
8402   (set_attr "mode" "QI")])
8403
8404(define_insn "*andqi_ext_1"
8405  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406			 (const_int 8)
8407			 (const_int 8))
8408	(and:SI 
8409	  (zero_extract:SI
8410	    (match_operand 1 "ext_register_operand" "0")
8411	    (const_int 8)
8412	    (const_int 8))
8413	  (zero_extend:SI
8414	    (match_operand:QI 2 "general_operand" "Qm"))))
8415   (clobber (reg:CC FLAGS_REG))]
8416  "!TARGET_64BIT"
8417  "and{b}\t{%2, %h0|%h0, %2}"
8418  [(set_attr "type" "alu")
8419   (set_attr "length_immediate" "0")
8420   (set_attr "mode" "QI")])
8421
8422(define_insn "*andqi_ext_1_rex64"
8423  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8424			 (const_int 8)
8425			 (const_int 8))
8426	(and:SI 
8427	  (zero_extract:SI
8428	    (match_operand 1 "ext_register_operand" "0")
8429	    (const_int 8)
8430	    (const_int 8))
8431	  (zero_extend:SI
8432	    (match_operand 2 "ext_register_operand" "Q"))))
8433   (clobber (reg:CC FLAGS_REG))]
8434  "TARGET_64BIT"
8435  "and{b}\t{%2, %h0|%h0, %2}"
8436  [(set_attr "type" "alu")
8437   (set_attr "length_immediate" "0")
8438   (set_attr "mode" "QI")])
8439
8440(define_insn "*andqi_ext_2"
8441  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442			 (const_int 8)
8443			 (const_int 8))
8444	(and:SI
8445	  (zero_extract:SI
8446	    (match_operand 1 "ext_register_operand" "%0")
8447	    (const_int 8)
8448	    (const_int 8))
8449	  (zero_extract:SI
8450	    (match_operand 2 "ext_register_operand" "Q")
8451	    (const_int 8)
8452	    (const_int 8))))
8453   (clobber (reg:CC FLAGS_REG))]
8454  ""
8455  "and{b}\t{%h2, %h0|%h0, %h2}"
8456  [(set_attr "type" "alu")
8457   (set_attr "length_immediate" "0")
8458   (set_attr "mode" "QI")])
8459
8460;; Convert wide AND instructions with immediate operand to shorter QImode
8461;; equivalents when possible.
8462;; Don't do the splitting with memory operands, since it introduces risk
8463;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8464;; for size, but that can (should?) be handled by generic code instead.
8465(define_split
8466  [(set (match_operand 0 "register_operand" "")
8467	(and (match_operand 1 "register_operand" "")
8468	     (match_operand 2 "const_int_operand" "")))
8469   (clobber (reg:CC FLAGS_REG))]
8470   "reload_completed
8471    && QI_REG_P (operands[0])
8472    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8473    && !(~INTVAL (operands[2]) & ~(255 << 8))
8474    && GET_MODE (operands[0]) != QImode"
8475  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8476		   (and:SI (zero_extract:SI (match_dup 1)
8477					    (const_int 8) (const_int 8))
8478			   (match_dup 2)))
8479	      (clobber (reg:CC FLAGS_REG))])]
8480  "operands[0] = gen_lowpart (SImode, operands[0]);
8481   operands[1] = gen_lowpart (SImode, operands[1]);
8482   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8483
8484;; Since AND can be encoded with sign extended immediate, this is only
8485;; profitable when 7th bit is not set.
8486(define_split
8487  [(set (match_operand 0 "register_operand" "")
8488	(and (match_operand 1 "general_operand" "")
8489	     (match_operand 2 "const_int_operand" "")))
8490   (clobber (reg:CC FLAGS_REG))]
8491   "reload_completed
8492    && ANY_QI_REG_P (operands[0])
8493    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8494    && !(~INTVAL (operands[2]) & ~255)
8495    && !(INTVAL (operands[2]) & 128)
8496    && GET_MODE (operands[0]) != QImode"
8497  [(parallel [(set (strict_low_part (match_dup 0))
8498		   (and:QI (match_dup 1)
8499			   (match_dup 2)))
8500	      (clobber (reg:CC FLAGS_REG))])]
8501  "operands[0] = gen_lowpart (QImode, operands[0]);
8502   operands[1] = gen_lowpart (QImode, operands[1]);
8503   operands[2] = gen_lowpart (QImode, operands[2]);")
8504
8505;; Logical inclusive OR instructions
8506
8507;; %%% This used to optimize known byte-wide and operations to memory.
8508;; If this is considered useful, it should be done with splitters.
8509
8510(define_expand "iordi3"
8511  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8512	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8513		(match_operand:DI 2 "x86_64_general_operand" "")))
8514   (clobber (reg:CC FLAGS_REG))]
8515  "TARGET_64BIT"
8516  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8517
8518(define_insn "*iordi_1_rex64"
8519  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8520	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8521		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8522   (clobber (reg:CC FLAGS_REG))]
8523  "TARGET_64BIT
8524   && ix86_binary_operator_ok (IOR, DImode, operands)"
8525  "or{q}\t{%2, %0|%0, %2}"
8526  [(set_attr "type" "alu")
8527   (set_attr "mode" "DI")])
8528
8529(define_insn "*iordi_2_rex64"
8530  [(set (reg FLAGS_REG)
8531	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8532			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8533		 (const_int 0)))
8534   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8535	(ior:DI (match_dup 1) (match_dup 2)))]
8536  "TARGET_64BIT
8537   && ix86_match_ccmode (insn, CCNOmode)
8538   && ix86_binary_operator_ok (IOR, DImode, operands)"
8539  "or{q}\t{%2, %0|%0, %2}"
8540  [(set_attr "type" "alu")
8541   (set_attr "mode" "DI")])
8542
8543(define_insn "*iordi_3_rex64"
8544  [(set (reg FLAGS_REG)
8545	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8546			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8547		 (const_int 0)))
8548   (clobber (match_scratch:DI 0 "=r"))]
8549  "TARGET_64BIT
8550   && ix86_match_ccmode (insn, CCNOmode)
8551   && ix86_binary_operator_ok (IOR, DImode, operands)"
8552  "or{q}\t{%2, %0|%0, %2}"
8553  [(set_attr "type" "alu")
8554   (set_attr "mode" "DI")])
8555
8556
8557(define_expand "iorsi3"
8558  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8559	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8560		(match_operand:SI 2 "general_operand" "")))
8561   (clobber (reg:CC FLAGS_REG))]
8562  ""
8563  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8564
8565(define_insn "*iorsi_1"
8566  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8567	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8568		(match_operand:SI 2 "general_operand" "ri,rmi")))
8569   (clobber (reg:CC FLAGS_REG))]
8570  "ix86_binary_operator_ok (IOR, SImode, operands)"
8571  "or{l}\t{%2, %0|%0, %2}"
8572  [(set_attr "type" "alu")
8573   (set_attr "mode" "SI")])
8574
8575;; See comment for addsi_1_zext why we do use nonimmediate_operand
8576(define_insn "*iorsi_1_zext"
8577  [(set (match_operand:DI 0 "register_operand" "=rm")
8578	(zero_extend:DI
8579	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8580		  (match_operand:SI 2 "general_operand" "rim"))))
8581   (clobber (reg:CC FLAGS_REG))]
8582  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8583  "or{l}\t{%2, %k0|%k0, %2}"
8584  [(set_attr "type" "alu")
8585   (set_attr "mode" "SI")])
8586
8587(define_insn "*iorsi_1_zext_imm"
8588  [(set (match_operand:DI 0 "register_operand" "=rm")
8589	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8590		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8591   (clobber (reg:CC FLAGS_REG))]
8592  "TARGET_64BIT"
8593  "or{l}\t{%2, %k0|%k0, %2}"
8594  [(set_attr "type" "alu")
8595   (set_attr "mode" "SI")])
8596
8597(define_insn "*iorsi_2"
8598  [(set (reg FLAGS_REG)
8599	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8600			 (match_operand:SI 2 "general_operand" "rim,ri"))
8601		 (const_int 0)))
8602   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8603	(ior:SI (match_dup 1) (match_dup 2)))]
8604  "ix86_match_ccmode (insn, CCNOmode)
8605   && ix86_binary_operator_ok (IOR, SImode, operands)"
8606  "or{l}\t{%2, %0|%0, %2}"
8607  [(set_attr "type" "alu")
8608   (set_attr "mode" "SI")])
8609
8610;; See comment for addsi_1_zext why we do use nonimmediate_operand
8611;; ??? Special case for immediate operand is missing - it is tricky.
8612(define_insn "*iorsi_2_zext"
8613  [(set (reg FLAGS_REG)
8614	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8615			 (match_operand:SI 2 "general_operand" "rim"))
8616		 (const_int 0)))
8617   (set (match_operand:DI 0 "register_operand" "=r")
8618	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8619  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8620   && ix86_binary_operator_ok (IOR, SImode, operands)"
8621  "or{l}\t{%2, %k0|%k0, %2}"
8622  [(set_attr "type" "alu")
8623   (set_attr "mode" "SI")])
8624
8625(define_insn "*iorsi_2_zext_imm"
8626  [(set (reg FLAGS_REG)
8627	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8628			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8629		 (const_int 0)))
8630   (set (match_operand:DI 0 "register_operand" "=r")
8631	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8632  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8633   && ix86_binary_operator_ok (IOR, SImode, operands)"
8634  "or{l}\t{%2, %k0|%k0, %2}"
8635  [(set_attr "type" "alu")
8636   (set_attr "mode" "SI")])
8637
8638(define_insn "*iorsi_3"
8639  [(set (reg FLAGS_REG)
8640	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8641			 (match_operand:SI 2 "general_operand" "rim"))
8642		 (const_int 0)))
8643   (clobber (match_scratch:SI 0 "=r"))]
8644  "ix86_match_ccmode (insn, CCNOmode)
8645   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8646  "or{l}\t{%2, %0|%0, %2}"
8647  [(set_attr "type" "alu")
8648   (set_attr "mode" "SI")])
8649
8650(define_expand "iorhi3"
8651  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8652	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8653		(match_operand:HI 2 "general_operand" "")))
8654   (clobber (reg:CC FLAGS_REG))]
8655  "TARGET_HIMODE_MATH"
8656  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8657
8658(define_insn "*iorhi_1"
8659  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8660	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8661		(match_operand:HI 2 "general_operand" "rmi,ri")))
8662   (clobber (reg:CC FLAGS_REG))]
8663  "ix86_binary_operator_ok (IOR, HImode, operands)"
8664  "or{w}\t{%2, %0|%0, %2}"
8665  [(set_attr "type" "alu")
8666   (set_attr "mode" "HI")])
8667
8668(define_insn "*iorhi_2"
8669  [(set (reg FLAGS_REG)
8670	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8671			 (match_operand:HI 2 "general_operand" "rim,ri"))
8672		 (const_int 0)))
8673   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8674	(ior:HI (match_dup 1) (match_dup 2)))]
8675  "ix86_match_ccmode (insn, CCNOmode)
8676   && ix86_binary_operator_ok (IOR, HImode, operands)"
8677  "or{w}\t{%2, %0|%0, %2}"
8678  [(set_attr "type" "alu")
8679   (set_attr "mode" "HI")])
8680
8681(define_insn "*iorhi_3"
8682  [(set (reg FLAGS_REG)
8683	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8684			 (match_operand:HI 2 "general_operand" "rim"))
8685		 (const_int 0)))
8686   (clobber (match_scratch:HI 0 "=r"))]
8687  "ix86_match_ccmode (insn, CCNOmode)
8688   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8689  "or{w}\t{%2, %0|%0, %2}"
8690  [(set_attr "type" "alu")
8691   (set_attr "mode" "HI")])
8692
8693(define_expand "iorqi3"
8694  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8695	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8696		(match_operand:QI 2 "general_operand" "")))
8697   (clobber (reg:CC FLAGS_REG))]
8698  "TARGET_QIMODE_MATH"
8699  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8700
8701;; %%% Potential partial reg stall on alternative 2.  What to do?
8702(define_insn "*iorqi_1"
8703  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8704	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8705		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8706   (clobber (reg:CC FLAGS_REG))]
8707  "ix86_binary_operator_ok (IOR, QImode, operands)"
8708  "@
8709   or{b}\t{%2, %0|%0, %2}
8710   or{b}\t{%2, %0|%0, %2}
8711   or{l}\t{%k2, %k0|%k0, %k2}"
8712  [(set_attr "type" "alu")
8713   (set_attr "mode" "QI,QI,SI")])
8714
8715(define_insn "*iorqi_1_slp"
8716  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8717	(ior:QI (match_dup 0)
8718		(match_operand:QI 1 "general_operand" "qmi,qi")))
8719   (clobber (reg:CC FLAGS_REG))]
8720  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8721   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8722  "or{b}\t{%1, %0|%0, %1}"
8723  [(set_attr "type" "alu1")
8724   (set_attr "mode" "QI")])
8725
8726(define_insn "*iorqi_2"
8727  [(set (reg FLAGS_REG)
8728	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8729			 (match_operand:QI 2 "general_operand" "qim,qi"))
8730		 (const_int 0)))
8731   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8732	(ior:QI (match_dup 1) (match_dup 2)))]
8733  "ix86_match_ccmode (insn, CCNOmode)
8734   && ix86_binary_operator_ok (IOR, QImode, operands)"
8735  "or{b}\t{%2, %0|%0, %2}"
8736  [(set_attr "type" "alu")
8737   (set_attr "mode" "QI")])
8738
8739(define_insn "*iorqi_2_slp"
8740  [(set (reg FLAGS_REG)
8741	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8742			 (match_operand:QI 1 "general_operand" "qim,qi"))
8743		 (const_int 0)))
8744   (set (strict_low_part (match_dup 0))
8745	(ior:QI (match_dup 0) (match_dup 1)))]
8746  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8747   && ix86_match_ccmode (insn, CCNOmode)
8748   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8749  "or{b}\t{%1, %0|%0, %1}"
8750  [(set_attr "type" "alu1")
8751   (set_attr "mode" "QI")])
8752
8753(define_insn "*iorqi_3"
8754  [(set (reg FLAGS_REG)
8755	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8756			 (match_operand:QI 2 "general_operand" "qim"))
8757		 (const_int 0)))
8758   (clobber (match_scratch:QI 0 "=q"))]
8759  "ix86_match_ccmode (insn, CCNOmode)
8760   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8761  "or{b}\t{%2, %0|%0, %2}"
8762  [(set_attr "type" "alu")
8763   (set_attr "mode" "QI")])
8764
8765(define_insn "iorqi_ext_0"
8766  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767			 (const_int 8)
8768			 (const_int 8))
8769	(ior:SI 
8770	  (zero_extract:SI
8771	    (match_operand 1 "ext_register_operand" "0")
8772	    (const_int 8)
8773	    (const_int 8))
8774	  (match_operand 2 "const_int_operand" "n")))
8775   (clobber (reg:CC FLAGS_REG))]
8776  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8777  "or{b}\t{%2, %h0|%h0, %2}"
8778  [(set_attr "type" "alu")
8779   (set_attr "length_immediate" "1")
8780   (set_attr "mode" "QI")])
8781
8782(define_insn "*iorqi_ext_1"
8783  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8784			 (const_int 8)
8785			 (const_int 8))
8786	(ior:SI 
8787	  (zero_extract:SI
8788	    (match_operand 1 "ext_register_operand" "0")
8789	    (const_int 8)
8790	    (const_int 8))
8791	  (zero_extend:SI
8792	    (match_operand:QI 2 "general_operand" "Qm"))))
8793   (clobber (reg:CC FLAGS_REG))]
8794  "!TARGET_64BIT
8795   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8796  "or{b}\t{%2, %h0|%h0, %2}"
8797  [(set_attr "type" "alu")
8798   (set_attr "length_immediate" "0")
8799   (set_attr "mode" "QI")])
8800
8801(define_insn "*iorqi_ext_1_rex64"
8802  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803			 (const_int 8)
8804			 (const_int 8))
8805	(ior:SI 
8806	  (zero_extract:SI
8807	    (match_operand 1 "ext_register_operand" "0")
8808	    (const_int 8)
8809	    (const_int 8))
8810	  (zero_extend:SI
8811	    (match_operand 2 "ext_register_operand" "Q"))))
8812   (clobber (reg:CC FLAGS_REG))]
8813  "TARGET_64BIT
8814   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8815  "or{b}\t{%2, %h0|%h0, %2}"
8816  [(set_attr "type" "alu")
8817   (set_attr "length_immediate" "0")
8818   (set_attr "mode" "QI")])
8819
8820(define_insn "*iorqi_ext_2"
8821  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8822			 (const_int 8)
8823			 (const_int 8))
8824	(ior:SI 
8825	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8826	  		   (const_int 8)
8827			   (const_int 8))
8828	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8829	  		   (const_int 8)
8830			   (const_int 8))))
8831   (clobber (reg:CC FLAGS_REG))]
8832  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8833  "ior{b}\t{%h2, %h0|%h0, %h2}"
8834  [(set_attr "type" "alu")
8835   (set_attr "length_immediate" "0")
8836   (set_attr "mode" "QI")])
8837
8838(define_split
8839  [(set (match_operand 0 "register_operand" "")
8840	(ior (match_operand 1 "register_operand" "")
8841	     (match_operand 2 "const_int_operand" "")))
8842   (clobber (reg:CC FLAGS_REG))]
8843   "reload_completed
8844    && QI_REG_P (operands[0])
8845    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8846    && !(INTVAL (operands[2]) & ~(255 << 8))
8847    && GET_MODE (operands[0]) != QImode"
8848  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8849		   (ior:SI (zero_extract:SI (match_dup 1)
8850					    (const_int 8) (const_int 8))
8851			   (match_dup 2)))
8852	      (clobber (reg:CC FLAGS_REG))])]
8853  "operands[0] = gen_lowpart (SImode, operands[0]);
8854   operands[1] = gen_lowpart (SImode, operands[1]);
8855   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8856
8857;; Since OR can be encoded with sign extended immediate, this is only
8858;; profitable when 7th bit is set.
8859(define_split
8860  [(set (match_operand 0 "register_operand" "")
8861	(ior (match_operand 1 "general_operand" "")
8862	     (match_operand 2 "const_int_operand" "")))
8863   (clobber (reg:CC FLAGS_REG))]
8864   "reload_completed
8865    && ANY_QI_REG_P (operands[0])
8866    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8867    && !(INTVAL (operands[2]) & ~255)
8868    && (INTVAL (operands[2]) & 128)
8869    && GET_MODE (operands[0]) != QImode"
8870  [(parallel [(set (strict_low_part (match_dup 0))
8871		   (ior:QI (match_dup 1)
8872			   (match_dup 2)))
8873	      (clobber (reg:CC FLAGS_REG))])]
8874  "operands[0] = gen_lowpart (QImode, operands[0]);
8875   operands[1] = gen_lowpart (QImode, operands[1]);
8876   operands[2] = gen_lowpart (QImode, operands[2]);")
8877
8878;; Logical XOR instructions
8879
8880;; %%% This used to optimize known byte-wide and operations to memory.
8881;; If this is considered useful, it should be done with splitters.
8882
8883(define_expand "xordi3"
8884  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8885	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8886		(match_operand:DI 2 "x86_64_general_operand" "")))
8887   (clobber (reg:CC FLAGS_REG))]
8888  "TARGET_64BIT"
8889  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8890
8891(define_insn "*xordi_1_rex64"
8892  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8893	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8894		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8895   (clobber (reg:CC FLAGS_REG))]
8896  "TARGET_64BIT
8897   && ix86_binary_operator_ok (XOR, DImode, operands)"
8898  "@
8899   xor{q}\t{%2, %0|%0, %2}
8900   xor{q}\t{%2, %0|%0, %2}"
8901  [(set_attr "type" "alu")
8902   (set_attr "mode" "DI,DI")])
8903
8904(define_insn "*xordi_2_rex64"
8905  [(set (reg FLAGS_REG)
8906	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8907			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8908		 (const_int 0)))
8909   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8910	(xor:DI (match_dup 1) (match_dup 2)))]
8911  "TARGET_64BIT
8912   && ix86_match_ccmode (insn, CCNOmode)
8913   && ix86_binary_operator_ok (XOR, DImode, operands)"
8914  "@
8915   xor{q}\t{%2, %0|%0, %2}
8916   xor{q}\t{%2, %0|%0, %2}"
8917  [(set_attr "type" "alu")
8918   (set_attr "mode" "DI,DI")])
8919
8920(define_insn "*xordi_3_rex64"
8921  [(set (reg FLAGS_REG)
8922	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8923			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8924		 (const_int 0)))
8925   (clobber (match_scratch:DI 0 "=r"))]
8926  "TARGET_64BIT
8927   && ix86_match_ccmode (insn, CCNOmode)
8928   && ix86_binary_operator_ok (XOR, DImode, operands)"
8929  "xor{q}\t{%2, %0|%0, %2}"
8930  [(set_attr "type" "alu")
8931   (set_attr "mode" "DI")])
8932
8933(define_expand "xorsi3"
8934  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8935	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8936		(match_operand:SI 2 "general_operand" "")))
8937   (clobber (reg:CC FLAGS_REG))]
8938  ""
8939  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8940
8941(define_insn "*xorsi_1"
8942  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8943	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944		(match_operand:SI 2 "general_operand" "ri,rm")))
8945   (clobber (reg:CC FLAGS_REG))]
8946  "ix86_binary_operator_ok (XOR, SImode, operands)"
8947  "xor{l}\t{%2, %0|%0, %2}"
8948  [(set_attr "type" "alu")
8949   (set_attr "mode" "SI")])
8950
8951;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952;; Add speccase for immediates
8953(define_insn "*xorsi_1_zext"
8954  [(set (match_operand:DI 0 "register_operand" "=r")
8955	(zero_extend:DI
8956	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8957		  (match_operand:SI 2 "general_operand" "rim"))))
8958   (clobber (reg:CC FLAGS_REG))]
8959  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8960  "xor{l}\t{%2, %k0|%k0, %2}"
8961  [(set_attr "type" "alu")
8962   (set_attr "mode" "SI")])
8963
8964(define_insn "*xorsi_1_zext_imm"
8965  [(set (match_operand:DI 0 "register_operand" "=r")
8966	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8967		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8968   (clobber (reg:CC FLAGS_REG))]
8969  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8970  "xor{l}\t{%2, %k0|%k0, %2}"
8971  [(set_attr "type" "alu")
8972   (set_attr "mode" "SI")])
8973
8974(define_insn "*xorsi_2"
8975  [(set (reg FLAGS_REG)
8976	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8977			 (match_operand:SI 2 "general_operand" "rim,ri"))
8978		 (const_int 0)))
8979   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8980	(xor:SI (match_dup 1) (match_dup 2)))]
8981  "ix86_match_ccmode (insn, CCNOmode)
8982   && ix86_binary_operator_ok (XOR, SImode, operands)"
8983  "xor{l}\t{%2, %0|%0, %2}"
8984  [(set_attr "type" "alu")
8985   (set_attr "mode" "SI")])
8986
8987;; See comment for addsi_1_zext why we do use nonimmediate_operand
8988;; ??? Special case for immediate operand is missing - it is tricky.
8989(define_insn "*xorsi_2_zext"
8990  [(set (reg FLAGS_REG)
8991	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8992			 (match_operand:SI 2 "general_operand" "rim"))
8993		 (const_int 0)))
8994   (set (match_operand:DI 0 "register_operand" "=r")
8995	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8996  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8997   && ix86_binary_operator_ok (XOR, SImode, operands)"
8998  "xor{l}\t{%2, %k0|%k0, %2}"
8999  [(set_attr "type" "alu")
9000   (set_attr "mode" "SI")])
9001
9002(define_insn "*xorsi_2_zext_imm"
9003  [(set (reg FLAGS_REG)
9004	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9005			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9006		 (const_int 0)))
9007   (set (match_operand:DI 0 "register_operand" "=r")
9008	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9009  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9010   && ix86_binary_operator_ok (XOR, SImode, operands)"
9011  "xor{l}\t{%2, %k0|%k0, %2}"
9012  [(set_attr "type" "alu")
9013   (set_attr "mode" "SI")])
9014
9015(define_insn "*xorsi_3"
9016  [(set (reg FLAGS_REG)
9017	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9018			 (match_operand:SI 2 "general_operand" "rim"))
9019		 (const_int 0)))
9020   (clobber (match_scratch:SI 0 "=r"))]
9021  "ix86_match_ccmode (insn, CCNOmode)
9022   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9023  "xor{l}\t{%2, %0|%0, %2}"
9024  [(set_attr "type" "alu")
9025   (set_attr "mode" "SI")])
9026
9027(define_expand "xorhi3"
9028  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9029	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9030		(match_operand:HI 2 "general_operand" "")))
9031   (clobber (reg:CC FLAGS_REG))]
9032  "TARGET_HIMODE_MATH"
9033  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9034
9035(define_insn "*xorhi_1"
9036  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9037	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9038		(match_operand:HI 2 "general_operand" "rmi,ri")))
9039   (clobber (reg:CC FLAGS_REG))]
9040  "ix86_binary_operator_ok (XOR, HImode, operands)"
9041  "xor{w}\t{%2, %0|%0, %2}"
9042  [(set_attr "type" "alu")
9043   (set_attr "mode" "HI")])
9044
9045(define_insn "*xorhi_2"
9046  [(set (reg FLAGS_REG)
9047	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9048			 (match_operand:HI 2 "general_operand" "rim,ri"))
9049		 (const_int 0)))
9050   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9051	(xor:HI (match_dup 1) (match_dup 2)))]
9052  "ix86_match_ccmode (insn, CCNOmode)
9053   && ix86_binary_operator_ok (XOR, HImode, operands)"
9054  "xor{w}\t{%2, %0|%0, %2}"
9055  [(set_attr "type" "alu")
9056   (set_attr "mode" "HI")])
9057
9058(define_insn "*xorhi_3"
9059  [(set (reg FLAGS_REG)
9060	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9061			 (match_operand:HI 2 "general_operand" "rim"))
9062		 (const_int 0)))
9063   (clobber (match_scratch:HI 0 "=r"))]
9064  "ix86_match_ccmode (insn, CCNOmode)
9065   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9066  "xor{w}\t{%2, %0|%0, %2}"
9067  [(set_attr "type" "alu")
9068   (set_attr "mode" "HI")])
9069
9070(define_expand "xorqi3"
9071  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9072	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9073		(match_operand:QI 2 "general_operand" "")))
9074   (clobber (reg:CC FLAGS_REG))]
9075  "TARGET_QIMODE_MATH"
9076  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9077
9078;; %%% Potential partial reg stall on alternative 2.  What to do?
9079(define_insn "*xorqi_1"
9080  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9081	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9082		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9083   (clobber (reg:CC FLAGS_REG))]
9084  "ix86_binary_operator_ok (XOR, QImode, operands)"
9085  "@
9086   xor{b}\t{%2, %0|%0, %2}
9087   xor{b}\t{%2, %0|%0, %2}
9088   xor{l}\t{%k2, %k0|%k0, %k2}"
9089  [(set_attr "type" "alu")
9090   (set_attr "mode" "QI,QI,SI")])
9091
9092(define_insn "*xorqi_1_slp"
9093  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9094	(xor:QI (match_dup 0)
9095		(match_operand:QI 1 "general_operand" "qi,qmi")))
9096   (clobber (reg:CC FLAGS_REG))]
9097  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9098   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9099  "xor{b}\t{%1, %0|%0, %1}"
9100  [(set_attr "type" "alu1")
9101   (set_attr "mode" "QI")])
9102
9103(define_insn "xorqi_ext_0"
9104  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9105			 (const_int 8)
9106			 (const_int 8))
9107	(xor:SI 
9108	  (zero_extract:SI
9109	    (match_operand 1 "ext_register_operand" "0")
9110	    (const_int 8)
9111	    (const_int 8))
9112	  (match_operand 2 "const_int_operand" "n")))
9113   (clobber (reg:CC FLAGS_REG))]
9114  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9115  "xor{b}\t{%2, %h0|%h0, %2}"
9116  [(set_attr "type" "alu")
9117   (set_attr "length_immediate" "1")
9118   (set_attr "mode" "QI")])
9119
9120(define_insn "*xorqi_ext_1"
9121  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9122			 (const_int 8)
9123			 (const_int 8))
9124	(xor:SI 
9125	  (zero_extract:SI
9126	    (match_operand 1 "ext_register_operand" "0")
9127	    (const_int 8)
9128	    (const_int 8))
9129	  (zero_extend:SI
9130	    (match_operand:QI 2 "general_operand" "Qm"))))
9131   (clobber (reg:CC FLAGS_REG))]
9132  "!TARGET_64BIT
9133   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9134  "xor{b}\t{%2, %h0|%h0, %2}"
9135  [(set_attr "type" "alu")
9136   (set_attr "length_immediate" "0")
9137   (set_attr "mode" "QI")])
9138
9139(define_insn "*xorqi_ext_1_rex64"
9140  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9141			 (const_int 8)
9142			 (const_int 8))
9143	(xor:SI 
9144	  (zero_extract:SI
9145	    (match_operand 1 "ext_register_operand" "0")
9146	    (const_int 8)
9147	    (const_int 8))
9148	  (zero_extend:SI
9149	    (match_operand 2 "ext_register_operand" "Q"))))
9150   (clobber (reg:CC FLAGS_REG))]
9151  "TARGET_64BIT
9152   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9153  "xor{b}\t{%2, %h0|%h0, %2}"
9154  [(set_attr "type" "alu")
9155   (set_attr "length_immediate" "0")
9156   (set_attr "mode" "QI")])
9157
9158(define_insn "*xorqi_ext_2"
9159  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160			 (const_int 8)
9161			 (const_int 8))
9162	(xor:SI 
9163	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9164	  		   (const_int 8)
9165			   (const_int 8))
9166	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9167	  		   (const_int 8)
9168			   (const_int 8))))
9169   (clobber (reg:CC FLAGS_REG))]
9170  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9171  "xor{b}\t{%h2, %h0|%h0, %h2}"
9172  [(set_attr "type" "alu")
9173   (set_attr "length_immediate" "0")
9174   (set_attr "mode" "QI")])
9175
9176(define_insn "*xorqi_cc_1"
9177  [(set (reg FLAGS_REG)
9178	(compare
9179	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9180		  (match_operand:QI 2 "general_operand" "qim,qi"))
9181	  (const_int 0)))
9182   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9183	(xor:QI (match_dup 1) (match_dup 2)))]
9184  "ix86_match_ccmode (insn, CCNOmode)
9185   && ix86_binary_operator_ok (XOR, QImode, operands)"
9186  "xor{b}\t{%2, %0|%0, %2}"
9187  [(set_attr "type" "alu")
9188   (set_attr "mode" "QI")])
9189
9190(define_insn "*xorqi_2_slp"
9191  [(set (reg FLAGS_REG)
9192	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9193			 (match_operand:QI 1 "general_operand" "qim,qi"))
9194		 (const_int 0)))
9195   (set (strict_low_part (match_dup 0))
9196	(xor:QI (match_dup 0) (match_dup 1)))]
9197  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9198   && ix86_match_ccmode (insn, CCNOmode)
9199   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9200  "xor{b}\t{%1, %0|%0, %1}"
9201  [(set_attr "type" "alu1")
9202   (set_attr "mode" "QI")])
9203
9204(define_insn "*xorqi_cc_2"
9205  [(set (reg FLAGS_REG)
9206	(compare
9207	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9208		  (match_operand:QI 2 "general_operand" "qim"))
9209	  (const_int 0)))
9210   (clobber (match_scratch:QI 0 "=q"))]
9211  "ix86_match_ccmode (insn, CCNOmode)
9212   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9213  "xor{b}\t{%2, %0|%0, %2}"
9214  [(set_attr "type" "alu")
9215   (set_attr "mode" "QI")])
9216
9217(define_insn "*xorqi_cc_ext_1"
9218  [(set (reg FLAGS_REG)
9219	(compare
9220	  (xor:SI
9221	    (zero_extract:SI
9222	      (match_operand 1 "ext_register_operand" "0")
9223	      (const_int 8)
9224	      (const_int 8))
9225	    (match_operand:QI 2 "general_operand" "qmn"))
9226	  (const_int 0)))
9227   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9228			 (const_int 8)
9229			 (const_int 8))
9230	(xor:SI 
9231	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9232	  (match_dup 2)))]
9233  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9234  "xor{b}\t{%2, %h0|%h0, %2}"
9235  [(set_attr "type" "alu")
9236   (set_attr "mode" "QI")])
9237
9238(define_insn "*xorqi_cc_ext_1_rex64"
9239  [(set (reg FLAGS_REG)
9240	(compare
9241	  (xor:SI
9242	    (zero_extract:SI
9243	      (match_operand 1 "ext_register_operand" "0")
9244	      (const_int 8)
9245	      (const_int 8))
9246	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9247	  (const_int 0)))
9248   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9249			 (const_int 8)
9250			 (const_int 8))
9251	(xor:SI 
9252	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9253	  (match_dup 2)))]
9254  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9255  "xor{b}\t{%2, %h0|%h0, %2}"
9256  [(set_attr "type" "alu")
9257   (set_attr "mode" "QI")])
9258
9259(define_expand "xorqi_cc_ext_1"
9260  [(parallel [
9261     (set (reg:CCNO FLAGS_REG)
9262	  (compare:CCNO
9263	    (xor:SI
9264	      (zero_extract:SI
9265		(match_operand 1 "ext_register_operand" "")
9266		(const_int 8)
9267		(const_int 8))
9268	      (match_operand:QI 2 "general_operand" ""))
9269	    (const_int 0)))
9270     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9271			   (const_int 8)
9272			   (const_int 8))
9273	  (xor:SI 
9274	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9275	    (match_dup 2)))])]
9276  ""
9277  "")
9278
9279(define_split
9280  [(set (match_operand 0 "register_operand" "")
9281	(xor (match_operand 1 "register_operand" "")
9282	     (match_operand 2 "const_int_operand" "")))
9283   (clobber (reg:CC FLAGS_REG))]
9284   "reload_completed
9285    && QI_REG_P (operands[0])
9286    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9287    && !(INTVAL (operands[2]) & ~(255 << 8))
9288    && GET_MODE (operands[0]) != QImode"
9289  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9290		   (xor:SI (zero_extract:SI (match_dup 1)
9291					    (const_int 8) (const_int 8))
9292			   (match_dup 2)))
9293	      (clobber (reg:CC FLAGS_REG))])]
9294  "operands[0] = gen_lowpart (SImode, operands[0]);
9295   operands[1] = gen_lowpart (SImode, operands[1]);
9296   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9297
9298;; Since XOR can be encoded with sign extended immediate, this is only
9299;; profitable when 7th bit is set.
9300(define_split
9301  [(set (match_operand 0 "register_operand" "")
9302	(xor (match_operand 1 "general_operand" "")
9303	     (match_operand 2 "const_int_operand" "")))
9304   (clobber (reg:CC FLAGS_REG))]
9305   "reload_completed
9306    && ANY_QI_REG_P (operands[0])
9307    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9308    && !(INTVAL (operands[2]) & ~255)
9309    && (INTVAL (operands[2]) & 128)
9310    && GET_MODE (operands[0]) != QImode"
9311  [(parallel [(set (strict_low_part (match_dup 0))
9312		   (xor:QI (match_dup 1)
9313			   (match_dup 2)))
9314	      (clobber (reg:CC FLAGS_REG))])]
9315  "operands[0] = gen_lowpart (QImode, operands[0]);
9316   operands[1] = gen_lowpart (QImode, operands[1]);
9317   operands[2] = gen_lowpart (QImode, operands[2]);")
9318
9319;; Negation instructions
9320
9321(define_expand "negti2"
9322  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9323		   (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9324	      (clobber (reg:CC FLAGS_REG))])]
9325  "TARGET_64BIT"
9326  "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9327
9328(define_insn "*negti2_1"
9329  [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9330	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9331   (clobber (reg:CC FLAGS_REG))]
9332  "TARGET_64BIT
9333   && ix86_unary_operator_ok (NEG, TImode, operands)"
9334  "#")
9335
9336(define_split
9337  [(set (match_operand:TI 0 "nonimmediate_operand" "")
9338	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9339   (clobber (reg:CC FLAGS_REG))]
9340  "TARGET_64BIT && reload_completed"
9341  [(parallel
9342    [(set (reg:CCZ FLAGS_REG)
9343	  (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9344     (set (match_dup 0) (neg:DI (match_dup 2)))])
9345   (parallel
9346    [(set (match_dup 1)
9347	  (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9348			    (match_dup 3))
9349		   (const_int 0)))
9350     (clobber (reg:CC FLAGS_REG))])
9351   (parallel
9352    [(set (match_dup 1)
9353	  (neg:DI (match_dup 1)))
9354     (clobber (reg:CC FLAGS_REG))])]
9355  "split_ti (operands+1, 1, operands+2, operands+3);
9356   split_ti (operands+0, 1, operands+0, operands+1);")
9357
9358(define_expand "negdi2"
9359  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9360		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9361	      (clobber (reg:CC FLAGS_REG))])]
9362  ""
9363  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9364
9365(define_insn "*negdi2_1"
9366  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9367	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9368   (clobber (reg:CC FLAGS_REG))]
9369  "!TARGET_64BIT
9370   && ix86_unary_operator_ok (NEG, DImode, operands)"
9371  "#")
9372
9373(define_split
9374  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9375	(neg:DI (match_operand:DI 1 "general_operand" "")))
9376   (clobber (reg:CC FLAGS_REG))]
9377  "!TARGET_64BIT && reload_completed"
9378  [(parallel
9379    [(set (reg:CCZ FLAGS_REG)
9380	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9381     (set (match_dup 0) (neg:SI (match_dup 2)))])
9382   (parallel
9383    [(set (match_dup 1)
9384	  (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9385			    (match_dup 3))
9386		   (const_int 0)))
9387     (clobber (reg:CC FLAGS_REG))])
9388   (parallel
9389    [(set (match_dup 1)
9390	  (neg:SI (match_dup 1)))
9391     (clobber (reg:CC FLAGS_REG))])]
9392  "split_di (operands+1, 1, operands+2, operands+3);
9393   split_di (operands+0, 1, operands+0, operands+1);")
9394
9395(define_insn "*negdi2_1_rex64"
9396  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9397	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9398   (clobber (reg:CC FLAGS_REG))]
9399  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9400  "neg{q}\t%0"
9401  [(set_attr "type" "negnot")
9402   (set_attr "mode" "DI")])
9403
9404;; The problem with neg is that it does not perform (compare x 0),
9405;; it really performs (compare 0 x), which leaves us with the zero
9406;; flag being the only useful item.
9407
9408(define_insn "*negdi2_cmpz_rex64"
9409  [(set (reg:CCZ FLAGS_REG)
9410	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9411		     (const_int 0)))
9412   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9413	(neg:DI (match_dup 1)))]
9414  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9415  "neg{q}\t%0"
9416  [(set_attr "type" "negnot")
9417   (set_attr "mode" "DI")])
9418
9419
9420(define_expand "negsi2"
9421  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9422		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9423	      (clobber (reg:CC FLAGS_REG))])]
9424  ""
9425  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9426
9427(define_insn "*negsi2_1"
9428  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9429	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9430   (clobber (reg:CC FLAGS_REG))]
9431  "ix86_unary_operator_ok (NEG, SImode, operands)"
9432  "neg{l}\t%0"
9433  [(set_attr "type" "negnot")
9434   (set_attr "mode" "SI")])
9435
9436;; Combine is quite creative about this pattern.
9437(define_insn "*negsi2_1_zext"
9438  [(set (match_operand:DI 0 "register_operand" "=r")
9439	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9440					(const_int 32)))
9441		     (const_int 32)))
9442   (clobber (reg:CC FLAGS_REG))]
9443  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9444  "neg{l}\t%k0"
9445  [(set_attr "type" "negnot")
9446   (set_attr "mode" "SI")])
9447
9448;; The problem with neg is that it does not perform (compare x 0),
9449;; it really performs (compare 0 x), which leaves us with the zero
9450;; flag being the only useful item.
9451
9452(define_insn "*negsi2_cmpz"
9453  [(set (reg:CCZ FLAGS_REG)
9454	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9455		     (const_int 0)))
9456   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9457	(neg:SI (match_dup 1)))]
9458  "ix86_unary_operator_ok (NEG, SImode, operands)"
9459  "neg{l}\t%0"
9460  [(set_attr "type" "negnot")
9461   (set_attr "mode" "SI")])
9462
9463(define_insn "*negsi2_cmpz_zext"
9464  [(set (reg:CCZ FLAGS_REG)
9465	(compare:CCZ (lshiftrt:DI
9466		       (neg:DI (ashift:DI
9467				 (match_operand:DI 1 "register_operand" "0")
9468				 (const_int 32)))
9469		       (const_int 32))
9470		     (const_int 0)))
9471   (set (match_operand:DI 0 "register_operand" "=r")
9472	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9473					(const_int 32)))
9474		     (const_int 32)))]
9475  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9476  "neg{l}\t%k0"
9477  [(set_attr "type" "negnot")
9478   (set_attr "mode" "SI")])
9479
9480(define_expand "neghi2"
9481  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9482		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9483	      (clobber (reg:CC FLAGS_REG))])]
9484  "TARGET_HIMODE_MATH"
9485  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9486
9487(define_insn "*neghi2_1"
9488  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9489	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9490   (clobber (reg:CC FLAGS_REG))]
9491  "ix86_unary_operator_ok (NEG, HImode, operands)"
9492  "neg{w}\t%0"
9493  [(set_attr "type" "negnot")
9494   (set_attr "mode" "HI")])
9495
9496(define_insn "*neghi2_cmpz"
9497  [(set (reg:CCZ FLAGS_REG)
9498	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9499		     (const_int 0)))
9500   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9501	(neg:HI (match_dup 1)))]
9502  "ix86_unary_operator_ok (NEG, HImode, operands)"
9503  "neg{w}\t%0"
9504  [(set_attr "type" "negnot")
9505   (set_attr "mode" "HI")])
9506
9507(define_expand "negqi2"
9508  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9509		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9510	      (clobber (reg:CC FLAGS_REG))])]
9511  "TARGET_QIMODE_MATH"
9512  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9513
9514(define_insn "*negqi2_1"
9515  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9516	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9517   (clobber (reg:CC FLAGS_REG))]
9518  "ix86_unary_operator_ok (NEG, QImode, operands)"
9519  "neg{b}\t%0"
9520  [(set_attr "type" "negnot")
9521   (set_attr "mode" "QI")])
9522
9523(define_insn "*negqi2_cmpz"
9524  [(set (reg:CCZ FLAGS_REG)
9525	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9526		     (const_int 0)))
9527   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9528	(neg:QI (match_dup 1)))]
9529  "ix86_unary_operator_ok (NEG, QImode, operands)"
9530  "neg{b}\t%0"
9531  [(set_attr "type" "negnot")
9532   (set_attr "mode" "QI")])
9533
9534;; Changing of sign for FP values is doable using integer unit too.
9535
9536(define_expand "negsf2"
9537  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9538	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9539  "TARGET_80387 || TARGET_SSE_MATH"
9540  "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9541
9542(define_expand "abssf2"
9543  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9544	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9545  "TARGET_80387 || TARGET_SSE_MATH"
9546  "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9547
9548(define_insn "*absnegsf2_mixed"
9549  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9550	(match_operator:SF 3 "absneg_operator"
9551	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9552   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9553   (clobber (reg:CC FLAGS_REG))]
9554  "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9555   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9556  "#")
9557
9558(define_insn "*absnegsf2_sse"
9559  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9560	(match_operator:SF 3 "absneg_operator"
9561	  [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9562   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9563   (clobber (reg:CC FLAGS_REG))]
9564  "TARGET_SSE_MATH
9565   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9566  "#")
9567
9568(define_insn "*absnegsf2_i387"
9569  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9570	(match_operator:SF 3 "absneg_operator"
9571	  [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9572   (use (match_operand 2 "" ""))
9573   (clobber (reg:CC FLAGS_REG))]
9574  "TARGET_80387 && !TARGET_SSE_MATH
9575   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9576  "#")
9577
9578(define_expand "copysignsf3"
9579  [(match_operand:SF 0 "register_operand" "")
9580   (match_operand:SF 1 "nonmemory_operand" "")
9581   (match_operand:SF 2 "register_operand" "")]
9582  "TARGET_SSE_MATH"
9583{
9584  ix86_expand_copysign (operands);
9585  DONE;
9586})
9587
9588(define_insn_and_split "copysignsf3_const"
9589  [(set (match_operand:SF 0 "register_operand"          "=x")
9590	(unspec:SF
9591	  [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9592	   (match_operand:SF 2 "register_operand"       "0")
9593	   (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9594	  UNSPEC_COPYSIGN))]
9595  "TARGET_SSE_MATH"
9596  "#"
9597  "&& reload_completed"
9598  [(const_int 0)]
9599{
9600  ix86_split_copysign_const (operands);
9601  DONE;
9602})
9603
9604(define_insn "copysignsf3_var"
9605  [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9606	(unspec:SF
9607	  [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9608	   (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9609	   (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9610	   (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9611	  UNSPEC_COPYSIGN))
9612   (clobber (match_scratch:V4SF 1			"=x, x, x, x,x"))]
9613  "TARGET_SSE_MATH"
9614  "#")
9615
9616(define_split
9617  [(set (match_operand:SF 0 "register_operand" "")
9618	(unspec:SF
9619	  [(match_operand:SF 2 "register_operand" "")
9620	   (match_operand:SF 3 "register_operand" "")
9621	   (match_operand:V4SF 4 "" "")
9622	   (match_operand:V4SF 5 "" "")]
9623	  UNSPEC_COPYSIGN))
9624   (clobber (match_scratch:V4SF 1 ""))]
9625  "TARGET_SSE_MATH && reload_completed"
9626  [(const_int 0)]
9627{
9628  ix86_split_copysign_var (operands);
9629  DONE;
9630})
9631
9632(define_expand "negdf2"
9633  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9634	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9635  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9636  "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9637
9638(define_expand "absdf2"
9639  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9640	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9641  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9642  "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9643
9644(define_insn "*absnegdf2_mixed"
9645  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9646	(match_operator:DF 3 "absneg_operator"
9647	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9648   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9649   (clobber (reg:CC FLAGS_REG))]
9650  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9651   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9652  "#")
9653
9654(define_insn "*absnegdf2_sse"
9655  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9656	(match_operator:DF 3 "absneg_operator"
9657	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9658   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9659   (clobber (reg:CC FLAGS_REG))]
9660  "TARGET_SSE2 && TARGET_SSE_MATH
9661   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9662  "#")
9663
9664(define_insn "*absnegdf2_i387"
9665  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9666	(match_operator:DF 3 "absneg_operator"
9667	  [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9668   (use (match_operand 2 "" ""))
9669   (clobber (reg:CC FLAGS_REG))]
9670  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9671   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9672  "#")
9673
9674(define_expand "copysigndf3"
9675  [(match_operand:DF 0 "register_operand" "")
9676   (match_operand:DF 1 "nonmemory_operand" "")
9677   (match_operand:DF 2 "register_operand" "")]
9678  "TARGET_SSE2 && TARGET_SSE_MATH"
9679{
9680  ix86_expand_copysign (operands);
9681  DONE;
9682})
9683
9684(define_insn_and_split "copysigndf3_const"
9685  [(set (match_operand:DF 0 "register_operand"          "=x")
9686	(unspec:DF
9687	  [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9688	   (match_operand:DF 2 "register_operand"       "0")
9689	   (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9690	  UNSPEC_COPYSIGN))]
9691  "TARGET_SSE2 && TARGET_SSE_MATH"
9692  "#"
9693  "&& reload_completed"
9694  [(const_int 0)]
9695{
9696  ix86_split_copysign_const (operands);
9697  DONE;
9698})
9699
9700(define_insn "copysigndf3_var"
9701  [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9702	(unspec:DF
9703	  [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9704	   (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9705	   (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9706	   (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9707	  UNSPEC_COPYSIGN))
9708   (clobber (match_scratch:V2DF 1			"=x, x, x, x,x"))]
9709  "TARGET_SSE2 && TARGET_SSE_MATH"
9710  "#")
9711
9712(define_split
9713  [(set (match_operand:DF 0 "register_operand" "")
9714	(unspec:DF
9715	  [(match_operand:DF 2 "register_operand" "")
9716	   (match_operand:DF 3 "register_operand" "")
9717	   (match_operand:V2DF 4 "" "")
9718	   (match_operand:V2DF 5 "" "")]
9719	  UNSPEC_COPYSIGN))
9720   (clobber (match_scratch:V2DF 1 ""))]
9721  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9722  [(const_int 0)]
9723{
9724  ix86_split_copysign_var (operands);
9725  DONE;
9726})
9727
9728(define_expand "negxf2"
9729  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9730	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9731  "TARGET_80387"
9732  "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9733
9734(define_expand "absxf2"
9735  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9736	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9737  "TARGET_80387"
9738  "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9739
9740(define_insn "*absnegxf2_i387"
9741  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9742	(match_operator:XF 3 "absneg_operator"
9743	  [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9744   (use (match_operand 2 "" ""))
9745   (clobber (reg:CC FLAGS_REG))]
9746  "TARGET_80387
9747   && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9748  "#")
9749
9750;; Splitters for fp abs and neg.
9751
9752(define_split
9753  [(set (match_operand 0 "fp_register_operand" "")
9754	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9755   (use (match_operand 2 "" ""))
9756   (clobber (reg:CC FLAGS_REG))]
9757  "reload_completed"
9758  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9759
9760(define_split
9761  [(set (match_operand 0 "register_operand" "")
9762	(match_operator 3 "absneg_operator"
9763	  [(match_operand 1 "register_operand" "")]))
9764   (use (match_operand 2 "nonimmediate_operand" ""))
9765   (clobber (reg:CC FLAGS_REG))]
9766  "reload_completed && SSE_REG_P (operands[0])"
9767  [(set (match_dup 0) (match_dup 3))]
9768{
9769  enum machine_mode mode = GET_MODE (operands[0]);
9770  enum machine_mode vmode = GET_MODE (operands[2]);
9771  rtx tmp;
9772  
9773  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9774  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9775  if (operands_match_p (operands[0], operands[2]))
9776    {
9777      tmp = operands[1];
9778      operands[1] = operands[2];
9779      operands[2] = tmp;
9780    }
9781  if (GET_CODE (operands[3]) == ABS)
9782    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9783  else
9784    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9785  operands[3] = tmp;
9786})
9787
9788(define_split
9789  [(set (match_operand:SF 0 "register_operand" "")
9790	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9791   (use (match_operand:V4SF 2 "" ""))
9792   (clobber (reg:CC FLAGS_REG))]
9793  "reload_completed"
9794  [(parallel [(set (match_dup 0) (match_dup 1))
9795	      (clobber (reg:CC FLAGS_REG))])]
9796{ 
9797  rtx tmp;
9798  operands[0] = gen_lowpart (SImode, operands[0]);
9799  if (GET_CODE (operands[1]) == ABS)
9800    {
9801      tmp = gen_int_mode (0x7fffffff, SImode);
9802      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9803    }
9804  else
9805    {
9806      tmp = gen_int_mode (0x80000000, SImode);
9807      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9808    }
9809  operands[1] = tmp;
9810})
9811
9812(define_split
9813  [(set (match_operand:DF 0 "register_operand" "")
9814	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9815   (use (match_operand 2 "" ""))
9816   (clobber (reg:CC FLAGS_REG))]
9817  "reload_completed"
9818  [(parallel [(set (match_dup 0) (match_dup 1))
9819	      (clobber (reg:CC FLAGS_REG))])]
9820{
9821  rtx tmp;
9822  if (TARGET_64BIT)
9823    {
9824      tmp = gen_lowpart (DImode, operands[0]);
9825      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9826      operands[0] = tmp;
9827
9828      if (GET_CODE (operands[1]) == ABS)
9829	tmp = const0_rtx;
9830      else
9831	tmp = gen_rtx_NOT (DImode, tmp);
9832    }
9833  else
9834    {
9835      operands[0] = gen_highpart (SImode, operands[0]);
9836      if (GET_CODE (operands[1]) == ABS)
9837	{
9838	  tmp = gen_int_mode (0x7fffffff, SImode);
9839	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
9840	}
9841      else
9842	{
9843	  tmp = gen_int_mode (0x80000000, SImode);
9844	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9845	}
9846    }
9847  operands[1] = tmp;
9848})
9849
9850(define_split
9851  [(set (match_operand:XF 0 "register_operand" "")
9852	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9853   (use (match_operand 2 "" ""))
9854   (clobber (reg:CC FLAGS_REG))]
9855  "reload_completed"
9856  [(parallel [(set (match_dup 0) (match_dup 1))
9857	      (clobber (reg:CC FLAGS_REG))])]
9858{
9859  rtx tmp;
9860  operands[0] = gen_rtx_REG (SImode,
9861			     true_regnum (operands[0])
9862			     + (TARGET_64BIT ? 1 : 2));
9863  if (GET_CODE (operands[1]) == ABS)
9864    {
9865      tmp = GEN_INT (0x7fff);
9866      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9867    }
9868  else
9869    {
9870      tmp = GEN_INT (0x8000);
9871      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9872    }
9873  operands[1] = tmp;
9874})
9875
9876(define_split
9877  [(set (match_operand 0 "memory_operand" "")
9878	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9879   (use (match_operand 2 "" ""))
9880   (clobber (reg:CC FLAGS_REG))]
9881  "reload_completed"
9882  [(parallel [(set (match_dup 0) (match_dup 1))
9883	      (clobber (reg:CC FLAGS_REG))])]
9884{
9885  enum machine_mode mode = GET_MODE (operands[0]);
9886  int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9887  rtx tmp;
9888
9889  operands[0] = adjust_address (operands[0], QImode, size - 1);
9890  if (GET_CODE (operands[1]) == ABS)
9891    {
9892      tmp = gen_int_mode (0x7f, QImode);
9893      tmp = gen_rtx_AND (QImode, operands[0], tmp);
9894    }
9895  else
9896    {
9897      tmp = gen_int_mode (0x80, QImode);
9898      tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9899    }
9900  operands[1] = tmp;
9901})
9902
9903;; Conditionalize these after reload. If they match before reload, we 
9904;; lose the clobber and ability to use integer instructions.
9905
9906(define_insn "*negsf2_1"
9907  [(set (match_operand:SF 0 "register_operand" "=f")
9908	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
9909  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9910  "fchs"
9911  [(set_attr "type" "fsgn")
9912   (set_attr "mode" "SF")])
9913
9914(define_insn "*negdf2_1"
9915  [(set (match_operand:DF 0 "register_operand" "=f")
9916	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
9917  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9918  "fchs"
9919  [(set_attr "type" "fsgn")
9920   (set_attr "mode" "DF")])
9921
9922(define_insn "*negxf2_1"
9923  [(set (match_operand:XF 0 "register_operand" "=f")
9924	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
9925  "TARGET_80387"
9926  "fchs"
9927  [(set_attr "type" "fsgn")
9928   (set_attr "mode" "XF")])
9929
9930(define_insn "*abssf2_1"
9931  [(set (match_operand:SF 0 "register_operand" "=f")
9932	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
9933  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9934  "fabs"
9935  [(set_attr "type" "fsgn")
9936   (set_attr "mode" "SF")])
9937
9938(define_insn "*absdf2_1"
9939  [(set (match_operand:DF 0 "register_operand" "=f")
9940	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
9941  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9942  "fabs"
9943  [(set_attr "type" "fsgn")
9944   (set_attr "mode" "DF")])
9945
9946(define_insn "*absxf2_1"
9947  [(set (match_operand:XF 0 "register_operand" "=f")
9948	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
9949  "TARGET_80387"
9950  "fabs"
9951  [(set_attr "type" "fsgn")
9952   (set_attr "mode" "DF")])
9953
9954(define_insn "*negextendsfdf2"
9955  [(set (match_operand:DF 0 "register_operand" "=f")
9956	(neg:DF (float_extend:DF
9957		  (match_operand:SF 1 "register_operand" "0"))))]
9958  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9959  "fchs"
9960  [(set_attr "type" "fsgn")
9961   (set_attr "mode" "DF")])
9962
9963(define_insn "*negextenddfxf2"
9964  [(set (match_operand:XF 0 "register_operand" "=f")
9965	(neg:XF (float_extend:XF
9966		  (match_operand:DF 1 "register_operand" "0"))))]
9967  "TARGET_80387"
9968  "fchs"
9969  [(set_attr "type" "fsgn")
9970   (set_attr "mode" "XF")])
9971
9972(define_insn "*negextendsfxf2"
9973  [(set (match_operand:XF 0 "register_operand" "=f")
9974	(neg:XF (float_extend:XF
9975		  (match_operand:SF 1 "register_operand" "0"))))]
9976  "TARGET_80387"
9977  "fchs"
9978  [(set_attr "type" "fsgn")
9979   (set_attr "mode" "XF")])
9980
9981(define_insn "*absextendsfdf2"
9982  [(set (match_operand:DF 0 "register_operand" "=f")
9983	(abs:DF (float_extend:DF
9984		  (match_operand:SF 1 "register_operand" "0"))))]
9985  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9986  "fabs"
9987  [(set_attr "type" "fsgn")
9988   (set_attr "mode" "DF")])
9989
9990(define_insn "*absextenddfxf2"
9991  [(set (match_operand:XF 0 "register_operand" "=f")
9992	(abs:XF (float_extend:XF
9993	  (match_operand:DF 1 "register_operand" "0"))))]
9994  "TARGET_80387"
9995  "fabs"
9996  [(set_attr "type" "fsgn")
9997   (set_attr "mode" "XF")])
9998
9999(define_insn "*absextendsfxf2"
10000  [(set (match_operand:XF 0 "register_operand" "=f")
10001	(abs:XF (float_extend:XF
10002	  (match_operand:SF 1 "register_operand" "0"))))]
10003  "TARGET_80387"
10004  "fabs"
10005  [(set_attr "type" "fsgn")
10006   (set_attr "mode" "XF")])
10007
10008;; One complement instructions
10009
10010(define_expand "one_cmpldi2"
10011  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10012	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10013  "TARGET_64BIT"
10014  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10015
10016(define_insn "*one_cmpldi2_1_rex64"
10017  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10018	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10019  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10020  "not{q}\t%0"
10021  [(set_attr "type" "negnot")
10022   (set_attr "mode" "DI")])
10023
10024(define_insn "*one_cmpldi2_2_rex64"
10025  [(set (reg FLAGS_REG)
10026	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10027		 (const_int 0)))
10028   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10029	(not:DI (match_dup 1)))]
10030  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10031   && ix86_unary_operator_ok (NOT, DImode, operands)"
10032  "#"
10033  [(set_attr "type" "alu1")
10034   (set_attr "mode" "DI")])
10035
10036(define_split
10037  [(set (match_operand 0 "flags_reg_operand" "")
10038	(match_operator 2 "compare_operator"
10039	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10040	   (const_int 0)]))
10041   (set (match_operand:DI 1 "nonimmediate_operand" "")
10042	(not:DI (match_dup 3)))]
10043  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10044  [(parallel [(set (match_dup 0)
10045		   (match_op_dup 2
10046		     [(xor:DI (match_dup 3) (const_int -1))
10047		      (const_int 0)]))
10048	      (set (match_dup 1)
10049		   (xor:DI (match_dup 3) (const_int -1)))])]
10050  "")
10051
10052(define_expand "one_cmplsi2"
10053  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10054	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10055  ""
10056  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10057
10058(define_insn "*one_cmplsi2_1"
10059  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10060	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10061  "ix86_unary_operator_ok (NOT, SImode, operands)"
10062  "not{l}\t%0"
10063  [(set_attr "type" "negnot")
10064   (set_attr "mode" "SI")])
10065
10066;; ??? Currently never generated - xor is used instead.
10067(define_insn "*one_cmplsi2_1_zext"
10068  [(set (match_operand:DI 0 "register_operand" "=r")
10069	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10070  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10071  "not{l}\t%k0"
10072  [(set_attr "type" "negnot")
10073   (set_attr "mode" "SI")])
10074
10075(define_insn "*one_cmplsi2_2"
10076  [(set (reg FLAGS_REG)
10077	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10078		 (const_int 0)))
10079   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10080	(not:SI (match_dup 1)))]
10081  "ix86_match_ccmode (insn, CCNOmode)
10082   && ix86_unary_operator_ok (NOT, SImode, operands)"
10083  "#"
10084  [(set_attr "type" "alu1")
10085   (set_attr "mode" "SI")])
10086
10087(define_split
10088  [(set (match_operand 0 "flags_reg_operand" "")
10089	(match_operator 2 "compare_operator"
10090	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10091	   (const_int 0)]))
10092   (set (match_operand:SI 1 "nonimmediate_operand" "")
10093	(not:SI (match_dup 3)))]
10094  "ix86_match_ccmode (insn, CCNOmode)"
10095  [(parallel [(set (match_dup 0)
10096		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10097				    (const_int 0)]))
10098	      (set (match_dup 1)
10099		   (xor:SI (match_dup 3) (const_int -1)))])]
10100  "")
10101
10102;; ??? Currently never generated - xor is used instead.
10103(define_insn "*one_cmplsi2_2_zext"
10104  [(set (reg FLAGS_REG)
10105	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10106		 (const_int 0)))
10107   (set (match_operand:DI 0 "register_operand" "=r")
10108	(zero_extend:DI (not:SI (match_dup 1))))]
10109  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10110   && ix86_unary_operator_ok (NOT, SImode, operands)"
10111  "#"
10112  [(set_attr "type" "alu1")
10113   (set_attr "mode" "SI")])
10114
10115(define_split
10116  [(set (match_operand 0 "flags_reg_operand" "")
10117	(match_operator 2 "compare_operator"
10118	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10119	   (const_int 0)]))
10120   (set (match_operand:DI 1 "register_operand" "")
10121	(zero_extend:DI (not:SI (match_dup 3))))]
10122  "ix86_match_ccmode (insn, CCNOmode)"
10123  [(parallel [(set (match_dup 0)
10124		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10125				    (const_int 0)]))
10126	      (set (match_dup 1)
10127		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10128  "")
10129
10130(define_expand "one_cmplhi2"
10131  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10132	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10133  "TARGET_HIMODE_MATH"
10134  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10135
10136(define_insn "*one_cmplhi2_1"
10137  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10138	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10139  "ix86_unary_operator_ok (NOT, HImode, operands)"
10140  "not{w}\t%0"
10141  [(set_attr "type" "negnot")
10142   (set_attr "mode" "HI")])
10143
10144(define_insn "*one_cmplhi2_2"
10145  [(set (reg FLAGS_REG)
10146	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10147		 (const_int 0)))
10148   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10149	(not:HI (match_dup 1)))]
10150  "ix86_match_ccmode (insn, CCNOmode)
10151   && ix86_unary_operator_ok (NEG, HImode, operands)"
10152  "#"
10153  [(set_attr "type" "alu1")
10154   (set_attr "mode" "HI")])
10155
10156(define_split
10157  [(set (match_operand 0 "flags_reg_operand" "")
10158	(match_operator 2 "compare_operator"
10159	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10160	   (const_int 0)]))
10161   (set (match_operand:HI 1 "nonimmediate_operand" "")
10162	(not:HI (match_dup 3)))]
10163  "ix86_match_ccmode (insn, CCNOmode)"
10164  [(parallel [(set (match_dup 0)
10165		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10166		      		    (const_int 0)]))
10167	      (set (match_dup 1)
10168		   (xor:HI (match_dup 3) (const_int -1)))])]
10169  "")
10170
10171;; %%% Potential partial reg stall on alternative 1.  What to do?
10172(define_expand "one_cmplqi2"
10173  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10174	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10175  "TARGET_QIMODE_MATH"
10176  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10177
10178(define_insn "*one_cmplqi2_1"
10179  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10180	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10181  "ix86_unary_operator_ok (NOT, QImode, operands)"
10182  "@
10183   not{b}\t%0
10184   not{l}\t%k0"
10185  [(set_attr "type" "negnot")
10186   (set_attr "mode" "QI,SI")])
10187
10188(define_insn "*one_cmplqi2_2"
10189  [(set (reg FLAGS_REG)
10190	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10191		 (const_int 0)))
10192   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10193	(not:QI (match_dup 1)))]
10194  "ix86_match_ccmode (insn, CCNOmode)
10195   && ix86_unary_operator_ok (NOT, QImode, operands)"
10196  "#"
10197  [(set_attr "type" "alu1")
10198   (set_attr "mode" "QI")])
10199
10200(define_split
10201  [(set (match_operand 0 "flags_reg_operand" "")
10202	(match_operator 2 "compare_operator"
10203	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10204	   (const_int 0)]))
10205   (set (match_operand:QI 1 "nonimmediate_operand" "")
10206	(not:QI (match_dup 3)))]
10207  "ix86_match_ccmode (insn, CCNOmode)"
10208  [(parallel [(set (match_dup 0)
10209		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10210		      		    (const_int 0)]))
10211	      (set (match_dup 1)
10212		   (xor:QI (match_dup 3) (const_int -1)))])]
10213  "")
10214
10215;; Arithmetic shift instructions
10216
10217;; DImode shifts are implemented using the i386 "shift double" opcode,
10218;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10219;; is variable, then the count is in %cl and the "imm" operand is dropped
10220;; from the assembler input.
10221;;
10222;; This instruction shifts the target reg/mem as usual, but instead of
10223;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10224;; is a left shift double, bits are taken from the high order bits of
10225;; reg, else if the insn is a shift right double, bits are taken from the
10226;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10227;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10228;;
10229;; Since sh[lr]d does not change the `reg' operand, that is done
10230;; separately, making all shifts emit pairs of shift double and normal
10231;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10232;; support a 63 bit shift, each shift where the count is in a reg expands
10233;; to a pair of shifts, a branch, a shift by 32 and a label.
10234;;
10235;; If the shift count is a constant, we need never emit more than one
10236;; shift pair, instead using moves and sign extension for counts greater
10237;; than 31.
10238
10239(define_expand "ashlti3"
10240  [(parallel [(set (match_operand:TI 0 "register_operand" "")
10241		   (ashift:TI (match_operand:TI 1 "register_operand" "")
10242			      (match_operand:QI 2 "nonmemory_operand" "")))
10243	      (clobber (reg:CC FLAGS_REG))])]
10244  "TARGET_64BIT"
10245{
10246  if (! immediate_operand (operands[2], QImode))
10247    {
10248      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10249      DONE;
10250    }
10251  ix86_expand_binary_operator (ASHIFT, TImode, operands);
10252  DONE;
10253})
10254
10255(define_insn "ashlti3_1"
10256  [(set (match_operand:TI 0 "register_operand" "=r")
10257	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10258		   (match_operand:QI 2 "register_operand" "c")))
10259   (clobber (match_scratch:DI 3 "=&r"))
10260   (clobber (reg:CC FLAGS_REG))]
10261  "TARGET_64BIT"
10262  "#"
10263  [(set_attr "type" "multi")])
10264
10265(define_insn "*ashlti3_2"
10266  [(set (match_operand:TI 0 "register_operand" "=r")
10267	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10268		   (match_operand:QI 2 "immediate_operand" "O")))
10269   (clobber (reg:CC FLAGS_REG))]
10270  "TARGET_64BIT"
10271  "#"
10272  [(set_attr "type" "multi")])
10273
10274(define_split
10275  [(set (match_operand:TI 0 "register_operand" "")
10276	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10277		   (match_operand:QI 2 "register_operand" "")))
10278   (clobber (match_scratch:DI 3 ""))
10279   (clobber (reg:CC FLAGS_REG))]
10280  "TARGET_64BIT && reload_completed"
10281  [(const_int 0)]
10282  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10283
10284(define_split
10285  [(set (match_operand:TI 0 "register_operand" "")
10286	(ashift:TI (match_operand:TI 1 "register_operand" "")
10287		   (match_operand:QI 2 "immediate_operand" "")))
10288   (clobber (reg:CC FLAGS_REG))]
10289  "TARGET_64BIT && reload_completed"
10290  [(const_int 0)]
10291  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10292
10293(define_insn "x86_64_shld"
10294  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10295        (ior:DI (ashift:DI (match_dup 0)
10296		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
10297		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10298		  (minus:QI (const_int 64) (match_dup 2)))))
10299   (clobber (reg:CC FLAGS_REG))]
10300  "TARGET_64BIT"
10301  "@
10302   shld{q}\t{%2, %1, %0|%0, %1, %2}
10303   shld{q}\t{%s2%1, %0|%0, %1, %2}"
10304  [(set_attr "type" "ishift")
10305   (set_attr "prefix_0f" "1")
10306   (set_attr "mode" "DI")
10307   (set_attr "athlon_decode" "vector")])
10308
10309(define_expand "x86_64_shift_adj"
10310  [(set (reg:CCZ FLAGS_REG)
10311	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10312			     (const_int 64))
10313		     (const_int 0)))
10314   (set (match_operand:DI 0 "register_operand" "")
10315        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10316			 (match_operand:DI 1 "register_operand" "")
10317			 (match_dup 0)))
10318   (set (match_dup 1)
10319	(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10320			 (match_operand:DI 3 "register_operand" "r")
10321			 (match_dup 1)))]
10322  "TARGET_64BIT"
10323  "")
10324
10325(define_expand "ashldi3"
10326  [(set (match_operand:DI 0 "shiftdi_operand" "")
10327	(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10328		   (match_operand:QI 2 "nonmemory_operand" "")))]
10329  ""
10330  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10331
10332(define_insn "*ashldi3_1_rex64"
10333  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10334	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10335		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10336   (clobber (reg:CC FLAGS_REG))]
10337  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10338{
10339  switch (get_attr_type (insn))
10340    {
10341    case TYPE_ALU:
10342      gcc_assert (operands[2] == const1_rtx);
10343      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10344      return "add{q}\t{%0, %0|%0, %0}";
10345
10346    case TYPE_LEA:
10347      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10348      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10349      operands[1] = gen_rtx_MULT (DImode, operands[1],
10350				  GEN_INT (1 << INTVAL (operands[2])));
10351      return "lea{q}\t{%a1, %0|%0, %a1}";
10352
10353    default:
10354      if (REG_P (operands[2]))
10355	return "sal{q}\t{%b2, %0|%0, %b2}";
10356      else if (operands[2] == const1_rtx
10357	       && (TARGET_SHIFT1 || optimize_size))
10358	return "sal{q}\t%0";
10359      else
10360	return "sal{q}\t{%2, %0|%0, %2}";
10361    }
10362}
10363  [(set (attr "type")
10364     (cond [(eq_attr "alternative" "1")
10365	      (const_string "lea")
10366            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10367		          (const_int 0))
10368		      (match_operand 0 "register_operand" ""))
10369		 (match_operand 2 "const1_operand" ""))
10370	      (const_string "alu")
10371	   ]
10372	   (const_string "ishift")))
10373   (set_attr "mode" "DI")])
10374
10375;; Convert lea to the lea pattern to avoid flags dependency.
10376(define_split
10377  [(set (match_operand:DI 0 "register_operand" "")
10378	(ashift:DI (match_operand:DI 1 "index_register_operand" "")
10379		   (match_operand:QI 2 "immediate_operand" "")))
10380   (clobber (reg:CC FLAGS_REG))]
10381  "TARGET_64BIT && reload_completed
10382   && true_regnum (operands[0]) != true_regnum (operands[1])"
10383  [(set (match_dup 0)
10384	(mult:DI (match_dup 1)
10385		 (match_dup 2)))]
10386  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10387
10388;; This pattern can't accept a variable shift count, since shifts by
10389;; zero don't affect the flags.  We assume that shifts by constant
10390;; zero are optimized away.
10391(define_insn "*ashldi3_cmp_rex64"
10392  [(set (reg FLAGS_REG)
10393	(compare
10394	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10395		     (match_operand:QI 2 "immediate_operand" "e"))
10396	  (const_int 0)))
10397   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10398	(ashift:DI (match_dup 1) (match_dup 2)))]
10399  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10400   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10401   && (optimize_size
10402       || !TARGET_PARTIAL_FLAG_REG_STALL
10403       || (operands[2] == const1_rtx
10404	   && (TARGET_SHIFT1
10405	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10406{
10407  switch (get_attr_type (insn))
10408    {
10409    case TYPE_ALU:
10410      gcc_assert (operands[2] == const1_rtx);
10411      return "add{q}\t{%0, %0|%0, %0}";
10412
10413    default:
10414      if (REG_P (operands[2]))
10415	return "sal{q}\t{%b2, %0|%0, %b2}";
10416      else if (operands[2] == const1_rtx
10417	       && (TARGET_SHIFT1 || optimize_size))
10418	return "sal{q}\t%0";
10419      else
10420	return "sal{q}\t{%2, %0|%0, %2}";
10421    }
10422}
10423  [(set (attr "type")
10424     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10425		          (const_int 0))
10426		      (match_operand 0 "register_operand" ""))
10427		 (match_operand 2 "const1_operand" ""))
10428	      (const_string "alu")
10429	   ]
10430	   (const_string "ishift")))
10431   (set_attr "mode" "DI")])
10432
10433(define_insn "*ashldi3_cconly_rex64"
10434  [(set (reg FLAGS_REG)
10435	(compare
10436	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10437		     (match_operand:QI 2 "immediate_operand" "e"))
10438	  (const_int 0)))
10439   (clobber (match_scratch:DI 0 "=r"))]
10440  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10441   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10442   && (optimize_size
10443       || !TARGET_PARTIAL_FLAG_REG_STALL
10444       || (operands[2] == const1_rtx
10445	   && (TARGET_SHIFT1
10446	       || TARGET_DOUBLE_WITH_ADD)))"
10447{
10448  switch (get_attr_type (insn))
10449    {
10450    case TYPE_ALU:
10451      gcc_assert (operands[2] == const1_rtx);
10452      return "add{q}\t{%0, %0|%0, %0}";
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 [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10466		          (const_int 0))
10467		      (match_operand 0 "register_operand" ""))
10468		 (match_operand 2 "const1_operand" ""))
10469	      (const_string "alu")
10470	   ]
10471	   (const_string "ishift")))
10472   (set_attr "mode" "DI")])
10473
10474(define_insn "*ashldi3_1"
10475  [(set (match_operand:DI 0 "register_operand" "=&r,r")
10476	(ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10477		   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10478   (clobber (reg:CC FLAGS_REG))]
10479  "!TARGET_64BIT"
10480  "#"
10481  [(set_attr "type" "multi")])
10482
10483;; By default we don't ask for a scratch register, because when DImode
10484;; values are manipulated, registers are already at a premium.  But if
10485;; we have one handy, we won't turn it away.
10486(define_peephole2
10487  [(match_scratch:SI 3 "r")
10488   (parallel [(set (match_operand:DI 0 "register_operand" "")
10489		   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10490			      (match_operand:QI 2 "nonmemory_operand" "")))
10491	      (clobber (reg:CC FLAGS_REG))])
10492   (match_dup 3)]
10493  "!TARGET_64BIT && TARGET_CMOVE"
10494  [(const_int 0)]
10495  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10496
10497(define_split
10498  [(set (match_operand:DI 0 "register_operand" "")
10499	(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10500		   (match_operand:QI 2 "nonmemory_operand" "")))
10501   (clobber (reg:CC FLAGS_REG))]
10502  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10503		     ? flow2_completed : reload_completed)"
10504  [(const_int 0)]
10505  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10506
10507(define_insn "x86_shld_1"
10508  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10509        (ior:SI (ashift:SI (match_dup 0)
10510		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10511		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10512		  (minus:QI (const_int 32) (match_dup 2)))))
10513   (clobber (reg:CC FLAGS_REG))]
10514  ""
10515  "@
10516   shld{l}\t{%2, %1, %0|%0, %1, %2}
10517   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10518  [(set_attr "type" "ishift")
10519   (set_attr "prefix_0f" "1")
10520   (set_attr "mode" "SI")
10521   (set_attr "pent_pair" "np")
10522   (set_attr "athlon_decode" "vector")])
10523
10524(define_expand "x86_shift_adj_1"
10525  [(set (reg:CCZ FLAGS_REG)
10526	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10527			     (const_int 32))
10528		     (const_int 0)))
10529   (set (match_operand:SI 0 "register_operand" "")
10530        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10531			 (match_operand:SI 1 "register_operand" "")
10532			 (match_dup 0)))
10533   (set (match_dup 1)
10534	(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10535			 (match_operand:SI 3 "register_operand" "r")
10536			 (match_dup 1)))]
10537  "TARGET_CMOVE"
10538  "")
10539
10540(define_expand "x86_shift_adj_2"
10541  [(use (match_operand:SI 0 "register_operand" ""))
10542   (use (match_operand:SI 1 "register_operand" ""))
10543   (use (match_operand:QI 2 "register_operand" ""))]
10544  ""
10545{
10546  rtx label = gen_label_rtx ();
10547  rtx tmp;
10548
10549  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10550
10551  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10552  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10553  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10554			      gen_rtx_LABEL_REF (VOIDmode, label),
10555			      pc_rtx);
10556  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10557  JUMP_LABEL (tmp) = label;
10558
10559  emit_move_insn (operands[0], operands[1]);
10560  ix86_expand_clear (operands[1]);
10561
10562  emit_label (label);
10563  LABEL_NUSES (label) = 1;
10564
10565  DONE;
10566})
10567
10568(define_expand "ashlsi3"
10569  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10570	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10571		   (match_operand:QI 2 "nonmemory_operand" "")))
10572   (clobber (reg:CC FLAGS_REG))]
10573  ""
10574  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10575
10576(define_insn "*ashlsi3_1"
10577  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10578	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10579		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10580   (clobber (reg:CC FLAGS_REG))]
10581  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10582{
10583  switch (get_attr_type (insn))
10584    {
10585    case TYPE_ALU:
10586      gcc_assert (operands[2] == const1_rtx);
10587      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10588      return "add{l}\t{%0, %0|%0, %0}";
10589
10590    case TYPE_LEA:
10591      return "#";
10592
10593    default:
10594      if (REG_P (operands[2]))
10595	return "sal{l}\t{%b2, %0|%0, %b2}";
10596      else if (operands[2] == const1_rtx
10597	       && (TARGET_SHIFT1 || optimize_size))
10598	return "sal{l}\t%0";
10599      else
10600	return "sal{l}\t{%2, %0|%0, %2}";
10601    }
10602}
10603  [(set (attr "type")
10604     (cond [(eq_attr "alternative" "1")
10605	      (const_string "lea")
10606            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10607		          (const_int 0))
10608		      (match_operand 0 "register_operand" ""))
10609		 (match_operand 2 "const1_operand" ""))
10610	      (const_string "alu")
10611	   ]
10612	   (const_string "ishift")))
10613   (set_attr "mode" "SI")])
10614
10615;; Convert lea to the lea pattern to avoid flags dependency.
10616(define_split
10617  [(set (match_operand 0 "register_operand" "")
10618	(ashift (match_operand 1 "index_register_operand" "")
10619                (match_operand:QI 2 "const_int_operand" "")))
10620   (clobber (reg:CC FLAGS_REG))]
10621  "reload_completed
10622   && true_regnum (operands[0]) != true_regnum (operands[1])
10623   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10624  [(const_int 0)]
10625{
10626  rtx pat;
10627  enum machine_mode mode = GET_MODE (operands[0]);
10628
10629  if (GET_MODE_SIZE (mode) < 4)
10630    operands[0] = gen_lowpart (SImode, operands[0]);
10631  if (mode != Pmode)
10632    operands[1] = gen_lowpart (Pmode, operands[1]);
10633  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10634
10635  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10636  if (Pmode != SImode)
10637    pat = gen_rtx_SUBREG (SImode, pat, 0);
10638  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10639  DONE;
10640})
10641
10642;; Rare case of shifting RSP is handled by generating move and shift
10643(define_split
10644  [(set (match_operand 0 "register_operand" "")
10645	(ashift (match_operand 1 "register_operand" "")
10646                (match_operand:QI 2 "const_int_operand" "")))
10647   (clobber (reg:CC FLAGS_REG))]
10648  "reload_completed
10649   && true_regnum (operands[0]) != true_regnum (operands[1])"
10650  [(const_int 0)]
10651{
10652  rtx pat, clob;
10653  emit_move_insn (operands[0], operands[1]);
10654  pat = gen_rtx_SET (VOIDmode, operands[0],
10655		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10656				     operands[0], operands[2]));
10657  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10658  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10659  DONE;
10660})
10661
10662(define_insn "*ashlsi3_1_zext"
10663  [(set (match_operand:DI 0 "register_operand" "=r,r")
10664	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10665			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10666   (clobber (reg:CC FLAGS_REG))]
10667  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10668{
10669  switch (get_attr_type (insn))
10670    {
10671    case TYPE_ALU:
10672      gcc_assert (operands[2] == const1_rtx);
10673      return "add{l}\t{%k0, %k0|%k0, %k0}";
10674
10675    case TYPE_LEA:
10676      return "#";
10677
10678    default:
10679      if (REG_P (operands[2]))
10680	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10681      else if (operands[2] == const1_rtx
10682	       && (TARGET_SHIFT1 || optimize_size))
10683	return "sal{l}\t%k0";
10684      else
10685	return "sal{l}\t{%2, %k0|%k0, %2}";
10686    }
10687}
10688  [(set (attr "type")
10689     (cond [(eq_attr "alternative" "1")
10690	      (const_string "lea")
10691            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10692		     (const_int 0))
10693		 (match_operand 2 "const1_operand" ""))
10694	      (const_string "alu")
10695	   ]
10696	   (const_string "ishift")))
10697   (set_attr "mode" "SI")])
10698
10699;; Convert lea to the lea pattern to avoid flags dependency.
10700(define_split
10701  [(set (match_operand:DI 0 "register_operand" "")
10702	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10703				(match_operand:QI 2 "const_int_operand" ""))))
10704   (clobber (reg:CC FLAGS_REG))]
10705  "TARGET_64BIT && reload_completed
10706   && true_regnum (operands[0]) != true_regnum (operands[1])"
10707  [(set (match_dup 0) (zero_extend:DI
10708			(subreg:SI (mult:SI (match_dup 1)
10709					    (match_dup 2)) 0)))]
10710{
10711  operands[1] = gen_lowpart (Pmode, operands[1]);
10712  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10713})
10714
10715;; This pattern can't accept a variable shift count, since shifts by
10716;; zero don't affect the flags.  We assume that shifts by constant
10717;; zero are optimized away.
10718(define_insn "*ashlsi3_cmp"
10719  [(set (reg FLAGS_REG)
10720	(compare
10721	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10722		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10723	  (const_int 0)))
10724   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10725	(ashift:SI (match_dup 1) (match_dup 2)))]
10726  "ix86_match_ccmode (insn, CCGOCmode)
10727   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10728   && (optimize_size
10729       || !TARGET_PARTIAL_FLAG_REG_STALL
10730       || (operands[2] == const1_rtx
10731	   && (TARGET_SHIFT1
10732	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10733{
10734  switch (get_attr_type (insn))
10735    {
10736    case TYPE_ALU:
10737      gcc_assert (operands[2] == const1_rtx);
10738      return "add{l}\t{%0, %0|%0, %0}";
10739
10740    default:
10741      if (REG_P (operands[2]))
10742	return "sal{l}\t{%b2, %0|%0, %b2}";
10743      else if (operands[2] == const1_rtx
10744	       && (TARGET_SHIFT1 || optimize_size))
10745	return "sal{l}\t%0";
10746      else
10747	return "sal{l}\t{%2, %0|%0, %2}";
10748    }
10749}
10750  [(set (attr "type")
10751     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10752		          (const_int 0))
10753		      (match_operand 0 "register_operand" ""))
10754		 (match_operand 2 "const1_operand" ""))
10755	      (const_string "alu")
10756	   ]
10757	   (const_string "ishift")))
10758   (set_attr "mode" "SI")])
10759
10760(define_insn "*ashlsi3_cconly"
10761  [(set (reg FLAGS_REG)
10762	(compare
10763	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10764		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10765	  (const_int 0)))
10766   (clobber (match_scratch:SI 0 "=r"))]
10767  "ix86_match_ccmode (insn, CCGOCmode)
10768   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10769   && (optimize_size
10770       || !TARGET_PARTIAL_FLAG_REG_STALL
10771       || (operands[2] == const1_rtx
10772	   && (TARGET_SHIFT1
10773	       || TARGET_DOUBLE_WITH_ADD)))"
10774{
10775  switch (get_attr_type (insn))
10776    {
10777    case TYPE_ALU:
10778      gcc_assert (operands[2] == const1_rtx);
10779      return "add{l}\t{%0, %0|%0, %0}";
10780
10781    default:
10782      if (REG_P (operands[2]))
10783	return "sal{l}\t{%b2, %0|%0, %b2}";
10784      else if (operands[2] == const1_rtx
10785	       && (TARGET_SHIFT1 || optimize_size))
10786	return "sal{l}\t%0";
10787      else
10788	return "sal{l}\t{%2, %0|%0, %2}";
10789    }
10790}
10791  [(set (attr "type")
10792     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10793		          (const_int 0))
10794		      (match_operand 0 "register_operand" ""))
10795		 (match_operand 2 "const1_operand" ""))
10796	      (const_string "alu")
10797	   ]
10798	   (const_string "ishift")))
10799   (set_attr "mode" "SI")])
10800
10801(define_insn "*ashlsi3_cmp_zext"
10802  [(set (reg FLAGS_REG)
10803	(compare
10804	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10805		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10806	  (const_int 0)))
10807   (set (match_operand:DI 0 "register_operand" "=r")
10808	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10809  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10810   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10811   && (optimize_size
10812       || !TARGET_PARTIAL_FLAG_REG_STALL
10813       || (operands[2] == const1_rtx
10814	   && (TARGET_SHIFT1
10815	       || TARGET_DOUBLE_WITH_ADD)))"
10816{
10817  switch (get_attr_type (insn))
10818    {
10819    case TYPE_ALU:
10820      gcc_assert (operands[2] == const1_rtx);
10821      return "add{l}\t{%k0, %k0|%k0, %k0}";
10822
10823    default:
10824      if (REG_P (operands[2]))
10825	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10826      else if (operands[2] == const1_rtx
10827	       && (TARGET_SHIFT1 || optimize_size))
10828	return "sal{l}\t%k0";
10829      else
10830	return "sal{l}\t{%2, %k0|%k0, %2}";
10831    }
10832}
10833  [(set (attr "type")
10834     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10835		     (const_int 0))
10836		 (match_operand 2 "const1_operand" ""))
10837	      (const_string "alu")
10838	   ]
10839	   (const_string "ishift")))
10840   (set_attr "mode" "SI")])
10841
10842(define_expand "ashlhi3"
10843  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10844	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10845		   (match_operand:QI 2 "nonmemory_operand" "")))
10846   (clobber (reg:CC FLAGS_REG))]
10847  "TARGET_HIMODE_MATH"
10848  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10849
10850(define_insn "*ashlhi3_1_lea"
10851  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10852	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10853		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10854   (clobber (reg:CC FLAGS_REG))]
10855  "!TARGET_PARTIAL_REG_STALL
10856   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10857{
10858  switch (get_attr_type (insn))
10859    {
10860    case TYPE_LEA:
10861      return "#";
10862    case TYPE_ALU:
10863      gcc_assert (operands[2] == const1_rtx);
10864      return "add{w}\t{%0, %0|%0, %0}";
10865
10866    default:
10867      if (REG_P (operands[2]))
10868	return "sal{w}\t{%b2, %0|%0, %b2}";
10869      else if (operands[2] == const1_rtx
10870	       && (TARGET_SHIFT1 || optimize_size))
10871	return "sal{w}\t%0";
10872      else
10873	return "sal{w}\t{%2, %0|%0, %2}";
10874    }
10875}
10876  [(set (attr "type")
10877     (cond [(eq_attr "alternative" "1")
10878	      (const_string "lea")
10879            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10880		          (const_int 0))
10881		      (match_operand 0 "register_operand" ""))
10882		 (match_operand 2 "const1_operand" ""))
10883	      (const_string "alu")
10884	   ]
10885	   (const_string "ishift")))
10886   (set_attr "mode" "HI,SI")])
10887
10888(define_insn "*ashlhi3_1"
10889  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10890	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10891		   (match_operand:QI 2 "nonmemory_operand" "cI")))
10892   (clobber (reg:CC FLAGS_REG))]
10893  "TARGET_PARTIAL_REG_STALL
10894   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10895{
10896  switch (get_attr_type (insn))
10897    {
10898    case TYPE_ALU:
10899      gcc_assert (operands[2] == const1_rtx);
10900      return "add{w}\t{%0, %0|%0, %0}";
10901
10902    default:
10903      if (REG_P (operands[2]))
10904	return "sal{w}\t{%b2, %0|%0, %b2}";
10905      else if (operands[2] == const1_rtx
10906	       && (TARGET_SHIFT1 || optimize_size))
10907	return "sal{w}\t%0";
10908      else
10909	return "sal{w}\t{%2, %0|%0, %2}";
10910    }
10911}
10912  [(set (attr "type")
10913     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10914		          (const_int 0))
10915		      (match_operand 0 "register_operand" ""))
10916		 (match_operand 2 "const1_operand" ""))
10917	      (const_string "alu")
10918	   ]
10919	   (const_string "ishift")))
10920   (set_attr "mode" "HI")])
10921
10922;; This pattern can't accept a variable shift count, since shifts by
10923;; zero don't affect the flags.  We assume that shifts by constant
10924;; zero are optimized away.
10925(define_insn "*ashlhi3_cmp"
10926  [(set (reg FLAGS_REG)
10927	(compare
10928	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10929		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10930	  (const_int 0)))
10931   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10932	(ashift:HI (match_dup 1) (match_dup 2)))]
10933  "ix86_match_ccmode (insn, CCGOCmode)
10934   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10935   && (optimize_size
10936       || !TARGET_PARTIAL_FLAG_REG_STALL
10937       || (operands[2] == const1_rtx
10938	   && (TARGET_SHIFT1
10939	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10940{
10941  switch (get_attr_type (insn))
10942    {
10943    case TYPE_ALU:
10944      gcc_assert (operands[2] == const1_rtx);
10945      return "add{w}\t{%0, %0|%0, %0}";
10946
10947    default:
10948      if (REG_P (operands[2]))
10949	return "sal{w}\t{%b2, %0|%0, %b2}";
10950      else if (operands[2] == const1_rtx
10951	       && (TARGET_SHIFT1 || optimize_size))
10952	return "sal{w}\t%0";
10953      else
10954	return "sal{w}\t{%2, %0|%0, %2}";
10955    }
10956}
10957  [(set (attr "type")
10958     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10959		          (const_int 0))
10960		      (match_operand 0 "register_operand" ""))
10961		 (match_operand 2 "const1_operand" ""))
10962	      (const_string "alu")
10963	   ]
10964	   (const_string "ishift")))
10965   (set_attr "mode" "HI")])
10966
10967(define_insn "*ashlhi3_cconly"
10968  [(set (reg FLAGS_REG)
10969	(compare
10970	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10971		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10972	  (const_int 0)))
10973   (clobber (match_scratch:HI 0 "=r"))]
10974  "ix86_match_ccmode (insn, CCGOCmode)
10975   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10976   && (optimize_size
10977       || !TARGET_PARTIAL_FLAG_REG_STALL
10978       || (operands[2] == const1_rtx
10979	   && (TARGET_SHIFT1
10980	       || TARGET_DOUBLE_WITH_ADD)))"
10981{
10982  switch (get_attr_type (insn))
10983    {
10984    case TYPE_ALU:
10985      gcc_assert (operands[2] == const1_rtx);
10986      return "add{w}\t{%0, %0|%0, %0}";
10987
10988    default:
10989      if (REG_P (operands[2]))
10990	return "sal{w}\t{%b2, %0|%0, %b2}";
10991      else if (operands[2] == const1_rtx
10992	       && (TARGET_SHIFT1 || optimize_size))
10993	return "sal{w}\t%0";
10994      else
10995	return "sal{w}\t{%2, %0|%0, %2}";
10996    }
10997}
10998  [(set (attr "type")
10999     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11000		          (const_int 0))
11001		      (match_operand 0 "register_operand" ""))
11002		 (match_operand 2 "const1_operand" ""))
11003	      (const_string "alu")
11004	   ]
11005	   (const_string "ishift")))
11006   (set_attr "mode" "HI")])
11007
11008(define_expand "ashlqi3"
11009  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11010	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11011		   (match_operand:QI 2 "nonmemory_operand" "")))
11012   (clobber (reg:CC FLAGS_REG))]
11013  "TARGET_QIMODE_MATH"
11014  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11015
11016;; %%% Potential partial reg stall on alternative 2.  What to do?
11017
11018(define_insn "*ashlqi3_1_lea"
11019  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11020	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11021		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11022   (clobber (reg:CC FLAGS_REG))]
11023  "!TARGET_PARTIAL_REG_STALL
11024   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11025{
11026  switch (get_attr_type (insn))
11027    {
11028    case TYPE_LEA:
11029      return "#";
11030    case TYPE_ALU:
11031      gcc_assert (operands[2] == const1_rtx);
11032      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11033        return "add{l}\t{%k0, %k0|%k0, %k0}";
11034      else
11035        return "add{b}\t{%0, %0|%0, %0}";
11036
11037    default:
11038      if (REG_P (operands[2]))
11039	{
11040	  if (get_attr_mode (insn) == MODE_SI)
11041	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11042	  else
11043	    return "sal{b}\t{%b2, %0|%0, %b2}";
11044	}
11045      else if (operands[2] == const1_rtx
11046	       && (TARGET_SHIFT1 || optimize_size))
11047	{
11048	  if (get_attr_mode (insn) == MODE_SI)
11049	    return "sal{l}\t%0";
11050	  else
11051	    return "sal{b}\t%0";
11052	}
11053      else
11054	{
11055	  if (get_attr_mode (insn) == MODE_SI)
11056	    return "sal{l}\t{%2, %k0|%k0, %2}";
11057	  else
11058	    return "sal{b}\t{%2, %0|%0, %2}";
11059	}
11060    }
11061}
11062  [(set (attr "type")
11063     (cond [(eq_attr "alternative" "2")
11064	      (const_string "lea")
11065            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11066		          (const_int 0))
11067		      (match_operand 0 "register_operand" ""))
11068		 (match_operand 2 "const1_operand" ""))
11069	      (const_string "alu")
11070	   ]
11071	   (const_string "ishift")))
11072   (set_attr "mode" "QI,SI,SI")])
11073
11074(define_insn "*ashlqi3_1"
11075  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11076	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11077		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11078   (clobber (reg:CC FLAGS_REG))]
11079  "TARGET_PARTIAL_REG_STALL
11080   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11081{
11082  switch (get_attr_type (insn))
11083    {
11084    case TYPE_ALU:
11085      gcc_assert (operands[2] == const1_rtx);
11086      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11087        return "add{l}\t{%k0, %k0|%k0, %k0}";
11088      else
11089        return "add{b}\t{%0, %0|%0, %0}";
11090
11091    default:
11092      if (REG_P (operands[2]))
11093	{
11094	  if (get_attr_mode (insn) == MODE_SI)
11095	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11096	  else
11097	    return "sal{b}\t{%b2, %0|%0, %b2}";
11098	}
11099      else if (operands[2] == const1_rtx
11100	       && (TARGET_SHIFT1 || optimize_size))
11101	{
11102	  if (get_attr_mode (insn) == MODE_SI)
11103	    return "sal{l}\t%0";
11104	  else
11105	    return "sal{b}\t%0";
11106	}
11107      else
11108	{
11109	  if (get_attr_mode (insn) == MODE_SI)
11110	    return "sal{l}\t{%2, %k0|%k0, %2}";
11111	  else
11112	    return "sal{b}\t{%2, %0|%0, %2}";
11113	}
11114    }
11115}
11116  [(set (attr "type")
11117     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11118		          (const_int 0))
11119		      (match_operand 0 "register_operand" ""))
11120		 (match_operand 2 "const1_operand" ""))
11121	      (const_string "alu")
11122	   ]
11123	   (const_string "ishift")))
11124   (set_attr "mode" "QI,SI")])
11125
11126;; This pattern can't accept a variable shift count, since shifts by
11127;; zero don't affect the flags.  We assume that shifts by constant
11128;; zero are optimized away.
11129(define_insn "*ashlqi3_cmp"
11130  [(set (reg FLAGS_REG)
11131	(compare
11132	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11133		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11134	  (const_int 0)))
11135   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11136	(ashift:QI (match_dup 1) (match_dup 2)))]
11137  "ix86_match_ccmode (insn, CCGOCmode)
11138   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11139   && (optimize_size
11140       || !TARGET_PARTIAL_FLAG_REG_STALL
11141       || (operands[2] == const1_rtx
11142	   && (TARGET_SHIFT1
11143	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11144{
11145  switch (get_attr_type (insn))
11146    {
11147    case TYPE_ALU:
11148      gcc_assert (operands[2] == const1_rtx);
11149      return "add{b}\t{%0, %0|%0, %0}";
11150
11151    default:
11152      if (REG_P (operands[2]))
11153	return "sal{b}\t{%b2, %0|%0, %b2}";
11154      else if (operands[2] == const1_rtx
11155	       && (TARGET_SHIFT1 || optimize_size))
11156	return "sal{b}\t%0";
11157      else
11158	return "sal{b}\t{%2, %0|%0, %2}";
11159    }
11160}
11161  [(set (attr "type")
11162     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11163		          (const_int 0))
11164		      (match_operand 0 "register_operand" ""))
11165		 (match_operand 2 "const1_operand" ""))
11166	      (const_string "alu")
11167	   ]
11168	   (const_string "ishift")))
11169   (set_attr "mode" "QI")])
11170
11171(define_insn "*ashlqi3_cconly"
11172  [(set (reg FLAGS_REG)
11173	(compare
11174	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11175		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11176	  (const_int 0)))
11177   (clobber (match_scratch:QI 0 "=q"))]
11178  "ix86_match_ccmode (insn, CCGOCmode)
11179   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11180   && (optimize_size
11181       || !TARGET_PARTIAL_FLAG_REG_STALL
11182       || (operands[2] == const1_rtx
11183	   && (TARGET_SHIFT1
11184	       || TARGET_DOUBLE_WITH_ADD)))"
11185{
11186  switch (get_attr_type (insn))
11187    {
11188    case TYPE_ALU:
11189      gcc_assert (operands[2] == const1_rtx);
11190      return "add{b}\t{%0, %0|%0, %0}";
11191
11192    default:
11193      if (REG_P (operands[2]))
11194	return "sal{b}\t{%b2, %0|%0, %b2}";
11195      else if (operands[2] == const1_rtx
11196	       && (TARGET_SHIFT1 || optimize_size))
11197	return "sal{b}\t%0";
11198      else
11199	return "sal{b}\t{%2, %0|%0, %2}";
11200    }
11201}
11202  [(set (attr "type")
11203     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11204		          (const_int 0))
11205		      (match_operand 0 "register_operand" ""))
11206		 (match_operand 2 "const1_operand" ""))
11207	      (const_string "alu")
11208	   ]
11209	   (const_string "ishift")))
11210   (set_attr "mode" "QI")])
11211
11212;; See comment above `ashldi3' about how this works.
11213
11214(define_expand "ashrti3"
11215  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11216		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11217				(match_operand:QI 2 "nonmemory_operand" "")))
11218	      (clobber (reg:CC FLAGS_REG))])]
11219  "TARGET_64BIT"
11220{
11221  if (! immediate_operand (operands[2], QImode))
11222    {
11223      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11224      DONE;
11225    }
11226  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11227  DONE;
11228})
11229
11230(define_insn "ashrti3_1"
11231  [(set (match_operand:TI 0 "register_operand" "=r")
11232	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11233		     (match_operand:QI 2 "register_operand" "c")))
11234   (clobber (match_scratch:DI 3 "=&r"))
11235   (clobber (reg:CC FLAGS_REG))]
11236  "TARGET_64BIT"
11237  "#"
11238  [(set_attr "type" "multi")])
11239
11240(define_insn "*ashrti3_2"
11241  [(set (match_operand:TI 0 "register_operand" "=r")
11242	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11243		     (match_operand:QI 2 "immediate_operand" "O")))
11244   (clobber (reg:CC FLAGS_REG))]
11245  "TARGET_64BIT"
11246  "#"
11247  [(set_attr "type" "multi")])
11248
11249(define_split
11250  [(set (match_operand:TI 0 "register_operand" "")
11251	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11252		     (match_operand:QI 2 "register_operand" "")))
11253   (clobber (match_scratch:DI 3 ""))
11254   (clobber (reg:CC FLAGS_REG))]
11255  "TARGET_64BIT && reload_completed"
11256  [(const_int 0)]
11257  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11258
11259(define_split
11260  [(set (match_operand:TI 0 "register_operand" "")
11261	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11262		     (match_operand:QI 2 "immediate_operand" "")))
11263   (clobber (reg:CC FLAGS_REG))]
11264  "TARGET_64BIT && reload_completed"
11265  [(const_int 0)]
11266  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11267
11268(define_insn "x86_64_shrd"
11269  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11270        (ior:DI (ashiftrt:DI (match_dup 0)
11271		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
11272		(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11273		  (minus:QI (const_int 64) (match_dup 2)))))
11274   (clobber (reg:CC FLAGS_REG))]
11275  "TARGET_64BIT"
11276  "@
11277   shrd{q}\t{%2, %1, %0|%0, %1, %2}
11278   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11279  [(set_attr "type" "ishift")
11280   (set_attr "prefix_0f" "1")
11281   (set_attr "mode" "DI")
11282   (set_attr "athlon_decode" "vector")])
11283
11284(define_expand "ashrdi3"
11285  [(set (match_operand:DI 0 "shiftdi_operand" "")
11286	(ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11287		     (match_operand:QI 2 "nonmemory_operand" "")))]
11288  ""
11289  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11290
11291(define_insn "*ashrdi3_63_rex64"
11292  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11293	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11294		     (match_operand:DI 2 "const_int_operand" "i,i")))
11295   (clobber (reg:CC FLAGS_REG))]
11296  "TARGET_64BIT && INTVAL (operands[2]) == 63
11297   && (TARGET_USE_CLTD || optimize_size)
11298   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11299  "@
11300   {cqto|cqo}
11301   sar{q}\t{%2, %0|%0, %2}"
11302  [(set_attr "type" "imovx,ishift")
11303   (set_attr "prefix_0f" "0,*")
11304   (set_attr "length_immediate" "0,*")
11305   (set_attr "modrm" "0,1")
11306   (set_attr "mode" "DI")])
11307
11308(define_insn "*ashrdi3_1_one_bit_rex64"
11309  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11310	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11311		     (match_operand:QI 2 "const1_operand" "")))
11312   (clobber (reg:CC FLAGS_REG))]
11313  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11314   && (TARGET_SHIFT1 || optimize_size)"
11315  "sar{q}\t%0"
11316  [(set_attr "type" "ishift")
11317   (set (attr "length") 
11318     (if_then_else (match_operand:DI 0 "register_operand" "") 
11319	(const_string "2")
11320	(const_string "*")))])
11321
11322(define_insn "*ashrdi3_1_rex64"
11323  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11324	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11325		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11326   (clobber (reg:CC FLAGS_REG))]
11327  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11328  "@
11329   sar{q}\t{%2, %0|%0, %2}
11330   sar{q}\t{%b2, %0|%0, %b2}"
11331  [(set_attr "type" "ishift")
11332   (set_attr "mode" "DI")])
11333
11334;; This pattern can't accept a variable shift count, since shifts by
11335;; zero don't affect the flags.  We assume that shifts by constant
11336;; zero are optimized away.
11337(define_insn "*ashrdi3_one_bit_cmp_rex64"
11338  [(set (reg FLAGS_REG)
11339	(compare
11340	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11341		       (match_operand:QI 2 "const1_operand" ""))
11342	  (const_int 0)))
11343   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11344	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11345  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11346   && (TARGET_SHIFT1 || optimize_size)
11347   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11348  "sar{q}\t%0"
11349  [(set_attr "type" "ishift")
11350   (set (attr "length") 
11351     (if_then_else (match_operand:DI 0 "register_operand" "") 
11352	(const_string "2")
11353	(const_string "*")))])
11354
11355(define_insn "*ashrdi3_one_bit_cconly_rex64"
11356  [(set (reg FLAGS_REG)
11357	(compare
11358	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11359		       (match_operand:QI 2 "const1_operand" ""))
11360	  (const_int 0)))
11361   (clobber (match_scratch:DI 0 "=r"))]
11362  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11363   && (TARGET_SHIFT1 || optimize_size)
11364   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11365  "sar{q}\t%0"
11366  [(set_attr "type" "ishift")
11367   (set_attr "length" "2")])
11368
11369;; This pattern can't accept a variable shift count, since shifts by
11370;; zero don't affect the flags.  We assume that shifts by constant
11371;; zero are optimized away.
11372(define_insn "*ashrdi3_cmp_rex64"
11373  [(set (reg FLAGS_REG)
11374	(compare
11375	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11376		       (match_operand:QI 2 "const_int_operand" "n"))
11377	  (const_int 0)))
11378   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11379	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11380  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11381   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11382   && (optimize_size
11383       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11384  "sar{q}\t{%2, %0|%0, %2}"
11385  [(set_attr "type" "ishift")
11386   (set_attr "mode" "DI")])
11387
11388(define_insn "*ashrdi3_cconly_rex64"
11389  [(set (reg FLAGS_REG)
11390	(compare
11391	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11392		       (match_operand:QI 2 "const_int_operand" "n"))
11393	  (const_int 0)))
11394   (clobber (match_scratch:DI 0 "=r"))]
11395  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11396   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11397   && (optimize_size
11398       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11399  "sar{q}\t{%2, %0|%0, %2}"
11400  [(set_attr "type" "ishift")
11401   (set_attr "mode" "DI")])
11402
11403(define_insn "*ashrdi3_1"
11404  [(set (match_operand:DI 0 "register_operand" "=r")
11405	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11406		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11407   (clobber (reg:CC FLAGS_REG))]
11408  "!TARGET_64BIT"
11409  "#"
11410  [(set_attr "type" "multi")])
11411
11412;; By default we don't ask for a scratch register, because when DImode
11413;; values are manipulated, registers are already at a premium.  But if
11414;; we have one handy, we won't turn it away.
11415(define_peephole2
11416  [(match_scratch:SI 3 "r")
11417   (parallel [(set (match_operand:DI 0 "register_operand" "")
11418		   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11419			        (match_operand:QI 2 "nonmemory_operand" "")))
11420	      (clobber (reg:CC FLAGS_REG))])
11421   (match_dup 3)]
11422  "!TARGET_64BIT && TARGET_CMOVE"
11423  [(const_int 0)]
11424  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11425
11426(define_split
11427  [(set (match_operand:DI 0 "register_operand" "")
11428	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11429		     (match_operand:QI 2 "nonmemory_operand" "")))
11430   (clobber (reg:CC FLAGS_REG))]
11431  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11432		     ? flow2_completed : reload_completed)"
11433  [(const_int 0)]
11434  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11435
11436(define_insn "x86_shrd_1"
11437  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11438        (ior:SI (ashiftrt:SI (match_dup 0)
11439		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11440		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11441		  (minus:QI (const_int 32) (match_dup 2)))))
11442   (clobber (reg:CC FLAGS_REG))]
11443  ""
11444  "@
11445   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11446   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11447  [(set_attr "type" "ishift")
11448   (set_attr "prefix_0f" "1")
11449   (set_attr "pent_pair" "np")
11450   (set_attr "mode" "SI")])
11451
11452(define_expand "x86_shift_adj_3"
11453  [(use (match_operand:SI 0 "register_operand" ""))
11454   (use (match_operand:SI 1 "register_operand" ""))
11455   (use (match_operand:QI 2 "register_operand" ""))]
11456  ""
11457{
11458  rtx label = gen_label_rtx ();
11459  rtx tmp;
11460
11461  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11462
11463  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11464  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11465  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11466			      gen_rtx_LABEL_REF (VOIDmode, label),
11467			      pc_rtx);
11468  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11469  JUMP_LABEL (tmp) = label;
11470
11471  emit_move_insn (operands[0], operands[1]);
11472  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11473
11474  emit_label (label);
11475  LABEL_NUSES (label) = 1;
11476
11477  DONE;
11478})
11479
11480(define_insn "ashrsi3_31"
11481  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11482	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11483		     (match_operand:SI 2 "const_int_operand" "i,i")))
11484   (clobber (reg:CC FLAGS_REG))]
11485  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11486   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11487  "@
11488   {cltd|cdq}
11489   sar{l}\t{%2, %0|%0, %2}"
11490  [(set_attr "type" "imovx,ishift")
11491   (set_attr "prefix_0f" "0,*")
11492   (set_attr "length_immediate" "0,*")
11493   (set_attr "modrm" "0,1")
11494   (set_attr "mode" "SI")])
11495
11496(define_insn "*ashrsi3_31_zext"
11497  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11498	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11499				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11500   (clobber (reg:CC FLAGS_REG))]
11501  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11502   && INTVAL (operands[2]) == 31
11503   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11504  "@
11505   {cltd|cdq}
11506   sar{l}\t{%2, %k0|%k0, %2}"
11507  [(set_attr "type" "imovx,ishift")
11508   (set_attr "prefix_0f" "0,*")
11509   (set_attr "length_immediate" "0,*")
11510   (set_attr "modrm" "0,1")
11511   (set_attr "mode" "SI")])
11512
11513(define_expand "ashrsi3"
11514  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11515	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11516		     (match_operand:QI 2 "nonmemory_operand" "")))
11517   (clobber (reg:CC FLAGS_REG))]
11518  ""
11519  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11520
11521(define_insn "*ashrsi3_1_one_bit"
11522  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11523	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11524		     (match_operand:QI 2 "const1_operand" "")))
11525   (clobber (reg:CC FLAGS_REG))]
11526  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11527   && (TARGET_SHIFT1 || optimize_size)"
11528  "sar{l}\t%0"
11529  [(set_attr "type" "ishift")
11530   (set (attr "length") 
11531     (if_then_else (match_operand:SI 0 "register_operand" "") 
11532	(const_string "2")
11533	(const_string "*")))])
11534
11535(define_insn "*ashrsi3_1_one_bit_zext"
11536  [(set (match_operand:DI 0 "register_operand" "=r")
11537	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11538				     (match_operand:QI 2 "const1_operand" ""))))
11539   (clobber (reg:CC FLAGS_REG))]
11540  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11541   && (TARGET_SHIFT1 || optimize_size)"
11542  "sar{l}\t%k0"
11543  [(set_attr "type" "ishift")
11544   (set_attr "length" "2")])
11545
11546(define_insn "*ashrsi3_1"
11547  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11548	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11549		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11550   (clobber (reg:CC FLAGS_REG))]
11551  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11552  "@
11553   sar{l}\t{%2, %0|%0, %2}
11554   sar{l}\t{%b2, %0|%0, %b2}"
11555  [(set_attr "type" "ishift")
11556   (set_attr "mode" "SI")])
11557
11558(define_insn "*ashrsi3_1_zext"
11559  [(set (match_operand:DI 0 "register_operand" "=r,r")
11560	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11561				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11562   (clobber (reg:CC FLAGS_REG))]
11563  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11564  "@
11565   sar{l}\t{%2, %k0|%k0, %2}
11566   sar{l}\t{%b2, %k0|%k0, %b2}"
11567  [(set_attr "type" "ishift")
11568   (set_attr "mode" "SI")])
11569
11570;; This pattern can't accept a variable shift count, since shifts by
11571;; zero don't affect the flags.  We assume that shifts by constant
11572;; zero are optimized away.
11573(define_insn "*ashrsi3_one_bit_cmp"
11574  [(set (reg FLAGS_REG)
11575	(compare
11576	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11577		       (match_operand:QI 2 "const1_operand" ""))
11578	  (const_int 0)))
11579   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11580	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11581  "ix86_match_ccmode (insn, CCGOCmode)
11582   && (TARGET_SHIFT1 || optimize_size)
11583   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11584  "sar{l}\t%0"
11585  [(set_attr "type" "ishift")
11586   (set (attr "length") 
11587     (if_then_else (match_operand:SI 0 "register_operand" "") 
11588	(const_string "2")
11589	(const_string "*")))])
11590
11591(define_insn "*ashrsi3_one_bit_cconly"
11592  [(set (reg FLAGS_REG)
11593	(compare
11594	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11595		       (match_operand:QI 2 "const1_operand" ""))
11596	  (const_int 0)))
11597   (clobber (match_scratch:SI 0 "=r"))]
11598  "ix86_match_ccmode (insn, CCGOCmode)
11599   && (TARGET_SHIFT1 || optimize_size)
11600   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11601  "sar{l}\t%0"
11602  [(set_attr "type" "ishift")
11603   (set_attr "length" "2")])
11604
11605(define_insn "*ashrsi3_one_bit_cmp_zext"
11606  [(set (reg FLAGS_REG)
11607	(compare
11608	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11609		       (match_operand:QI 2 "const1_operand" ""))
11610	  (const_int 0)))
11611   (set (match_operand:DI 0 "register_operand" "=r")
11612	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11613  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11614   && (TARGET_SHIFT1 || optimize_size)
11615   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11616  "sar{l}\t%k0"
11617  [(set_attr "type" "ishift")
11618   (set_attr "length" "2")])
11619
11620;; This pattern can't accept a variable shift count, since shifts by
11621;; zero don't affect the flags.  We assume that shifts by constant
11622;; zero are optimized away.
11623(define_insn "*ashrsi3_cmp"
11624  [(set (reg FLAGS_REG)
11625	(compare
11626	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11627		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11628	  (const_int 0)))
11629   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11630	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11631  "ix86_match_ccmode (insn, CCGOCmode)
11632   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11633   && (optimize_size
11634       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11635  "sar{l}\t{%2, %0|%0, %2}"
11636  [(set_attr "type" "ishift")
11637   (set_attr "mode" "SI")])
11638
11639(define_insn "*ashrsi3_cconly"
11640  [(set (reg FLAGS_REG)
11641	(compare
11642	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11643		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11644	  (const_int 0)))
11645   (clobber (match_scratch:SI 0 "=r"))]
11646  "ix86_match_ccmode (insn, CCGOCmode)
11647   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11648   && (optimize_size
11649       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11650  "sar{l}\t{%2, %0|%0, %2}"
11651  [(set_attr "type" "ishift")
11652   (set_attr "mode" "SI")])
11653
11654(define_insn "*ashrsi3_cmp_zext"
11655  [(set (reg FLAGS_REG)
11656	(compare
11657	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11658		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11659	  (const_int 0)))
11660   (set (match_operand:DI 0 "register_operand" "=r")
11661	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11662  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11663   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11664   && (optimize_size
11665       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11666  "sar{l}\t{%2, %k0|%k0, %2}"
11667  [(set_attr "type" "ishift")
11668   (set_attr "mode" "SI")])
11669
11670(define_expand "ashrhi3"
11671  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11672	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11673		     (match_operand:QI 2 "nonmemory_operand" "")))
11674   (clobber (reg:CC FLAGS_REG))]
11675  "TARGET_HIMODE_MATH"
11676  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11677
11678(define_insn "*ashrhi3_1_one_bit"
11679  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11680	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11681		     (match_operand:QI 2 "const1_operand" "")))
11682   (clobber (reg:CC FLAGS_REG))]
11683  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11684   && (TARGET_SHIFT1 || optimize_size)"
11685  "sar{w}\t%0"
11686  [(set_attr "type" "ishift")
11687   (set (attr "length") 
11688     (if_then_else (match_operand 0 "register_operand" "") 
11689	(const_string "2")
11690	(const_string "*")))])
11691
11692(define_insn "*ashrhi3_1"
11693  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11694	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11695		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11696   (clobber (reg:CC FLAGS_REG))]
11697  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11698  "@
11699   sar{w}\t{%2, %0|%0, %2}
11700   sar{w}\t{%b2, %0|%0, %b2}"
11701  [(set_attr "type" "ishift")
11702   (set_attr "mode" "HI")])
11703
11704;; This pattern can't accept a variable shift count, since shifts by
11705;; zero don't affect the flags.  We assume that shifts by constant
11706;; zero are optimized away.
11707(define_insn "*ashrhi3_one_bit_cmp"
11708  [(set (reg FLAGS_REG)
11709	(compare
11710	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11711		       (match_operand:QI 2 "const1_operand" ""))
11712	  (const_int 0)))
11713   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11714	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11715  "ix86_match_ccmode (insn, CCGOCmode)
11716   && (TARGET_SHIFT1 || optimize_size)
11717   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11718  "sar{w}\t%0"
11719  [(set_attr "type" "ishift")
11720   (set (attr "length") 
11721     (if_then_else (match_operand 0 "register_operand" "") 
11722	(const_string "2")
11723	(const_string "*")))])
11724
11725(define_insn "*ashrhi3_one_bit_cconly"
11726  [(set (reg FLAGS_REG)
11727	(compare
11728	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11729		       (match_operand:QI 2 "const1_operand" ""))
11730	  (const_int 0)))
11731   (clobber (match_scratch:HI 0 "=r"))]
11732  "ix86_match_ccmode (insn, CCGOCmode)
11733   && (TARGET_SHIFT1 || optimize_size)
11734   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11735  "sar{w}\t%0"
11736  [(set_attr "type" "ishift")
11737   (set_attr "length" "2")])
11738
11739;; This pattern can't accept a variable shift count, since shifts by
11740;; zero don't affect the flags.  We assume that shifts by constant
11741;; zero are optimized away.
11742(define_insn "*ashrhi3_cmp"
11743  [(set (reg FLAGS_REG)
11744	(compare
11745	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11746		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11747	  (const_int 0)))
11748   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11749	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11750  "ix86_match_ccmode (insn, CCGOCmode)
11751   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11752   && (optimize_size
11753       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11754  "sar{w}\t{%2, %0|%0, %2}"
11755  [(set_attr "type" "ishift")
11756   (set_attr "mode" "HI")])
11757
11758(define_insn "*ashrhi3_cconly"
11759  [(set (reg FLAGS_REG)
11760	(compare
11761	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11762		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11763	  (const_int 0)))
11764   (clobber (match_scratch:HI 0 "=r"))]
11765  "ix86_match_ccmode (insn, CCGOCmode)
11766   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11767   && (optimize_size
11768       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11769  "sar{w}\t{%2, %0|%0, %2}"
11770  [(set_attr "type" "ishift")
11771   (set_attr "mode" "HI")])
11772
11773(define_expand "ashrqi3"
11774  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11775	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11776		     (match_operand:QI 2 "nonmemory_operand" "")))
11777   (clobber (reg:CC FLAGS_REG))]
11778  "TARGET_QIMODE_MATH"
11779  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11780
11781(define_insn "*ashrqi3_1_one_bit"
11782  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11783	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11784		     (match_operand:QI 2 "const1_operand" "")))
11785   (clobber (reg:CC FLAGS_REG))]
11786  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11787   && (TARGET_SHIFT1 || optimize_size)"
11788  "sar{b}\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 "*ashrqi3_1_one_bit_slp"
11796  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11797	(ashiftrt:QI (match_dup 0)
11798		     (match_operand:QI 1 "const1_operand" "")))
11799   (clobber (reg:CC FLAGS_REG))]
11800  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11801   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11802   && (TARGET_SHIFT1 || optimize_size)"
11803  "sar{b}\t%0"
11804  [(set_attr "type" "ishift1")
11805   (set (attr "length") 
11806     (if_then_else (match_operand 0 "register_operand" "") 
11807	(const_string "2")
11808	(const_string "*")))])
11809
11810(define_insn "*ashrqi3_1"
11811  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11812	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11813		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11814   (clobber (reg:CC FLAGS_REG))]
11815  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11816  "@
11817   sar{b}\t{%2, %0|%0, %2}
11818   sar{b}\t{%b2, %0|%0, %b2}"
11819  [(set_attr "type" "ishift")
11820   (set_attr "mode" "QI")])
11821
11822(define_insn "*ashrqi3_1_slp"
11823  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11824	(ashiftrt:QI (match_dup 0)
11825		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11826   (clobber (reg:CC FLAGS_REG))]
11827  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11828   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11829  "@
11830   sar{b}\t{%1, %0|%0, %1}
11831   sar{b}\t{%b1, %0|%0, %b1}"
11832  [(set_attr "type" "ishift1")
11833   (set_attr "mode" "QI")])
11834
11835;; This pattern can't accept a variable shift count, since shifts by
11836;; zero don't affect the flags.  We assume that shifts by constant
11837;; zero are optimized away.
11838(define_insn "*ashrqi3_one_bit_cmp"
11839  [(set (reg FLAGS_REG)
11840	(compare
11841	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11842		       (match_operand:QI 2 "const1_operand" "I"))
11843	  (const_int 0)))
11844   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11845	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11846  "ix86_match_ccmode (insn, CCGOCmode)
11847   && (TARGET_SHIFT1 || optimize_size)
11848   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11849  "sar{b}\t%0"
11850  [(set_attr "type" "ishift")
11851   (set (attr "length") 
11852     (if_then_else (match_operand 0 "register_operand" "") 
11853	(const_string "2")
11854	(const_string "*")))])
11855
11856(define_insn "*ashrqi3_one_bit_cconly"
11857  [(set (reg FLAGS_REG)
11858	(compare
11859	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11860		       (match_operand:QI 2 "const1_operand" "I"))
11861	  (const_int 0)))
11862   (clobber (match_scratch:QI 0 "=q"))]
11863  "ix86_match_ccmode (insn, CCGOCmode)
11864   && (TARGET_SHIFT1 || optimize_size)
11865   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11866  "sar{b}\t%0"
11867  [(set_attr "type" "ishift")
11868   (set_attr "length" "2")])
11869
11870;; This pattern can't accept a variable shift count, since shifts by
11871;; zero don't affect the flags.  We assume that shifts by constant
11872;; zero are optimized away.
11873(define_insn "*ashrqi3_cmp"
11874  [(set (reg FLAGS_REG)
11875	(compare
11876	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11877		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11878	  (const_int 0)))
11879   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11880	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11881  "ix86_match_ccmode (insn, CCGOCmode)
11882   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11883   && (optimize_size
11884       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11885  "sar{b}\t{%2, %0|%0, %2}"
11886  [(set_attr "type" "ishift")
11887   (set_attr "mode" "QI")])
11888
11889(define_insn "*ashrqi3_cconly"
11890  [(set (reg FLAGS_REG)
11891	(compare
11892	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11893		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11894	  (const_int 0)))
11895   (clobber (match_scratch:QI 0 "=q"))]
11896  "ix86_match_ccmode (insn, CCGOCmode)
11897   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11898   && (optimize_size
11899       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11900  "sar{b}\t{%2, %0|%0, %2}"
11901  [(set_attr "type" "ishift")
11902   (set_attr "mode" "QI")])
11903
11904
11905;; Logical shift instructions
11906
11907;; See comment above `ashldi3' about how this works.
11908
11909(define_expand "lshrti3"
11910  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11911		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11912			        (match_operand:QI 2 "nonmemory_operand" "")))
11913	      (clobber (reg:CC FLAGS_REG))])]
11914  "TARGET_64BIT"
11915{
11916  if (! immediate_operand (operands[2], QImode))
11917    {
11918      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11919      DONE;
11920    }
11921  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11922  DONE;
11923})
11924
11925(define_insn "lshrti3_1"
11926  [(set (match_operand:TI 0 "register_operand" "=r")
11927	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11928		     (match_operand:QI 2 "register_operand" "c")))
11929   (clobber (match_scratch:DI 3 "=&r"))
11930   (clobber (reg:CC FLAGS_REG))]
11931  "TARGET_64BIT"
11932  "#"
11933  [(set_attr "type" "multi")])
11934
11935(define_insn "*lshrti3_2"
11936  [(set (match_operand:TI 0 "register_operand" "=r")
11937	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11938		     (match_operand:QI 2 "immediate_operand" "O")))
11939   (clobber (reg:CC FLAGS_REG))]
11940  "TARGET_64BIT"
11941  "#"
11942  [(set_attr "type" "multi")])
11943
11944(define_split 
11945  [(set (match_operand:TI 0 "register_operand" "")
11946	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11947		     (match_operand:QI 2 "register_operand" "")))
11948   (clobber (match_scratch:DI 3 ""))
11949   (clobber (reg:CC FLAGS_REG))]
11950  "TARGET_64BIT && reload_completed"
11951  [(const_int 0)]
11952  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11953
11954(define_split 
11955  [(set (match_operand:TI 0 "register_operand" "")
11956	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11957		     (match_operand:QI 2 "immediate_operand" "")))
11958   (clobber (reg:CC FLAGS_REG))]
11959  "TARGET_64BIT && reload_completed"
11960  [(const_int 0)]
11961  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11962
11963(define_expand "lshrdi3"
11964  [(set (match_operand:DI 0 "shiftdi_operand" "")
11965	(lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11966		     (match_operand:QI 2 "nonmemory_operand" "")))]
11967  ""
11968  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11969
11970(define_insn "*lshrdi3_1_one_bit_rex64"
11971  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11972	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11973		     (match_operand:QI 2 "const1_operand" "")))
11974   (clobber (reg:CC FLAGS_REG))]
11975  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11976   && (TARGET_SHIFT1 || optimize_size)"
11977  "shr{q}\t%0"
11978  [(set_attr "type" "ishift")
11979   (set (attr "length") 
11980     (if_then_else (match_operand:DI 0 "register_operand" "") 
11981	(const_string "2")
11982	(const_string "*")))])
11983
11984(define_insn "*lshrdi3_1_rex64"
11985  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11986	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11987		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11988   (clobber (reg:CC FLAGS_REG))]
11989  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11990  "@
11991   shr{q}\t{%2, %0|%0, %2}
11992   shr{q}\t{%b2, %0|%0, %b2}"
11993  [(set_attr "type" "ishift")
11994   (set_attr "mode" "DI")])
11995
11996;; This pattern can't accept a variable shift count, since shifts by
11997;; zero don't affect the flags.  We assume that shifts by constant
11998;; zero are optimized away.
11999(define_insn "*lshrdi3_cmp_one_bit_rex64"
12000  [(set (reg FLAGS_REG)
12001	(compare
12002	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12003		       (match_operand:QI 2 "const1_operand" ""))
12004	  (const_int 0)))
12005   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12006	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12007  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12008   && (TARGET_SHIFT1 || optimize_size)
12009   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12010  "shr{q}\t%0"
12011  [(set_attr "type" "ishift")
12012   (set (attr "length") 
12013     (if_then_else (match_operand:DI 0 "register_operand" "") 
12014	(const_string "2")
12015	(const_string "*")))])
12016
12017(define_insn "*lshrdi3_cconly_one_bit_rex64"
12018  [(set (reg FLAGS_REG)
12019	(compare
12020	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12021		       (match_operand:QI 2 "const1_operand" ""))
12022	  (const_int 0)))
12023   (clobber (match_scratch:DI 0 "=r"))]
12024  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12025   && (TARGET_SHIFT1 || optimize_size)
12026   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12027  "shr{q}\t%0"
12028  [(set_attr "type" "ishift")
12029   (set_attr "length" "2")])
12030
12031;; This pattern can't accept a variable shift count, since shifts by
12032;; zero don't affect the flags.  We assume that shifts by constant
12033;; zero are optimized away.
12034(define_insn "*lshrdi3_cmp_rex64"
12035  [(set (reg FLAGS_REG)
12036	(compare
12037	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12038		       (match_operand:QI 2 "const_int_operand" "e"))
12039	  (const_int 0)))
12040   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12041	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12042  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12043   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12044   && (optimize_size
12045       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12046  "shr{q}\t{%2, %0|%0, %2}"
12047  [(set_attr "type" "ishift")
12048   (set_attr "mode" "DI")])
12049
12050(define_insn "*lshrdi3_cconly_rex64"
12051  [(set (reg FLAGS_REG)
12052	(compare
12053	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12054		       (match_operand:QI 2 "const_int_operand" "e"))
12055	  (const_int 0)))
12056   (clobber (match_scratch:DI 0 "=r"))]
12057  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12058   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12059   && (optimize_size
12060       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12061  "shr{q}\t{%2, %0|%0, %2}"
12062  [(set_attr "type" "ishift")
12063   (set_attr "mode" "DI")])
12064
12065(define_insn "*lshrdi3_1"
12066  [(set (match_operand:DI 0 "register_operand" "=r")
12067	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12068		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
12069   (clobber (reg:CC FLAGS_REG))]
12070  "!TARGET_64BIT"
12071  "#"
12072  [(set_attr "type" "multi")])
12073
12074;; By default we don't ask for a scratch register, because when DImode
12075;; values are manipulated, registers are already at a premium.  But if
12076;; we have one handy, we won't turn it away.
12077(define_peephole2
12078  [(match_scratch:SI 3 "r")
12079   (parallel [(set (match_operand:DI 0 "register_operand" "")
12080		   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12081			        (match_operand:QI 2 "nonmemory_operand" "")))
12082	      (clobber (reg:CC FLAGS_REG))])
12083   (match_dup 3)]
12084  "!TARGET_64BIT && TARGET_CMOVE"
12085  [(const_int 0)]
12086  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12087
12088(define_split 
12089  [(set (match_operand:DI 0 "register_operand" "")
12090	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12091		     (match_operand:QI 2 "nonmemory_operand" "")))
12092   (clobber (reg:CC FLAGS_REG))]
12093  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12094		     ? flow2_completed : reload_completed)"
12095  [(const_int 0)]
12096  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12097
12098(define_expand "lshrsi3"
12099  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12100	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12101		     (match_operand:QI 2 "nonmemory_operand" "")))
12102   (clobber (reg:CC FLAGS_REG))]
12103  ""
12104  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12105
12106(define_insn "*lshrsi3_1_one_bit"
12107  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12108	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12109		     (match_operand:QI 2 "const1_operand" "")))
12110   (clobber (reg:CC FLAGS_REG))]
12111  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12112   && (TARGET_SHIFT1 || optimize_size)"
12113  "shr{l}\t%0"
12114  [(set_attr "type" "ishift")
12115   (set (attr "length") 
12116     (if_then_else (match_operand:SI 0 "register_operand" "") 
12117	(const_string "2")
12118	(const_string "*")))])
12119
12120(define_insn "*lshrsi3_1_one_bit_zext"
12121  [(set (match_operand:DI 0 "register_operand" "=r")
12122	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12123		     (match_operand:QI 2 "const1_operand" "")))
12124   (clobber (reg:CC FLAGS_REG))]
12125  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12126   && (TARGET_SHIFT1 || optimize_size)"
12127  "shr{l}\t%k0"
12128  [(set_attr "type" "ishift")
12129   (set_attr "length" "2")])
12130
12131(define_insn "*lshrsi3_1"
12132  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12133	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12134		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12135   (clobber (reg:CC FLAGS_REG))]
12136  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12137  "@
12138   shr{l}\t{%2, %0|%0, %2}
12139   shr{l}\t{%b2, %0|%0, %b2}"
12140  [(set_attr "type" "ishift")
12141   (set_attr "mode" "SI")])
12142
12143(define_insn "*lshrsi3_1_zext"
12144  [(set (match_operand:DI 0 "register_operand" "=r,r")
12145	(zero_extend:DI
12146	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12147		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12148   (clobber (reg:CC FLAGS_REG))]
12149  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12150  "@
12151   shr{l}\t{%2, %k0|%k0, %2}
12152   shr{l}\t{%b2, %k0|%k0, %b2}"
12153  [(set_attr "type" "ishift")
12154   (set_attr "mode" "SI")])
12155
12156;; This pattern can't accept a variable shift count, since shifts by
12157;; zero don't affect the flags.  We assume that shifts by constant
12158;; zero are optimized away.
12159(define_insn "*lshrsi3_one_bit_cmp"
12160  [(set (reg FLAGS_REG)
12161	(compare
12162	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163		       (match_operand:QI 2 "const1_operand" ""))
12164	  (const_int 0)))
12165   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12166	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12167  "ix86_match_ccmode (insn, CCGOCmode)
12168   && (TARGET_SHIFT1 || optimize_size)
12169   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12170  "shr{l}\t%0"
12171  [(set_attr "type" "ishift")
12172   (set (attr "length") 
12173     (if_then_else (match_operand:SI 0 "register_operand" "") 
12174	(const_string "2")
12175	(const_string "*")))])
12176
12177(define_insn "*lshrsi3_one_bit_cconly"
12178  [(set (reg FLAGS_REG)
12179	(compare
12180	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12181		       (match_operand:QI 2 "const1_operand" ""))
12182	  (const_int 0)))
12183   (clobber (match_scratch:SI 0 "=r"))]
12184  "ix86_match_ccmode (insn, CCGOCmode)
12185   && (TARGET_SHIFT1 || optimize_size)
12186   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12187  "shr{l}\t%0"
12188  [(set_attr "type" "ishift")
12189   (set_attr "length" "2")])
12190
12191(define_insn "*lshrsi3_cmp_one_bit_zext"
12192  [(set (reg FLAGS_REG)
12193	(compare
12194	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12195		       (match_operand:QI 2 "const1_operand" ""))
12196	  (const_int 0)))
12197   (set (match_operand:DI 0 "register_operand" "=r")
12198	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12199  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12200   && (TARGET_SHIFT1 || optimize_size)
12201   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12202  "shr{l}\t%k0"
12203  [(set_attr "type" "ishift")
12204   (set_attr "length" "2")])
12205
12206;; This pattern can't accept a variable shift count, since shifts by
12207;; zero don't affect the flags.  We assume that shifts by constant
12208;; zero are optimized away.
12209(define_insn "*lshrsi3_cmp"
12210  [(set (reg FLAGS_REG)
12211	(compare
12212	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12213		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12214	  (const_int 0)))
12215   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12216	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12217  "ix86_match_ccmode (insn, CCGOCmode)
12218   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12219   && (optimize_size
12220       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12221  "shr{l}\t{%2, %0|%0, %2}"
12222  [(set_attr "type" "ishift")
12223   (set_attr "mode" "SI")])
12224
12225(define_insn "*lshrsi3_cconly"
12226  [(set (reg FLAGS_REG)
12227      (compare
12228	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12229		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
12230        (const_int 0)))
12231   (clobber (match_scratch:SI 0 "=r"))]
12232  "ix86_match_ccmode (insn, CCGOCmode)
12233   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12234   && (optimize_size
12235       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12236  "shr{l}\t{%2, %0|%0, %2}"
12237  [(set_attr "type" "ishift")
12238   (set_attr "mode" "SI")])
12239
12240(define_insn "*lshrsi3_cmp_zext"
12241  [(set (reg FLAGS_REG)
12242	(compare
12243	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12244		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12245	  (const_int 0)))
12246   (set (match_operand:DI 0 "register_operand" "=r")
12247	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12248  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12249   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12250   && (optimize_size
12251       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12252  "shr{l}\t{%2, %k0|%k0, %2}"
12253  [(set_attr "type" "ishift")
12254   (set_attr "mode" "SI")])
12255
12256(define_expand "lshrhi3"
12257  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12258	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12259		     (match_operand:QI 2 "nonmemory_operand" "")))
12260   (clobber (reg:CC FLAGS_REG))]
12261  "TARGET_HIMODE_MATH"
12262  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12263
12264(define_insn "*lshrhi3_1_one_bit"
12265  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12266	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12267		     (match_operand:QI 2 "const1_operand" "")))
12268   (clobber (reg:CC FLAGS_REG))]
12269  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12270   && (TARGET_SHIFT1 || optimize_size)"
12271  "shr{w}\t%0"
12272  [(set_attr "type" "ishift")
12273   (set (attr "length") 
12274     (if_then_else (match_operand 0 "register_operand" "") 
12275	(const_string "2")
12276	(const_string "*")))])
12277
12278(define_insn "*lshrhi3_1"
12279  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12280	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12281		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12282   (clobber (reg:CC FLAGS_REG))]
12283  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12284  "@
12285   shr{w}\t{%2, %0|%0, %2}
12286   shr{w}\t{%b2, %0|%0, %b2}"
12287  [(set_attr "type" "ishift")
12288   (set_attr "mode" "HI")])
12289
12290;; This pattern can't accept a variable shift count, since shifts by
12291;; zero don't affect the flags.  We assume that shifts by constant
12292;; zero are optimized away.
12293(define_insn "*lshrhi3_one_bit_cmp"
12294  [(set (reg FLAGS_REG)
12295	(compare
12296	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12297		       (match_operand:QI 2 "const1_operand" ""))
12298	  (const_int 0)))
12299   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12300	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12301  "ix86_match_ccmode (insn, CCGOCmode)
12302   && (TARGET_SHIFT1 || optimize_size)
12303   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12304  "shr{w}\t%0"
12305  [(set_attr "type" "ishift")
12306   (set (attr "length") 
12307     (if_then_else (match_operand:SI 0 "register_operand" "") 
12308	(const_string "2")
12309	(const_string "*")))])
12310
12311(define_insn "*lshrhi3_one_bit_cconly"
12312  [(set (reg FLAGS_REG)
12313	(compare
12314	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12315		       (match_operand:QI 2 "const1_operand" ""))
12316	  (const_int 0)))
12317   (clobber (match_scratch:HI 0 "=r"))]
12318  "ix86_match_ccmode (insn, CCGOCmode)
12319   && (TARGET_SHIFT1 || optimize_size)
12320   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12321  "shr{w}\t%0"
12322  [(set_attr "type" "ishift")
12323   (set_attr "length" "2")])
12324
12325;; This pattern can't accept a variable shift count, since shifts by
12326;; zero don't affect the flags.  We assume that shifts by constant
12327;; zero are optimized away.
12328(define_insn "*lshrhi3_cmp"
12329  [(set (reg FLAGS_REG)
12330	(compare
12331	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12332		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12333	  (const_int 0)))
12334   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12335	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12336  "ix86_match_ccmode (insn, CCGOCmode)
12337   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12338   && (optimize_size
12339       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12340  "shr{w}\t{%2, %0|%0, %2}"
12341  [(set_attr "type" "ishift")
12342   (set_attr "mode" "HI")])
12343
12344(define_insn "*lshrhi3_cconly"
12345  [(set (reg FLAGS_REG)
12346	(compare
12347	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12348		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12349	  (const_int 0)))
12350   (clobber (match_scratch:HI 0 "=r"))]
12351  "ix86_match_ccmode (insn, CCGOCmode)
12352   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12353   && (optimize_size
12354       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12355  "shr{w}\t{%2, %0|%0, %2}"
12356  [(set_attr "type" "ishift")
12357   (set_attr "mode" "HI")])
12358
12359(define_expand "lshrqi3"
12360  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12361	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12362		     (match_operand:QI 2 "nonmemory_operand" "")))
12363   (clobber (reg:CC FLAGS_REG))]
12364  "TARGET_QIMODE_MATH"
12365  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12366
12367(define_insn "*lshrqi3_1_one_bit"
12368  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12369	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12370		     (match_operand:QI 2 "const1_operand" "")))
12371   (clobber (reg:CC FLAGS_REG))]
12372  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12373   && (TARGET_SHIFT1 || optimize_size)"
12374  "shr{b}\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 "*lshrqi3_1_one_bit_slp"
12382  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12383	(lshiftrt:QI (match_dup 0)
12384		     (match_operand:QI 1 "const1_operand" "")))
12385   (clobber (reg:CC FLAGS_REG))]
12386  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12387   && (TARGET_SHIFT1 || optimize_size)"
12388  "shr{b}\t%0"
12389  [(set_attr "type" "ishift1")
12390   (set (attr "length") 
12391     (if_then_else (match_operand 0 "register_operand" "") 
12392	(const_string "2")
12393	(const_string "*")))])
12394
12395(define_insn "*lshrqi3_1"
12396  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12397	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12398		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12399   (clobber (reg:CC FLAGS_REG))]
12400  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12401  "@
12402   shr{b}\t{%2, %0|%0, %2}
12403   shr{b}\t{%b2, %0|%0, %b2}"
12404  [(set_attr "type" "ishift")
12405   (set_attr "mode" "QI")])
12406
12407(define_insn "*lshrqi3_1_slp"
12408  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12409	(lshiftrt:QI (match_dup 0)
12410		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12411   (clobber (reg:CC FLAGS_REG))]
12412  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12413   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12414  "@
12415   shr{b}\t{%1, %0|%0, %1}
12416   shr{b}\t{%b1, %0|%0, %b1}"
12417  [(set_attr "type" "ishift1")
12418   (set_attr "mode" "QI")])
12419
12420;; This pattern can't accept a variable shift count, since shifts by
12421;; zero don't affect the flags.  We assume that shifts by constant
12422;; zero are optimized away.
12423(define_insn "*lshrqi2_one_bit_cmp"
12424  [(set (reg FLAGS_REG)
12425	(compare
12426	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12427		       (match_operand:QI 2 "const1_operand" ""))
12428	  (const_int 0)))
12429   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12430	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12431  "ix86_match_ccmode (insn, CCGOCmode)
12432   && (TARGET_SHIFT1 || optimize_size)
12433   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12434  "shr{b}\t%0"
12435  [(set_attr "type" "ishift")
12436   (set (attr "length") 
12437     (if_then_else (match_operand:SI 0 "register_operand" "") 
12438	(const_string "2")
12439	(const_string "*")))])
12440
12441(define_insn "*lshrqi2_one_bit_cconly"
12442  [(set (reg FLAGS_REG)
12443	(compare
12444	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12445		       (match_operand:QI 2 "const1_operand" ""))
12446	  (const_int 0)))
12447   (clobber (match_scratch:QI 0 "=q"))]
12448  "ix86_match_ccmode (insn, CCGOCmode)
12449   && (TARGET_SHIFT1 || optimize_size)
12450   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12451  "shr{b}\t%0"
12452  [(set_attr "type" "ishift")
12453   (set_attr "length" "2")])
12454
12455;; This pattern can't accept a variable shift count, since shifts by
12456;; zero don't affect the flags.  We assume that shifts by constant
12457;; zero are optimized away.
12458(define_insn "*lshrqi2_cmp"
12459  [(set (reg FLAGS_REG)
12460	(compare
12461	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12462		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12463	  (const_int 0)))
12464   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12465	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12466  "ix86_match_ccmode (insn, CCGOCmode)
12467   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12468   && (optimize_size
12469       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12470  "shr{b}\t{%2, %0|%0, %2}"
12471  [(set_attr "type" "ishift")
12472   (set_attr "mode" "QI")])
12473
12474(define_insn "*lshrqi2_cconly"
12475  [(set (reg FLAGS_REG)
12476	(compare
12477	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12478		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12479	  (const_int 0)))
12480   (clobber (match_scratch:QI 0 "=q"))]
12481  "ix86_match_ccmode (insn, CCGOCmode)
12482   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12483   && (optimize_size
12484       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12485  "shr{b}\t{%2, %0|%0, %2}"
12486  [(set_attr "type" "ishift")
12487   (set_attr "mode" "QI")])
12488
12489;; Rotate instructions
12490
12491(define_expand "rotldi3"
12492  [(set (match_operand:DI 0 "shiftdi_operand" "")
12493	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12494		   (match_operand:QI 2 "nonmemory_operand" "")))
12495   (clobber (reg:CC FLAGS_REG))]
12496 ""
12497{
12498  if (TARGET_64BIT)
12499    {
12500      ix86_expand_binary_operator (ROTATE, DImode, operands);
12501      DONE;
12502    }
12503  if (!const_1_to_31_operand (operands[2], VOIDmode))
12504    FAIL;
12505  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12506  DONE;
12507})
12508
12509;; Implement rotation using two double-precision shift instructions
12510;; and a scratch register.   
12511(define_insn_and_split "ix86_rotldi3"
12512 [(set (match_operand:DI 0 "register_operand" "=r")
12513       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12514                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12515  (clobber (reg:CC FLAGS_REG))
12516  (clobber (match_scratch:SI 3 "=&r"))]
12517 "!TARGET_64BIT"
12518 "" 
12519 "&& reload_completed"
12520 [(set (match_dup 3) (match_dup 4))
12521  (parallel
12522   [(set (match_dup 4)
12523         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12524                 (lshiftrt:SI (match_dup 5)
12525                              (minus:QI (const_int 32) (match_dup 2)))))
12526    (clobber (reg:CC FLAGS_REG))])
12527  (parallel
12528   [(set (match_dup 5)
12529         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12530                 (lshiftrt:SI (match_dup 3)
12531                              (minus:QI (const_int 32) (match_dup 2)))))
12532    (clobber (reg:CC FLAGS_REG))])]
12533 "split_di (operands, 1, operands + 4, operands + 5);")
12534 
12535(define_insn "*rotlsi3_1_one_bit_rex64"
12536  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12537	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12538		   (match_operand:QI 2 "const1_operand" "")))
12539   (clobber (reg:CC FLAGS_REG))]
12540  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12541   && (TARGET_SHIFT1 || optimize_size)"
12542  "rol{q}\t%0"
12543  [(set_attr "type" "rotate")
12544   (set (attr "length") 
12545     (if_then_else (match_operand:DI 0 "register_operand" "") 
12546	(const_string "2")
12547	(const_string "*")))])
12548
12549(define_insn "*rotldi3_1_rex64"
12550  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12551	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12552		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12553   (clobber (reg:CC FLAGS_REG))]
12554  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12555  "@
12556   rol{q}\t{%2, %0|%0, %2}
12557   rol{q}\t{%b2, %0|%0, %b2}"
12558  [(set_attr "type" "rotate")
12559   (set_attr "mode" "DI")])
12560
12561(define_expand "rotlsi3"
12562  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12563	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12564		   (match_operand:QI 2 "nonmemory_operand" "")))
12565   (clobber (reg:CC FLAGS_REG))]
12566  ""
12567  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12568
12569(define_insn "*rotlsi3_1_one_bit"
12570  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12571	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12572		   (match_operand:QI 2 "const1_operand" "")))
12573   (clobber (reg:CC FLAGS_REG))]
12574  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12575   && (TARGET_SHIFT1 || optimize_size)"
12576  "rol{l}\t%0"
12577  [(set_attr "type" "rotate")
12578   (set (attr "length") 
12579     (if_then_else (match_operand:SI 0 "register_operand" "") 
12580	(const_string "2")
12581	(const_string "*")))])
12582
12583(define_insn "*rotlsi3_1_one_bit_zext"
12584  [(set (match_operand:DI 0 "register_operand" "=r")
12585	(zero_extend:DI
12586	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12587		     (match_operand:QI 2 "const1_operand" ""))))
12588   (clobber (reg:CC FLAGS_REG))]
12589  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12590   && (TARGET_SHIFT1 || optimize_size)"
12591  "rol{l}\t%k0"
12592  [(set_attr "type" "rotate")
12593   (set_attr "length" "2")])
12594
12595(define_insn "*rotlsi3_1"
12596  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12597	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12598		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12599   (clobber (reg:CC FLAGS_REG))]
12600  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12601  "@
12602   rol{l}\t{%2, %0|%0, %2}
12603   rol{l}\t{%b2, %0|%0, %b2}"
12604  [(set_attr "type" "rotate")
12605   (set_attr "mode" "SI")])
12606
12607(define_insn "*rotlsi3_1_zext"
12608  [(set (match_operand:DI 0 "register_operand" "=r,r")
12609	(zero_extend:DI
12610	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12611		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12612   (clobber (reg:CC FLAGS_REG))]
12613  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12614  "@
12615   rol{l}\t{%2, %k0|%k0, %2}
12616   rol{l}\t{%b2, %k0|%k0, %b2}"
12617  [(set_attr "type" "rotate")
12618   (set_attr "mode" "SI")])
12619
12620(define_expand "rotlhi3"
12621  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12622	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12623		   (match_operand:QI 2 "nonmemory_operand" "")))
12624   (clobber (reg:CC FLAGS_REG))]
12625  "TARGET_HIMODE_MATH"
12626  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12627
12628(define_insn "*rotlhi3_1_one_bit"
12629  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12630	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12631		   (match_operand:QI 2 "const1_operand" "")))
12632   (clobber (reg:CC FLAGS_REG))]
12633  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12634   && (TARGET_SHIFT1 || optimize_size)"
12635  "rol{w}\t%0"
12636  [(set_attr "type" "rotate")
12637   (set (attr "length") 
12638     (if_then_else (match_operand 0 "register_operand" "") 
12639	(const_string "2")
12640	(const_string "*")))])
12641
12642(define_insn "*rotlhi3_1"
12643  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12644	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12645		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12646   (clobber (reg:CC FLAGS_REG))]
12647  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12648  "@
12649   rol{w}\t{%2, %0|%0, %2}
12650   rol{w}\t{%b2, %0|%0, %b2}"
12651  [(set_attr "type" "rotate")
12652   (set_attr "mode" "HI")])
12653
12654(define_expand "rotlqi3"
12655  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12656	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12657		   (match_operand:QI 2 "nonmemory_operand" "")))
12658   (clobber (reg:CC FLAGS_REG))]
12659  "TARGET_QIMODE_MATH"
12660  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12661
12662(define_insn "*rotlqi3_1_one_bit_slp"
12663  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12664	(rotate:QI (match_dup 0)
12665		   (match_operand:QI 1 "const1_operand" "")))
12666   (clobber (reg:CC FLAGS_REG))]
12667  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12668   && (TARGET_SHIFT1 || optimize_size)"
12669  "rol{b}\t%0"
12670  [(set_attr "type" "rotate1")
12671   (set (attr "length") 
12672     (if_then_else (match_operand 0 "register_operand" "") 
12673	(const_string "2")
12674	(const_string "*")))])
12675
12676(define_insn "*rotlqi3_1_one_bit"
12677  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12678	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12679		   (match_operand:QI 2 "const1_operand" "")))
12680   (clobber (reg:CC FLAGS_REG))]
12681  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12682   && (TARGET_SHIFT1 || optimize_size)"
12683  "rol{b}\t%0"
12684  [(set_attr "type" "rotate")
12685   (set (attr "length") 
12686     (if_then_else (match_operand 0 "register_operand" "") 
12687	(const_string "2")
12688	(const_string "*")))])
12689
12690(define_insn "*rotlqi3_1_slp"
12691  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12692	(rotate:QI (match_dup 0)
12693		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12694   (clobber (reg:CC FLAGS_REG))]
12695  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12696   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12697  "@
12698   rol{b}\t{%1, %0|%0, %1}
12699   rol{b}\t{%b1, %0|%0, %b1}"
12700  [(set_attr "type" "rotate1")
12701   (set_attr "mode" "QI")])
12702
12703(define_insn "*rotlqi3_1"
12704  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12705	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12706		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12707   (clobber (reg:CC FLAGS_REG))]
12708  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12709  "@
12710   rol{b}\t{%2, %0|%0, %2}
12711   rol{b}\t{%b2, %0|%0, %b2}"
12712  [(set_attr "type" "rotate")
12713   (set_attr "mode" "QI")])
12714
12715(define_expand "rotrdi3"
12716  [(set (match_operand:DI 0 "shiftdi_operand" "")
12717	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12718		   (match_operand:QI 2 "nonmemory_operand" "")))
12719   (clobber (reg:CC FLAGS_REG))]
12720 ""
12721{
12722  if (TARGET_64BIT)
12723    {
12724      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12725      DONE;
12726    }
12727  if (!const_1_to_31_operand (operands[2], VOIDmode))
12728    FAIL;
12729  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12730  DONE;
12731})
12732  
12733;; Implement rotation using two double-precision shift instructions
12734;; and a scratch register.   
12735(define_insn_and_split "ix86_rotrdi3"
12736 [(set (match_operand:DI 0 "register_operand" "=r")
12737       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12738                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12739  (clobber (reg:CC FLAGS_REG))
12740  (clobber (match_scratch:SI 3 "=&r"))]
12741 "!TARGET_64BIT"
12742 ""
12743 "&& reload_completed"
12744 [(set (match_dup 3) (match_dup 4))
12745  (parallel
12746   [(set (match_dup 4)
12747         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12748                 (ashift:SI (match_dup 5)
12749                            (minus:QI (const_int 32) (match_dup 2)))))
12750    (clobber (reg:CC FLAGS_REG))])
12751  (parallel
12752   [(set (match_dup 5)
12753         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12754                 (ashift:SI (match_dup 3)
12755                            (minus:QI (const_int 32) (match_dup 2)))))
12756    (clobber (reg:CC FLAGS_REG))])]
12757 "split_di (operands, 1, operands + 4, operands + 5);")
12758
12759(define_insn "*rotrdi3_1_one_bit_rex64"
12760  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12761	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12762		     (match_operand:QI 2 "const1_operand" "")))
12763   (clobber (reg:CC FLAGS_REG))]
12764  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12765   && (TARGET_SHIFT1 || optimize_size)"
12766  "ror{q}\t%0"
12767  [(set_attr "type" "rotate")
12768   (set (attr "length") 
12769     (if_then_else (match_operand:DI 0 "register_operand" "") 
12770	(const_string "2")
12771	(const_string "*")))])
12772
12773(define_insn "*rotrdi3_1_rex64"
12774  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12775	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12776		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12777   (clobber (reg:CC FLAGS_REG))]
12778  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12779  "@
12780   ror{q}\t{%2, %0|%0, %2}
12781   ror{q}\t{%b2, %0|%0, %b2}"
12782  [(set_attr "type" "rotate")
12783   (set_attr "mode" "DI")])
12784
12785(define_expand "rotrsi3"
12786  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12787	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12788		     (match_operand:QI 2 "nonmemory_operand" "")))
12789   (clobber (reg:CC FLAGS_REG))]
12790  ""
12791  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12792
12793(define_insn "*rotrsi3_1_one_bit"
12794  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12795	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12796		     (match_operand:QI 2 "const1_operand" "")))
12797   (clobber (reg:CC FLAGS_REG))]
12798  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12799   && (TARGET_SHIFT1 || optimize_size)"
12800  "ror{l}\t%0"
12801  [(set_attr "type" "rotate")
12802   (set (attr "length") 
12803     (if_then_else (match_operand:SI 0 "register_operand" "") 
12804	(const_string "2")
12805	(const_string "*")))])
12806
12807(define_insn "*rotrsi3_1_one_bit_zext"
12808  [(set (match_operand:DI 0 "register_operand" "=r")
12809	(zero_extend:DI
12810	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12811		       (match_operand:QI 2 "const1_operand" ""))))
12812   (clobber (reg:CC FLAGS_REG))]
12813  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12814   && (TARGET_SHIFT1 || optimize_size)"
12815  "ror{l}\t%k0"
12816  [(set_attr "type" "rotate")
12817   (set (attr "length") 
12818     (if_then_else (match_operand:SI 0 "register_operand" "") 
12819	(const_string "2")
12820	(const_string "*")))])
12821
12822(define_insn "*rotrsi3_1"
12823  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12824	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12825		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12826   (clobber (reg:CC FLAGS_REG))]
12827  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12828  "@
12829   ror{l}\t{%2, %0|%0, %2}
12830   ror{l}\t{%b2, %0|%0, %b2}"
12831  [(set_attr "type" "rotate")
12832   (set_attr "mode" "SI")])
12833
12834(define_insn "*rotrsi3_1_zext"
12835  [(set (match_operand:DI 0 "register_operand" "=r,r")
12836	(zero_extend:DI
12837	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12838		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12839   (clobber (reg:CC FLAGS_REG))]
12840  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12841  "@
12842   ror{l}\t{%2, %k0|%k0, %2}
12843   ror{l}\t{%b2, %k0|%k0, %b2}"
12844  [(set_attr "type" "rotate")
12845   (set_attr "mode" "SI")])
12846
12847(define_expand "rotrhi3"
12848  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12849	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12850		     (match_operand:QI 2 "nonmemory_operand" "")))
12851   (clobber (reg:CC FLAGS_REG))]
12852  "TARGET_HIMODE_MATH"
12853  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12854
12855(define_insn "*rotrhi3_one_bit"
12856  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12857	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12858		     (match_operand:QI 2 "const1_operand" "")))
12859   (clobber (reg:CC FLAGS_REG))]
12860  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12861   && (TARGET_SHIFT1 || optimize_size)"
12862  "ror{w}\t%0"
12863  [(set_attr "type" "rotate")
12864   (set (attr "length") 
12865     (if_then_else (match_operand 0 "register_operand" "") 
12866	(const_string "2")
12867	(const_string "*")))])
12868
12869(define_insn "*rotrhi3"
12870  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12871	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12872		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12873   (clobber (reg:CC FLAGS_REG))]
12874  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12875  "@
12876   ror{w}\t{%2, %0|%0, %2}
12877   ror{w}\t{%b2, %0|%0, %b2}"
12878  [(set_attr "type" "rotate")
12879   (set_attr "mode" "HI")])
12880
12881(define_expand "rotrqi3"
12882  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12883	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12884		     (match_operand:QI 2 "nonmemory_operand" "")))
12885   (clobber (reg:CC FLAGS_REG))]
12886  "TARGET_QIMODE_MATH"
12887  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12888
12889(define_insn "*rotrqi3_1_one_bit"
12890  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12891	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12892		     (match_operand:QI 2 "const1_operand" "")))
12893   (clobber (reg:CC FLAGS_REG))]
12894  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12895   && (TARGET_SHIFT1 || optimize_size)"
12896  "ror{b}\t%0"
12897  [(set_attr "type" "rotate")
12898   (set (attr "length") 
12899     (if_then_else (match_operand 0 "register_operand" "") 
12900	(const_string "2")
12901	(const_string "*")))])
12902
12903(define_insn "*rotrqi3_1_one_bit_slp"
12904  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12905	(rotatert:QI (match_dup 0)
12906		     (match_operand:QI 1 "const1_operand" "")))
12907   (clobber (reg:CC FLAGS_REG))]
12908  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12909   && (TARGET_SHIFT1 || optimize_size)"
12910  "ror{b}\t%0"
12911  [(set_attr "type" "rotate1")
12912   (set (attr "length") 
12913     (if_then_else (match_operand 0 "register_operand" "") 
12914	(const_string "2")
12915	(const_string "*")))])
12916
12917(define_insn "*rotrqi3_1"
12918  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12919	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12920		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12921   (clobber (reg:CC FLAGS_REG))]
12922  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12923  "@
12924   ror{b}\t{%2, %0|%0, %2}
12925   ror{b}\t{%b2, %0|%0, %b2}"
12926  [(set_attr "type" "rotate")
12927   (set_attr "mode" "QI")])
12928
12929(define_insn "*rotrqi3_1_slp"
12930  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12931	(rotatert:QI (match_dup 0)
12932		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12933   (clobber (reg:CC FLAGS_REG))]
12934  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12935   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12936  "@
12937   ror{b}\t{%1, %0|%0, %1}
12938   ror{b}\t{%b1, %0|%0, %b1}"
12939  [(set_attr "type" "rotate1")
12940   (set_attr "mode" "QI")])
12941
12942;; Bit set / bit test instructions
12943
12944(define_expand "extv"
12945  [(set (match_operand:SI 0 "register_operand" "")
12946	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
12947			 (match_operand:SI 2 "const8_operand" "")
12948			 (match_operand:SI 3 "const8_operand" "")))]
12949  ""
12950{
12951  /* Handle extractions from %ah et al.  */
12952  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12953    FAIL;
12954
12955  /* From mips.md: extract_bit_field doesn't verify that our source
12956     matches the predicate, so check it again here.  */
12957  if (! ext_register_operand (operands[1], VOIDmode))
12958    FAIL;
12959})
12960
12961(define_expand "extzv"
12962  [(set (match_operand:SI 0 "register_operand" "")
12963	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
12964			 (match_operand:SI 2 "const8_operand" "")
12965			 (match_operand:SI 3 "const8_operand" "")))]
12966  ""
12967{
12968  /* Handle extractions from %ah et al.  */
12969  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12970    FAIL;
12971
12972  /* From mips.md: extract_bit_field doesn't verify that our source
12973     matches the predicate, so check it again here.  */
12974  if (! ext_register_operand (operands[1], VOIDmode))
12975    FAIL;
12976})
12977
12978(define_expand "insv"
12979  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12980		      (match_operand 1 "const8_operand" "")
12981		      (match_operand 2 "const8_operand" ""))
12982        (match_operand 3 "register_operand" ""))]
12983  ""
12984{
12985  /* Handle insertions to %ah et al.  */
12986  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12987    FAIL;
12988
12989  /* From mips.md: insert_bit_field doesn't verify that our source
12990     matches the predicate, so check it again here.  */
12991  if (! ext_register_operand (operands[0], VOIDmode))
12992    FAIL;
12993
12994  if (TARGET_64BIT)
12995    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12996  else
12997    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12998
12999  DONE;
13000})
13001
13002;; %%% bts, btr, btc, bt.
13003;; In general these instructions are *slow* when applied to memory,
13004;; since they enforce atomic operation.  When applied to registers,
13005;; it depends on the cpu implementation.  They're never faster than
13006;; the corresponding and/ior/xor operations, so with 32-bit there's
13007;; no point.  But in 64-bit, we can't hold the relevant immediates
13008;; within the instruction itself, so operating on bits in the high
13009;; 32-bits of a register becomes easier.
13010;;
13011;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13012;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13013;; negdf respectively, so they can never be disabled entirely.
13014
13015(define_insn "*btsq"
13016  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13017			 (const_int 1)
13018			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13019	(const_int 1))
13020   (clobber (reg:CC FLAGS_REG))]
13021  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13022  "bts{q} %1,%0"
13023  [(set_attr "type" "alu1")])
13024
13025(define_insn "*btrq"
13026  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13027			 (const_int 1)
13028			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13029	(const_int 0))
13030   (clobber (reg:CC FLAGS_REG))]
13031  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13032  "btr{q} %1,%0"
13033  [(set_attr "type" "alu1")])
13034
13035(define_insn "*btcq"
13036  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13037			 (const_int 1)
13038			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13039	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13040   (clobber (reg:CC FLAGS_REG))]
13041  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13042  "btc{q} %1,%0"
13043  [(set_attr "type" "alu1")])
13044
13045;; Allow Nocona to avoid these instructions if a register is available.
13046
13047(define_peephole2
13048  [(match_scratch:DI 2 "r")
13049   (parallel [(set (zero_extract:DI
13050		     (match_operand:DI 0 "register_operand" "")
13051		     (const_int 1)
13052		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13053		   (const_int 1))
13054	      (clobber (reg:CC FLAGS_REG))])]
13055  "TARGET_64BIT && !TARGET_USE_BT"
13056  [(const_int 0)]
13057{
13058  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13059  rtx op1;
13060
13061  if (HOST_BITS_PER_WIDE_INT >= 64)
13062    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13063  else if (i < HOST_BITS_PER_WIDE_INT)
13064    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13065  else
13066    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13067
13068  op1 = immed_double_const (lo, hi, DImode);
13069  if (i >= 31)
13070    {
13071      emit_move_insn (operands[2], op1);
13072      op1 = operands[2];
13073    }
13074
13075  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13076  DONE;
13077})
13078
13079(define_peephole2
13080  [(match_scratch:DI 2 "r")
13081   (parallel [(set (zero_extract:DI
13082		     (match_operand:DI 0 "register_operand" "")
13083		     (const_int 1)
13084		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13085		   (const_int 0))
13086	      (clobber (reg:CC FLAGS_REG))])]
13087  "TARGET_64BIT && !TARGET_USE_BT"
13088  [(const_int 0)]
13089{
13090  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13091  rtx op1;
13092
13093  if (HOST_BITS_PER_WIDE_INT >= 64)
13094    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13095  else if (i < HOST_BITS_PER_WIDE_INT)
13096    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13097  else
13098    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13099
13100  op1 = immed_double_const (~lo, ~hi, DImode);
13101  if (i >= 32)
13102    {
13103      emit_move_insn (operands[2], op1);
13104      op1 = operands[2];
13105    }
13106
13107  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13108  DONE;
13109})
13110
13111(define_peephole2
13112  [(match_scratch:DI 2 "r")
13113   (parallel [(set (zero_extract:DI
13114		     (match_operand:DI 0 "register_operand" "")
13115		     (const_int 1)
13116		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13117	      (not:DI (zero_extract:DI
13118			(match_dup 0) (const_int 1) (match_dup 1))))
13119	      (clobber (reg:CC FLAGS_REG))])]
13120  "TARGET_64BIT && !TARGET_USE_BT"
13121  [(const_int 0)]
13122{
13123  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13124  rtx op1;
13125
13126  if (HOST_BITS_PER_WIDE_INT >= 64)
13127    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13128  else if (i < HOST_BITS_PER_WIDE_INT)
13129    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13130  else
13131    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13132
13133  op1 = immed_double_const (lo, hi, DImode);
13134  if (i >= 31)
13135    {
13136      emit_move_insn (operands[2], op1);
13137      op1 = operands[2];
13138    }
13139
13140  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13141  DONE;
13142})
13143
13144;; Store-flag instructions.
13145
13146;; For all sCOND expanders, also expand the compare or test insn that
13147;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13148
13149;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13150;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13151;; way, which can later delete the movzx if only QImode is needed.
13152
13153(define_expand "seq"
13154  [(set (match_operand:QI 0 "register_operand" "")
13155        (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13156  ""
13157  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13158
13159(define_expand "sne"
13160  [(set (match_operand:QI 0 "register_operand" "")
13161        (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13162  ""
13163  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13164
13165(define_expand "sgt"
13166  [(set (match_operand:QI 0 "register_operand" "")
13167        (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13168  ""
13169  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13170
13171(define_expand "sgtu"
13172  [(set (match_operand:QI 0 "register_operand" "")
13173        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13174  ""
13175  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13176
13177(define_expand "slt"
13178  [(set (match_operand:QI 0 "register_operand" "")
13179        (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13180  ""
13181  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13182
13183(define_expand "sltu"
13184  [(set (match_operand:QI 0 "register_operand" "")
13185        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13186  ""
13187  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13188
13189(define_expand "sge"
13190  [(set (match_operand:QI 0 "register_operand" "")
13191        (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13192  ""
13193  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13194
13195(define_expand "sgeu"
13196  [(set (match_operand:QI 0 "register_operand" "")
13197        (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13198  ""
13199  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13200
13201(define_expand "sle"
13202  [(set (match_operand:QI 0 "register_operand" "")
13203        (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13204  ""
13205  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13206
13207(define_expand "sleu"
13208  [(set (match_operand:QI 0 "register_operand" "")
13209        (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210  ""
13211  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13212
13213(define_expand "sunordered"
13214  [(set (match_operand:QI 0 "register_operand" "")
13215        (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216  "TARGET_80387 || TARGET_SSE"
13217  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13218
13219(define_expand "sordered"
13220  [(set (match_operand:QI 0 "register_operand" "")
13221        (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222  "TARGET_80387"
13223  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13224
13225(define_expand "suneq"
13226  [(set (match_operand:QI 0 "register_operand" "")
13227        (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228  "TARGET_80387 || TARGET_SSE"
13229  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13230
13231(define_expand "sunge"
13232  [(set (match_operand:QI 0 "register_operand" "")
13233        (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234  "TARGET_80387 || TARGET_SSE"
13235  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13236
13237(define_expand "sungt"
13238  [(set (match_operand:QI 0 "register_operand" "")
13239        (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240  "TARGET_80387 || TARGET_SSE"
13241  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13242
13243(define_expand "sunle"
13244  [(set (match_operand:QI 0 "register_operand" "")
13245        (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246  "TARGET_80387 || TARGET_SSE"
13247  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13248
13249(define_expand "sunlt"
13250  [(set (match_operand:QI 0 "register_operand" "")
13251        (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252  "TARGET_80387 || TARGET_SSE"
13253  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13254
13255(define_expand "sltgt"
13256  [(set (match_operand:QI 0 "register_operand" "")
13257        (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258  "TARGET_80387 || TARGET_SSE"
13259  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13260
13261(define_insn "*setcc_1"
13262  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13263	(match_operator:QI 1 "ix86_comparison_operator"
13264	  [(reg FLAGS_REG) (const_int 0)]))]
13265  ""
13266  "set%C1\t%0"
13267  [(set_attr "type" "setcc")
13268   (set_attr "mode" "QI")])
13269
13270(define_insn "*setcc_2"
13271  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13272	(match_operator:QI 1 "ix86_comparison_operator"
13273	  [(reg FLAGS_REG) (const_int 0)]))]
13274  ""
13275  "set%C1\t%0"
13276  [(set_attr "type" "setcc")
13277   (set_attr "mode" "QI")])
13278
13279;; In general it is not safe to assume too much about CCmode registers,
13280;; so simplify-rtx stops when it sees a second one.  Under certain 
13281;; conditions this is safe on x86, so help combine not create
13282;;
13283;;	seta	%al
13284;;	testb	%al, %al
13285;;	sete	%al
13286
13287(define_split 
13288  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13289	(ne:QI (match_operator 1 "ix86_comparison_operator"
13290	         [(reg FLAGS_REG) (const_int 0)])
13291	    (const_int 0)))]
13292  ""
13293  [(set (match_dup 0) (match_dup 1))]
13294{
13295  PUT_MODE (operands[1], QImode);
13296})
13297
13298(define_split 
13299  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13300	(ne:QI (match_operator 1 "ix86_comparison_operator"
13301	         [(reg FLAGS_REG) (const_int 0)])
13302	    (const_int 0)))]
13303  ""
13304  [(set (match_dup 0) (match_dup 1))]
13305{
13306  PUT_MODE (operands[1], QImode);
13307})
13308
13309(define_split 
13310  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13311	(eq:QI (match_operator 1 "ix86_comparison_operator"
13312	         [(reg FLAGS_REG) (const_int 0)])
13313	    (const_int 0)))]
13314  ""
13315  [(set (match_dup 0) (match_dup 1))]
13316{
13317  rtx new_op1 = copy_rtx (operands[1]);
13318  operands[1] = new_op1;
13319  PUT_MODE (new_op1, QImode);
13320  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13321					     GET_MODE (XEXP (new_op1, 0))));
13322
13323  /* Make sure that (a) the CCmode we have for the flags is strong
13324     enough for the reversed compare or (b) we have a valid FP compare.  */
13325  if (! ix86_comparison_operator (new_op1, VOIDmode))
13326    FAIL;
13327})
13328
13329(define_split 
13330  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13331	(eq:QI (match_operator 1 "ix86_comparison_operator"
13332	         [(reg FLAGS_REG) (const_int 0)])
13333	    (const_int 0)))]
13334  ""
13335  [(set (match_dup 0) (match_dup 1))]
13336{
13337  rtx new_op1 = copy_rtx (operands[1]);
13338  operands[1] = new_op1;
13339  PUT_MODE (new_op1, QImode);
13340  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13341					     GET_MODE (XEXP (new_op1, 0))));
13342
13343  /* Make sure that (a) the CCmode we have for the flags is strong
13344     enough for the reversed compare or (b) we have a valid FP compare.  */
13345  if (! ix86_comparison_operator (new_op1, VOIDmode))
13346    FAIL;
13347})
13348
13349;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13350;; subsequent logical operations are used to imitate conditional moves.
13351;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13352;; it directly.
13353
13354(define_insn "*sse_setccsf"
13355  [(set (match_operand:SF 0 "register_operand" "=x")
13356	(match_operator:SF 1 "sse_comparison_operator"
13357	  [(match_operand:SF 2 "register_operand" "0")
13358	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13359  "TARGET_SSE"
13360  "cmp%D1ss\t{%3, %0|%0, %3}"
13361  [(set_attr "type" "ssecmp")
13362   (set_attr "mode" "SF")])
13363
13364(define_insn "*sse_setccdf"
13365  [(set (match_operand:DF 0 "register_operand" "=Y")
13366	(match_operator:DF 1 "sse_comparison_operator"
13367	  [(match_operand:DF 2 "register_operand" "0")
13368	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13369  "TARGET_SSE2"
13370  "cmp%D1sd\t{%3, %0|%0, %3}"
13371  [(set_attr "type" "ssecmp")
13372   (set_attr "mode" "DF")])
13373
13374;; Basic conditional jump instructions.
13375;; We ignore the overflow flag for signed branch instructions.
13376
13377;; For all bCOND expanders, also expand the compare or test insn that
13378;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13379
13380(define_expand "beq"
13381  [(set (pc)
13382	(if_then_else (match_dup 1)
13383		      (label_ref (match_operand 0 "" ""))
13384		      (pc)))]
13385  ""
13386  "ix86_expand_branch (EQ, operands[0]); DONE;")
13387
13388(define_expand "bne"
13389  [(set (pc)
13390	(if_then_else (match_dup 1)
13391		      (label_ref (match_operand 0 "" ""))
13392		      (pc)))]
13393  ""
13394  "ix86_expand_branch (NE, operands[0]); DONE;")
13395
13396(define_expand "bgt"
13397  [(set (pc)
13398	(if_then_else (match_dup 1)
13399		      (label_ref (match_operand 0 "" ""))
13400		      (pc)))]
13401  ""
13402  "ix86_expand_branch (GT, operands[0]); DONE;")
13403
13404(define_expand "bgtu"
13405  [(set (pc)
13406	(if_then_else (match_dup 1)
13407		      (label_ref (match_operand 0 "" ""))
13408		      (pc)))]
13409  ""
13410  "ix86_expand_branch (GTU, operands[0]); DONE;")
13411
13412(define_expand "blt"
13413  [(set (pc)
13414	(if_then_else (match_dup 1)
13415		      (label_ref (match_operand 0 "" ""))
13416		      (pc)))]
13417  ""
13418  "ix86_expand_branch (LT, operands[0]); DONE;")
13419
13420(define_expand "bltu"
13421  [(set (pc)
13422	(if_then_else (match_dup 1)
13423		      (label_ref (match_operand 0 "" ""))
13424		      (pc)))]
13425  ""
13426  "ix86_expand_branch (LTU, operands[0]); DONE;")
13427
13428(define_expand "bge"
13429  [(set (pc)
13430	(if_then_else (match_dup 1)
13431		      (label_ref (match_operand 0 "" ""))
13432		      (pc)))]
13433  ""
13434  "ix86_expand_branch (GE, operands[0]); DONE;")
13435
13436(define_expand "bgeu"
13437  [(set (pc)
13438	(if_then_else (match_dup 1)
13439		      (label_ref (match_operand 0 "" ""))
13440		      (pc)))]
13441  ""
13442  "ix86_expand_branch (GEU, operands[0]); DONE;")
13443
13444(define_expand "ble"
13445  [(set (pc)
13446	(if_then_else (match_dup 1)
13447		      (label_ref (match_operand 0 "" ""))
13448		      (pc)))]
13449  ""
13450  "ix86_expand_branch (LE, operands[0]); DONE;")
13451
13452(define_expand "bleu"
13453  [(set (pc)
13454	(if_then_else (match_dup 1)
13455		      (label_ref (match_operand 0 "" ""))
13456		      (pc)))]
13457  ""
13458  "ix86_expand_branch (LEU, operands[0]); DONE;")
13459
13460(define_expand "bunordered"
13461  [(set (pc)
13462	(if_then_else (match_dup 1)
13463		      (label_ref (match_operand 0 "" ""))
13464		      (pc)))]
13465  "TARGET_80387 || TARGET_SSE_MATH"
13466  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13467
13468(define_expand "bordered"
13469  [(set (pc)
13470	(if_then_else (match_dup 1)
13471		      (label_ref (match_operand 0 "" ""))
13472		      (pc)))]
13473  "TARGET_80387 || TARGET_SSE_MATH"
13474  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13475
13476(define_expand "buneq"
13477  [(set (pc)
13478	(if_then_else (match_dup 1)
13479		      (label_ref (match_operand 0 "" ""))
13480		      (pc)))]
13481  "TARGET_80387 || TARGET_SSE_MATH"
13482  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13483
13484(define_expand "bunge"
13485  [(set (pc)
13486	(if_then_else (match_dup 1)
13487		      (label_ref (match_operand 0 "" ""))
13488		      (pc)))]
13489  "TARGET_80387 || TARGET_SSE_MATH"
13490  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13491
13492(define_expand "bungt"
13493  [(set (pc)
13494	(if_then_else (match_dup 1)
13495		      (label_ref (match_operand 0 "" ""))
13496		      (pc)))]
13497  "TARGET_80387 || TARGET_SSE_MATH"
13498  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13499
13500(define_expand "bunle"
13501  [(set (pc)
13502	(if_then_else (match_dup 1)
13503		      (label_ref (match_operand 0 "" ""))
13504		      (pc)))]
13505  "TARGET_80387 || TARGET_SSE_MATH"
13506  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13507
13508(define_expand "bunlt"
13509  [(set (pc)
13510	(if_then_else (match_dup 1)
13511		      (label_ref (match_operand 0 "" ""))
13512		      (pc)))]
13513  "TARGET_80387 || TARGET_SSE_MATH"
13514  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13515
13516(define_expand "bltgt"
13517  [(set (pc)
13518	(if_then_else (match_dup 1)
13519		      (label_ref (match_operand 0 "" ""))
13520		      (pc)))]
13521  "TARGET_80387 || TARGET_SSE_MATH"
13522  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13523
13524(define_insn "*jcc_1"
13525  [(set (pc)
13526	(if_then_else (match_operator 1 "ix86_comparison_operator"
13527				      [(reg FLAGS_REG) (const_int 0)])
13528		      (label_ref (match_operand 0 "" ""))
13529		      (pc)))]
13530  ""
13531  "%+j%C1\t%l0"
13532  [(set_attr "type" "ibr")
13533   (set_attr "modrm" "0")
13534   (set (attr "length")
13535	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13536				  (const_int -126))
13537			      (lt (minus (match_dup 0) (pc))
13538				  (const_int 128)))
13539	     (const_int 2)
13540	     (const_int 6)))])
13541
13542(define_insn "*jcc_2"
13543  [(set (pc)
13544	(if_then_else (match_operator 1 "ix86_comparison_operator"
13545				      [(reg FLAGS_REG) (const_int 0)])
13546		      (pc)
13547		      (label_ref (match_operand 0 "" ""))))]
13548  ""
13549  "%+j%c1\t%l0"
13550  [(set_attr "type" "ibr")
13551   (set_attr "modrm" "0")
13552   (set (attr "length")
13553	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13554				  (const_int -126))
13555			      (lt (minus (match_dup 0) (pc))
13556				  (const_int 128)))
13557	     (const_int 2)
13558	     (const_int 6)))])
13559
13560;; In general it is not safe to assume too much about CCmode registers,
13561;; so simplify-rtx stops when it sees a second one.  Under certain 
13562;; conditions this is safe on x86, so help combine not create
13563;;
13564;;	seta	%al
13565;;	testb	%al, %al
13566;;	je	Lfoo
13567
13568(define_split 
13569  [(set (pc)
13570	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13571				      [(reg FLAGS_REG) (const_int 0)])
13572			  (const_int 0))
13573		      (label_ref (match_operand 1 "" ""))
13574		      (pc)))]
13575  ""
13576  [(set (pc)
13577	(if_then_else (match_dup 0)
13578		      (label_ref (match_dup 1))
13579		      (pc)))]
13580{
13581  PUT_MODE (operands[0], VOIDmode);
13582})
13583  
13584(define_split 
13585  [(set (pc)
13586	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13587				      [(reg FLAGS_REG) (const_int 0)])
13588			  (const_int 0))
13589		      (label_ref (match_operand 1 "" ""))
13590		      (pc)))]
13591  ""
13592  [(set (pc)
13593	(if_then_else (match_dup 0)
13594		      (label_ref (match_dup 1))
13595		      (pc)))]
13596{
13597  rtx new_op0 = copy_rtx (operands[0]);
13598  operands[0] = new_op0;
13599  PUT_MODE (new_op0, VOIDmode);
13600  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13601					     GET_MODE (XEXP (new_op0, 0))));
13602
13603  /* Make sure that (a) the CCmode we have for the flags is strong
13604     enough for the reversed compare or (b) we have a valid FP compare.  */
13605  if (! ix86_comparison_operator (new_op0, VOIDmode))
13606    FAIL;
13607})
13608
13609;; Define combination compare-and-branch fp compare instructions to use
13610;; during early optimization.  Splitting the operation apart early makes
13611;; for bad code when we want to reverse the operation.
13612
13613(define_insn "*fp_jcc_1_mixed"
13614  [(set (pc)
13615	(if_then_else (match_operator 0 "comparison_operator"
13616			[(match_operand 1 "register_operand" "f,x")
13617			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13618	  (label_ref (match_operand 3 "" ""))
13619	  (pc)))
13620   (clobber (reg:CCFP FPSR_REG))
13621   (clobber (reg:CCFP FLAGS_REG))]
13622  "TARGET_MIX_SSE_I387
13623   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13624   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13625   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13626  "#")
13627
13628(define_insn "*fp_jcc_1_sse"
13629  [(set (pc)
13630	(if_then_else (match_operator 0 "comparison_operator"
13631			[(match_operand 1 "register_operand" "x")
13632			 (match_operand 2 "nonimmediate_operand" "xm")])
13633	  (label_ref (match_operand 3 "" ""))
13634	  (pc)))
13635   (clobber (reg:CCFP FPSR_REG))
13636   (clobber (reg:CCFP FLAGS_REG))]
13637  "TARGET_SSE_MATH
13638   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13639   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13640   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13641  "#")
13642
13643(define_insn "*fp_jcc_1_387"
13644  [(set (pc)
13645	(if_then_else (match_operator 0 "comparison_operator"
13646			[(match_operand 1 "register_operand" "f")
13647			 (match_operand 2 "register_operand" "f")])
13648	  (label_ref (match_operand 3 "" ""))
13649	  (pc)))
13650   (clobber (reg:CCFP FPSR_REG))
13651   (clobber (reg:CCFP FLAGS_REG))]
13652  "TARGET_CMOVE && TARGET_80387
13653   && FLOAT_MODE_P (GET_MODE (operands[1]))
13654   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13655   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13656  "#")
13657
13658(define_insn "*fp_jcc_2_mixed"
13659  [(set (pc)
13660	(if_then_else (match_operator 0 "comparison_operator"
13661			[(match_operand 1 "register_operand" "f,x")
13662			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13663	  (pc)
13664	  (label_ref (match_operand 3 "" ""))))
13665   (clobber (reg:CCFP FPSR_REG))
13666   (clobber (reg:CCFP FLAGS_REG))]
13667  "TARGET_MIX_SSE_I387
13668   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13669   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13670   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13671  "#")
13672
13673(define_insn "*fp_jcc_2_sse"
13674  [(set (pc)
13675	(if_then_else (match_operator 0 "comparison_operator"
13676			[(match_operand 1 "register_operand" "x")
13677			 (match_operand 2 "nonimmediate_operand" "xm")])
13678	  (pc)
13679	  (label_ref (match_operand 3 "" ""))))
13680   (clobber (reg:CCFP FPSR_REG))
13681   (clobber (reg:CCFP FLAGS_REG))]
13682  "TARGET_SSE_MATH
13683   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13684   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13685   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13686  "#")
13687
13688(define_insn "*fp_jcc_2_387"
13689  [(set (pc)
13690	(if_then_else (match_operator 0 "comparison_operator"
13691			[(match_operand 1 "register_operand" "f")
13692			 (match_operand 2 "register_operand" "f")])
13693	  (pc)
13694	  (label_ref (match_operand 3 "" ""))))
13695   (clobber (reg:CCFP FPSR_REG))
13696   (clobber (reg:CCFP FLAGS_REG))]
13697  "TARGET_CMOVE && TARGET_80387
13698   && FLOAT_MODE_P (GET_MODE (operands[1]))
13699   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13700   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13701  "#")
13702
13703(define_insn "*fp_jcc_3_387"
13704  [(set (pc)
13705	(if_then_else (match_operator 0 "comparison_operator"
13706			[(match_operand 1 "register_operand" "f")
13707			 (match_operand 2 "nonimmediate_operand" "fm")])
13708	  (label_ref (match_operand 3 "" ""))
13709	  (pc)))
13710   (clobber (reg:CCFP FPSR_REG))
13711   (clobber (reg:CCFP FLAGS_REG))
13712   (clobber (match_scratch:HI 4 "=a"))]
13713  "TARGET_80387
13714   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13715   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13716   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13717   && SELECT_CC_MODE (GET_CODE (operands[0]),
13718		      operands[1], operands[2]) == CCFPmode
13719   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13720  "#")
13721
13722(define_insn "*fp_jcc_4_387"
13723  [(set (pc)
13724	(if_then_else (match_operator 0 "comparison_operator"
13725			[(match_operand 1 "register_operand" "f")
13726			 (match_operand 2 "nonimmediate_operand" "fm")])
13727	  (pc)
13728	  (label_ref (match_operand 3 "" ""))))
13729   (clobber (reg:CCFP FPSR_REG))
13730   (clobber (reg:CCFP FLAGS_REG))
13731   (clobber (match_scratch:HI 4 "=a"))]
13732  "TARGET_80387
13733   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13734   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13735   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13736   && SELECT_CC_MODE (GET_CODE (operands[0]),
13737		      operands[1], operands[2]) == CCFPmode
13738   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13739  "#")
13740
13741(define_insn "*fp_jcc_5_387"
13742  [(set (pc)
13743	(if_then_else (match_operator 0 "comparison_operator"
13744			[(match_operand 1 "register_operand" "f")
13745			 (match_operand 2 "register_operand" "f")])
13746	  (label_ref (match_operand 3 "" ""))
13747	  (pc)))
13748   (clobber (reg:CCFP FPSR_REG))
13749   (clobber (reg:CCFP FLAGS_REG))
13750   (clobber (match_scratch:HI 4 "=a"))]
13751  "TARGET_80387
13752   && FLOAT_MODE_P (GET_MODE (operands[1]))
13753   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13754   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13755  "#")
13756
13757(define_insn "*fp_jcc_6_387"
13758  [(set (pc)
13759	(if_then_else (match_operator 0 "comparison_operator"
13760			[(match_operand 1 "register_operand" "f")
13761			 (match_operand 2 "register_operand" "f")])
13762	  (pc)
13763	  (label_ref (match_operand 3 "" ""))))
13764   (clobber (reg:CCFP FPSR_REG))
13765   (clobber (reg:CCFP FLAGS_REG))
13766   (clobber (match_scratch:HI 4 "=a"))]
13767  "TARGET_80387
13768   && FLOAT_MODE_P (GET_MODE (operands[1]))
13769   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13771  "#")
13772
13773(define_insn "*fp_jcc_7_387"
13774  [(set (pc)
13775	(if_then_else (match_operator 0 "comparison_operator"
13776			[(match_operand 1 "register_operand" "f")
13777			 (match_operand 2 "const0_operand" "X")])
13778	  (label_ref (match_operand 3 "" ""))
13779	  (pc)))
13780   (clobber (reg:CCFP FPSR_REG))
13781   (clobber (reg:CCFP FLAGS_REG))
13782   (clobber (match_scratch:HI 4 "=a"))]
13783  "TARGET_80387
13784   && FLOAT_MODE_P (GET_MODE (operands[1]))
13785   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13786   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13787   && SELECT_CC_MODE (GET_CODE (operands[0]),
13788		      operands[1], operands[2]) == CCFPmode
13789   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13790  "#")
13791
13792;; The order of operands in *fp_jcc_8_387 is forced by combine in
13793;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13794;; with a precedence over other operators and is always put in the first
13795;; place. Swap condition and operands to match ficom instruction.
13796
13797(define_insn "*fp_jcc_8<mode>_387"
13798  [(set (pc)
13799	(if_then_else (match_operator 0 "comparison_operator"
13800			[(match_operator 1 "float_operator"
13801			   [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13802			   (match_operand 3 "register_operand" "f,f")])
13803	  (label_ref (match_operand 4 "" ""))
13804	  (pc)))
13805   (clobber (reg:CCFP FPSR_REG))
13806   (clobber (reg:CCFP FLAGS_REG))
13807   (clobber (match_scratch:HI 5 "=a,a"))]
13808  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13809   && FLOAT_MODE_P (GET_MODE (operands[3]))
13810   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13811   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13812   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13813   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13814  "#")
13815
13816(define_split
13817  [(set (pc)
13818	(if_then_else (match_operator 0 "comparison_operator"
13819			[(match_operand 1 "register_operand" "")
13820			 (match_operand 2 "nonimmediate_operand" "")])
13821	  (match_operand 3 "" "")
13822	  (match_operand 4 "" "")))
13823   (clobber (reg:CCFP FPSR_REG))
13824   (clobber (reg:CCFP FLAGS_REG))]
13825  "reload_completed"
13826  [(const_int 0)]
13827{
13828  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13829	                operands[3], operands[4], NULL_RTX, NULL_RTX);
13830  DONE;
13831})
13832
13833(define_split
13834  [(set (pc)
13835	(if_then_else (match_operator 0 "comparison_operator"
13836			[(match_operand 1 "register_operand" "")
13837			 (match_operand 2 "general_operand" "")])
13838	  (match_operand 3 "" "")
13839	  (match_operand 4 "" "")))
13840   (clobber (reg:CCFP FPSR_REG))
13841   (clobber (reg:CCFP FLAGS_REG))
13842   (clobber (match_scratch:HI 5 "=a"))]
13843  "reload_completed"
13844  [(const_int 0)]
13845{
13846  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13847	     		operands[3], operands[4], operands[5], NULL_RTX);
13848  DONE;
13849})
13850
13851(define_split
13852  [(set (pc)
13853	(if_then_else (match_operator 0 "comparison_operator"
13854			[(match_operator 1 "float_operator"
13855			   [(match_operand:X87MODEI12 2 "memory_operand" "")])
13856			   (match_operand 3 "register_operand" "")])
13857	  (match_operand 4 "" "")
13858	  (match_operand 5 "" "")))
13859   (clobber (reg:CCFP FPSR_REG))
13860   (clobber (reg:CCFP FLAGS_REG))
13861   (clobber (match_scratch:HI 6 "=a"))]
13862  "reload_completed"
13863  [(const_int 0)]
13864{
13865  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13866  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13867			operands[3], operands[7],
13868			operands[4], operands[5], operands[6], NULL_RTX);
13869  DONE;
13870})
13871
13872;; %%% Kill this when reload knows how to do it.
13873(define_split
13874  [(set (pc)
13875	(if_then_else (match_operator 0 "comparison_operator"
13876			[(match_operator 1 "float_operator"
13877			   [(match_operand:X87MODEI12 2 "register_operand" "")])
13878			   (match_operand 3 "register_operand" "")])
13879	  (match_operand 4 "" "")
13880	  (match_operand 5 "" "")))
13881   (clobber (reg:CCFP FPSR_REG))
13882   (clobber (reg:CCFP FLAGS_REG))
13883   (clobber (match_scratch:HI 6 "=a"))]
13884  "reload_completed"
13885  [(const_int 0)]
13886{
13887  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13888  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13889  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13890			operands[3], operands[7],
13891			operands[4], operands[5], operands[6], operands[2]);
13892  DONE;
13893})
13894
13895;; Unconditional and other jump instructions
13896
13897(define_insn "jump"
13898  [(set (pc)
13899	(label_ref (match_operand 0 "" "")))]
13900  ""
13901  "jmp\t%l0"
13902  [(set_attr "type" "ibr")
13903   (set (attr "length")
13904	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13905				  (const_int -126))
13906			      (lt (minus (match_dup 0) (pc))
13907				  (const_int 128)))
13908	     (const_int 2)
13909	     (const_int 5)))
13910   (set_attr "modrm" "0")])
13911
13912(define_expand "indirect_jump"
13913  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13914  ""
13915  "")
13916
13917(define_insn "*indirect_jump"
13918  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13919  "!TARGET_64BIT"
13920  "jmp\t%A0"
13921  [(set_attr "type" "ibr")
13922   (set_attr "length_immediate" "0")])
13923
13924(define_insn "*indirect_jump_rtx64"
13925  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13926  "TARGET_64BIT"
13927  "jmp\t%A0"
13928  [(set_attr "type" "ibr")
13929   (set_attr "length_immediate" "0")])
13930
13931(define_expand "tablejump"
13932  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13933	      (use (label_ref (match_operand 1 "" "")))])]
13934  ""
13935{
13936  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13937     relative.  Convert the relative address to an absolute address.  */
13938  if (flag_pic)
13939    {
13940      rtx op0, op1;
13941      enum rtx_code code;
13942
13943      if (TARGET_64BIT)
13944	{
13945	  code = PLUS;
13946	  op0 = operands[0];
13947	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13948	}
13949      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13950	{
13951	  code = PLUS;
13952	  op0 = operands[0];
13953	  op1 = pic_offset_table_rtx;
13954	}
13955      else
13956	{
13957	  code = MINUS;
13958	  op0 = pic_offset_table_rtx;
13959	  op1 = operands[0];
13960	}
13961
13962      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13963					 OPTAB_DIRECT);
13964    }
13965})
13966
13967(define_insn "*tablejump_1"
13968  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13969   (use (label_ref (match_operand 1 "" "")))]
13970  "!TARGET_64BIT"
13971  "jmp\t%A0"
13972  [(set_attr "type" "ibr")
13973   (set_attr "length_immediate" "0")])
13974
13975(define_insn "*tablejump_1_rtx64"
13976  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13977   (use (label_ref (match_operand 1 "" "")))]
13978  "TARGET_64BIT"
13979  "jmp\t%A0"
13980  [(set_attr "type" "ibr")
13981   (set_attr "length_immediate" "0")])
13982
13983;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13984
13985(define_peephole2
13986  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13987   (set (match_operand:QI 1 "register_operand" "")
13988	(match_operator:QI 2 "ix86_comparison_operator"
13989	  [(reg FLAGS_REG) (const_int 0)]))
13990   (set (match_operand 3 "q_regs_operand" "")
13991	(zero_extend (match_dup 1)))]
13992  "(peep2_reg_dead_p (3, operands[1])
13993    || operands_match_p (operands[1], operands[3]))
13994   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13995  [(set (match_dup 4) (match_dup 0))
13996   (set (strict_low_part (match_dup 5))
13997	(match_dup 2))]
13998{
13999  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14000  operands[5] = gen_lowpart (QImode, operands[3]);
14001  ix86_expand_clear (operands[3]);
14002})
14003
14004;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14005
14006(define_peephole2
14007  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14008   (set (match_operand:QI 1 "register_operand" "")
14009	(match_operator:QI 2 "ix86_comparison_operator"
14010	  [(reg FLAGS_REG) (const_int 0)]))
14011   (parallel [(set (match_operand 3 "q_regs_operand" "")
14012		   (zero_extend (match_dup 1)))
14013	      (clobber (reg:CC FLAGS_REG))])]
14014  "(peep2_reg_dead_p (3, operands[1])
14015    || operands_match_p (operands[1], operands[3]))
14016   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14017  [(set (match_dup 4) (match_dup 0))
14018   (set (strict_low_part (match_dup 5))
14019	(match_dup 2))]
14020{
14021  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14022  operands[5] = gen_lowpart (QImode, operands[3]);
14023  ix86_expand_clear (operands[3]);
14024})
14025
14026;; Call instructions.
14027
14028;; The predicates normally associated with named expanders are not properly
14029;; checked for calls.  This is a bug in the generic code, but it isn't that
14030;; easy to fix.  Ignore it for now and be prepared to fix things up.
14031
14032;; Call subroutine returning no value.
14033
14034(define_expand "call_pop"
14035  [(parallel [(call (match_operand:QI 0 "" "")
14036		    (match_operand:SI 1 "" ""))
14037	      (set (reg:SI SP_REG)
14038		   (plus:SI (reg:SI SP_REG)
14039			    (match_operand:SI 3 "" "")))])]
14040  "!TARGET_64BIT"
14041{
14042  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14043  DONE;
14044})
14045
14046(define_insn "*call_pop_0"
14047  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14048	 (match_operand:SI 1 "" ""))
14049   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14050			    (match_operand:SI 2 "immediate_operand" "")))]
14051  "!TARGET_64BIT"
14052{
14053  if (SIBLING_CALL_P (insn))
14054    return "jmp\t%P0";
14055  else
14056    return "call\t%P0";
14057}
14058  [(set_attr "type" "call")])
14059  
14060(define_insn "*call_pop_1"
14061  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14062	 (match_operand:SI 1 "" ""))
14063   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14064			    (match_operand:SI 2 "immediate_operand" "i")))]
14065  "!TARGET_64BIT"
14066{
14067  if (constant_call_address_operand (operands[0], Pmode))
14068    {
14069      if (SIBLING_CALL_P (insn))
14070	return "jmp\t%P0";
14071      else
14072	return "call\t%P0";
14073    }
14074  if (SIBLING_CALL_P (insn))
14075    return "jmp\t%A0";
14076  else
14077    return "call\t%A0";
14078}
14079  [(set_attr "type" "call")])
14080
14081(define_expand "call"
14082  [(call (match_operand:QI 0 "" "")
14083	 (match_operand 1 "" ""))
14084   (use (match_operand 2 "" ""))]
14085  ""
14086{
14087  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14088  DONE;
14089})
14090
14091(define_expand "sibcall"
14092  [(call (match_operand:QI 0 "" "")
14093	 (match_operand 1 "" ""))
14094   (use (match_operand 2 "" ""))]
14095  ""
14096{
14097  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14098  DONE;
14099})
14100
14101(define_insn "*call_0"
14102  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14103	 (match_operand 1 "" ""))]
14104  ""
14105{
14106  if (SIBLING_CALL_P (insn))
14107    return "jmp\t%P0";
14108  else
14109    return "call\t%P0";
14110}
14111  [(set_attr "type" "call")])
14112
14113(define_insn "*call_1"
14114  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14115	 (match_operand 1 "" ""))]
14116  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14117{
14118  if (constant_call_address_operand (operands[0], Pmode))
14119    return "call\t%P0";
14120  return "call\t%A0";
14121}
14122  [(set_attr "type" "call")])
14123
14124(define_insn "*sibcall_1"
14125  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14126	 (match_operand 1 "" ""))]
14127  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14128{
14129  if (constant_call_address_operand (operands[0], Pmode))
14130    return "jmp\t%P0";
14131  return "jmp\t%A0";
14132}
14133  [(set_attr "type" "call")])
14134
14135(define_insn "*call_1_rex64"
14136  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14137	 (match_operand 1 "" ""))]
14138  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14139{
14140  if (constant_call_address_operand (operands[0], Pmode))
14141    return "call\t%P0";
14142  return "call\t%A0";
14143}
14144  [(set_attr "type" "call")])
14145
14146(define_insn "*sibcall_1_rex64"
14147  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14148	 (match_operand 1 "" ""))]
14149  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14150  "jmp\t%P0"
14151  [(set_attr "type" "call")])
14152
14153(define_insn "*sibcall_1_rex64_v"
14154  [(call (mem:QI (reg:DI 40))
14155	 (match_operand 0 "" ""))]
14156  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14157  "jmp\t*%%r11"
14158  [(set_attr "type" "call")])
14159
14160
14161;; Call subroutine, returning value in operand 0
14162
14163(define_expand "call_value_pop"
14164  [(parallel [(set (match_operand 0 "" "")
14165		   (call (match_operand:QI 1 "" "")
14166			 (match_operand:SI 2 "" "")))
14167	      (set (reg:SI SP_REG)
14168		   (plus:SI (reg:SI SP_REG)
14169			    (match_operand:SI 4 "" "")))])]
14170  "!TARGET_64BIT"
14171{
14172  ix86_expand_call (operands[0], operands[1], operands[2],
14173		    operands[3], operands[4], 0);
14174  DONE;
14175})
14176
14177(define_expand "call_value"
14178  [(set (match_operand 0 "" "")
14179	(call (match_operand:QI 1 "" "")
14180	      (match_operand:SI 2 "" "")))
14181   (use (match_operand:SI 3 "" ""))]
14182  ;; Operand 2 not used on the i386.
14183  ""
14184{
14185  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14186  DONE;
14187})
14188
14189(define_expand "sibcall_value"
14190  [(set (match_operand 0 "" "")
14191	(call (match_operand:QI 1 "" "")
14192	      (match_operand:SI 2 "" "")))
14193   (use (match_operand:SI 3 "" ""))]
14194  ;; Operand 2 not used on the i386.
14195  ""
14196{
14197  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14198  DONE;
14199})
14200
14201;; Call subroutine returning any type.
14202
14203(define_expand "untyped_call"
14204  [(parallel [(call (match_operand 0 "" "")
14205		    (const_int 0))
14206	      (match_operand 1 "" "")
14207	      (match_operand 2 "" "")])]
14208  ""
14209{
14210  int i;
14211
14212  /* In order to give reg-stack an easier job in validating two
14213     coprocessor registers as containing a possible return value,
14214     simply pretend the untyped call returns a complex long double
14215     value.  */
14216
14217  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14218		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14219		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14220		    NULL, 0);
14221
14222  for (i = 0; i < XVECLEN (operands[2], 0); i++)
14223    {
14224      rtx set = XVECEXP (operands[2], 0, i);
14225      emit_move_insn (SET_DEST (set), SET_SRC (set));
14226    }
14227
14228  /* The optimizer does not know that the call sets the function value
14229     registers we stored in the result block.  We avoid problems by
14230     claiming that all hard registers are used and clobbered at this
14231     point.  */
14232  emit_insn (gen_blockage (const0_rtx));
14233
14234  DONE;
14235})
14236
14237;; Prologue and epilogue instructions
14238
14239;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14240;; all of memory.  This blocks insns from being moved across this point.
14241
14242(define_insn "blockage"
14243  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14244  ""
14245  ""
14246  [(set_attr "length" "0")])
14247
14248;; Insn emitted into the body of a function to return from a function.
14249;; This is only done if the function's epilogue is known to be simple.
14250;; See comments for ix86_can_use_return_insn_p in i386.c.
14251
14252(define_expand "return"
14253  [(return)]
14254  "ix86_can_use_return_insn_p ()"
14255{
14256  if (current_function_pops_args)
14257    {
14258      rtx popc = GEN_INT (current_function_pops_args);
14259      emit_jump_insn (gen_return_pop_internal (popc));
14260      DONE;
14261    }
14262})
14263
14264(define_insn "return_internal"
14265  [(return)]
14266  "reload_completed"
14267  "ret"
14268  [(set_attr "length" "1")
14269   (set_attr "length_immediate" "0")
14270   (set_attr "modrm" "0")])
14271
14272;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14273;; instruction Athlon and K8 have.
14274
14275(define_insn "return_internal_long"
14276  [(return)
14277   (unspec [(const_int 0)] UNSPEC_REP)]
14278  "reload_completed"
14279  "rep {;} ret"
14280  [(set_attr "length" "1")
14281   (set_attr "length_immediate" "0")
14282   (set_attr "prefix_rep" "1")
14283   (set_attr "modrm" "0")])
14284
14285(define_insn "return_pop_internal"
14286  [(return)
14287   (use (match_operand:SI 0 "const_int_operand" ""))]
14288  "reload_completed"
14289  "ret\t%0"
14290  [(set_attr "length" "3")
14291   (set_attr "length_immediate" "2")
14292   (set_attr "modrm" "0")])
14293
14294(define_insn "return_indirect_internal"
14295  [(return)
14296   (use (match_operand:SI 0 "register_operand" "r"))]
14297  "reload_completed"
14298  "jmp\t%A0"
14299  [(set_attr "type" "ibr")
14300   (set_attr "length_immediate" "0")])
14301
14302(define_insn "nop"
14303  [(const_int 0)]
14304  ""
14305  "nop"
14306  [(set_attr "length" "1")
14307   (set_attr "length_immediate" "0")
14308   (set_attr "modrm" "0")])
14309
14310;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14311;; branch prediction penalty for the third jump in a 16-byte
14312;; block on K8.
14313
14314(define_insn "align"
14315  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14316  ""
14317{
14318#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14319  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14320#else
14321  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14322     The align insn is used to avoid 3 jump instructions in the row to improve
14323     branch prediction and the benefits hardly outweigh the cost of extra 8
14324     nops on the average inserted by full alignment pseudo operation.  */
14325#endif
14326  return "";
14327}
14328  [(set_attr "length" "16")])
14329
14330(define_expand "prologue"
14331  [(const_int 1)]
14332  ""
14333  "ix86_expand_prologue (); DONE;")
14334
14335(define_insn "set_got"
14336  [(set (match_operand:SI 0 "register_operand" "=r")
14337	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14338   (clobber (reg:CC FLAGS_REG))]
14339  "!TARGET_64BIT"
14340  { return output_set_got (operands[0], NULL_RTX); }
14341  [(set_attr "type" "multi")
14342   (set_attr "length" "12")])
14343
14344(define_insn "set_got_labelled"
14345  [(set (match_operand:SI 0 "register_operand" "=r")
14346	(unspec:SI [(label_ref (match_operand 1 "" ""))]
14347	 UNSPEC_SET_GOT))
14348   (clobber (reg:CC FLAGS_REG))]
14349  "!TARGET_64BIT"
14350  { return output_set_got (operands[0], operands[1]); }
14351  [(set_attr "type" "multi")
14352   (set_attr "length" "12")])
14353
14354(define_insn "set_got_rex64"
14355  [(set (match_operand:DI 0 "register_operand" "=r")
14356	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14357  "TARGET_64BIT"
14358  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14359  [(set_attr "type" "lea")
14360   (set_attr "length" "6")])
14361
14362(define_expand "epilogue"
14363  [(const_int 1)]
14364  ""
14365  "ix86_expand_epilogue (1); DONE;")
14366
14367(define_expand "sibcall_epilogue"
14368  [(const_int 1)]
14369  ""
14370  "ix86_expand_epilogue (0); DONE;")
14371
14372(define_expand "eh_return"
14373  [(use (match_operand 0 "register_operand" ""))]
14374  ""
14375{
14376  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14377
14378  /* Tricky bit: we write the address of the handler to which we will
14379     be returning into someone else's stack frame, one word below the
14380     stack address we wish to restore.  */
14381  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14382  tmp = plus_constant (tmp, -UNITS_PER_WORD);
14383  tmp = gen_rtx_MEM (Pmode, tmp);
14384  emit_move_insn (tmp, ra);
14385
14386  if (Pmode == SImode)
14387    emit_jump_insn (gen_eh_return_si (sa));
14388  else
14389    emit_jump_insn (gen_eh_return_di (sa));
14390  emit_barrier ();
14391  DONE;
14392})
14393
14394(define_insn_and_split "eh_return_si"
14395  [(set (pc) 
14396        (unspec [(match_operand:SI 0 "register_operand" "c")]
14397	         UNSPEC_EH_RETURN))]
14398  "!TARGET_64BIT"
14399  "#"
14400  "reload_completed"
14401  [(const_int 1)]
14402  "ix86_expand_epilogue (2); DONE;")
14403
14404(define_insn_and_split "eh_return_di"
14405  [(set (pc) 
14406        (unspec [(match_operand:DI 0 "register_operand" "c")]
14407	         UNSPEC_EH_RETURN))]
14408  "TARGET_64BIT"
14409  "#"
14410  "reload_completed"
14411  [(const_int 1)]
14412  "ix86_expand_epilogue (2); DONE;")
14413
14414(define_insn "leave"
14415  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14416   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14417   (clobber (mem:BLK (scratch)))]
14418  "!TARGET_64BIT"
14419  "leave"
14420  [(set_attr "type" "leave")])
14421
14422(define_insn "leave_rex64"
14423  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14424   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14425   (clobber (mem:BLK (scratch)))]
14426  "TARGET_64BIT"
14427  "leave"
14428  [(set_attr "type" "leave")])
14429
14430(define_expand "ffssi2"
14431  [(parallel
14432     [(set (match_operand:SI 0 "register_operand" "") 
14433	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14434      (clobber (match_scratch:SI 2 ""))
14435      (clobber (reg:CC FLAGS_REG))])]
14436  ""
14437  "")
14438
14439(define_insn_and_split "*ffs_cmove"
14440  [(set (match_operand:SI 0 "register_operand" "=r") 
14441	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14442   (clobber (match_scratch:SI 2 "=&r"))
14443   (clobber (reg:CC FLAGS_REG))]
14444  "TARGET_CMOVE"
14445  "#"
14446  "&& reload_completed"
14447  [(set (match_dup 2) (const_int -1))
14448   (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14449	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14450   (set (match_dup 0) (if_then_else:SI
14451			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14452			(match_dup 2)
14453			(match_dup 0)))
14454   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14455	      (clobber (reg:CC FLAGS_REG))])]
14456  "")
14457
14458(define_insn_and_split "*ffs_no_cmove"
14459  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14460	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14461   (clobber (match_scratch:SI 2 "=&q"))
14462   (clobber (reg:CC FLAGS_REG))]
14463  ""
14464  "#"
14465  "reload_completed"
14466  [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14467	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14468   (set (strict_low_part (match_dup 3))
14469	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14470   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14471	      (clobber (reg:CC FLAGS_REG))])
14472   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14473	      (clobber (reg:CC FLAGS_REG))])
14474   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14475	      (clobber (reg:CC FLAGS_REG))])]
14476{
14477  operands[3] = gen_lowpart (QImode, operands[2]);
14478  ix86_expand_clear (operands[2]);
14479})
14480
14481(define_insn "*ffssi_1"
14482  [(set (reg:CCZ FLAGS_REG)
14483	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14484		     (const_int 0)))
14485   (set (match_operand:SI 0 "register_operand" "=r")
14486	(ctz:SI (match_dup 1)))]
14487  ""
14488  "bsf{l}\t{%1, %0|%0, %1}"
14489  [(set_attr "prefix_0f" "1")])
14490
14491(define_expand "ffsdi2"
14492  [(parallel
14493     [(set (match_operand:DI 0 "register_operand" "") 
14494	   (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14495      (clobber (match_scratch:DI 2 ""))
14496      (clobber (reg:CC FLAGS_REG))])]
14497  "TARGET_64BIT && TARGET_CMOVE"
14498  "")
14499
14500(define_insn_and_split "*ffs_rex64"
14501  [(set (match_operand:DI 0 "register_operand" "=r") 
14502	(ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14503   (clobber (match_scratch:DI 2 "=&r"))
14504   (clobber (reg:CC FLAGS_REG))]
14505  "TARGET_64BIT && TARGET_CMOVE"
14506  "#"
14507  "&& reload_completed"
14508  [(set (match_dup 2) (const_int -1))
14509   (parallel [(set (reg:CCZ FLAGS_REG)
14510		   (compare:CCZ (match_dup 1) (const_int 0)))
14511	      (set (match_dup 0) (ctz:DI (match_dup 1)))])
14512   (set (match_dup 0) (if_then_else:DI
14513			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14514			(match_dup 2)
14515			(match_dup 0)))
14516   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14517	      (clobber (reg:CC FLAGS_REG))])]
14518  "")
14519
14520(define_insn "*ffsdi_1"
14521  [(set (reg:CCZ FLAGS_REG)
14522	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14523		     (const_int 0)))
14524   (set (match_operand:DI 0 "register_operand" "=r")
14525	(ctz:DI (match_dup 1)))]
14526  "TARGET_64BIT"
14527  "bsf{q}\t{%1, %0|%0, %1}"
14528  [(set_attr "prefix_0f" "1")])
14529
14530(define_insn "ctzsi2"
14531  [(set (match_operand:SI 0 "register_operand" "=r")
14532	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14533   (clobber (reg:CC FLAGS_REG))]
14534  ""
14535  "bsf{l}\t{%1, %0|%0, %1}"
14536  [(set_attr "prefix_0f" "1")])
14537
14538(define_insn "ctzdi2"
14539  [(set (match_operand:DI 0 "register_operand" "=r")
14540	(ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14541   (clobber (reg:CC FLAGS_REG))]
14542  "TARGET_64BIT"
14543  "bsf{q}\t{%1, %0|%0, %1}"
14544  [(set_attr "prefix_0f" "1")])
14545
14546(define_expand "clzsi2"
14547  [(parallel
14548     [(set (match_operand:SI 0 "register_operand" "")
14549	   (minus:SI (const_int 31)
14550		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14551      (clobber (reg:CC FLAGS_REG))])
14552   (parallel
14553     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14554      (clobber (reg:CC FLAGS_REG))])]
14555  ""
14556  "")
14557
14558(define_insn "*bsr"
14559  [(set (match_operand:SI 0 "register_operand" "=r")
14560	(minus:SI (const_int 31)
14561		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14562   (clobber (reg:CC FLAGS_REG))]
14563  ""
14564  "bsr{l}\t{%1, %0|%0, %1}"
14565  [(set_attr "prefix_0f" "1")])
14566
14567(define_expand "clzdi2"
14568  [(parallel
14569     [(set (match_operand:DI 0 "register_operand" "")
14570	   (minus:DI (const_int 63)
14571		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14572      (clobber (reg:CC FLAGS_REG))])
14573   (parallel
14574     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14575      (clobber (reg:CC FLAGS_REG))])]
14576  "TARGET_64BIT"
14577  "")
14578
14579(define_insn "*bsr_rex64"
14580  [(set (match_operand:DI 0 "register_operand" "=r")
14581	(minus:DI (const_int 63)
14582		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14583   (clobber (reg:CC FLAGS_REG))]
14584  "TARGET_64BIT"
14585  "bsr{q}\t{%1, %0|%0, %1}"
14586  [(set_attr "prefix_0f" "1")])
14587
14588;; Thread-local storage patterns for ELF.
14589;;
14590;; Note that these code sequences must appear exactly as shown
14591;; in order to allow linker relaxation.
14592
14593(define_insn "*tls_global_dynamic_32_gnu"
14594  [(set (match_operand:SI 0 "register_operand" "=a")
14595	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14596		    (match_operand:SI 2 "tls_symbolic_operand" "")
14597		    (match_operand:SI 3 "call_insn_operand" "")]
14598		    UNSPEC_TLS_GD))
14599   (clobber (match_scratch:SI 4 "=d"))
14600   (clobber (match_scratch:SI 5 "=c"))
14601   (clobber (reg:CC FLAGS_REG))]
14602  "!TARGET_64BIT && TARGET_GNU_TLS"
14603  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14604  [(set_attr "type" "multi")
14605   (set_attr "length" "12")])
14606
14607(define_insn "*tls_global_dynamic_32_sun"
14608  [(set (match_operand:SI 0 "register_operand" "=a")
14609	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14610		    (match_operand:SI 2 "tls_symbolic_operand" "")
14611		    (match_operand:SI 3 "call_insn_operand" "")]
14612		    UNSPEC_TLS_GD))
14613   (clobber (match_scratch:SI 4 "=d"))
14614   (clobber (match_scratch:SI 5 "=c"))
14615   (clobber (reg:CC FLAGS_REG))]
14616  "!TARGET_64BIT && TARGET_SUN_TLS"
14617  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14618	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14619  [(set_attr "type" "multi")
14620   (set_attr "length" "14")])
14621
14622(define_expand "tls_global_dynamic_32"
14623  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14624		   (unspec:SI
14625		    [(match_dup 2)
14626		     (match_operand:SI 1 "tls_symbolic_operand" "")
14627		     (match_dup 3)]
14628		    UNSPEC_TLS_GD))
14629	      (clobber (match_scratch:SI 4 ""))
14630	      (clobber (match_scratch:SI 5 ""))
14631	      (clobber (reg:CC FLAGS_REG))])]
14632  ""
14633{
14634  if (flag_pic)
14635    operands[2] = pic_offset_table_rtx;
14636  else
14637    {
14638      operands[2] = gen_reg_rtx (Pmode);
14639      emit_insn (gen_set_got (operands[2]));
14640    }
14641  if (TARGET_GNU2_TLS)
14642    {
14643       emit_insn (gen_tls_dynamic_gnu2_32
14644		  (operands[0], operands[1], operands[2]));
14645       DONE;
14646    }
14647  operands[3] = ix86_tls_get_addr ();
14648})
14649
14650(define_insn "*tls_global_dynamic_64"
14651  [(set (match_operand:DI 0 "register_operand" "=a")
14652	(call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14653		 (match_operand:DI 3 "" "")))
14654   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14655	      UNSPEC_TLS_GD)]
14656  "TARGET_64BIT"
14657  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14658  [(set_attr "type" "multi")
14659   (set_attr "length" "16")])
14660
14661(define_expand "tls_global_dynamic_64"
14662  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14663		   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14664	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14665			 UNSPEC_TLS_GD)])]
14666  ""
14667{
14668  if (TARGET_GNU2_TLS)
14669    {
14670       emit_insn (gen_tls_dynamic_gnu2_64
14671		  (operands[0], operands[1]));
14672       DONE;
14673    }
14674  operands[2] = ix86_tls_get_addr ();
14675})
14676
14677(define_insn "*tls_local_dynamic_base_32_gnu"
14678  [(set (match_operand:SI 0 "register_operand" "=a")
14679	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14680                    (match_operand:SI 2 "call_insn_operand" "")]
14681		   UNSPEC_TLS_LD_BASE))
14682   (clobber (match_scratch:SI 3 "=d"))
14683   (clobber (match_scratch:SI 4 "=c"))
14684   (clobber (reg:CC FLAGS_REG))]
14685  "!TARGET_64BIT && TARGET_GNU_TLS"
14686  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14687  [(set_attr "type" "multi")
14688   (set_attr "length" "11")])
14689
14690(define_insn "*tls_local_dynamic_base_32_sun"
14691  [(set (match_operand:SI 0 "register_operand" "=a")
14692	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14693                    (match_operand:SI 2 "call_insn_operand" "")]
14694		   UNSPEC_TLS_LD_BASE))
14695   (clobber (match_scratch:SI 3 "=d"))
14696   (clobber (match_scratch:SI 4 "=c"))
14697   (clobber (reg:CC FLAGS_REG))]
14698  "!TARGET_64BIT && TARGET_SUN_TLS"
14699  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14700	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14701  [(set_attr "type" "multi")
14702   (set_attr "length" "13")])
14703
14704(define_expand "tls_local_dynamic_base_32"
14705  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14706		   (unspec:SI [(match_dup 1) (match_dup 2)]
14707			      UNSPEC_TLS_LD_BASE))
14708	      (clobber (match_scratch:SI 3 ""))
14709	      (clobber (match_scratch:SI 4 ""))
14710	      (clobber (reg:CC FLAGS_REG))])]
14711  ""
14712{
14713  if (flag_pic)
14714    operands[1] = pic_offset_table_rtx;
14715  else
14716    {
14717      operands[1] = gen_reg_rtx (Pmode);
14718      emit_insn (gen_set_got (operands[1]));
14719    }
14720  if (TARGET_GNU2_TLS)
14721    {
14722       emit_insn (gen_tls_dynamic_gnu2_32
14723		  (operands[0], ix86_tls_module_base (), operands[1]));
14724       DONE;
14725    }
14726  operands[2] = ix86_tls_get_addr ();
14727})
14728
14729(define_insn "*tls_local_dynamic_base_64"
14730  [(set (match_operand:DI 0 "register_operand" "=a")
14731	(call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14732		 (match_operand:DI 2 "" "")))
14733   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14734  "TARGET_64BIT"
14735  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14736  [(set_attr "type" "multi")
14737   (set_attr "length" "12")])
14738
14739(define_expand "tls_local_dynamic_base_64"
14740  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14741		   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14742	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14743  ""
14744{
14745  if (TARGET_GNU2_TLS)
14746    {
14747       emit_insn (gen_tls_dynamic_gnu2_64
14748		  (operands[0], ix86_tls_module_base ()));
14749       DONE;
14750    }
14751  operands[1] = ix86_tls_get_addr ();
14752})
14753
14754;; Local dynamic of a single variable is a lose.  Show combine how
14755;; to convert that back to global dynamic.
14756
14757(define_insn_and_split "*tls_local_dynamic_32_once"
14758  [(set (match_operand:SI 0 "register_operand" "=a")
14759	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14760			     (match_operand:SI 2 "call_insn_operand" "")]
14761			    UNSPEC_TLS_LD_BASE)
14762		 (const:SI (unspec:SI
14763			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
14764			    UNSPEC_DTPOFF))))
14765   (clobber (match_scratch:SI 4 "=d"))
14766   (clobber (match_scratch:SI 5 "=c"))
14767   (clobber (reg:CC FLAGS_REG))]
14768  ""
14769  "#"
14770  ""
14771  [(parallel [(set (match_dup 0)
14772		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14773			      UNSPEC_TLS_GD))
14774	      (clobber (match_dup 4))
14775	      (clobber (match_dup 5))
14776	      (clobber (reg:CC FLAGS_REG))])]
14777  "")
14778
14779;; Load and add the thread base pointer from %gs:0.
14780
14781(define_insn "*load_tp_si"
14782  [(set (match_operand:SI 0 "register_operand" "=r")
14783	(unspec:SI [(const_int 0)] UNSPEC_TP))]
14784  "!TARGET_64BIT"
14785  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14786  [(set_attr "type" "imov")
14787   (set_attr "modrm" "0")
14788   (set_attr "length" "7")
14789   (set_attr "memory" "load")
14790   (set_attr "imm_disp" "false")])
14791
14792(define_insn "*add_tp_si"
14793  [(set (match_operand:SI 0 "register_operand" "=r")
14794	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14795		 (match_operand:SI 1 "register_operand" "0")))
14796   (clobber (reg:CC FLAGS_REG))]
14797  "!TARGET_64BIT"
14798  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14799  [(set_attr "type" "alu")
14800   (set_attr "modrm" "0")
14801   (set_attr "length" "7")
14802   (set_attr "memory" "load")
14803   (set_attr "imm_disp" "false")])
14804
14805(define_insn "*load_tp_di"
14806  [(set (match_operand:DI 0 "register_operand" "=r")
14807	(unspec:DI [(const_int 0)] UNSPEC_TP))]
14808  "TARGET_64BIT"
14809  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14810  [(set_attr "type" "imov")
14811   (set_attr "modrm" "0")
14812   (set_attr "length" "7")
14813   (set_attr "memory" "load")
14814   (set_attr "imm_disp" "false")])
14815
14816(define_insn "*add_tp_di"
14817  [(set (match_operand:DI 0 "register_operand" "=r")
14818	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14819		 (match_operand:DI 1 "register_operand" "0")))
14820   (clobber (reg:CC FLAGS_REG))]
14821  "TARGET_64BIT"
14822  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14823  [(set_attr "type" "alu")
14824   (set_attr "modrm" "0")
14825   (set_attr "length" "7")
14826   (set_attr "memory" "load")
14827   (set_attr "imm_disp" "false")])
14828
14829;; GNU2 TLS patterns can be split.
14830
14831(define_expand "tls_dynamic_gnu2_32"
14832  [(set (match_dup 3)
14833	(plus:SI (match_operand:SI 2 "register_operand" "")
14834		 (const:SI
14835		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14836			     UNSPEC_TLSDESC))))
14837   (parallel
14838    [(set (match_operand:SI 0 "register_operand" "")
14839	  (unspec:SI [(match_dup 1) (match_dup 3)
14840		      (match_dup 2) (reg:SI SP_REG)]
14841		      UNSPEC_TLSDESC))
14842     (clobber (reg:CC FLAGS_REG))])]
14843  "!TARGET_64BIT && TARGET_GNU2_TLS"
14844{
14845  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14846  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14847})
14848
14849(define_insn "*tls_dynamic_lea_32"
14850  [(set (match_operand:SI 0 "register_operand" "=r")
14851	(plus:SI (match_operand:SI 1 "register_operand" "b")
14852		 (const:SI
14853		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14854			      UNSPEC_TLSDESC))))]
14855  "!TARGET_64BIT && TARGET_GNU2_TLS"
14856  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14857  [(set_attr "type" "lea")
14858   (set_attr "mode" "SI")
14859   (set_attr "length" "6")
14860   (set_attr "length_address" "4")])
14861
14862(define_insn "*tls_dynamic_call_32"
14863  [(set (match_operand:SI 0 "register_operand" "=a")
14864	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14865		    (match_operand:SI 2 "register_operand" "0")
14866		    ;; we have to make sure %ebx still points to the GOT
14867		    (match_operand:SI 3 "register_operand" "b")
14868		    (reg:SI SP_REG)]
14869		   UNSPEC_TLSDESC))
14870   (clobber (reg:CC FLAGS_REG))]
14871  "!TARGET_64BIT && TARGET_GNU2_TLS"
14872  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14873  [(set_attr "type" "call")
14874   (set_attr "length" "2")
14875   (set_attr "length_address" "0")])
14876
14877(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14878  [(set (match_operand:SI 0 "register_operand" "=&a")
14879	(plus:SI
14880	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14881		     (match_operand:SI 4 "" "")
14882		     (match_operand:SI 2 "register_operand" "b")
14883		     (reg:SI SP_REG)]
14884		    UNSPEC_TLSDESC)
14885	 (const:SI (unspec:SI
14886		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
14887		    UNSPEC_DTPOFF))))
14888   (clobber (reg:CC FLAGS_REG))]
14889  "!TARGET_64BIT && TARGET_GNU2_TLS"
14890  "#"
14891  ""
14892  [(set (match_dup 0) (match_dup 5))]
14893{
14894  operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14895  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14896})
14897
14898(define_expand "tls_dynamic_gnu2_64"
14899  [(set (match_dup 2)
14900	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14901		   UNSPEC_TLSDESC))
14902   (parallel
14903    [(set (match_operand:DI 0 "register_operand" "")
14904	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14905		     UNSPEC_TLSDESC))
14906     (clobber (reg:CC FLAGS_REG))])]
14907  "TARGET_64BIT && TARGET_GNU2_TLS"
14908{
14909  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14910  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14911})
14912
14913(define_insn "*tls_dynamic_lea_64"
14914  [(set (match_operand:DI 0 "register_operand" "=r")
14915	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14916		   UNSPEC_TLSDESC))]
14917  "TARGET_64BIT && TARGET_GNU2_TLS"
14918  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14919  [(set_attr "type" "lea")
14920   (set_attr "mode" "DI")
14921   (set_attr "length" "7")
14922   (set_attr "length_address" "4")])
14923
14924(define_insn "*tls_dynamic_call_64"
14925  [(set (match_operand:DI 0 "register_operand" "=a")
14926	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14927		    (match_operand:DI 2 "register_operand" "0")
14928		    (reg:DI SP_REG)]
14929		   UNSPEC_TLSDESC))
14930   (clobber (reg:CC FLAGS_REG))]
14931  "TARGET_64BIT && TARGET_GNU2_TLS"
14932  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14933  [(set_attr "type" "call")
14934   (set_attr "length" "2")
14935   (set_attr "length_address" "0")])
14936
14937(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14938  [(set (match_operand:DI 0 "register_operand" "=&a")
14939	(plus:DI
14940	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14941		     (match_operand:DI 3 "" "")
14942		     (reg:DI SP_REG)]
14943		    UNSPEC_TLSDESC)
14944	 (const:DI (unspec:DI
14945		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
14946		    UNSPEC_DTPOFF))))
14947   (clobber (reg:CC FLAGS_REG))]
14948  "TARGET_64BIT && TARGET_GNU2_TLS"
14949  "#"
14950  ""
14951  [(set (match_dup 0) (match_dup 4))]
14952{
14953  operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14954  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14955})
14956
14957;;
14958
14959;; These patterns match the binary 387 instructions for addM3, subM3,
14960;; mulM3 and divM3.  There are three patterns for each of DFmode and
14961;; SFmode.  The first is the normal insn, the second the same insn but
14962;; with one operand a conversion, and the third the same insn but with
14963;; the other operand a conversion.  The conversion may be SFmode or
14964;; SImode if the target mode DFmode, but only SImode if the target mode
14965;; is SFmode.
14966
14967;; Gcc is slightly more smart about handling normal two address instructions
14968;; so use special patterns for add and mull.
14969
14970(define_insn "*fop_sf_comm_mixed"
14971  [(set (match_operand:SF 0 "register_operand" "=f,x")
14972	(match_operator:SF 3 "binary_fp_operator"
14973			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14974			 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14975  "TARGET_MIX_SSE_I387
14976   && COMMUTATIVE_ARITH_P (operands[3])
14977   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14978  "* return output_387_binary_op (insn, operands);"
14979  [(set (attr "type") 
14980	(if_then_else (eq_attr "alternative" "1")
14981	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14982	      (const_string "ssemul")
14983	      (const_string "sseadd"))
14984	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14985	      (const_string "fmul")
14986	      (const_string "fop"))))
14987   (set_attr "mode" "SF")])
14988
14989(define_insn "*fop_sf_comm_sse"
14990  [(set (match_operand:SF 0 "register_operand" "=x")
14991	(match_operator:SF 3 "binary_fp_operator"
14992			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14993			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14994  "TARGET_SSE_MATH
14995   && COMMUTATIVE_ARITH_P (operands[3])
14996   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14997  "* return output_387_binary_op (insn, operands);"
14998  [(set (attr "type") 
14999        (if_then_else (match_operand:SF 3 "mult_operator" "") 
15000	   (const_string "ssemul")
15001	   (const_string "sseadd")))
15002   (set_attr "mode" "SF")])
15003
15004(define_insn "*fop_sf_comm_i387"
15005  [(set (match_operand:SF 0 "register_operand" "=f")
15006	(match_operator:SF 3 "binary_fp_operator"
15007			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15008			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15009  "TARGET_80387
15010   && COMMUTATIVE_ARITH_P (operands[3])
15011   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15012  "* return output_387_binary_op (insn, operands);"
15013  [(set (attr "type") 
15014	(if_then_else (match_operand:SF 3 "mult_operator" "") 
15015	   (const_string "fmul")
15016	   (const_string "fop")))
15017   (set_attr "mode" "SF")])
15018
15019(define_insn "*fop_sf_1_mixed"
15020  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15021	(match_operator:SF 3 "binary_fp_operator"
15022			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15023			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15024  "TARGET_MIX_SSE_I387
15025   && !COMMUTATIVE_ARITH_P (operands[3])
15026   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15027  "* return output_387_binary_op (insn, operands);"
15028  [(set (attr "type") 
15029        (cond [(and (eq_attr "alternative" "2")
15030	            (match_operand:SF 3 "mult_operator" ""))
15031                 (const_string "ssemul")
15032	       (and (eq_attr "alternative" "2")
15033	            (match_operand:SF 3 "div_operator" ""))
15034                 (const_string "ssediv")
15035	       (eq_attr "alternative" "2")
15036                 (const_string "sseadd")
15037	       (match_operand:SF 3 "mult_operator" "") 
15038                 (const_string "fmul")
15039               (match_operand:SF 3 "div_operator" "") 
15040                 (const_string "fdiv")
15041              ]
15042              (const_string "fop")))
15043   (set_attr "mode" "SF")])
15044
15045(define_insn "*fop_sf_1_sse"
15046  [(set (match_operand:SF 0 "register_operand" "=x")
15047	(match_operator:SF 3 "binary_fp_operator"
15048			[(match_operand:SF 1 "register_operand" "0")
15049			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15050  "TARGET_SSE_MATH
15051   && !COMMUTATIVE_ARITH_P (operands[3])"
15052  "* return output_387_binary_op (insn, operands);"
15053  [(set (attr "type") 
15054        (cond [(match_operand:SF 3 "mult_operator" "")
15055                 (const_string "ssemul")
15056	       (match_operand:SF 3 "div_operator" "")
15057                 (const_string "ssediv")
15058              ]
15059              (const_string "sseadd")))
15060   (set_attr "mode" "SF")])
15061
15062;; This pattern is not fully shadowed by the pattern above.
15063(define_insn "*fop_sf_1_i387"
15064  [(set (match_operand:SF 0 "register_operand" "=f,f")
15065	(match_operator:SF 3 "binary_fp_operator"
15066			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15067			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15068  "TARGET_80387 && !TARGET_SSE_MATH
15069   && !COMMUTATIVE_ARITH_P (operands[3])
15070   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15071  "* return output_387_binary_op (insn, operands);"
15072  [(set (attr "type") 
15073        (cond [(match_operand:SF 3 "mult_operator" "") 
15074                 (const_string "fmul")
15075               (match_operand:SF 3 "div_operator" "") 
15076                 (const_string "fdiv")
15077              ]
15078              (const_string "fop")))
15079   (set_attr "mode" "SF")])
15080
15081;; ??? Add SSE splitters for these!
15082(define_insn "*fop_sf_2<mode>_i387"
15083  [(set (match_operand:SF 0 "register_operand" "=f,f")
15084	(match_operator:SF 3 "binary_fp_operator"
15085	  [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15086	   (match_operand:SF 2 "register_operand" "0,0")]))]
15087  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15088  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15089  [(set (attr "type") 
15090        (cond [(match_operand:SF 3 "mult_operator" "") 
15091                 (const_string "fmul")
15092               (match_operand:SF 3 "div_operator" "") 
15093                 (const_string "fdiv")
15094              ]
15095              (const_string "fop")))
15096   (set_attr "fp_int_src" "true")
15097   (set_attr "mode" "<MODE>")])
15098
15099(define_insn "*fop_sf_3<mode>_i387"
15100  [(set (match_operand:SF 0 "register_operand" "=f,f")
15101	(match_operator:SF 3 "binary_fp_operator"
15102	  [(match_operand:SF 1 "register_operand" "0,0")
15103	   (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15104  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15105  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15106  [(set (attr "type") 
15107        (cond [(match_operand:SF 3 "mult_operator" "") 
15108                 (const_string "fmul")
15109               (match_operand:SF 3 "div_operator" "") 
15110                 (const_string "fdiv")
15111              ]
15112              (const_string "fop")))
15113   (set_attr "fp_int_src" "true")
15114   (set_attr "mode" "<MODE>")])
15115
15116(define_insn "*fop_df_comm_mixed"
15117  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15118	(match_operator:DF 3 "binary_fp_operator"
15119			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15120			 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15121  "TARGET_SSE2 && TARGET_MIX_SSE_I387
15122   && COMMUTATIVE_ARITH_P (operands[3])
15123   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15124  "* return output_387_binary_op (insn, operands);"
15125  [(set (attr "type") 
15126	(if_then_else (eq_attr "alternative" "1")
15127	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15128	      (const_string "ssemul")
15129	      (const_string "sseadd"))
15130	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15131	      (const_string "fmul")
15132	      (const_string "fop"))))
15133   (set_attr "mode" "DF")])
15134
15135(define_insn "*fop_df_comm_sse"
15136  [(set (match_operand:DF 0 "register_operand" "=Y")
15137	(match_operator:DF 3 "binary_fp_operator"
15138			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15139			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15140  "TARGET_SSE2 && TARGET_SSE_MATH
15141   && COMMUTATIVE_ARITH_P (operands[3])
15142   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15143  "* return output_387_binary_op (insn, operands);"
15144  [(set (attr "type") 
15145        (if_then_else (match_operand:DF 3 "mult_operator" "") 
15146	   (const_string "ssemul")
15147	   (const_string "sseadd")))
15148   (set_attr "mode" "DF")])
15149
15150(define_insn "*fop_df_comm_i387"
15151  [(set (match_operand:DF 0 "register_operand" "=f")
15152	(match_operator:DF 3 "binary_fp_operator"
15153			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15154			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15155  "TARGET_80387
15156   && COMMUTATIVE_ARITH_P (operands[3])
15157   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15158  "* return output_387_binary_op (insn, operands);"
15159  [(set (attr "type") 
15160	(if_then_else (match_operand:DF 3 "mult_operator" "") 
15161	   (const_string "fmul")
15162	   (const_string "fop")))
15163   (set_attr "mode" "DF")])
15164
15165(define_insn "*fop_df_1_mixed"
15166  [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15167	(match_operator:DF 3 "binary_fp_operator"
15168			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15169			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15170  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15171   && !COMMUTATIVE_ARITH_P (operands[3])
15172   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15173  "* return output_387_binary_op (insn, operands);"
15174  [(set (attr "type") 
15175        (cond [(and (eq_attr "alternative" "2")
15176	            (match_operand:DF 3 "mult_operator" ""))
15177                 (const_string "ssemul")
15178	       (and (eq_attr "alternative" "2")
15179	            (match_operand:DF 3 "div_operator" ""))
15180                 (const_string "ssediv")
15181	       (eq_attr "alternative" "2")
15182                 (const_string "sseadd")
15183	       (match_operand:DF 3 "mult_operator" "") 
15184                 (const_string "fmul")
15185               (match_operand:DF 3 "div_operator" "") 
15186                 (const_string "fdiv")
15187              ]
15188              (const_string "fop")))
15189   (set_attr "mode" "DF")])
15190
15191(define_insn "*fop_df_1_sse"
15192  [(set (match_operand:DF 0 "register_operand" "=Y")
15193	(match_operator:DF 3 "binary_fp_operator"
15194			[(match_operand:DF 1 "register_operand" "0")
15195			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15196  "TARGET_SSE2 && TARGET_SSE_MATH
15197   && !COMMUTATIVE_ARITH_P (operands[3])"
15198  "* return output_387_binary_op (insn, operands);"
15199  [(set_attr "mode" "DF")
15200   (set (attr "type") 
15201        (cond [(match_operand:DF 3 "mult_operator" "")
15202                 (const_string "ssemul")
15203	       (match_operand:DF 3 "div_operator" "")
15204                 (const_string "ssediv")
15205              ]
15206              (const_string "sseadd")))])
15207
15208;; This pattern is not fully shadowed by the pattern above.
15209(define_insn "*fop_df_1_i387"
15210  [(set (match_operand:DF 0 "register_operand" "=f,f")
15211	(match_operator:DF 3 "binary_fp_operator"
15212			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15213			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15214  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15215   && !COMMUTATIVE_ARITH_P (operands[3])
15216   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15217  "* return output_387_binary_op (insn, operands);"
15218  [(set (attr "type") 
15219        (cond [(match_operand:DF 3 "mult_operator" "") 
15220                 (const_string "fmul")
15221               (match_operand:DF 3 "div_operator" "")
15222                 (const_string "fdiv")
15223              ]
15224              (const_string "fop")))
15225   (set_attr "mode" "DF")])
15226
15227;; ??? Add SSE splitters for these!
15228(define_insn "*fop_df_2<mode>_i387"
15229  [(set (match_operand:DF 0 "register_operand" "=f,f")
15230	(match_operator:DF 3 "binary_fp_operator"
15231	   [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15232	    (match_operand:DF 2 "register_operand" "0,0")]))]
15233  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15234   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15235  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15236  [(set (attr "type") 
15237        (cond [(match_operand:DF 3 "mult_operator" "") 
15238                 (const_string "fmul")
15239               (match_operand:DF 3 "div_operator" "") 
15240                 (const_string "fdiv")
15241              ]
15242              (const_string "fop")))
15243   (set_attr "fp_int_src" "true")
15244   (set_attr "mode" "<MODE>")])
15245
15246(define_insn "*fop_df_3<mode>_i387"
15247  [(set (match_operand:DF 0 "register_operand" "=f,f")
15248	(match_operator:DF 3 "binary_fp_operator"
15249	   [(match_operand:DF 1 "register_operand" "0,0")
15250	    (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15251  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15252   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15253  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15254  [(set (attr "type") 
15255        (cond [(match_operand:DF 3 "mult_operator" "") 
15256                 (const_string "fmul")
15257               (match_operand:DF 3 "div_operator" "") 
15258                 (const_string "fdiv")
15259              ]
15260              (const_string "fop")))
15261   (set_attr "fp_int_src" "true")
15262   (set_attr "mode" "<MODE>")])
15263
15264(define_insn "*fop_df_4_i387"
15265  [(set (match_operand:DF 0 "register_operand" "=f,f")
15266	(match_operator:DF 3 "binary_fp_operator"
15267	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15268	    (match_operand:DF 2 "register_operand" "0,f")]))]
15269  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15270   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15271  "* return output_387_binary_op (insn, operands);"
15272  [(set (attr "type") 
15273        (cond [(match_operand:DF 3 "mult_operator" "") 
15274                 (const_string "fmul")
15275               (match_operand:DF 3 "div_operator" "") 
15276                 (const_string "fdiv")
15277              ]
15278              (const_string "fop")))
15279   (set_attr "mode" "SF")])
15280
15281(define_insn "*fop_df_5_i387"
15282  [(set (match_operand:DF 0 "register_operand" "=f,f")
15283	(match_operator:DF 3 "binary_fp_operator"
15284	  [(match_operand:DF 1 "register_operand" "0,f")
15285	   (float_extend:DF
15286	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15287  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15288  "* return output_387_binary_op (insn, operands);"
15289  [(set (attr "type") 
15290        (cond [(match_operand:DF 3 "mult_operator" "") 
15291                 (const_string "fmul")
15292               (match_operand:DF 3 "div_operator" "") 
15293                 (const_string "fdiv")
15294              ]
15295              (const_string "fop")))
15296   (set_attr "mode" "SF")])
15297
15298(define_insn "*fop_df_6_i387"
15299  [(set (match_operand:DF 0 "register_operand" "=f,f")
15300	(match_operator:DF 3 "binary_fp_operator"
15301	  [(float_extend:DF
15302	    (match_operand:SF 1 "register_operand" "0,f"))
15303	   (float_extend:DF
15304	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15305  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15306  "* return output_387_binary_op (insn, operands);"
15307  [(set (attr "type") 
15308        (cond [(match_operand:DF 3 "mult_operator" "") 
15309                 (const_string "fmul")
15310               (match_operand:DF 3 "div_operator" "") 
15311                 (const_string "fdiv")
15312              ]
15313              (const_string "fop")))
15314   (set_attr "mode" "SF")])
15315
15316(define_insn "*fop_xf_comm_i387"
15317  [(set (match_operand:XF 0 "register_operand" "=f")
15318	(match_operator:XF 3 "binary_fp_operator"
15319			[(match_operand:XF 1 "register_operand" "%0")
15320			 (match_operand:XF 2 "register_operand" "f")]))]
15321  "TARGET_80387
15322   && COMMUTATIVE_ARITH_P (operands[3])"
15323  "* return output_387_binary_op (insn, operands);"
15324  [(set (attr "type") 
15325        (if_then_else (match_operand:XF 3 "mult_operator" "") 
15326           (const_string "fmul")
15327           (const_string "fop")))
15328   (set_attr "mode" "XF")])
15329
15330(define_insn "*fop_xf_1_i387"
15331  [(set (match_operand:XF 0 "register_operand" "=f,f")
15332	(match_operator:XF 3 "binary_fp_operator"
15333			[(match_operand:XF 1 "register_operand" "0,f")
15334			 (match_operand:XF 2 "register_operand" "f,0")]))]
15335  "TARGET_80387
15336   && !COMMUTATIVE_ARITH_P (operands[3])"
15337  "* return output_387_binary_op (insn, operands);"
15338  [(set (attr "type") 
15339        (cond [(match_operand:XF 3 "mult_operator" "") 
15340                 (const_string "fmul")
15341               (match_operand:XF 3 "div_operator" "") 
15342                 (const_string "fdiv")
15343              ]
15344              (const_string "fop")))
15345   (set_attr "mode" "XF")])
15346
15347(define_insn "*fop_xf_2<mode>_i387"
15348  [(set (match_operand:XF 0 "register_operand" "=f,f")
15349	(match_operator:XF 3 "binary_fp_operator"
15350	   [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15351	    (match_operand:XF 2 "register_operand" "0,0")]))]
15352  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15353  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15354  [(set (attr "type") 
15355        (cond [(match_operand:XF 3 "mult_operator" "") 
15356                 (const_string "fmul")
15357               (match_operand:XF 3 "div_operator" "") 
15358                 (const_string "fdiv")
15359              ]
15360              (const_string "fop")))
15361   (set_attr "fp_int_src" "true")
15362   (set_attr "mode" "<MODE>")])
15363
15364(define_insn "*fop_xf_3<mode>_i387"
15365  [(set (match_operand:XF 0 "register_operand" "=f,f")
15366	(match_operator:XF 3 "binary_fp_operator"
15367	  [(match_operand:XF 1 "register_operand" "0,0")
15368	   (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15369  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15370  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15371  [(set (attr "type") 
15372        (cond [(match_operand:XF 3 "mult_operator" "") 
15373                 (const_string "fmul")
15374               (match_operand:XF 3 "div_operator" "") 
15375                 (const_string "fdiv")
15376              ]
15377              (const_string "fop")))
15378   (set_attr "fp_int_src" "true")
15379   (set_attr "mode" "<MODE>")])
15380
15381(define_insn "*fop_xf_4_i387"
15382  [(set (match_operand:XF 0 "register_operand" "=f,f")
15383	(match_operator:XF 3 "binary_fp_operator"
15384	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15385	    (match_operand:XF 2 "register_operand" "0,f")]))]
15386  "TARGET_80387"
15387  "* return output_387_binary_op (insn, operands);"
15388  [(set (attr "type") 
15389        (cond [(match_operand:XF 3 "mult_operator" "") 
15390                 (const_string "fmul")
15391               (match_operand:XF 3 "div_operator" "") 
15392                 (const_string "fdiv")
15393              ]
15394              (const_string "fop")))
15395   (set_attr "mode" "SF")])
15396
15397(define_insn "*fop_xf_5_i387"
15398  [(set (match_operand:XF 0 "register_operand" "=f,f")
15399	(match_operator:XF 3 "binary_fp_operator"
15400	  [(match_operand:XF 1 "register_operand" "0,f")
15401	   (float_extend:XF
15402	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15403  "TARGET_80387"
15404  "* return output_387_binary_op (insn, operands);"
15405  [(set (attr "type") 
15406        (cond [(match_operand:XF 3 "mult_operator" "") 
15407                 (const_string "fmul")
15408               (match_operand:XF 3 "div_operator" "") 
15409                 (const_string "fdiv")
15410              ]
15411              (const_string "fop")))
15412   (set_attr "mode" "SF")])
15413
15414(define_insn "*fop_xf_6_i387"
15415  [(set (match_operand:XF 0 "register_operand" "=f,f")
15416	(match_operator:XF 3 "binary_fp_operator"
15417	  [(float_extend:XF
15418	    (match_operand 1 "register_operand" "0,f"))
15419	   (float_extend:XF
15420	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15421  "TARGET_80387"
15422  "* return output_387_binary_op (insn, operands);"
15423  [(set (attr "type") 
15424        (cond [(match_operand:XF 3 "mult_operator" "") 
15425                 (const_string "fmul")
15426               (match_operand:XF 3 "div_operator" "") 
15427                 (const_string "fdiv")
15428              ]
15429              (const_string "fop")))
15430   (set_attr "mode" "SF")])
15431
15432(define_split
15433  [(set (match_operand 0 "register_operand" "")
15434	(match_operator 3 "binary_fp_operator"
15435	   [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15436	    (match_operand 2 "register_operand" "")]))]
15437  "TARGET_80387 && reload_completed
15438   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15439  [(const_int 0)]
15440{ 
15441  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15442  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15443  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15444			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15445					  GET_MODE (operands[3]),
15446					  operands[4],
15447					  operands[2])));
15448  ix86_free_from_memory (GET_MODE (operands[1]));
15449  DONE;
15450})
15451
15452(define_split
15453  [(set (match_operand 0 "register_operand" "")
15454	(match_operator 3 "binary_fp_operator"
15455	   [(match_operand 1 "register_operand" "")
15456	    (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15457  "TARGET_80387 && reload_completed
15458   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15459  [(const_int 0)]
15460{
15461  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15462  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15463  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15464			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15465					  GET_MODE (operands[3]),
15466					  operands[1],
15467					  operands[4])));
15468  ix86_free_from_memory (GET_MODE (operands[2]));
15469  DONE;
15470})
15471
15472;; FPU special functions.
15473
15474(define_expand "sqrtsf2"
15475  [(set (match_operand:SF 0 "register_operand" "")
15476	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15477  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15478{
15479  if (!TARGET_SSE_MATH)
15480    operands[1] = force_reg (SFmode, operands[1]);
15481})
15482
15483(define_insn "*sqrtsf2_mixed"
15484  [(set (match_operand:SF 0 "register_operand" "=f,x")
15485	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15486  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15487  "@
15488   fsqrt
15489   sqrtss\t{%1, %0|%0, %1}"
15490  [(set_attr "type" "fpspc,sse")
15491   (set_attr "mode" "SF,SF")
15492   (set_attr "athlon_decode" "direct,*")])
15493
15494(define_insn "*sqrtsf2_sse"
15495  [(set (match_operand:SF 0 "register_operand" "=x")
15496	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15497  "TARGET_SSE_MATH"
15498  "sqrtss\t{%1, %0|%0, %1}"
15499  [(set_attr "type" "sse")
15500   (set_attr "mode" "SF")
15501   (set_attr "athlon_decode" "*")])
15502
15503(define_insn "*sqrtsf2_i387"
15504  [(set (match_operand:SF 0 "register_operand" "=f")
15505	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15506  "TARGET_USE_FANCY_MATH_387"
15507  "fsqrt"
15508  [(set_attr "type" "fpspc")
15509   (set_attr "mode" "SF")
15510   (set_attr "athlon_decode" "direct")])
15511
15512(define_expand "sqrtdf2"
15513  [(set (match_operand:DF 0 "register_operand" "")
15514	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15515  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15516{
15517  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15518    operands[1] = force_reg (DFmode, operands[1]);
15519})
15520
15521(define_insn "*sqrtdf2_mixed"
15522  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15523	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15524  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15525  "@
15526   fsqrt
15527   sqrtsd\t{%1, %0|%0, %1}"
15528  [(set_attr "type" "fpspc,sse")
15529   (set_attr "mode" "DF,DF")
15530   (set_attr "athlon_decode" "direct,*")])
15531
15532(define_insn "*sqrtdf2_sse"
15533  [(set (match_operand:DF 0 "register_operand" "=Y")
15534	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15535  "TARGET_SSE2 && TARGET_SSE_MATH"
15536  "sqrtsd\t{%1, %0|%0, %1}"
15537  [(set_attr "type" "sse")
15538   (set_attr "mode" "DF")
15539   (set_attr "athlon_decode" "*")])
15540
15541(define_insn "*sqrtdf2_i387"
15542  [(set (match_operand:DF 0 "register_operand" "=f")
15543	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15544  "TARGET_USE_FANCY_MATH_387"
15545  "fsqrt"
15546  [(set_attr "type" "fpspc")
15547   (set_attr "mode" "DF")
15548   (set_attr "athlon_decode" "direct")])
15549
15550(define_insn "*sqrtextendsfdf2_i387"
15551  [(set (match_operand:DF 0 "register_operand" "=f")
15552	(sqrt:DF (float_extend:DF
15553		  (match_operand:SF 1 "register_operand" "0"))))]
15554  "TARGET_USE_FANCY_MATH_387
15555   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15556  "fsqrt"
15557  [(set_attr "type" "fpspc")
15558   (set_attr "mode" "DF")
15559   (set_attr "athlon_decode" "direct")])
15560
15561(define_insn "sqrtxf2"
15562  [(set (match_operand:XF 0 "register_operand" "=f")
15563	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15564  "TARGET_USE_FANCY_MATH_387"
15565  "fsqrt"
15566  [(set_attr "type" "fpspc")
15567   (set_attr "mode" "XF")
15568   (set_attr "athlon_decode" "direct")])
15569
15570(define_insn "*sqrtextendsfxf2_i387"
15571  [(set (match_operand:XF 0 "register_operand" "=f")
15572	(sqrt:XF (float_extend:XF
15573		  (match_operand:SF 1 "register_operand" "0"))))]
15574  "TARGET_USE_FANCY_MATH_387"
15575  "fsqrt"
15576  [(set_attr "type" "fpspc")
15577   (set_attr "mode" "XF")
15578   (set_attr "athlon_decode" "direct")])
15579
15580(define_insn "*sqrtextenddfxf2_i387"
15581  [(set (match_operand:XF 0 "register_operand" "=f")
15582	(sqrt:XF (float_extend:XF
15583		  (match_operand:DF 1 "register_operand" "0"))))]
15584  "TARGET_USE_FANCY_MATH_387"
15585  "fsqrt"
15586  [(set_attr "type" "fpspc")
15587   (set_attr "mode" "XF")
15588   (set_attr "athlon_decode" "direct")])
15589
15590(define_insn "fpremxf4"
15591  [(set (match_operand:XF 0 "register_operand" "=f")
15592	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15593		    (match_operand:XF 3 "register_operand" "1")]
15594		   UNSPEC_FPREM_F))
15595   (set (match_operand:XF 1 "register_operand" "=u")
15596	(unspec:XF [(match_dup 2) (match_dup 3)]
15597		   UNSPEC_FPREM_U))
15598   (set (reg:CCFP FPSR_REG)
15599	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15600  "TARGET_USE_FANCY_MATH_387
15601   && flag_unsafe_math_optimizations"
15602  "fprem"
15603  [(set_attr "type" "fpspc")
15604   (set_attr "mode" "XF")])
15605
15606(define_expand "fmodsf3"
15607  [(use (match_operand:SF 0 "register_operand" ""))
15608   (use (match_operand:SF 1 "register_operand" ""))
15609   (use (match_operand:SF 2 "register_operand" ""))]
15610  "TARGET_USE_FANCY_MATH_387
15611   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15612   && flag_unsafe_math_optimizations"
15613{
15614  rtx label = gen_label_rtx ();
15615
15616  rtx op1 = gen_reg_rtx (XFmode);
15617  rtx op2 = gen_reg_rtx (XFmode);
15618
15619  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15620  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15621
15622  emit_label (label);
15623
15624  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15625  ix86_emit_fp_unordered_jump (label);
15626
15627  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15628  DONE;
15629})
15630
15631(define_expand "fmoddf3"
15632  [(use (match_operand:DF 0 "register_operand" ""))
15633   (use (match_operand:DF 1 "register_operand" ""))
15634   (use (match_operand:DF 2 "register_operand" ""))]
15635  "TARGET_USE_FANCY_MATH_387
15636   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15637   && flag_unsafe_math_optimizations"
15638{
15639  rtx label = gen_label_rtx ();
15640
15641  rtx op1 = gen_reg_rtx (XFmode);
15642  rtx op2 = gen_reg_rtx (XFmode);
15643
15644  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15645  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15646
15647  emit_label (label);
15648
15649  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15650  ix86_emit_fp_unordered_jump (label);
15651
15652  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15653  DONE;
15654})
15655
15656(define_expand "fmodxf3"
15657  [(use (match_operand:XF 0 "register_operand" ""))
15658   (use (match_operand:XF 1 "register_operand" ""))
15659   (use (match_operand:XF 2 "register_operand" ""))]
15660  "TARGET_USE_FANCY_MATH_387
15661   && flag_unsafe_math_optimizations"
15662{
15663  rtx label = gen_label_rtx ();
15664
15665  emit_label (label);
15666
15667  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15668			   operands[1], operands[2]));
15669  ix86_emit_fp_unordered_jump (label);
15670
15671  emit_move_insn (operands[0], operands[1]);
15672  DONE;
15673})
15674
15675(define_insn "fprem1xf4"
15676  [(set (match_operand:XF 0 "register_operand" "=f")
15677	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15678		    (match_operand:XF 3 "register_operand" "1")]
15679		   UNSPEC_FPREM1_F))
15680   (set (match_operand:XF 1 "register_operand" "=u")
15681	(unspec:XF [(match_dup 2) (match_dup 3)]
15682		   UNSPEC_FPREM1_U))
15683   (set (reg:CCFP FPSR_REG)
15684	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15685  "TARGET_USE_FANCY_MATH_387
15686   && flag_unsafe_math_optimizations"
15687  "fprem1"
15688  [(set_attr "type" "fpspc")
15689   (set_attr "mode" "XF")])
15690
15691(define_expand "dremsf3"
15692  [(use (match_operand:SF 0 "register_operand" ""))
15693   (use (match_operand:SF 1 "register_operand" ""))
15694   (use (match_operand:SF 2 "register_operand" ""))]
15695  "TARGET_USE_FANCY_MATH_387
15696   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15697   && flag_unsafe_math_optimizations"
15698{
15699  rtx label = gen_label_rtx ();
15700
15701  rtx op1 = gen_reg_rtx (XFmode);
15702  rtx op2 = gen_reg_rtx (XFmode);
15703
15704  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15705  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15706
15707  emit_label (label);
15708
15709  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15710  ix86_emit_fp_unordered_jump (label);
15711
15712  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15713  DONE;
15714})
15715
15716(define_expand "dremdf3"
15717  [(use (match_operand:DF 0 "register_operand" ""))
15718   (use (match_operand:DF 1 "register_operand" ""))
15719   (use (match_operand:DF 2 "register_operand" ""))]
15720  "TARGET_USE_FANCY_MATH_387
15721   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15722   && flag_unsafe_math_optimizations"
15723{
15724  rtx label = gen_label_rtx ();
15725
15726  rtx op1 = gen_reg_rtx (XFmode);
15727  rtx op2 = gen_reg_rtx (XFmode);
15728
15729  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15730  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15731
15732  emit_label (label);
15733
15734  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15735  ix86_emit_fp_unordered_jump (label);
15736
15737  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15738  DONE;
15739})
15740
15741(define_expand "dremxf3"
15742  [(use (match_operand:XF 0 "register_operand" ""))
15743   (use (match_operand:XF 1 "register_operand" ""))
15744   (use (match_operand:XF 2 "register_operand" ""))]
15745  "TARGET_USE_FANCY_MATH_387
15746   && flag_unsafe_math_optimizations"
15747{
15748  rtx label = gen_label_rtx ();
15749
15750  emit_label (label);
15751
15752  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15753			    operands[1], operands[2]));
15754  ix86_emit_fp_unordered_jump (label);
15755
15756  emit_move_insn (operands[0], operands[1]);
15757  DONE;
15758})
15759
15760(define_insn "*sindf2"
15761  [(set (match_operand:DF 0 "register_operand" "=f")
15762	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15763  "TARGET_USE_FANCY_MATH_387
15764   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15765   && flag_unsafe_math_optimizations"
15766  "fsin"
15767  [(set_attr "type" "fpspc")
15768   (set_attr "mode" "DF")])
15769
15770(define_insn "*sinsf2"
15771  [(set (match_operand:SF 0 "register_operand" "=f")
15772	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15773  "TARGET_USE_FANCY_MATH_387
15774   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15775   && flag_unsafe_math_optimizations"
15776  "fsin"
15777  [(set_attr "type" "fpspc")
15778   (set_attr "mode" "SF")])
15779
15780(define_insn "*sinextendsfdf2"
15781  [(set (match_operand:DF 0 "register_operand" "=f")
15782	(unspec:DF [(float_extend:DF
15783		     (match_operand:SF 1 "register_operand" "0"))]
15784		   UNSPEC_SIN))]
15785  "TARGET_USE_FANCY_MATH_387
15786   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15787   && flag_unsafe_math_optimizations"
15788  "fsin"
15789  [(set_attr "type" "fpspc")
15790   (set_attr "mode" "DF")])
15791
15792(define_insn "*sinxf2"
15793  [(set (match_operand:XF 0 "register_operand" "=f")
15794	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15795  "TARGET_USE_FANCY_MATH_387
15796   && flag_unsafe_math_optimizations"
15797  "fsin"
15798  [(set_attr "type" "fpspc")
15799   (set_attr "mode" "XF")])
15800
15801(define_insn "*cosdf2"
15802  [(set (match_operand:DF 0 "register_operand" "=f")
15803	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15804  "TARGET_USE_FANCY_MATH_387
15805   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15806   && flag_unsafe_math_optimizations"
15807  "fcos"
15808  [(set_attr "type" "fpspc")
15809   (set_attr "mode" "DF")])
15810
15811(define_insn "*cossf2"
15812  [(set (match_operand:SF 0 "register_operand" "=f")
15813	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15814  "TARGET_USE_FANCY_MATH_387
15815   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15816   && flag_unsafe_math_optimizations"
15817  "fcos"
15818  [(set_attr "type" "fpspc")
15819   (set_attr "mode" "SF")])
15820
15821(define_insn "*cosextendsfdf2"
15822  [(set (match_operand:DF 0 "register_operand" "=f")
15823	(unspec:DF [(float_extend:DF
15824		     (match_operand:SF 1 "register_operand" "0"))]
15825		   UNSPEC_COS))]
15826  "TARGET_USE_FANCY_MATH_387
15827   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15828   && flag_unsafe_math_optimizations"
15829  "fcos"
15830  [(set_attr "type" "fpspc")
15831   (set_attr "mode" "DF")])
15832
15833(define_insn "*cosxf2"
15834  [(set (match_operand:XF 0 "register_operand" "=f")
15835	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15836  "TARGET_USE_FANCY_MATH_387
15837   && flag_unsafe_math_optimizations"
15838  "fcos"
15839  [(set_attr "type" "fpspc")
15840   (set_attr "mode" "XF")])
15841
15842;; With sincos pattern defined, sin and cos builtin function will be
15843;; expanded to sincos pattern with one of its outputs left unused. 
15844;; Cse pass  will detected, if two sincos patterns can be combined,
15845;; otherwise sincos pattern will be split back to sin or cos pattern,
15846;; depending on the unused output.
15847
15848(define_insn "sincosdf3"
15849  [(set (match_operand:DF 0 "register_operand" "=f")
15850	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15851		   UNSPEC_SINCOS_COS))
15852   (set (match_operand:DF 1 "register_operand" "=u")
15853        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15854  "TARGET_USE_FANCY_MATH_387
15855   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15856   && flag_unsafe_math_optimizations"
15857  "fsincos"
15858  [(set_attr "type" "fpspc")
15859   (set_attr "mode" "DF")])
15860
15861(define_split
15862  [(set (match_operand:DF 0 "register_operand" "")
15863	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15864		   UNSPEC_SINCOS_COS))
15865   (set (match_operand:DF 1 "register_operand" "")
15866	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15867  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15868   && !reload_completed && !reload_in_progress"
15869  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15870  "")
15871
15872(define_split
15873  [(set (match_operand:DF 0 "register_operand" "")
15874	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15875		   UNSPEC_SINCOS_COS))
15876   (set (match_operand:DF 1 "register_operand" "")
15877	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15878  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15879   && !reload_completed && !reload_in_progress"
15880  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15881  "")
15882
15883(define_insn "sincossf3"
15884  [(set (match_operand:SF 0 "register_operand" "=f")
15885	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15886		   UNSPEC_SINCOS_COS))
15887   (set (match_operand:SF 1 "register_operand" "=u")
15888        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15889  "TARGET_USE_FANCY_MATH_387
15890   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15891   && flag_unsafe_math_optimizations"
15892  "fsincos"
15893  [(set_attr "type" "fpspc")
15894   (set_attr "mode" "SF")])
15895
15896(define_split
15897  [(set (match_operand:SF 0 "register_operand" "")
15898	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15899		   UNSPEC_SINCOS_COS))
15900   (set (match_operand:SF 1 "register_operand" "")
15901	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15902  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15903   && !reload_completed && !reload_in_progress"
15904  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15905  "")
15906
15907(define_split
15908  [(set (match_operand:SF 0 "register_operand" "")
15909	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15910		   UNSPEC_SINCOS_COS))
15911   (set (match_operand:SF 1 "register_operand" "")
15912	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15913  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15914   && !reload_completed && !reload_in_progress"
15915  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15916  "")
15917
15918(define_insn "*sincosextendsfdf3"
15919  [(set (match_operand:DF 0 "register_operand" "=f")
15920	(unspec:DF [(float_extend:DF
15921		     (match_operand:SF 2 "register_operand" "0"))]
15922		   UNSPEC_SINCOS_COS))
15923   (set (match_operand:DF 1 "register_operand" "=u")
15924        (unspec:DF [(float_extend:DF
15925		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15926  "TARGET_USE_FANCY_MATH_387
15927   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15928   && flag_unsafe_math_optimizations"
15929  "fsincos"
15930  [(set_attr "type" "fpspc")
15931   (set_attr "mode" "DF")])
15932
15933(define_split
15934  [(set (match_operand:DF 0 "register_operand" "")
15935	(unspec:DF [(float_extend:DF
15936		     (match_operand:SF 2 "register_operand" ""))]
15937		   UNSPEC_SINCOS_COS))
15938   (set (match_operand:DF 1 "register_operand" "")
15939        (unspec:DF [(float_extend:DF
15940		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15941  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15942   && !reload_completed && !reload_in_progress"
15943  [(set (match_dup 1) (unspec:DF [(float_extend:DF
15944				   (match_dup 2))] UNSPEC_SIN))]
15945  "")
15946
15947(define_split
15948  [(set (match_operand:DF 0 "register_operand" "")
15949	(unspec:DF [(float_extend:DF
15950		     (match_operand:SF 2 "register_operand" ""))]
15951		   UNSPEC_SINCOS_COS))
15952   (set (match_operand:DF 1 "register_operand" "")
15953        (unspec:DF [(float_extend:DF
15954		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15955  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15956   && !reload_completed && !reload_in_progress"
15957  [(set (match_dup 0) (unspec:DF [(float_extend:DF
15958				   (match_dup 2))] UNSPEC_COS))]
15959  "")
15960
15961(define_insn "sincosxf3"
15962  [(set (match_operand:XF 0 "register_operand" "=f")
15963	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15964		   UNSPEC_SINCOS_COS))
15965   (set (match_operand:XF 1 "register_operand" "=u")
15966        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15967  "TARGET_USE_FANCY_MATH_387
15968   && flag_unsafe_math_optimizations"
15969  "fsincos"
15970  [(set_attr "type" "fpspc")
15971   (set_attr "mode" "XF")])
15972
15973(define_split
15974  [(set (match_operand:XF 0 "register_operand" "")
15975	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15976		   UNSPEC_SINCOS_COS))
15977   (set (match_operand:XF 1 "register_operand" "")
15978	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15979  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15980   && !reload_completed && !reload_in_progress"
15981  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15982  "")
15983
15984(define_split
15985  [(set (match_operand:XF 0 "register_operand" "")
15986	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15987		   UNSPEC_SINCOS_COS))
15988   (set (match_operand:XF 1 "register_operand" "")
15989	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15990  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15991   && !reload_completed && !reload_in_progress"
15992  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15993  "")
15994
15995(define_insn "*tandf3_1"
15996  [(set (match_operand:DF 0 "register_operand" "=f")
15997	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15998		   UNSPEC_TAN_ONE))
15999   (set (match_operand:DF 1 "register_operand" "=u")
16000        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16001  "TARGET_USE_FANCY_MATH_387
16002   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16003   && flag_unsafe_math_optimizations"
16004  "fptan"
16005  [(set_attr "type" "fpspc")
16006   (set_attr "mode" "DF")])
16007
16008;; optimize sequence: fptan
16009;;		      fstp    %st(0)
16010;;		      fld1
16011;; into fptan insn.
16012
16013(define_peephole2
16014  [(parallel[(set (match_operand:DF 0 "register_operand" "")
16015		  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16016			     UNSPEC_TAN_ONE))
16017	     (set (match_operand:DF 1 "register_operand" "")
16018		  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16019   (set (match_dup 0)
16020        (match_operand:DF 3 "immediate_operand" ""))]
16021  "standard_80387_constant_p (operands[3]) == 2"
16022  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16023   	     (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16024  "")
16025
16026(define_expand "tandf2"
16027  [(parallel [(set (match_dup 2)
16028		   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16029			      UNSPEC_TAN_ONE))
16030	      (set (match_operand:DF 0 "register_operand" "")
16031		   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16032  "TARGET_USE_FANCY_MATH_387
16033   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16034   && flag_unsafe_math_optimizations"
16035{
16036  operands[2] = gen_reg_rtx (DFmode);
16037})
16038
16039(define_insn "*tansf3_1"
16040  [(set (match_operand:SF 0 "register_operand" "=f")
16041	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16042		   UNSPEC_TAN_ONE))
16043   (set (match_operand:SF 1 "register_operand" "=u")
16044        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16045  "TARGET_USE_FANCY_MATH_387
16046   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16047   && flag_unsafe_math_optimizations"
16048  "fptan"
16049  [(set_attr "type" "fpspc")
16050   (set_attr "mode" "SF")])
16051
16052;; optimize sequence: fptan
16053;;		      fstp    %st(0)
16054;;		      fld1
16055;; into fptan insn.
16056
16057(define_peephole2
16058  [(parallel[(set (match_operand:SF 0 "register_operand" "")
16059		  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16060			     UNSPEC_TAN_ONE))
16061	     (set (match_operand:SF 1 "register_operand" "")
16062		  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16063   (set (match_dup 0)
16064        (match_operand:SF 3 "immediate_operand" ""))]
16065  "standard_80387_constant_p (operands[3]) == 2"
16066  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16067   	     (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16068  "")
16069
16070(define_expand "tansf2"
16071  [(parallel [(set (match_dup 2)
16072		   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16073			      UNSPEC_TAN_ONE))
16074	      (set (match_operand:SF 0 "register_operand" "")
16075		   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16076  "TARGET_USE_FANCY_MATH_387
16077   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16078   && flag_unsafe_math_optimizations"
16079{
16080  operands[2] = gen_reg_rtx (SFmode);
16081})
16082
16083(define_insn "*tanxf3_1"
16084  [(set (match_operand:XF 0 "register_operand" "=f")
16085	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16086		   UNSPEC_TAN_ONE))
16087   (set (match_operand:XF 1 "register_operand" "=u")
16088        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16089  "TARGET_USE_FANCY_MATH_387
16090   && flag_unsafe_math_optimizations"
16091  "fptan"
16092  [(set_attr "type" "fpspc")
16093   (set_attr "mode" "XF")])
16094
16095;; optimize sequence: fptan
16096;;		      fstp    %st(0)
16097;;		      fld1
16098;; into fptan insn.
16099
16100(define_peephole2
16101  [(parallel[(set (match_operand:XF 0 "register_operand" "")
16102		  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16103			     UNSPEC_TAN_ONE))
16104	     (set (match_operand:XF 1 "register_operand" "")
16105		  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16106   (set (match_dup 0)
16107        (match_operand:XF 3 "immediate_operand" ""))]
16108  "standard_80387_constant_p (operands[3]) == 2"
16109  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16110   	     (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16111  "")
16112
16113(define_expand "tanxf2"
16114  [(parallel [(set (match_dup 2)
16115		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16116			      UNSPEC_TAN_ONE))
16117	      (set (match_operand:XF 0 "register_operand" "")
16118		   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16119  "TARGET_USE_FANCY_MATH_387
16120   && flag_unsafe_math_optimizations"
16121{
16122  operands[2] = gen_reg_rtx (XFmode);
16123})
16124
16125(define_insn "atan2df3_1"
16126  [(set (match_operand:DF 0 "register_operand" "=f")
16127	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
16128		    (match_operand:DF 1 "register_operand" "u")]
16129		   UNSPEC_FPATAN))
16130   (clobber (match_scratch:DF 3 "=1"))]
16131  "TARGET_USE_FANCY_MATH_387
16132   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16133   && flag_unsafe_math_optimizations"
16134  "fpatan"
16135  [(set_attr "type" "fpspc")
16136   (set_attr "mode" "DF")])
16137
16138(define_expand "atan2df3"
16139  [(use (match_operand:DF 0 "register_operand" ""))
16140   (use (match_operand:DF 2 "register_operand" ""))
16141   (use (match_operand:DF 1 "register_operand" ""))]
16142  "TARGET_USE_FANCY_MATH_387
16143   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16144   && flag_unsafe_math_optimizations"
16145{
16146  rtx copy = gen_reg_rtx (DFmode);
16147  emit_move_insn (copy, operands[1]);
16148  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16149  DONE;
16150})
16151
16152(define_expand "atandf2"
16153  [(parallel [(set (match_operand:DF 0 "register_operand" "")
16154		   (unspec:DF [(match_dup 2)
16155			       (match_operand:DF 1 "register_operand" "")]
16156		    UNSPEC_FPATAN))
16157	      (clobber (match_scratch:DF 3 ""))])]
16158  "TARGET_USE_FANCY_MATH_387
16159   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16160   && flag_unsafe_math_optimizations"
16161{
16162  operands[2] = gen_reg_rtx (DFmode);
16163  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16164})
16165
16166(define_insn "atan2sf3_1"
16167  [(set (match_operand:SF 0 "register_operand" "=f")
16168        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16169		    (match_operand:SF 1 "register_operand" "u")]
16170		   UNSPEC_FPATAN))
16171   (clobber (match_scratch:SF 3 "=1"))]
16172  "TARGET_USE_FANCY_MATH_387
16173   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16174   && flag_unsafe_math_optimizations"
16175  "fpatan"
16176  [(set_attr "type" "fpspc")
16177   (set_attr "mode" "SF")])
16178
16179(define_expand "atan2sf3"
16180  [(use (match_operand:SF 0 "register_operand" ""))
16181   (use (match_operand:SF 2 "register_operand" ""))
16182   (use (match_operand:SF 1 "register_operand" ""))]
16183  "TARGET_USE_FANCY_MATH_387
16184   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16185   && flag_unsafe_math_optimizations"
16186{
16187  rtx copy = gen_reg_rtx (SFmode);
16188  emit_move_insn (copy, operands[1]);
16189  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16190  DONE;
16191})
16192
16193(define_expand "atansf2"
16194  [(parallel [(set (match_operand:SF 0 "register_operand" "")
16195		   (unspec:SF [(match_dup 2)
16196			       (match_operand:SF 1 "register_operand" "")]
16197		    UNSPEC_FPATAN))
16198	      (clobber (match_scratch:SF 3 ""))])]
16199  "TARGET_USE_FANCY_MATH_387
16200   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16201   && flag_unsafe_math_optimizations"
16202{
16203  operands[2] = gen_reg_rtx (SFmode);
16204  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16205})
16206
16207(define_insn "atan2xf3_1"
16208  [(set (match_operand:XF 0 "register_operand" "=f")
16209        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16210	            (match_operand:XF 1 "register_operand" "u")]
16211	           UNSPEC_FPATAN))
16212   (clobber (match_scratch:XF 3 "=1"))]
16213  "TARGET_USE_FANCY_MATH_387
16214   && flag_unsafe_math_optimizations"
16215  "fpatan"
16216  [(set_attr "type" "fpspc")
16217   (set_attr "mode" "XF")])
16218
16219(define_expand "atan2xf3"
16220  [(use (match_operand:XF 0 "register_operand" ""))
16221   (use (match_operand:XF 2 "register_operand" ""))
16222   (use (match_operand:XF 1 "register_operand" ""))]
16223  "TARGET_USE_FANCY_MATH_387
16224   && flag_unsafe_math_optimizations"
16225{
16226  rtx copy = gen_reg_rtx (XFmode);
16227  emit_move_insn (copy, operands[1]);
16228  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16229  DONE;
16230})
16231
16232(define_expand "atanxf2"
16233  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16234		   (unspec:XF [(match_dup 2)
16235			       (match_operand:XF 1 "register_operand" "")]
16236		    UNSPEC_FPATAN))
16237	      (clobber (match_scratch:XF 3 ""))])]
16238  "TARGET_USE_FANCY_MATH_387
16239   && flag_unsafe_math_optimizations"
16240{
16241  operands[2] = gen_reg_rtx (XFmode);
16242  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16243})
16244
16245(define_expand "asindf2"
16246  [(set (match_dup 2)
16247	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16248   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16249   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16250   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16251   (parallel [(set (match_dup 7)
16252        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16253			      UNSPEC_FPATAN))
16254   	      (clobber (match_scratch:XF 8 ""))])
16255   (set (match_operand:DF 0 "register_operand" "")
16256	(float_truncate:DF (match_dup 7)))]
16257  "TARGET_USE_FANCY_MATH_387
16258   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16259   && flag_unsafe_math_optimizations"
16260{
16261  int i;
16262
16263  for (i=2; i<8; i++)
16264    operands[i] = gen_reg_rtx (XFmode);
16265
16266  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16267})
16268
16269(define_expand "asinsf2"
16270  [(set (match_dup 2)
16271	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16272   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16273   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16274   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16275   (parallel [(set (match_dup 7)
16276        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16277			      UNSPEC_FPATAN))
16278   	      (clobber (match_scratch:XF 8 ""))])
16279   (set (match_operand:SF 0 "register_operand" "")
16280	(float_truncate:SF (match_dup 7)))]
16281  "TARGET_USE_FANCY_MATH_387
16282   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16283   && flag_unsafe_math_optimizations"
16284{
16285  int i;
16286
16287  for (i=2; i<8; i++)
16288    operands[i] = gen_reg_rtx (XFmode);
16289
16290  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16291})
16292
16293(define_expand "asinxf2"
16294  [(set (match_dup 2)
16295	(mult:XF (match_operand:XF 1 "register_operand" "")
16296		 (match_dup 1)))
16297   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16298   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16299   (parallel [(set (match_operand:XF 0 "register_operand" "")
16300        	   (unspec:XF [(match_dup 5) (match_dup 1)]
16301			      UNSPEC_FPATAN))
16302   	      (clobber (match_scratch:XF 6 ""))])]
16303  "TARGET_USE_FANCY_MATH_387
16304   && flag_unsafe_math_optimizations"
16305{
16306  int i;
16307
16308  for (i=2; i<6; i++)
16309    operands[i] = gen_reg_rtx (XFmode);
16310
16311  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16312})
16313
16314(define_expand "acosdf2"
16315  [(set (match_dup 2)
16316	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16317   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16318   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16319   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16320   (parallel [(set (match_dup 7)
16321        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16322			      UNSPEC_FPATAN))
16323   	      (clobber (match_scratch:XF 8 ""))])
16324   (set (match_operand:DF 0 "register_operand" "")
16325	(float_truncate:DF (match_dup 7)))]
16326  "TARGET_USE_FANCY_MATH_387
16327   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16328   && flag_unsafe_math_optimizations"
16329{
16330  int i;
16331
16332  for (i=2; i<8; i++)
16333    operands[i] = gen_reg_rtx (XFmode);
16334
16335  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16336})
16337
16338(define_expand "acossf2"
16339  [(set (match_dup 2)
16340	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16341   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16342   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16343   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16344   (parallel [(set (match_dup 7)
16345        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16346			      UNSPEC_FPATAN))
16347   	      (clobber (match_scratch:XF 8 ""))])
16348   (set (match_operand:SF 0 "register_operand" "")
16349	(float_truncate:SF (match_dup 7)))]
16350  "TARGET_USE_FANCY_MATH_387
16351   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16352   && flag_unsafe_math_optimizations"
16353{
16354  int i;
16355
16356  for (i=2; i<8; i++)
16357    operands[i] = gen_reg_rtx (XFmode);
16358
16359  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16360})
16361
16362(define_expand "acosxf2"
16363  [(set (match_dup 2)
16364	(mult:XF (match_operand:XF 1 "register_operand" "")
16365		 (match_dup 1)))
16366   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16367   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16368   (parallel [(set (match_operand:XF 0 "register_operand" "")
16369        	   (unspec:XF [(match_dup 1) (match_dup 5)]
16370			      UNSPEC_FPATAN))
16371   	      (clobber (match_scratch:XF 6 ""))])]
16372  "TARGET_USE_FANCY_MATH_387
16373   && flag_unsafe_math_optimizations"
16374{
16375  int i;
16376
16377  for (i=2; i<6; i++)
16378    operands[i] = gen_reg_rtx (XFmode);
16379
16380  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16381})
16382
16383(define_insn "fyl2x_xf3"
16384  [(set (match_operand:XF 0 "register_operand" "=f")
16385        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16386		    (match_operand:XF 1 "register_operand" "u")]
16387	           UNSPEC_FYL2X))
16388   (clobber (match_scratch:XF 3 "=1"))]
16389  "TARGET_USE_FANCY_MATH_387
16390   && flag_unsafe_math_optimizations"
16391  "fyl2x"
16392  [(set_attr "type" "fpspc")
16393   (set_attr "mode" "XF")])
16394
16395(define_expand "logsf2"
16396  [(set (match_dup 2)
16397	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16398   (parallel [(set (match_dup 4)
16399		   (unspec:XF [(match_dup 2)
16400			       (match_dup 3)] UNSPEC_FYL2X))
16401	      (clobber (match_scratch:XF 5 ""))])
16402   (set (match_operand:SF 0 "register_operand" "")
16403	(float_truncate:SF (match_dup 4)))]
16404  "TARGET_USE_FANCY_MATH_387
16405   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16406   && flag_unsafe_math_optimizations"
16407{
16408  rtx temp;
16409
16410  operands[2] = gen_reg_rtx (XFmode);
16411  operands[3] = gen_reg_rtx (XFmode);
16412  operands[4] = gen_reg_rtx (XFmode);
16413
16414  temp = standard_80387_constant_rtx (4); /* fldln2 */
16415  emit_move_insn (operands[3], temp);
16416})
16417
16418(define_expand "logdf2"
16419  [(set (match_dup 2)
16420	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16421   (parallel [(set (match_dup 4)
16422		   (unspec:XF [(match_dup 2)
16423			       (match_dup 3)] UNSPEC_FYL2X))
16424	      (clobber (match_scratch:XF 5 ""))])
16425   (set (match_operand:DF 0 "register_operand" "")
16426	(float_truncate:DF (match_dup 4)))]
16427  "TARGET_USE_FANCY_MATH_387
16428   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16429   && flag_unsafe_math_optimizations"
16430{
16431  rtx temp;
16432
16433  operands[2] = gen_reg_rtx (XFmode);
16434  operands[3] = gen_reg_rtx (XFmode);
16435  operands[4] = gen_reg_rtx (XFmode);
16436
16437  temp = standard_80387_constant_rtx (4); /* fldln2 */
16438  emit_move_insn (operands[3], temp);
16439})
16440
16441(define_expand "logxf2"
16442  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16443		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16444			       (match_dup 2)] UNSPEC_FYL2X))
16445	      (clobber (match_scratch:XF 3 ""))])]
16446  "TARGET_USE_FANCY_MATH_387
16447   && flag_unsafe_math_optimizations"
16448{
16449  rtx temp;
16450
16451  operands[2] = gen_reg_rtx (XFmode);
16452  temp = standard_80387_constant_rtx (4); /* fldln2 */
16453  emit_move_insn (operands[2], temp);
16454})
16455
16456(define_expand "log10sf2"
16457  [(set (match_dup 2)
16458	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16459   (parallel [(set (match_dup 4)
16460		   (unspec:XF [(match_dup 2)
16461			       (match_dup 3)] UNSPEC_FYL2X))
16462	      (clobber (match_scratch:XF 5 ""))])
16463   (set (match_operand:SF 0 "register_operand" "")
16464	(float_truncate:SF (match_dup 4)))]
16465  "TARGET_USE_FANCY_MATH_387
16466   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16467   && flag_unsafe_math_optimizations"
16468{
16469  rtx temp;
16470
16471  operands[2] = gen_reg_rtx (XFmode);
16472  operands[3] = gen_reg_rtx (XFmode);
16473  operands[4] = gen_reg_rtx (XFmode);
16474
16475  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16476  emit_move_insn (operands[3], temp);
16477})
16478
16479(define_expand "log10df2"
16480  [(set (match_dup 2)
16481	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16482   (parallel [(set (match_dup 4)
16483		   (unspec:XF [(match_dup 2)
16484			       (match_dup 3)] UNSPEC_FYL2X))
16485	      (clobber (match_scratch:XF 5 ""))])
16486   (set (match_operand:DF 0 "register_operand" "")
16487	(float_truncate:DF (match_dup 4)))]
16488  "TARGET_USE_FANCY_MATH_387
16489   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16490   && flag_unsafe_math_optimizations"
16491{
16492  rtx temp;
16493
16494  operands[2] = gen_reg_rtx (XFmode);
16495  operands[3] = gen_reg_rtx (XFmode);
16496  operands[4] = gen_reg_rtx (XFmode);
16497
16498  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16499  emit_move_insn (operands[3], temp);
16500})
16501
16502(define_expand "log10xf2"
16503  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16504		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16505			       (match_dup 2)] UNSPEC_FYL2X))
16506	      (clobber (match_scratch:XF 3 ""))])]
16507  "TARGET_USE_FANCY_MATH_387
16508   && flag_unsafe_math_optimizations"
16509{
16510  rtx temp;
16511
16512  operands[2] = gen_reg_rtx (XFmode);
16513  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16514  emit_move_insn (operands[2], temp);
16515})
16516
16517(define_expand "log2sf2"
16518  [(set (match_dup 2)
16519	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16520   (parallel [(set (match_dup 4)
16521		   (unspec:XF [(match_dup 2)
16522			       (match_dup 3)] UNSPEC_FYL2X))
16523	      (clobber (match_scratch:XF 5 ""))])
16524   (set (match_operand:SF 0 "register_operand" "")
16525	(float_truncate:SF (match_dup 4)))]
16526  "TARGET_USE_FANCY_MATH_387
16527   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16528   && flag_unsafe_math_optimizations"
16529{
16530  operands[2] = gen_reg_rtx (XFmode);
16531  operands[3] = gen_reg_rtx (XFmode);
16532  operands[4] = gen_reg_rtx (XFmode);
16533
16534  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16535})
16536
16537(define_expand "log2df2"
16538  [(set (match_dup 2)
16539	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16540   (parallel [(set (match_dup 4)
16541		   (unspec:XF [(match_dup 2)
16542			       (match_dup 3)] UNSPEC_FYL2X))
16543	      (clobber (match_scratch:XF 5 ""))])
16544   (set (match_operand:DF 0 "register_operand" "")
16545	(float_truncate:DF (match_dup 4)))]
16546  "TARGET_USE_FANCY_MATH_387
16547   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16548   && flag_unsafe_math_optimizations"
16549{
16550  operands[2] = gen_reg_rtx (XFmode);
16551  operands[3] = gen_reg_rtx (XFmode);
16552  operands[4] = gen_reg_rtx (XFmode);
16553
16554  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16555})
16556
16557(define_expand "log2xf2"
16558  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16559		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16560			       (match_dup 2)] UNSPEC_FYL2X))
16561	      (clobber (match_scratch:XF 3 ""))])]
16562  "TARGET_USE_FANCY_MATH_387
16563   && flag_unsafe_math_optimizations"
16564{
16565  operands[2] = gen_reg_rtx (XFmode);
16566  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16567})
16568
16569(define_insn "fyl2xp1_xf3"
16570  [(set (match_operand:XF 0 "register_operand" "=f")
16571        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16572		    (match_operand:XF 1 "register_operand" "u")]
16573	           UNSPEC_FYL2XP1))
16574   (clobber (match_scratch:XF 3 "=1"))]
16575  "TARGET_USE_FANCY_MATH_387
16576   && flag_unsafe_math_optimizations"
16577  "fyl2xp1"
16578  [(set_attr "type" "fpspc")
16579   (set_attr "mode" "XF")])
16580
16581(define_expand "log1psf2"
16582  [(use (match_operand:SF 0 "register_operand" ""))
16583   (use (match_operand:SF 1 "register_operand" ""))]
16584  "TARGET_USE_FANCY_MATH_387
16585   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16586   && flag_unsafe_math_optimizations"
16587{
16588  rtx op0 = gen_reg_rtx (XFmode);
16589  rtx op1 = gen_reg_rtx (XFmode);
16590
16591  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16592  ix86_emit_i387_log1p (op0, op1);
16593  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16594  DONE;
16595})
16596
16597(define_expand "log1pdf2"
16598  [(use (match_operand:DF 0 "register_operand" ""))
16599   (use (match_operand:DF 1 "register_operand" ""))]
16600  "TARGET_USE_FANCY_MATH_387
16601   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16602   && flag_unsafe_math_optimizations"
16603{
16604  rtx op0 = gen_reg_rtx (XFmode);
16605  rtx op1 = gen_reg_rtx (XFmode);
16606
16607  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16608  ix86_emit_i387_log1p (op0, op1);
16609  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16610  DONE;
16611})
16612
16613(define_expand "log1pxf2"
16614  [(use (match_operand:XF 0 "register_operand" ""))
16615   (use (match_operand:XF 1 "register_operand" ""))]
16616  "TARGET_USE_FANCY_MATH_387
16617   && flag_unsafe_math_optimizations"
16618{
16619  ix86_emit_i387_log1p (operands[0], operands[1]);
16620  DONE;
16621})
16622
16623(define_insn "*fxtractxf3"
16624  [(set (match_operand:XF 0 "register_operand" "=f")
16625	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16626		   UNSPEC_XTRACT_FRACT))
16627   (set (match_operand:XF 1 "register_operand" "=u")
16628        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16629  "TARGET_USE_FANCY_MATH_387
16630   && flag_unsafe_math_optimizations"
16631  "fxtract"
16632  [(set_attr "type" "fpspc")
16633   (set_attr "mode" "XF")])
16634
16635(define_expand "logbsf2"
16636  [(set (match_dup 2)
16637	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16638   (parallel [(set (match_dup 3)
16639		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16640	      (set (match_dup 4)
16641		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16642   (set (match_operand:SF 0 "register_operand" "")
16643	(float_truncate:SF (match_dup 4)))]
16644  "TARGET_USE_FANCY_MATH_387
16645   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16646   && flag_unsafe_math_optimizations"
16647{
16648  operands[2] = gen_reg_rtx (XFmode);
16649  operands[3] = gen_reg_rtx (XFmode);
16650  operands[4] = gen_reg_rtx (XFmode);
16651})
16652
16653(define_expand "logbdf2"
16654  [(set (match_dup 2)
16655	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16656   (parallel [(set (match_dup 3)
16657		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16658	      (set (match_dup 4)
16659		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16660   (set (match_operand:DF 0 "register_operand" "")
16661	(float_truncate:DF (match_dup 4)))]
16662  "TARGET_USE_FANCY_MATH_387
16663   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16664   && flag_unsafe_math_optimizations"
16665{
16666  operands[2] = gen_reg_rtx (XFmode);
16667  operands[3] = gen_reg_rtx (XFmode);
16668  operands[4] = gen_reg_rtx (XFmode);
16669})
16670
16671(define_expand "logbxf2"
16672  [(parallel [(set (match_dup 2)
16673		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16674			      UNSPEC_XTRACT_FRACT))
16675	      (set (match_operand:XF 0 "register_operand" "")
16676		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16677  "TARGET_USE_FANCY_MATH_387
16678   && flag_unsafe_math_optimizations"
16679{
16680  operands[2] = gen_reg_rtx (XFmode);
16681})
16682
16683(define_expand "ilogbsi2"
16684  [(parallel [(set (match_dup 2)
16685		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16686			      UNSPEC_XTRACT_FRACT))
16687	      (set (match_operand:XF 3 "register_operand" "")
16688		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16689   (parallel [(set (match_operand:SI 0 "register_operand" "")
16690	           (fix:SI (match_dup 3)))
16691	      (clobber (reg:CC FLAGS_REG))])]
16692  "TARGET_USE_FANCY_MATH_387
16693   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16694   && flag_unsafe_math_optimizations"
16695{
16696  operands[2] = gen_reg_rtx (XFmode);
16697  operands[3] = gen_reg_rtx (XFmode);
16698})
16699
16700(define_insn "*f2xm1xf2"
16701  [(set (match_operand:XF 0 "register_operand" "=f")
16702	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16703	 UNSPEC_F2XM1))]
16704  "TARGET_USE_FANCY_MATH_387
16705   && flag_unsafe_math_optimizations"
16706  "f2xm1"
16707  [(set_attr "type" "fpspc")
16708   (set_attr "mode" "XF")])
16709
16710(define_insn "*fscalexf4"
16711  [(set (match_operand:XF 0 "register_operand" "=f")
16712	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16713		    (match_operand:XF 3 "register_operand" "1")]
16714		   UNSPEC_FSCALE_FRACT))
16715   (set (match_operand:XF 1 "register_operand" "=u")
16716	(unspec:XF [(match_dup 2) (match_dup 3)]
16717		   UNSPEC_FSCALE_EXP))]
16718  "TARGET_USE_FANCY_MATH_387
16719   && flag_unsafe_math_optimizations"
16720  "fscale"
16721  [(set_attr "type" "fpspc")
16722   (set_attr "mode" "XF")])
16723
16724(define_expand "expsf2"
16725  [(set (match_dup 2)
16726	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16727   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16728   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16729   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16730   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16731   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16732   (parallel [(set (match_dup 10)
16733		   (unspec:XF [(match_dup 9) (match_dup 5)]
16734			      UNSPEC_FSCALE_FRACT))
16735	      (set (match_dup 11)
16736		   (unspec:XF [(match_dup 9) (match_dup 5)]
16737			      UNSPEC_FSCALE_EXP))])
16738   (set (match_operand:SF 0 "register_operand" "")
16739	(float_truncate:SF (match_dup 10)))]
16740  "TARGET_USE_FANCY_MATH_387
16741   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16742   && flag_unsafe_math_optimizations"
16743{
16744  rtx temp;
16745  int i;
16746
16747  for (i=2; i<12; i++)
16748    operands[i] = gen_reg_rtx (XFmode);
16749  temp = standard_80387_constant_rtx (5); /* fldl2e */
16750  emit_move_insn (operands[3], temp);
16751  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16752})
16753
16754(define_expand "expdf2"
16755  [(set (match_dup 2)
16756	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16757   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16758   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16759   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16760   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16761   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16762   (parallel [(set (match_dup 10)
16763		   (unspec:XF [(match_dup 9) (match_dup 5)]
16764			      UNSPEC_FSCALE_FRACT))
16765	      (set (match_dup 11)
16766		   (unspec:XF [(match_dup 9) (match_dup 5)]
16767			      UNSPEC_FSCALE_EXP))])
16768   (set (match_operand:DF 0 "register_operand" "")
16769	(float_truncate:DF (match_dup 10)))]
16770  "TARGET_USE_FANCY_MATH_387
16771   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16772   && flag_unsafe_math_optimizations"
16773{
16774  rtx temp;
16775  int i;
16776
16777  for (i=2; i<12; i++)
16778    operands[i] = gen_reg_rtx (XFmode);
16779  temp = standard_80387_constant_rtx (5); /* fldl2e */
16780  emit_move_insn (operands[3], temp);
16781  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16782})
16783
16784(define_expand "expxf2"
16785  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16786			       (match_dup 2)))
16787   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16788   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16789   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16790   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16791   (parallel [(set (match_operand:XF 0 "register_operand" "")
16792		   (unspec:XF [(match_dup 8) (match_dup 4)]
16793			      UNSPEC_FSCALE_FRACT))
16794	      (set (match_dup 9)
16795		   (unspec:XF [(match_dup 8) (match_dup 4)]
16796			      UNSPEC_FSCALE_EXP))])]
16797  "TARGET_USE_FANCY_MATH_387
16798   && flag_unsafe_math_optimizations"
16799{
16800  rtx temp;
16801  int i;
16802
16803  for (i=2; i<10; i++)
16804    operands[i] = gen_reg_rtx (XFmode);
16805  temp = standard_80387_constant_rtx (5); /* fldl2e */
16806  emit_move_insn (operands[2], temp);
16807  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16808})
16809
16810(define_expand "exp10sf2"
16811  [(set (match_dup 2)
16812	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16813   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16814   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16815   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16816   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16817   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16818   (parallel [(set (match_dup 10)
16819		   (unspec:XF [(match_dup 9) (match_dup 5)]
16820			      UNSPEC_FSCALE_FRACT))
16821	      (set (match_dup 11)
16822		   (unspec:XF [(match_dup 9) (match_dup 5)]
16823			      UNSPEC_FSCALE_EXP))])
16824   (set (match_operand:SF 0 "register_operand" "")
16825	(float_truncate:SF (match_dup 10)))]
16826  "TARGET_USE_FANCY_MATH_387
16827   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16828   && flag_unsafe_math_optimizations"
16829{
16830  rtx temp;
16831  int i;
16832
16833  for (i=2; i<12; i++)
16834    operands[i] = gen_reg_rtx (XFmode);
16835  temp = standard_80387_constant_rtx (6); /* fldl2t */
16836  emit_move_insn (operands[3], temp);
16837  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16838})
16839
16840(define_expand "exp10df2"
16841  [(set (match_dup 2)
16842	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16843   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16844   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16845   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16846   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16847   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16848   (parallel [(set (match_dup 10)
16849		   (unspec:XF [(match_dup 9) (match_dup 5)]
16850			      UNSPEC_FSCALE_FRACT))
16851	      (set (match_dup 11)
16852		   (unspec:XF [(match_dup 9) (match_dup 5)]
16853			      UNSPEC_FSCALE_EXP))])
16854   (set (match_operand:DF 0 "register_operand" "")
16855	(float_truncate:DF (match_dup 10)))]
16856  "TARGET_USE_FANCY_MATH_387
16857   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16858   && flag_unsafe_math_optimizations"
16859{
16860  rtx temp;
16861  int i;
16862
16863  for (i=2; i<12; i++)
16864    operands[i] = gen_reg_rtx (XFmode);
16865  temp = standard_80387_constant_rtx (6); /* fldl2t */
16866  emit_move_insn (operands[3], temp);
16867  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16868})
16869
16870(define_expand "exp10xf2"
16871  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16872			       (match_dup 2)))
16873   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16874   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16875   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16876   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16877   (parallel [(set (match_operand:XF 0 "register_operand" "")
16878		   (unspec:XF [(match_dup 8) (match_dup 4)]
16879			      UNSPEC_FSCALE_FRACT))
16880	      (set (match_dup 9)
16881		   (unspec:XF [(match_dup 8) (match_dup 4)]
16882			      UNSPEC_FSCALE_EXP))])]
16883  "TARGET_USE_FANCY_MATH_387
16884   && flag_unsafe_math_optimizations"
16885{
16886  rtx temp;
16887  int i;
16888
16889  for (i=2; i<10; i++)
16890    operands[i] = gen_reg_rtx (XFmode);
16891  temp = standard_80387_constant_rtx (6); /* fldl2t */
16892  emit_move_insn (operands[2], temp);
16893  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16894})
16895
16896(define_expand "exp2sf2"
16897  [(set (match_dup 2)
16898	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16899   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16900   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16901   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16902   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16903   (parallel [(set (match_dup 8)
16904		   (unspec:XF [(match_dup 7) (match_dup 3)]
16905			      UNSPEC_FSCALE_FRACT))
16906	      (set (match_dup 9)
16907		   (unspec:XF [(match_dup 7) (match_dup 3)]
16908			      UNSPEC_FSCALE_EXP))])
16909   (set (match_operand:SF 0 "register_operand" "")
16910	(float_truncate:SF (match_dup 8)))]
16911  "TARGET_USE_FANCY_MATH_387
16912   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16913   && flag_unsafe_math_optimizations"
16914{
16915  int i;
16916
16917  for (i=2; i<10; i++)
16918    operands[i] = gen_reg_rtx (XFmode);
16919  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16920})
16921
16922(define_expand "exp2df2"
16923  [(set (match_dup 2)
16924	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16925   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16926   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16927   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16928   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16929   (parallel [(set (match_dup 8)
16930		   (unspec:XF [(match_dup 7) (match_dup 3)]
16931			      UNSPEC_FSCALE_FRACT))
16932	      (set (match_dup 9)
16933		   (unspec:XF [(match_dup 7) (match_dup 3)]
16934			      UNSPEC_FSCALE_EXP))])
16935   (set (match_operand:DF 0 "register_operand" "")
16936	(float_truncate:DF (match_dup 8)))]
16937  "TARGET_USE_FANCY_MATH_387
16938   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16939   && flag_unsafe_math_optimizations"
16940{
16941  int i;
16942
16943  for (i=2; i<10; i++)
16944    operands[i] = gen_reg_rtx (XFmode);
16945  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16946})
16947
16948(define_expand "exp2xf2"
16949  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16950   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16951   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16952   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16953   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16954   (parallel [(set (match_operand:XF 0 "register_operand" "")
16955		   (unspec:XF [(match_dup 7) (match_dup 3)]
16956			      UNSPEC_FSCALE_FRACT))
16957	      (set (match_dup 8)
16958		   (unspec:XF [(match_dup 7) (match_dup 3)]
16959			      UNSPEC_FSCALE_EXP))])]
16960  "TARGET_USE_FANCY_MATH_387
16961   && flag_unsafe_math_optimizations"
16962{
16963  int i;
16964
16965  for (i=2; i<9; i++)
16966    operands[i] = gen_reg_rtx (XFmode);
16967  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16968})
16969
16970(define_expand "expm1df2"
16971  [(set (match_dup 2)
16972	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16973   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16974   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16975   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16976   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16977   (parallel [(set (match_dup 8)
16978		   (unspec:XF [(match_dup 7) (match_dup 5)]
16979			      UNSPEC_FSCALE_FRACT))
16980		   (set (match_dup 9)
16981		   (unspec:XF [(match_dup 7) (match_dup 5)]
16982			      UNSPEC_FSCALE_EXP))])
16983   (parallel [(set (match_dup 11)
16984		   (unspec:XF [(match_dup 10) (match_dup 9)]
16985			      UNSPEC_FSCALE_FRACT))
16986	      (set (match_dup 12)
16987		   (unspec:XF [(match_dup 10) (match_dup 9)]
16988			      UNSPEC_FSCALE_EXP))])
16989   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16990   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16991   (set (match_operand:DF 0 "register_operand" "")
16992	(float_truncate:DF (match_dup 14)))]
16993  "TARGET_USE_FANCY_MATH_387
16994   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16995   && flag_unsafe_math_optimizations"
16996{
16997  rtx temp;
16998  int i;
16999
17000  for (i=2; i<15; i++)
17001    operands[i] = gen_reg_rtx (XFmode);
17002  temp = standard_80387_constant_rtx (5); /* fldl2e */
17003  emit_move_insn (operands[3], temp);
17004  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17005})
17006
17007(define_expand "expm1sf2"
17008  [(set (match_dup 2)
17009	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17010   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17011   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17012   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17013   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17014   (parallel [(set (match_dup 8)
17015		   (unspec:XF [(match_dup 7) (match_dup 5)]
17016			      UNSPEC_FSCALE_FRACT))
17017		   (set (match_dup 9)
17018		   (unspec:XF [(match_dup 7) (match_dup 5)]
17019			      UNSPEC_FSCALE_EXP))])
17020   (parallel [(set (match_dup 11)
17021		   (unspec:XF [(match_dup 10) (match_dup 9)]
17022			      UNSPEC_FSCALE_FRACT))
17023	      (set (match_dup 12)
17024		   (unspec:XF [(match_dup 10) (match_dup 9)]
17025			      UNSPEC_FSCALE_EXP))])
17026   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17027   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17028   (set (match_operand:SF 0 "register_operand" "")
17029	(float_truncate:SF (match_dup 14)))]
17030  "TARGET_USE_FANCY_MATH_387
17031   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17032   && flag_unsafe_math_optimizations"
17033{
17034  rtx temp;
17035  int i;
17036
17037  for (i=2; i<15; i++)
17038    operands[i] = gen_reg_rtx (XFmode);
17039  temp = standard_80387_constant_rtx (5); /* fldl2e */
17040  emit_move_insn (operands[3], temp);
17041  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17042})
17043
17044(define_expand "expm1xf2"
17045  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17046			       (match_dup 2)))
17047   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17048   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17049   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17050   (parallel [(set (match_dup 7)
17051		   (unspec:XF [(match_dup 6) (match_dup 4)]
17052			      UNSPEC_FSCALE_FRACT))
17053		   (set (match_dup 8)
17054		   (unspec:XF [(match_dup 6) (match_dup 4)]
17055			      UNSPEC_FSCALE_EXP))])
17056   (parallel [(set (match_dup 10)
17057		   (unspec:XF [(match_dup 9) (match_dup 8)]
17058			      UNSPEC_FSCALE_FRACT))
17059	      (set (match_dup 11)
17060		   (unspec:XF [(match_dup 9) (match_dup 8)]
17061			      UNSPEC_FSCALE_EXP))])
17062   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17063   (set (match_operand:XF 0 "register_operand" "")
17064	(plus:XF (match_dup 12) (match_dup 7)))]
17065  "TARGET_USE_FANCY_MATH_387
17066   && flag_unsafe_math_optimizations"
17067{
17068  rtx temp;
17069  int i;
17070
17071  for (i=2; i<13; i++)
17072    operands[i] = gen_reg_rtx (XFmode);
17073  temp = standard_80387_constant_rtx (5); /* fldl2e */
17074  emit_move_insn (operands[2], temp);
17075  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17076})
17077
17078(define_expand "ldexpdf3"
17079  [(set (match_dup 3)
17080	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17081   (set (match_dup 4)
17082	(float:XF (match_operand:SI 2 "register_operand" "")))
17083   (parallel [(set (match_dup 5)
17084		   (unspec:XF [(match_dup 3) (match_dup 4)]
17085			      UNSPEC_FSCALE_FRACT))
17086	      (set (match_dup 6)
17087		   (unspec:XF [(match_dup 3) (match_dup 4)]
17088			      UNSPEC_FSCALE_EXP))])
17089   (set (match_operand:DF 0 "register_operand" "")
17090	(float_truncate:DF (match_dup 5)))]
17091  "TARGET_USE_FANCY_MATH_387
17092   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17093   && flag_unsafe_math_optimizations"
17094{
17095  int i;
17096
17097  for (i=3; i<7; i++)
17098    operands[i] = gen_reg_rtx (XFmode);
17099})
17100
17101(define_expand "ldexpsf3"
17102  [(set (match_dup 3)
17103	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17104   (set (match_dup 4)
17105	(float:XF (match_operand:SI 2 "register_operand" "")))
17106   (parallel [(set (match_dup 5)
17107		   (unspec:XF [(match_dup 3) (match_dup 4)]
17108			      UNSPEC_FSCALE_FRACT))
17109	      (set (match_dup 6)
17110		   (unspec:XF [(match_dup 3) (match_dup 4)]
17111			      UNSPEC_FSCALE_EXP))])
17112   (set (match_operand:SF 0 "register_operand" "")
17113	(float_truncate:SF (match_dup 5)))]
17114  "TARGET_USE_FANCY_MATH_387
17115   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17116   && flag_unsafe_math_optimizations"
17117{
17118  int i;
17119
17120  for (i=3; i<7; i++)
17121    operands[i] = gen_reg_rtx (XFmode);
17122})
17123
17124(define_expand "ldexpxf3"
17125  [(set (match_dup 3)
17126	(float:XF (match_operand:SI 2 "register_operand" "")))
17127   (parallel [(set (match_operand:XF 0 " register_operand" "")
17128		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
17129			       (match_dup 3)]
17130			      UNSPEC_FSCALE_FRACT))
17131	      (set (match_dup 4)
17132		   (unspec:XF [(match_dup 1) (match_dup 3)]
17133			      UNSPEC_FSCALE_EXP))])]
17134  "TARGET_USE_FANCY_MATH_387
17135   && flag_unsafe_math_optimizations"
17136{
17137  int i;
17138
17139  for (i=3; i<5; i++)
17140    operands[i] = gen_reg_rtx (XFmode);
17141})
17142
17143
17144(define_insn "frndintxf2"
17145  [(set (match_operand:XF 0 "register_operand" "=f")
17146	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17147	 UNSPEC_FRNDINT))]
17148  "TARGET_USE_FANCY_MATH_387
17149   && flag_unsafe_math_optimizations"
17150  "frndint"
17151  [(set_attr "type" "fpspc")
17152   (set_attr "mode" "XF")])
17153
17154(define_expand "rintdf2"
17155  [(use (match_operand:DF 0 "register_operand" ""))
17156   (use (match_operand:DF 1 "register_operand" ""))]
17157  "TARGET_USE_FANCY_MATH_387
17158   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17159   && flag_unsafe_math_optimizations"
17160{
17161  rtx op0 = gen_reg_rtx (XFmode);
17162  rtx op1 = gen_reg_rtx (XFmode);
17163
17164  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17165  emit_insn (gen_frndintxf2 (op0, op1));
17166
17167  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17168  DONE;
17169})
17170
17171(define_expand "rintsf2"
17172  [(use (match_operand:SF 0 "register_operand" ""))
17173   (use (match_operand:SF 1 "register_operand" ""))]
17174  "TARGET_USE_FANCY_MATH_387
17175   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17176   && flag_unsafe_math_optimizations"
17177{
17178  rtx op0 = gen_reg_rtx (XFmode);
17179  rtx op1 = gen_reg_rtx (XFmode);
17180
17181  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17182  emit_insn (gen_frndintxf2 (op0, op1));
17183
17184  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17185  DONE;
17186})
17187
17188(define_expand "rintxf2"
17189  [(use (match_operand:XF 0 "register_operand" ""))
17190   (use (match_operand:XF 1 "register_operand" ""))]
17191  "TARGET_USE_FANCY_MATH_387
17192   && flag_unsafe_math_optimizations"
17193{
17194  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17195  DONE;
17196})
17197
17198(define_insn_and_split "*fistdi2_1"
17199  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17200	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17201	 UNSPEC_FIST))]
17202  "TARGET_USE_FANCY_MATH_387
17203   && flag_unsafe_math_optimizations
17204   && !(reload_completed || reload_in_progress)"
17205  "#"
17206  "&& 1"
17207  [(const_int 0)]
17208{
17209  if (memory_operand (operands[0], VOIDmode))
17210    emit_insn (gen_fistdi2 (operands[0], operands[1]));
17211  else
17212    {
17213      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17214      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17215					 operands[2]));
17216    }
17217  DONE;
17218}
17219  [(set_attr "type" "fpspc")
17220   (set_attr "mode" "DI")])
17221
17222(define_insn "fistdi2"
17223  [(set (match_operand:DI 0 "memory_operand" "=m")
17224	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17225	 UNSPEC_FIST))
17226   (clobber (match_scratch:XF 2 "=&1f"))]
17227  "TARGET_USE_FANCY_MATH_387
17228   && flag_unsafe_math_optimizations"
17229  "* return output_fix_trunc (insn, operands, 0);"
17230  [(set_attr "type" "fpspc")
17231   (set_attr "mode" "DI")])
17232
17233(define_insn "fistdi2_with_temp"
17234  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17235	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17236	 UNSPEC_FIST))
17237   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17238   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17239  "TARGET_USE_FANCY_MATH_387
17240   && flag_unsafe_math_optimizations"
17241  "#"
17242  [(set_attr "type" "fpspc")
17243   (set_attr "mode" "DI")])
17244
17245(define_split 
17246  [(set (match_operand:DI 0 "register_operand" "")
17247	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17248	 UNSPEC_FIST))
17249   (clobber (match_operand:DI 2 "memory_operand" ""))
17250   (clobber (match_scratch 3 ""))]
17251  "reload_completed"
17252  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17253	      (clobber (match_dup 3))])
17254   (set (match_dup 0) (match_dup 2))]
17255  "")
17256
17257(define_split 
17258  [(set (match_operand:DI 0 "memory_operand" "")
17259	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17260	 UNSPEC_FIST))
17261   (clobber (match_operand:DI 2 "memory_operand" ""))
17262   (clobber (match_scratch 3 ""))]
17263  "reload_completed"
17264  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17265	      (clobber (match_dup 3))])]
17266  "")
17267
17268(define_insn_and_split "*fist<mode>2_1"
17269  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17270	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17271	 UNSPEC_FIST))]
17272  "TARGET_USE_FANCY_MATH_387
17273   && flag_unsafe_math_optimizations
17274   && !(reload_completed || reload_in_progress)"
17275  "#"
17276  "&& 1"
17277  [(const_int 0)]
17278{
17279  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17280  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17281					operands[2]));
17282  DONE;
17283}
17284  [(set_attr "type" "fpspc")
17285   (set_attr "mode" "<MODE>")])
17286
17287(define_insn "fist<mode>2"
17288  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17289	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17290	 UNSPEC_FIST))]
17291  "TARGET_USE_FANCY_MATH_387
17292   && flag_unsafe_math_optimizations"
17293  "* return output_fix_trunc (insn, operands, 0);"
17294  [(set_attr "type" "fpspc")
17295   (set_attr "mode" "<MODE>")])
17296
17297(define_insn "fist<mode>2_with_temp"
17298  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17299	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17300	 UNSPEC_FIST))
17301   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17302  "TARGET_USE_FANCY_MATH_387
17303   && flag_unsafe_math_optimizations"
17304  "#"
17305  [(set_attr "type" "fpspc")
17306   (set_attr "mode" "<MODE>")])
17307
17308(define_split 
17309  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17310	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17311	 UNSPEC_FIST))
17312   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17313  "reload_completed"
17314  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17315		       UNSPEC_FIST))
17316   (set (match_dup 0) (match_dup 2))]
17317  "")
17318
17319(define_split 
17320  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17321	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17322	 UNSPEC_FIST))
17323   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17324  "reload_completed"
17325  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17326		       UNSPEC_FIST))]
17327  "")
17328
17329(define_expand "lrint<mode>2"
17330  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17331	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17332	 UNSPEC_FIST))]
17333  "TARGET_USE_FANCY_MATH_387
17334   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17335   && flag_unsafe_math_optimizations"
17336  "")
17337
17338;; Rounding mode control word calculation could clobber FLAGS_REG.
17339(define_insn_and_split "frndintxf2_floor"
17340  [(set (match_operand:XF 0 "register_operand" "=f")
17341	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17342	 UNSPEC_FRNDINT_FLOOR))
17343   (clobber (reg:CC FLAGS_REG))]
17344  "TARGET_USE_FANCY_MATH_387
17345   && flag_unsafe_math_optimizations
17346   && !(reload_completed || reload_in_progress)"
17347  "#"
17348  "&& 1"
17349  [(const_int 0)]
17350{
17351  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17352
17353  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17354  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17355
17356  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17357					operands[2], operands[3]));
17358  DONE;
17359}
17360  [(set_attr "type" "frndint")
17361   (set_attr "i387_cw" "floor")
17362   (set_attr "mode" "XF")])
17363
17364(define_insn "frndintxf2_floor_i387"
17365  [(set (match_operand:XF 0 "register_operand" "=f")
17366	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17367	 UNSPEC_FRNDINT_FLOOR))
17368   (use (match_operand:HI 2 "memory_operand" "m"))
17369   (use (match_operand:HI 3 "memory_operand" "m"))]
17370  "TARGET_USE_FANCY_MATH_387
17371   && flag_unsafe_math_optimizations"
17372  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17373  [(set_attr "type" "frndint")
17374   (set_attr "i387_cw" "floor")
17375   (set_attr "mode" "XF")])
17376
17377(define_expand "floorxf2"
17378  [(use (match_operand:XF 0 "register_operand" ""))
17379   (use (match_operand:XF 1 "register_operand" ""))]
17380  "TARGET_USE_FANCY_MATH_387
17381   && flag_unsafe_math_optimizations"
17382{
17383  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17384  DONE;
17385})
17386
17387(define_expand "floordf2"
17388  [(use (match_operand:DF 0 "register_operand" ""))
17389   (use (match_operand:DF 1 "register_operand" ""))]
17390  "TARGET_USE_FANCY_MATH_387
17391   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17392   && flag_unsafe_math_optimizations"
17393{
17394  rtx op0 = gen_reg_rtx (XFmode);
17395  rtx op1 = gen_reg_rtx (XFmode);
17396
17397  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17398  emit_insn (gen_frndintxf2_floor (op0, op1));
17399
17400  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17401  DONE;
17402})
17403
17404(define_expand "floorsf2"
17405  [(use (match_operand:SF 0 "register_operand" ""))
17406   (use (match_operand:SF 1 "register_operand" ""))]
17407  "TARGET_USE_FANCY_MATH_387
17408   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17409   && flag_unsafe_math_optimizations"
17410{
17411  rtx op0 = gen_reg_rtx (XFmode);
17412  rtx op1 = gen_reg_rtx (XFmode);
17413
17414  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17415  emit_insn (gen_frndintxf2_floor (op0, op1));
17416
17417  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17418  DONE;
17419})
17420
17421(define_insn_and_split "*fist<mode>2_floor_1"
17422  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17423	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17424	 UNSPEC_FIST_FLOOR))
17425   (clobber (reg:CC FLAGS_REG))]
17426  "TARGET_USE_FANCY_MATH_387
17427   && flag_unsafe_math_optimizations
17428   && !(reload_completed || reload_in_progress)"
17429  "#"
17430  "&& 1"
17431  [(const_int 0)]
17432{
17433  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17434
17435  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17436  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17437  if (memory_operand (operands[0], VOIDmode))
17438    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17439				      operands[2], operands[3]));
17440  else
17441    {
17442      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17443      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17444						  operands[2], operands[3],
17445						  operands[4]));
17446    }
17447  DONE;
17448}
17449  [(set_attr "type" "fistp")
17450   (set_attr "i387_cw" "floor")
17451   (set_attr "mode" "<MODE>")])
17452
17453(define_insn "fistdi2_floor"
17454  [(set (match_operand:DI 0 "memory_operand" "=m")
17455	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17456	 UNSPEC_FIST_FLOOR))
17457   (use (match_operand:HI 2 "memory_operand" "m"))
17458   (use (match_operand:HI 3 "memory_operand" "m"))
17459   (clobber (match_scratch:XF 4 "=&1f"))]
17460  "TARGET_USE_FANCY_MATH_387
17461   && flag_unsafe_math_optimizations"
17462  "* return output_fix_trunc (insn, operands, 0);"
17463  [(set_attr "type" "fistp")
17464   (set_attr "i387_cw" "floor")
17465   (set_attr "mode" "DI")])
17466
17467(define_insn "fistdi2_floor_with_temp"
17468  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17469	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17470	 UNSPEC_FIST_FLOOR))
17471   (use (match_operand:HI 2 "memory_operand" "m,m"))
17472   (use (match_operand:HI 3 "memory_operand" "m,m"))
17473   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17474   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17475  "TARGET_USE_FANCY_MATH_387
17476   && flag_unsafe_math_optimizations"
17477  "#"
17478  [(set_attr "type" "fistp")
17479   (set_attr "i387_cw" "floor")
17480   (set_attr "mode" "DI")])
17481
17482(define_split 
17483  [(set (match_operand:DI 0 "register_operand" "")
17484	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17485	 UNSPEC_FIST_FLOOR))
17486   (use (match_operand:HI 2 "memory_operand" ""))
17487   (use (match_operand:HI 3 "memory_operand" ""))
17488   (clobber (match_operand:DI 4 "memory_operand" ""))
17489   (clobber (match_scratch 5 ""))]
17490  "reload_completed"
17491  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17492	      (use (match_dup 2))
17493	      (use (match_dup 3))
17494	      (clobber (match_dup 5))])
17495   (set (match_dup 0) (match_dup 4))]
17496  "")
17497
17498(define_split 
17499  [(set (match_operand:DI 0 "memory_operand" "")
17500	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17501	 UNSPEC_FIST_FLOOR))
17502   (use (match_operand:HI 2 "memory_operand" ""))
17503   (use (match_operand:HI 3 "memory_operand" ""))
17504   (clobber (match_operand:DI 4 "memory_operand" ""))
17505   (clobber (match_scratch 5 ""))]
17506  "reload_completed"
17507  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17508	      (use (match_dup 2))
17509	      (use (match_dup 3))
17510	      (clobber (match_dup 5))])]
17511  "")
17512
17513(define_insn "fist<mode>2_floor"
17514  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17515	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17516	 UNSPEC_FIST_FLOOR))
17517   (use (match_operand:HI 2 "memory_operand" "m"))
17518   (use (match_operand:HI 3 "memory_operand" "m"))]
17519  "TARGET_USE_FANCY_MATH_387
17520   && flag_unsafe_math_optimizations"
17521  "* return output_fix_trunc (insn, operands, 0);"
17522  [(set_attr "type" "fistp")
17523   (set_attr "i387_cw" "floor")
17524   (set_attr "mode" "<MODE>")])
17525
17526(define_insn "fist<mode>2_floor_with_temp"
17527  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17528	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17529	 UNSPEC_FIST_FLOOR))
17530   (use (match_operand:HI 2 "memory_operand" "m,m"))
17531   (use (match_operand:HI 3 "memory_operand" "m,m"))
17532   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17533  "TARGET_USE_FANCY_MATH_387
17534   && flag_unsafe_math_optimizations"
17535  "#"
17536  [(set_attr "type" "fistp")
17537   (set_attr "i387_cw" "floor")
17538   (set_attr "mode" "<MODE>")])
17539
17540(define_split 
17541  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17542	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17543	 UNSPEC_FIST_FLOOR))
17544   (use (match_operand:HI 2 "memory_operand" ""))
17545   (use (match_operand:HI 3 "memory_operand" ""))
17546   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17547  "reload_completed"
17548  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17549				  UNSPEC_FIST_FLOOR))
17550	      (use (match_dup 2))
17551	      (use (match_dup 3))])
17552   (set (match_dup 0) (match_dup 4))]
17553  "")
17554
17555(define_split 
17556  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17557	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17558	 UNSPEC_FIST_FLOOR))
17559   (use (match_operand:HI 2 "memory_operand" ""))
17560   (use (match_operand:HI 3 "memory_operand" ""))
17561   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17562  "reload_completed"
17563  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17564				  UNSPEC_FIST_FLOOR))
17565	      (use (match_dup 2))
17566	      (use (match_dup 3))])]
17567  "")
17568
17569(define_expand "lfloor<mode>2"
17570  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17571		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17572		    UNSPEC_FIST_FLOOR))
17573	      (clobber (reg:CC FLAGS_REG))])]
17574  "TARGET_USE_FANCY_MATH_387
17575   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17576   && flag_unsafe_math_optimizations"
17577  "")
17578
17579;; Rounding mode control word calculation could clobber FLAGS_REG.
17580(define_insn_and_split "frndintxf2_ceil"
17581  [(set (match_operand:XF 0 "register_operand" "=f")
17582	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17583	 UNSPEC_FRNDINT_CEIL))
17584   (clobber (reg:CC FLAGS_REG))]
17585  "TARGET_USE_FANCY_MATH_387
17586   && flag_unsafe_math_optimizations
17587   && !(reload_completed || reload_in_progress)"
17588  "#"
17589  "&& 1"
17590  [(const_int 0)]
17591{
17592  ix86_optimize_mode_switching[I387_CEIL] = 1;
17593
17594  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17595  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17596
17597  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17598				       operands[2], operands[3]));
17599  DONE;
17600}
17601  [(set_attr "type" "frndint")
17602   (set_attr "i387_cw" "ceil")
17603   (set_attr "mode" "XF")])
17604
17605(define_insn "frndintxf2_ceil_i387"
17606  [(set (match_operand:XF 0 "register_operand" "=f")
17607	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17608	 UNSPEC_FRNDINT_CEIL))
17609   (use (match_operand:HI 2 "memory_operand" "m"))
17610   (use (match_operand:HI 3 "memory_operand" "m"))]
17611  "TARGET_USE_FANCY_MATH_387
17612   && flag_unsafe_math_optimizations"
17613  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17614  [(set_attr "type" "frndint")
17615   (set_attr "i387_cw" "ceil")
17616   (set_attr "mode" "XF")])
17617
17618(define_expand "ceilxf2"
17619  [(use (match_operand:XF 0 "register_operand" ""))
17620   (use (match_operand:XF 1 "register_operand" ""))]
17621  "TARGET_USE_FANCY_MATH_387
17622   && flag_unsafe_math_optimizations"
17623{
17624  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17625  DONE;
17626})
17627
17628(define_expand "ceildf2"
17629  [(use (match_operand:DF 0 "register_operand" ""))
17630   (use (match_operand:DF 1 "register_operand" ""))]
17631  "TARGET_USE_FANCY_MATH_387
17632   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17633   && flag_unsafe_math_optimizations"
17634{
17635  rtx op0 = gen_reg_rtx (XFmode);
17636  rtx op1 = gen_reg_rtx (XFmode);
17637
17638  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17639  emit_insn (gen_frndintxf2_ceil (op0, op1));
17640
17641  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17642  DONE;
17643})
17644
17645(define_expand "ceilsf2"
17646  [(use (match_operand:SF 0 "register_operand" ""))
17647   (use (match_operand:SF 1 "register_operand" ""))]
17648  "TARGET_USE_FANCY_MATH_387
17649   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17650   && flag_unsafe_math_optimizations"
17651{
17652  rtx op0 = gen_reg_rtx (XFmode);
17653  rtx op1 = gen_reg_rtx (XFmode);
17654
17655  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17656  emit_insn (gen_frndintxf2_ceil (op0, op1));
17657
17658  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17659  DONE;
17660})
17661
17662(define_insn_and_split "*fist<mode>2_ceil_1"
17663  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17664	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17665	 UNSPEC_FIST_CEIL))
17666   (clobber (reg:CC FLAGS_REG))]
17667  "TARGET_USE_FANCY_MATH_387
17668   && flag_unsafe_math_optimizations
17669   && !(reload_completed || reload_in_progress)"
17670  "#"
17671  "&& 1"
17672  [(const_int 0)]
17673{
17674  ix86_optimize_mode_switching[I387_CEIL] = 1;
17675
17676  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17677  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17678  if (memory_operand (operands[0], VOIDmode))
17679    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17680				     operands[2], operands[3]));
17681  else
17682    {
17683      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17684      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17685						 operands[2], operands[3],
17686						 operands[4]));
17687    }
17688  DONE;
17689}
17690  [(set_attr "type" "fistp")
17691   (set_attr "i387_cw" "ceil")
17692   (set_attr "mode" "<MODE>")])
17693
17694(define_insn "fistdi2_ceil"
17695  [(set (match_operand:DI 0 "memory_operand" "=m")
17696	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17697	 UNSPEC_FIST_CEIL))
17698   (use (match_operand:HI 2 "memory_operand" "m"))
17699   (use (match_operand:HI 3 "memory_operand" "m"))
17700   (clobber (match_scratch:XF 4 "=&1f"))]
17701  "TARGET_USE_FANCY_MATH_387
17702   && flag_unsafe_math_optimizations"
17703  "* return output_fix_trunc (insn, operands, 0);"
17704  [(set_attr "type" "fistp")
17705   (set_attr "i387_cw" "ceil")
17706   (set_attr "mode" "DI")])
17707
17708(define_insn "fistdi2_ceil_with_temp"
17709  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17710	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17711	 UNSPEC_FIST_CEIL))
17712   (use (match_operand:HI 2 "memory_operand" "m,m"))
17713   (use (match_operand:HI 3 "memory_operand" "m,m"))
17714   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17715   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17716  "TARGET_USE_FANCY_MATH_387
17717   && flag_unsafe_math_optimizations"
17718  "#"
17719  [(set_attr "type" "fistp")
17720   (set_attr "i387_cw" "ceil")
17721   (set_attr "mode" "DI")])
17722
17723(define_split 
17724  [(set (match_operand:DI 0 "register_operand" "")
17725	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17726	 UNSPEC_FIST_CEIL))
17727   (use (match_operand:HI 2 "memory_operand" ""))
17728   (use (match_operand:HI 3 "memory_operand" ""))
17729   (clobber (match_operand:DI 4 "memory_operand" ""))
17730   (clobber (match_scratch 5 ""))]
17731  "reload_completed"
17732  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17733	      (use (match_dup 2))
17734	      (use (match_dup 3))
17735	      (clobber (match_dup 5))])
17736   (set (match_dup 0) (match_dup 4))]
17737  "")
17738
17739(define_split 
17740  [(set (match_operand:DI 0 "memory_operand" "")
17741	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17742	 UNSPEC_FIST_CEIL))
17743   (use (match_operand:HI 2 "memory_operand" ""))
17744   (use (match_operand:HI 3 "memory_operand" ""))
17745   (clobber (match_operand:DI 4 "memory_operand" ""))
17746   (clobber (match_scratch 5 ""))]
17747  "reload_completed"
17748  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17749	      (use (match_dup 2))
17750	      (use (match_dup 3))
17751	      (clobber (match_dup 5))])]
17752  "")
17753
17754(define_insn "fist<mode>2_ceil"
17755  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17756	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17757	 UNSPEC_FIST_CEIL))
17758   (use (match_operand:HI 2 "memory_operand" "m"))
17759   (use (match_operand:HI 3 "memory_operand" "m"))]
17760  "TARGET_USE_FANCY_MATH_387
17761   && flag_unsafe_math_optimizations"
17762  "* return output_fix_trunc (insn, operands, 0);"
17763  [(set_attr "type" "fistp")
17764   (set_attr "i387_cw" "ceil")
17765   (set_attr "mode" "<MODE>")])
17766
17767(define_insn "fist<mode>2_ceil_with_temp"
17768  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17769	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17770	 UNSPEC_FIST_CEIL))
17771   (use (match_operand:HI 2 "memory_operand" "m,m"))
17772   (use (match_operand:HI 3 "memory_operand" "m,m"))
17773   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17774  "TARGET_USE_FANCY_MATH_387
17775   && flag_unsafe_math_optimizations"
17776  "#"
17777  [(set_attr "type" "fistp")
17778   (set_attr "i387_cw" "ceil")
17779   (set_attr "mode" "<MODE>")])
17780
17781(define_split 
17782  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17783	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17784	 UNSPEC_FIST_CEIL))
17785   (use (match_operand:HI 2 "memory_operand" ""))
17786   (use (match_operand:HI 3 "memory_operand" ""))
17787   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17788  "reload_completed"
17789  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17790				  UNSPEC_FIST_CEIL))
17791	      (use (match_dup 2))
17792	      (use (match_dup 3))])
17793   (set (match_dup 0) (match_dup 4))]
17794  "")
17795
17796(define_split 
17797  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17798	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17799	 UNSPEC_FIST_CEIL))
17800   (use (match_operand:HI 2 "memory_operand" ""))
17801   (use (match_operand:HI 3 "memory_operand" ""))
17802   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17803  "reload_completed"
17804  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17805				  UNSPEC_FIST_CEIL))
17806	      (use (match_dup 2))
17807	      (use (match_dup 3))])]
17808  "")
17809
17810(define_expand "lceil<mode>2"
17811  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17812		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17813		    UNSPEC_FIST_CEIL))
17814	      (clobber (reg:CC FLAGS_REG))])]
17815  "TARGET_USE_FANCY_MATH_387
17816   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17817   && flag_unsafe_math_optimizations"
17818  "")
17819
17820;; Rounding mode control word calculation could clobber FLAGS_REG.
17821(define_insn_and_split "frndintxf2_trunc"
17822  [(set (match_operand:XF 0 "register_operand" "=f")
17823	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17824	 UNSPEC_FRNDINT_TRUNC))
17825   (clobber (reg:CC FLAGS_REG))]
17826  "TARGET_USE_FANCY_MATH_387
17827   && flag_unsafe_math_optimizations
17828   && !(reload_completed || reload_in_progress)"
17829  "#"
17830  "&& 1"
17831  [(const_int 0)]
17832{
17833  ix86_optimize_mode_switching[I387_TRUNC] = 1;
17834
17835  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17836  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17837
17838  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17839					operands[2], operands[3]));
17840  DONE;
17841}
17842  [(set_attr "type" "frndint")
17843   (set_attr "i387_cw" "trunc")
17844   (set_attr "mode" "XF")])
17845
17846(define_insn "frndintxf2_trunc_i387"
17847  [(set (match_operand:XF 0 "register_operand" "=f")
17848	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17849	 UNSPEC_FRNDINT_TRUNC))
17850   (use (match_operand:HI 2 "memory_operand" "m"))
17851   (use (match_operand:HI 3 "memory_operand" "m"))]
17852  "TARGET_USE_FANCY_MATH_387
17853   && flag_unsafe_math_optimizations"
17854  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17855  [(set_attr "type" "frndint")
17856   (set_attr "i387_cw" "trunc")
17857   (set_attr "mode" "XF")])
17858
17859(define_expand "btruncxf2"
17860  [(use (match_operand:XF 0 "register_operand" ""))
17861   (use (match_operand:XF 1 "register_operand" ""))]
17862  "TARGET_USE_FANCY_MATH_387
17863   && flag_unsafe_math_optimizations"
17864{
17865  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17866  DONE;
17867})
17868
17869(define_expand "btruncdf2"
17870  [(use (match_operand:DF 0 "register_operand" ""))
17871   (use (match_operand:DF 1 "register_operand" ""))]
17872  "TARGET_USE_FANCY_MATH_387
17873   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17874   && flag_unsafe_math_optimizations"
17875{
17876  rtx op0 = gen_reg_rtx (XFmode);
17877  rtx op1 = gen_reg_rtx (XFmode);
17878
17879  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17880  emit_insn (gen_frndintxf2_trunc (op0, op1));
17881
17882  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17883  DONE;
17884})
17885
17886(define_expand "btruncsf2"
17887  [(use (match_operand:SF 0 "register_operand" ""))
17888   (use (match_operand:SF 1 "register_operand" ""))]
17889  "TARGET_USE_FANCY_MATH_387
17890   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17891   && flag_unsafe_math_optimizations"
17892{
17893  rtx op0 = gen_reg_rtx (XFmode);
17894  rtx op1 = gen_reg_rtx (XFmode);
17895
17896  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17897  emit_insn (gen_frndintxf2_trunc (op0, op1));
17898
17899  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17900  DONE;
17901})
17902
17903;; Rounding mode control word calculation could clobber FLAGS_REG.
17904(define_insn_and_split "frndintxf2_mask_pm"
17905  [(set (match_operand:XF 0 "register_operand" "=f")
17906	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17907	 UNSPEC_FRNDINT_MASK_PM))
17908   (clobber (reg:CC FLAGS_REG))]
17909  "TARGET_USE_FANCY_MATH_387
17910   && flag_unsafe_math_optimizations
17911   && !(reload_completed || reload_in_progress)"
17912  "#"
17913  "&& 1"
17914  [(const_int 0)]
17915{
17916  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17917
17918  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17919  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17920
17921  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17922					  operands[2], operands[3]));
17923  DONE;
17924}
17925  [(set_attr "type" "frndint")
17926   (set_attr "i387_cw" "mask_pm")
17927   (set_attr "mode" "XF")])
17928
17929(define_insn "frndintxf2_mask_pm_i387"
17930  [(set (match_operand:XF 0 "register_operand" "=f")
17931	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17932	 UNSPEC_FRNDINT_MASK_PM))
17933   (use (match_operand:HI 2 "memory_operand" "m"))
17934   (use (match_operand:HI 3 "memory_operand" "m"))]
17935  "TARGET_USE_FANCY_MATH_387
17936   && flag_unsafe_math_optimizations"
17937  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17938  [(set_attr "type" "frndint")
17939   (set_attr "i387_cw" "mask_pm")
17940   (set_attr "mode" "XF")])
17941
17942(define_expand "nearbyintxf2"
17943  [(use (match_operand:XF 0 "register_operand" ""))
17944   (use (match_operand:XF 1 "register_operand" ""))]
17945  "TARGET_USE_FANCY_MATH_387
17946   && flag_unsafe_math_optimizations"
17947{
17948  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17949
17950  DONE;
17951})
17952
17953(define_expand "nearbyintdf2"
17954  [(use (match_operand:DF 0 "register_operand" ""))
17955   (use (match_operand:DF 1 "register_operand" ""))]
17956  "TARGET_USE_FANCY_MATH_387
17957   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17958   && flag_unsafe_math_optimizations"
17959{
17960  rtx op0 = gen_reg_rtx (XFmode);
17961  rtx op1 = gen_reg_rtx (XFmode);
17962
17963  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17964  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17965
17966  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17967  DONE;
17968})
17969
17970(define_expand "nearbyintsf2"
17971  [(use (match_operand:SF 0 "register_operand" ""))
17972   (use (match_operand:SF 1 "register_operand" ""))]
17973  "TARGET_USE_FANCY_MATH_387
17974   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17975   && flag_unsafe_math_optimizations"
17976{
17977  rtx op0 = gen_reg_rtx (XFmode);
17978  rtx op1 = gen_reg_rtx (XFmode);
17979
17980  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17981  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17982
17983  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17984  DONE;
17985})
17986
17987
17988;; Block operation instructions
17989
17990(define_insn "cld"
17991 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17992 ""
17993 "cld"
17994  [(set_attr "type" "cld")])
17995
17996(define_expand "movmemsi"
17997  [(use (match_operand:BLK 0 "memory_operand" ""))
17998   (use (match_operand:BLK 1 "memory_operand" ""))
17999   (use (match_operand:SI 2 "nonmemory_operand" ""))
18000   (use (match_operand:SI 3 "const_int_operand" ""))]
18001  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18002{
18003 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18004   DONE;
18005 else
18006   FAIL;
18007})
18008
18009(define_expand "movmemdi"
18010  [(use (match_operand:BLK 0 "memory_operand" ""))
18011   (use (match_operand:BLK 1 "memory_operand" ""))
18012   (use (match_operand:DI 2 "nonmemory_operand" ""))
18013   (use (match_operand:DI 3 "const_int_operand" ""))]
18014  "TARGET_64BIT"
18015{
18016 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18017   DONE;
18018 else
18019   FAIL;
18020})
18021
18022;; Most CPUs don't like single string operations
18023;; Handle this case here to simplify previous expander.
18024
18025(define_expand "strmov"
18026  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18027   (set (match_operand 1 "memory_operand" "") (match_dup 4))
18028   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18029	      (clobber (reg:CC FLAGS_REG))])
18030   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18031	      (clobber (reg:CC FLAGS_REG))])]
18032  ""
18033{
18034  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18035
18036  /* If .md ever supports :P for Pmode, these can be directly
18037     in the pattern above.  */
18038  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18039  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18040
18041  if (TARGET_SINGLE_STRINGOP || optimize_size)
18042    {
18043      emit_insn (gen_strmov_singleop (operands[0], operands[1],
18044				      operands[2], operands[3],
18045				      operands[5], operands[6]));
18046      DONE;
18047    }
18048
18049  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18050})
18051
18052(define_expand "strmov_singleop"
18053  [(parallel [(set (match_operand 1 "memory_operand" "")
18054		   (match_operand 3 "memory_operand" ""))
18055	      (set (match_operand 0 "register_operand" "")
18056		   (match_operand 4 "" ""))
18057	      (set (match_operand 2 "register_operand" "")
18058		   (match_operand 5 "" ""))
18059	      (use (reg:SI DIRFLAG_REG))])]
18060  "TARGET_SINGLE_STRINGOP || optimize_size"
18061  "")
18062
18063(define_insn "*strmovdi_rex_1"
18064  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18065	(mem:DI (match_operand:DI 3 "register_operand" "1")))
18066   (set (match_operand:DI 0 "register_operand" "=D")
18067	(plus:DI (match_dup 2)
18068		 (const_int 8)))
18069   (set (match_operand:DI 1 "register_operand" "=S")
18070	(plus:DI (match_dup 3)
18071		 (const_int 8)))
18072   (use (reg:SI DIRFLAG_REG))]
18073  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18074  "movsq"
18075  [(set_attr "type" "str")
18076   (set_attr "mode" "DI")
18077   (set_attr "memory" "both")])
18078
18079(define_insn "*strmovsi_1"
18080  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18081	(mem:SI (match_operand:SI 3 "register_operand" "1")))
18082   (set (match_operand:SI 0 "register_operand" "=D")
18083	(plus:SI (match_dup 2)
18084		 (const_int 4)))
18085   (set (match_operand:SI 1 "register_operand" "=S")
18086	(plus:SI (match_dup 3)
18087		 (const_int 4)))
18088   (use (reg:SI DIRFLAG_REG))]
18089  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18090  "{movsl|movsd}"
18091  [(set_attr "type" "str")
18092   (set_attr "mode" "SI")
18093   (set_attr "memory" "both")])
18094
18095(define_insn "*strmovsi_rex_1"
18096  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18097	(mem:SI (match_operand:DI 3 "register_operand" "1")))
18098   (set (match_operand:DI 0 "register_operand" "=D")
18099	(plus:DI (match_dup 2)
18100		 (const_int 4)))
18101   (set (match_operand:DI 1 "register_operand" "=S")
18102	(plus:DI (match_dup 3)
18103		 (const_int 4)))
18104   (use (reg:SI DIRFLAG_REG))]
18105  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18106  "{movsl|movsd}"
18107  [(set_attr "type" "str")
18108   (set_attr "mode" "SI")
18109   (set_attr "memory" "both")])
18110
18111(define_insn "*strmovhi_1"
18112  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18113	(mem:HI (match_operand:SI 3 "register_operand" "1")))
18114   (set (match_operand:SI 0 "register_operand" "=D")
18115	(plus:SI (match_dup 2)
18116		 (const_int 2)))
18117   (set (match_operand:SI 1 "register_operand" "=S")
18118	(plus:SI (match_dup 3)
18119		 (const_int 2)))
18120   (use (reg:SI DIRFLAG_REG))]
18121  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18122  "movsw"
18123  [(set_attr "type" "str")
18124   (set_attr "memory" "both")
18125   (set_attr "mode" "HI")])
18126
18127(define_insn "*strmovhi_rex_1"
18128  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18129	(mem:HI (match_operand:DI 3 "register_operand" "1")))
18130   (set (match_operand:DI 0 "register_operand" "=D")
18131	(plus:DI (match_dup 2)
18132		 (const_int 2)))
18133   (set (match_operand:DI 1 "register_operand" "=S")
18134	(plus:DI (match_dup 3)
18135		 (const_int 2)))
18136   (use (reg:SI DIRFLAG_REG))]
18137  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18138  "movsw"
18139  [(set_attr "type" "str")
18140   (set_attr "memory" "both")
18141   (set_attr "mode" "HI")])
18142
18143(define_insn "*strmovqi_1"
18144  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18145	(mem:QI (match_operand:SI 3 "register_operand" "1")))
18146   (set (match_operand:SI 0 "register_operand" "=D")
18147	(plus:SI (match_dup 2)
18148		 (const_int 1)))
18149   (set (match_operand:SI 1 "register_operand" "=S")
18150	(plus:SI (match_dup 3)
18151		 (const_int 1)))
18152   (use (reg:SI DIRFLAG_REG))]
18153  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18154  "movsb"
18155  [(set_attr "type" "str")
18156   (set_attr "memory" "both")
18157   (set_attr "mode" "QI")])
18158
18159(define_insn "*strmovqi_rex_1"
18160  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18161	(mem:QI (match_operand:DI 3 "register_operand" "1")))
18162   (set (match_operand:DI 0 "register_operand" "=D")
18163	(plus:DI (match_dup 2)
18164		 (const_int 1)))
18165   (set (match_operand:DI 1 "register_operand" "=S")
18166	(plus:DI (match_dup 3)
18167		 (const_int 1)))
18168   (use (reg:SI DIRFLAG_REG))]
18169  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18170  "movsb"
18171  [(set_attr "type" "str")
18172   (set_attr "memory" "both")
18173   (set_attr "mode" "QI")])
18174
18175(define_expand "rep_mov"
18176  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18177	      (set (match_operand 0 "register_operand" "")
18178		   (match_operand 5 "" ""))
18179	      (set (match_operand 2 "register_operand" "")
18180		   (match_operand 6 "" ""))
18181	      (set (match_operand 1 "memory_operand" "")
18182		   (match_operand 3 "memory_operand" ""))
18183	      (use (match_dup 4))
18184	      (use (reg:SI DIRFLAG_REG))])]
18185  ""
18186  "")
18187
18188(define_insn "*rep_movdi_rex64"
18189  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18190   (set (match_operand:DI 0 "register_operand" "=D") 
18191        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18192			    (const_int 3))
18193		 (match_operand:DI 3 "register_operand" "0")))
18194   (set (match_operand:DI 1 "register_operand" "=S") 
18195        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18196		 (match_operand:DI 4 "register_operand" "1")))
18197   (set (mem:BLK (match_dup 3))
18198	(mem:BLK (match_dup 4)))
18199   (use (match_dup 5))
18200   (use (reg:SI DIRFLAG_REG))]
18201  "TARGET_64BIT"
18202  "{rep\;movsq|rep movsq}"
18203  [(set_attr "type" "str")
18204   (set_attr "prefix_rep" "1")
18205   (set_attr "memory" "both")
18206   (set_attr "mode" "DI")])
18207
18208(define_insn "*rep_movsi"
18209  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18210   (set (match_operand:SI 0 "register_operand" "=D") 
18211        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18212			    (const_int 2))
18213		 (match_operand:SI 3 "register_operand" "0")))
18214   (set (match_operand:SI 1 "register_operand" "=S") 
18215        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18216		 (match_operand:SI 4 "register_operand" "1")))
18217   (set (mem:BLK (match_dup 3))
18218	(mem:BLK (match_dup 4)))
18219   (use (match_dup 5))
18220   (use (reg:SI DIRFLAG_REG))]
18221  "!TARGET_64BIT"
18222  "{rep\;movsl|rep movsd}"
18223  [(set_attr "type" "str")
18224   (set_attr "prefix_rep" "1")
18225   (set_attr "memory" "both")
18226   (set_attr "mode" "SI")])
18227
18228(define_insn "*rep_movsi_rex64"
18229  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18230   (set (match_operand:DI 0 "register_operand" "=D") 
18231        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18232			    (const_int 2))
18233		 (match_operand:DI 3 "register_operand" "0")))
18234   (set (match_operand:DI 1 "register_operand" "=S") 
18235        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18236		 (match_operand:DI 4 "register_operand" "1")))
18237   (set (mem:BLK (match_dup 3))
18238	(mem:BLK (match_dup 4)))
18239   (use (match_dup 5))
18240   (use (reg:SI DIRFLAG_REG))]
18241  "TARGET_64BIT"
18242  "{rep\;movsl|rep movsd}"
18243  [(set_attr "type" "str")
18244   (set_attr "prefix_rep" "1")
18245   (set_attr "memory" "both")
18246   (set_attr "mode" "SI")])
18247
18248(define_insn "*rep_movqi"
18249  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18250   (set (match_operand:SI 0 "register_operand" "=D") 
18251        (plus:SI (match_operand:SI 3 "register_operand" "0")
18252		 (match_operand:SI 5 "register_operand" "2")))
18253   (set (match_operand:SI 1 "register_operand" "=S") 
18254        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18255   (set (mem:BLK (match_dup 3))
18256	(mem:BLK (match_dup 4)))
18257   (use (match_dup 5))
18258   (use (reg:SI DIRFLAG_REG))]
18259  "!TARGET_64BIT"
18260  "{rep\;movsb|rep movsb}"
18261  [(set_attr "type" "str")
18262   (set_attr "prefix_rep" "1")
18263   (set_attr "memory" "both")
18264   (set_attr "mode" "SI")])
18265
18266(define_insn "*rep_movqi_rex64"
18267  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18268   (set (match_operand:DI 0 "register_operand" "=D") 
18269        (plus:DI (match_operand:DI 3 "register_operand" "0")
18270		 (match_operand:DI 5 "register_operand" "2")))
18271   (set (match_operand:DI 1 "register_operand" "=S") 
18272        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18273   (set (mem:BLK (match_dup 3))
18274	(mem:BLK (match_dup 4)))
18275   (use (match_dup 5))
18276   (use (reg:SI DIRFLAG_REG))]
18277  "TARGET_64BIT"
18278  "{rep\;movsb|rep movsb}"
18279  [(set_attr "type" "str")
18280   (set_attr "prefix_rep" "1")
18281   (set_attr "memory" "both")
18282   (set_attr "mode" "SI")])
18283
18284(define_expand "setmemsi"
18285   [(use (match_operand:BLK 0 "memory_operand" ""))
18286    (use (match_operand:SI 1 "nonmemory_operand" ""))
18287    (use (match_operand 2 "const_int_operand" ""))
18288    (use (match_operand 3 "const_int_operand" ""))]
18289  ""
18290{
18291 /* If value to set is not zero, use the library routine.  */
18292 if (operands[2] != const0_rtx)
18293   FAIL;
18294
18295 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18296   DONE;
18297 else
18298   FAIL;
18299})
18300
18301(define_expand "setmemdi"
18302   [(use (match_operand:BLK 0 "memory_operand" ""))
18303    (use (match_operand:DI 1 "nonmemory_operand" ""))
18304    (use (match_operand 2 "const_int_operand" ""))
18305    (use (match_operand 3 "const_int_operand" ""))]
18306  "TARGET_64BIT"
18307{
18308 /* If value to set is not zero, use the library routine.  */
18309 if (operands[2] != const0_rtx)
18310   FAIL;
18311
18312 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18313   DONE;
18314 else
18315   FAIL;
18316})
18317
18318;; Most CPUs don't like single string operations
18319;; Handle this case here to simplify previous expander.
18320
18321(define_expand "strset"
18322  [(set (match_operand 1 "memory_operand" "")
18323	(match_operand 2 "register_operand" ""))
18324   (parallel [(set (match_operand 0 "register_operand" "")
18325		   (match_dup 3))
18326	      (clobber (reg:CC FLAGS_REG))])]
18327  ""
18328{
18329  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18330    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18331
18332  /* If .md ever supports :P for Pmode, this can be directly
18333     in the pattern above.  */
18334  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18335			      GEN_INT (GET_MODE_SIZE (GET_MODE
18336						      (operands[2]))));
18337  if (TARGET_SINGLE_STRINGOP || optimize_size)
18338    {
18339      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18340				      operands[3]));
18341      DONE;
18342    }
18343})
18344
18345(define_expand "strset_singleop"
18346  [(parallel [(set (match_operand 1 "memory_operand" "")
18347		   (match_operand 2 "register_operand" ""))
18348	      (set (match_operand 0 "register_operand" "")
18349		   (match_operand 3 "" ""))
18350	      (use (reg:SI DIRFLAG_REG))])]
18351  "TARGET_SINGLE_STRINGOP || optimize_size"
18352  "")
18353
18354(define_insn "*strsetdi_rex_1"
18355  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18356	(match_operand:DI 2 "register_operand" "a"))
18357   (set (match_operand:DI 0 "register_operand" "=D")
18358	(plus:DI (match_dup 1)
18359		 (const_int 8)))
18360   (use (reg:SI DIRFLAG_REG))]
18361  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18362  "stosq"
18363  [(set_attr "type" "str")
18364   (set_attr "memory" "store")
18365   (set_attr "mode" "DI")])
18366
18367(define_insn "*strsetsi_1"
18368  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18369	(match_operand:SI 2 "register_operand" "a"))
18370   (set (match_operand:SI 0 "register_operand" "=D")
18371	(plus:SI (match_dup 1)
18372		 (const_int 4)))
18373   (use (reg:SI DIRFLAG_REG))]
18374  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18375  "{stosl|stosd}"
18376  [(set_attr "type" "str")
18377   (set_attr "memory" "store")
18378   (set_attr "mode" "SI")])
18379
18380(define_insn "*strsetsi_rex_1"
18381  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18382	(match_operand:SI 2 "register_operand" "a"))
18383   (set (match_operand:DI 0 "register_operand" "=D")
18384	(plus:DI (match_dup 1)
18385		 (const_int 4)))
18386   (use (reg:SI DIRFLAG_REG))]
18387  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18388  "{stosl|stosd}"
18389  [(set_attr "type" "str")
18390   (set_attr "memory" "store")
18391   (set_attr "mode" "SI")])
18392
18393(define_insn "*strsethi_1"
18394  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18395	(match_operand:HI 2 "register_operand" "a"))
18396   (set (match_operand:SI 0 "register_operand" "=D")
18397	(plus:SI (match_dup 1)
18398		 (const_int 2)))
18399   (use (reg:SI DIRFLAG_REG))]
18400  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18401  "stosw"
18402  [(set_attr "type" "str")
18403   (set_attr "memory" "store")
18404   (set_attr "mode" "HI")])
18405
18406(define_insn "*strsethi_rex_1"
18407  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18408	(match_operand:HI 2 "register_operand" "a"))
18409   (set (match_operand:DI 0 "register_operand" "=D")
18410	(plus:DI (match_dup 1)
18411		 (const_int 2)))
18412   (use (reg:SI DIRFLAG_REG))]
18413  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18414  "stosw"
18415  [(set_attr "type" "str")
18416   (set_attr "memory" "store")
18417   (set_attr "mode" "HI")])
18418
18419(define_insn "*strsetqi_1"
18420  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18421	(match_operand:QI 2 "register_operand" "a"))
18422   (set (match_operand:SI 0 "register_operand" "=D")
18423	(plus:SI (match_dup 1)
18424		 (const_int 1)))
18425   (use (reg:SI DIRFLAG_REG))]
18426  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18427  "stosb"
18428  [(set_attr "type" "str")
18429   (set_attr "memory" "store")
18430   (set_attr "mode" "QI")])
18431
18432(define_insn "*strsetqi_rex_1"
18433  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18434	(match_operand:QI 2 "register_operand" "a"))
18435   (set (match_operand:DI 0 "register_operand" "=D")
18436	(plus:DI (match_dup 1)
18437		 (const_int 1)))
18438   (use (reg:SI DIRFLAG_REG))]
18439  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18440  "stosb"
18441  [(set_attr "type" "str")
18442   (set_attr "memory" "store")
18443   (set_attr "mode" "QI")])
18444
18445(define_expand "rep_stos"
18446  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18447	      (set (match_operand 0 "register_operand" "")
18448		   (match_operand 4 "" ""))
18449	      (set (match_operand 2 "memory_operand" "") (const_int 0))
18450	      (use (match_operand 3 "register_operand" ""))
18451	      (use (match_dup 1))
18452	      (use (reg:SI DIRFLAG_REG))])]
18453  ""
18454  "")
18455
18456(define_insn "*rep_stosdi_rex64"
18457  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18458   (set (match_operand:DI 0 "register_operand" "=D") 
18459        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18460			    (const_int 3))
18461		 (match_operand:DI 3 "register_operand" "0")))
18462   (set (mem:BLK (match_dup 3))
18463	(const_int 0))
18464   (use (match_operand:DI 2 "register_operand" "a"))
18465   (use (match_dup 4))
18466   (use (reg:SI DIRFLAG_REG))]
18467  "TARGET_64BIT"
18468  "{rep\;stosq|rep stosq}"
18469  [(set_attr "type" "str")
18470   (set_attr "prefix_rep" "1")
18471   (set_attr "memory" "store")
18472   (set_attr "mode" "DI")])
18473
18474(define_insn "*rep_stossi"
18475  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18476   (set (match_operand:SI 0 "register_operand" "=D") 
18477        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18478			    (const_int 2))
18479		 (match_operand:SI 3 "register_operand" "0")))
18480   (set (mem:BLK (match_dup 3))
18481	(const_int 0))
18482   (use (match_operand:SI 2 "register_operand" "a"))
18483   (use (match_dup 4))
18484   (use (reg:SI DIRFLAG_REG))]
18485  "!TARGET_64BIT"
18486  "{rep\;stosl|rep stosd}"
18487  [(set_attr "type" "str")
18488   (set_attr "prefix_rep" "1")
18489   (set_attr "memory" "store")
18490   (set_attr "mode" "SI")])
18491
18492(define_insn "*rep_stossi_rex64"
18493  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18494   (set (match_operand:DI 0 "register_operand" "=D") 
18495        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18496			    (const_int 2))
18497		 (match_operand:DI 3 "register_operand" "0")))
18498   (set (mem:BLK (match_dup 3))
18499	(const_int 0))
18500   (use (match_operand:SI 2 "register_operand" "a"))
18501   (use (match_dup 4))
18502   (use (reg:SI DIRFLAG_REG))]
18503  "TARGET_64BIT"
18504  "{rep\;stosl|rep stosd}"
18505  [(set_attr "type" "str")
18506   (set_attr "prefix_rep" "1")
18507   (set_attr "memory" "store")
18508   (set_attr "mode" "SI")])
18509
18510(define_insn "*rep_stosqi"
18511  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18512   (set (match_operand:SI 0 "register_operand" "=D") 
18513        (plus:SI (match_operand:SI 3 "register_operand" "0")
18514		 (match_operand:SI 4 "register_operand" "1")))
18515   (set (mem:BLK (match_dup 3))
18516	(const_int 0))
18517   (use (match_operand:QI 2 "register_operand" "a"))
18518   (use (match_dup 4))
18519   (use (reg:SI DIRFLAG_REG))]
18520  "!TARGET_64BIT"
18521  "{rep\;stosb|rep stosb}"
18522  [(set_attr "type" "str")
18523   (set_attr "prefix_rep" "1")
18524   (set_attr "memory" "store")
18525   (set_attr "mode" "QI")])
18526
18527(define_insn "*rep_stosqi_rex64"
18528  [(set (match_operand:DI 1 "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 4 "register_operand" "1")))
18532   (set (mem:BLK (match_dup 3))
18533	(const_int 0))
18534   (use (match_operand:QI 2 "register_operand" "a"))
18535   (use (match_dup 4))
18536   (use (reg:SI DIRFLAG_REG))]
18537  "TARGET_64BIT"
18538  "{rep\;stosb|rep stosb}"
18539  [(set_attr "type" "str")
18540   (set_attr "prefix_rep" "1")
18541   (set_attr "memory" "store")
18542   (set_attr "mode" "QI")])
18543
18544(define_expand "cmpstrnsi"
18545  [(set (match_operand:SI 0 "register_operand" "")
18546	(compare:SI (match_operand:BLK 1 "general_operand" "")
18547		    (match_operand:BLK 2 "general_operand" "")))
18548   (use (match_operand 3 "general_operand" ""))
18549   (use (match_operand 4 "immediate_operand" ""))]
18550  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18551{
18552  rtx addr1, addr2, out, outlow, count, countreg, align;
18553
18554  /* Can't use this if the user has appropriated esi or edi.  */
18555  if (global_regs[4] || global_regs[5])
18556    FAIL;
18557
18558  out = operands[0];
18559  if (GET_CODE (out) != REG)
18560    out = gen_reg_rtx (SImode);
18561
18562  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18563  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18564  if (addr1 != XEXP (operands[1], 0))
18565    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18566  if (addr2 != XEXP (operands[2], 0))
18567    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18568
18569  count = operands[3];
18570  countreg = ix86_zero_extend_to_Pmode (count);
18571
18572  /* %%% Iff we are testing strict equality, we can use known alignment
18573     to good advantage.  This may be possible with combine, particularly
18574     once cc0 is dead.  */
18575  align = operands[4];
18576
18577  emit_insn (gen_cld ());
18578  if (GET_CODE (count) == CONST_INT)
18579    {
18580      if (INTVAL (count) == 0)
18581	{
18582	  emit_move_insn (operands[0], const0_rtx);
18583	  DONE;
18584	}
18585      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18586				     operands[1], operands[2]));
18587    }
18588  else
18589    {
18590      if (TARGET_64BIT)
18591	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18592      else
18593	emit_insn (gen_cmpsi_1 (countreg, countreg));
18594      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18595				  operands[1], operands[2]));
18596    }
18597
18598  outlow = gen_lowpart (QImode, out);
18599  emit_insn (gen_cmpintqi (outlow));
18600  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18601
18602  if (operands[0] != out)
18603    emit_move_insn (operands[0], out);
18604
18605  DONE;
18606})
18607
18608;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18609
18610(define_expand "cmpintqi"
18611  [(set (match_dup 1)
18612	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18613   (set (match_dup 2)
18614	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18615   (parallel [(set (match_operand:QI 0 "register_operand" "")
18616		   (minus:QI (match_dup 1)
18617			     (match_dup 2)))
18618	      (clobber (reg:CC FLAGS_REG))])]
18619  ""
18620  "operands[1] = gen_reg_rtx (QImode);
18621   operands[2] = gen_reg_rtx (QImode);")
18622
18623;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18624;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18625
18626(define_expand "cmpstrnqi_nz_1"
18627  [(parallel [(set (reg:CC FLAGS_REG)
18628		   (compare:CC (match_operand 4 "memory_operand" "")
18629			       (match_operand 5 "memory_operand" "")))
18630	      (use (match_operand 2 "register_operand" ""))
18631	      (use (match_operand:SI 3 "immediate_operand" ""))
18632	      (use (reg:SI DIRFLAG_REG))
18633	      (clobber (match_operand 0 "register_operand" ""))
18634	      (clobber (match_operand 1 "register_operand" ""))
18635	      (clobber (match_dup 2))])]
18636  ""
18637  "")
18638
18639(define_insn "*cmpstrnqi_nz_1"
18640  [(set (reg:CC FLAGS_REG)
18641	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18642		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18643   (use (match_operand:SI 6 "register_operand" "2"))
18644   (use (match_operand:SI 3 "immediate_operand" "i"))
18645   (use (reg:SI DIRFLAG_REG))
18646   (clobber (match_operand:SI 0 "register_operand" "=S"))
18647   (clobber (match_operand:SI 1 "register_operand" "=D"))
18648   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18649  "!TARGET_64BIT"
18650  "repz{\;| }cmpsb"
18651  [(set_attr "type" "str")
18652   (set_attr "mode" "QI")
18653   (set_attr "prefix_rep" "1")])
18654
18655(define_insn "*cmpstrnqi_nz_rex_1"
18656  [(set (reg:CC FLAGS_REG)
18657	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18658		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18659   (use (match_operand:DI 6 "register_operand" "2"))
18660   (use (match_operand:SI 3 "immediate_operand" "i"))
18661   (use (reg:SI DIRFLAG_REG))
18662   (clobber (match_operand:DI 0 "register_operand" "=S"))
18663   (clobber (match_operand:DI 1 "register_operand" "=D"))
18664   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18665  "TARGET_64BIT"
18666  "repz{\;| }cmpsb"
18667  [(set_attr "type" "str")
18668   (set_attr "mode" "QI")
18669   (set_attr "prefix_rep" "1")])
18670
18671;; The same, but the count is not known to not be zero.
18672
18673(define_expand "cmpstrnqi_1"
18674  [(parallel [(set (reg:CC FLAGS_REG)
18675		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
18676				     (const_int 0))
18677		  (compare:CC (match_operand 4 "memory_operand" "")
18678			      (match_operand 5 "memory_operand" ""))
18679		  (const_int 0)))
18680	      (use (match_operand:SI 3 "immediate_operand" ""))
18681	      (use (reg:CC FLAGS_REG))
18682	      (use (reg:SI DIRFLAG_REG))
18683	      (clobber (match_operand 0 "register_operand" ""))
18684	      (clobber (match_operand 1 "register_operand" ""))
18685	      (clobber (match_dup 2))])]
18686  ""
18687  "")
18688
18689(define_insn "*cmpstrnqi_1"
18690  [(set (reg:CC FLAGS_REG)
18691	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18692			     (const_int 0))
18693	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18694		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18695	  (const_int 0)))
18696   (use (match_operand:SI 3 "immediate_operand" "i"))
18697   (use (reg:CC FLAGS_REG))
18698   (use (reg:SI DIRFLAG_REG))
18699   (clobber (match_operand:SI 0 "register_operand" "=S"))
18700   (clobber (match_operand:SI 1 "register_operand" "=D"))
18701   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18702  "!TARGET_64BIT"
18703  "repz{\;| }cmpsb"
18704  [(set_attr "type" "str")
18705   (set_attr "mode" "QI")
18706   (set_attr "prefix_rep" "1")])
18707
18708(define_insn "*cmpstrnqi_rex_1"
18709  [(set (reg:CC FLAGS_REG)
18710	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18711			     (const_int 0))
18712	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18713		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18714	  (const_int 0)))
18715   (use (match_operand:SI 3 "immediate_operand" "i"))
18716   (use (reg:CC FLAGS_REG))
18717   (use (reg:SI DIRFLAG_REG))
18718   (clobber (match_operand:DI 0 "register_operand" "=S"))
18719   (clobber (match_operand:DI 1 "register_operand" "=D"))
18720   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18721  "TARGET_64BIT"
18722  "repz{\;| }cmpsb"
18723  [(set_attr "type" "str")
18724   (set_attr "mode" "QI")
18725   (set_attr "prefix_rep" "1")])
18726
18727(define_expand "strlensi"
18728  [(set (match_operand:SI 0 "register_operand" "")
18729	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
18730		    (match_operand:QI 2 "immediate_operand" "")
18731		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18732  ""
18733{
18734 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18735   DONE;
18736 else
18737   FAIL;
18738})
18739
18740(define_expand "strlendi"
18741  [(set (match_operand:DI 0 "register_operand" "")
18742	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
18743		    (match_operand:QI 2 "immediate_operand" "")
18744		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18745  ""
18746{
18747 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18748   DONE;
18749 else
18750   FAIL;
18751})
18752
18753(define_expand "strlenqi_1"
18754  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18755	      (use (reg:SI DIRFLAG_REG))
18756	      (clobber (match_operand 1 "register_operand" ""))
18757	      (clobber (reg:CC FLAGS_REG))])]
18758  ""
18759  "")
18760
18761(define_insn "*strlenqi_1"
18762  [(set (match_operand:SI 0 "register_operand" "=&c")
18763	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18764		    (match_operand:QI 2 "register_operand" "a")
18765		    (match_operand:SI 3 "immediate_operand" "i")
18766		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18767   (use (reg:SI DIRFLAG_REG))
18768   (clobber (match_operand:SI 1 "register_operand" "=D"))
18769   (clobber (reg:CC FLAGS_REG))]
18770  "!TARGET_64BIT"
18771  "repnz{\;| }scasb"
18772  [(set_attr "type" "str")
18773   (set_attr "mode" "QI")
18774   (set_attr "prefix_rep" "1")])
18775
18776(define_insn "*strlenqi_rex_1"
18777  [(set (match_operand:DI 0 "register_operand" "=&c")
18778	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18779		    (match_operand:QI 2 "register_operand" "a")
18780		    (match_operand:DI 3 "immediate_operand" "i")
18781		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18782   (use (reg:SI DIRFLAG_REG))
18783   (clobber (match_operand:DI 1 "register_operand" "=D"))
18784   (clobber (reg:CC FLAGS_REG))]
18785  "TARGET_64BIT"
18786  "repnz{\;| }scasb"
18787  [(set_attr "type" "str")
18788   (set_attr "mode" "QI")
18789   (set_attr "prefix_rep" "1")])
18790
18791;; Peephole optimizations to clean up after cmpstrn*.  This should be
18792;; handled in combine, but it is not currently up to the task.
18793;; When used for their truth value, the cmpstrn* expanders generate
18794;; code like this:
18795;;
18796;;   repz cmpsb
18797;;   seta 	%al
18798;;   setb 	%dl
18799;;   cmpb 	%al, %dl
18800;;   jcc	label
18801;;
18802;; The intermediate three instructions are unnecessary.
18803
18804;; This one handles cmpstrn*_nz_1...
18805(define_peephole2
18806  [(parallel[
18807     (set (reg:CC FLAGS_REG)
18808	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18809		      (mem:BLK (match_operand 5 "register_operand" ""))))
18810     (use (match_operand 6 "register_operand" ""))
18811     (use (match_operand:SI 3 "immediate_operand" ""))
18812     (use (reg:SI DIRFLAG_REG))
18813     (clobber (match_operand 0 "register_operand" ""))
18814     (clobber (match_operand 1 "register_operand" ""))
18815     (clobber (match_operand 2 "register_operand" ""))])
18816   (set (match_operand:QI 7 "register_operand" "")
18817	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18818   (set (match_operand:QI 8 "register_operand" "")
18819	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18820   (set (reg FLAGS_REG)
18821	(compare (match_dup 7) (match_dup 8)))
18822  ]
18823  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18824  [(parallel[
18825     (set (reg:CC FLAGS_REG)
18826	  (compare:CC (mem:BLK (match_dup 4))
18827		      (mem:BLK (match_dup 5))))
18828     (use (match_dup 6))
18829     (use (match_dup 3))
18830     (use (reg:SI DIRFLAG_REG))
18831     (clobber (match_dup 0))
18832     (clobber (match_dup 1))
18833     (clobber (match_dup 2))])]
18834  "")
18835
18836;; ...and this one handles cmpstrn*_1.
18837(define_peephole2
18838  [(parallel[
18839     (set (reg:CC FLAGS_REG)
18840	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18841			       (const_int 0))
18842	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18843		        (mem:BLK (match_operand 5 "register_operand" "")))
18844	    (const_int 0)))
18845     (use (match_operand:SI 3 "immediate_operand" ""))
18846     (use (reg:CC FLAGS_REG))
18847     (use (reg:SI DIRFLAG_REG))
18848     (clobber (match_operand 0 "register_operand" ""))
18849     (clobber (match_operand 1 "register_operand" ""))
18850     (clobber (match_operand 2 "register_operand" ""))])
18851   (set (match_operand:QI 7 "register_operand" "")
18852	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18853   (set (match_operand:QI 8 "register_operand" "")
18854	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18855   (set (reg FLAGS_REG)
18856	(compare (match_dup 7) (match_dup 8)))
18857  ]
18858  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18859  [(parallel[
18860     (set (reg:CC FLAGS_REG)
18861	  (if_then_else:CC (ne (match_dup 6)
18862			       (const_int 0))
18863	    (compare:CC (mem:BLK (match_dup 4))
18864			(mem:BLK (match_dup 5)))
18865	    (const_int 0)))
18866     (use (match_dup 3))
18867     (use (reg:CC FLAGS_REG))
18868     (use (reg:SI DIRFLAG_REG))
18869     (clobber (match_dup 0))
18870     (clobber (match_dup 1))
18871     (clobber (match_dup 2))])]
18872  "")
18873
18874
18875
18876;; Conditional move instructions.
18877
18878(define_expand "movdicc"
18879  [(set (match_operand:DI 0 "register_operand" "")
18880	(if_then_else:DI (match_operand 1 "comparison_operator" "")
18881			 (match_operand:DI 2 "general_operand" "")
18882			 (match_operand:DI 3 "general_operand" "")))]
18883  "TARGET_64BIT"
18884  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18885
18886(define_insn "x86_movdicc_0_m1_rex64"
18887  [(set (match_operand:DI 0 "register_operand" "=r")
18888	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18889	  (const_int -1)
18890	  (const_int 0)))
18891   (clobber (reg:CC FLAGS_REG))]
18892  "TARGET_64BIT"
18893  "sbb{q}\t%0, %0"
18894  ; Since we don't have the proper number of operands for an alu insn,
18895  ; fill in all the blanks.
18896  [(set_attr "type" "alu")
18897   (set_attr "pent_pair" "pu")
18898   (set_attr "memory" "none")
18899   (set_attr "imm_disp" "false")
18900   (set_attr "mode" "DI")
18901   (set_attr "length_immediate" "0")])
18902
18903(define_insn "*movdicc_c_rex64"
18904  [(set (match_operand:DI 0 "register_operand" "=r,r")
18905	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18906				[(reg FLAGS_REG) (const_int 0)])
18907		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18908		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18909  "TARGET_64BIT && TARGET_CMOVE
18910   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18911  "@
18912   cmov%O2%C1\t{%2, %0|%0, %2}
18913   cmov%O2%c1\t{%3, %0|%0, %3}"
18914  [(set_attr "type" "icmov")
18915   (set_attr "mode" "DI")])
18916
18917(define_expand "movsicc"
18918  [(set (match_operand:SI 0 "register_operand" "")
18919	(if_then_else:SI (match_operand 1 "comparison_operator" "")
18920			 (match_operand:SI 2 "general_operand" "")
18921			 (match_operand:SI 3 "general_operand" "")))]
18922  ""
18923  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18924
18925;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18926;; the register first winds up with `sbbl $0,reg', which is also weird.
18927;; So just document what we're doing explicitly.
18928
18929(define_insn "x86_movsicc_0_m1"
18930  [(set (match_operand:SI 0 "register_operand" "=r")
18931	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18932	  (const_int -1)
18933	  (const_int 0)))
18934   (clobber (reg:CC FLAGS_REG))]
18935  ""
18936  "sbb{l}\t%0, %0"
18937  ; Since we don't have the proper number of operands for an alu insn,
18938  ; fill in all the blanks.
18939  [(set_attr "type" "alu")
18940   (set_attr "pent_pair" "pu")
18941   (set_attr "memory" "none")
18942   (set_attr "imm_disp" "false")
18943   (set_attr "mode" "SI")
18944   (set_attr "length_immediate" "0")])
18945
18946(define_insn "*movsicc_noc"
18947  [(set (match_operand:SI 0 "register_operand" "=r,r")
18948	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18949				[(reg FLAGS_REG) (const_int 0)])
18950		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18951		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18952  "TARGET_CMOVE
18953   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18954  "@
18955   cmov%O2%C1\t{%2, %0|%0, %2}
18956   cmov%O2%c1\t{%3, %0|%0, %3}"
18957  [(set_attr "type" "icmov")
18958   (set_attr "mode" "SI")])
18959
18960(define_expand "movhicc"
18961  [(set (match_operand:HI 0 "register_operand" "")
18962	(if_then_else:HI (match_operand 1 "comparison_operator" "")
18963			 (match_operand:HI 2 "general_operand" "")
18964			 (match_operand:HI 3 "general_operand" "")))]
18965  "TARGET_HIMODE_MATH"
18966  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18967
18968(define_insn "*movhicc_noc"
18969  [(set (match_operand:HI 0 "register_operand" "=r,r")
18970	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18971				[(reg FLAGS_REG) (const_int 0)])
18972		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18973		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18974  "TARGET_CMOVE
18975   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18976  "@
18977   cmov%O2%C1\t{%2, %0|%0, %2}
18978   cmov%O2%c1\t{%3, %0|%0, %3}"
18979  [(set_attr "type" "icmov")
18980   (set_attr "mode" "HI")])
18981
18982(define_expand "movqicc"
18983  [(set (match_operand:QI 0 "register_operand" "")
18984	(if_then_else:QI (match_operand 1 "comparison_operator" "")
18985			 (match_operand:QI 2 "general_operand" "")
18986			 (match_operand:QI 3 "general_operand" "")))]
18987  "TARGET_QIMODE_MATH"
18988  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18989
18990(define_insn_and_split "*movqicc_noc"
18991  [(set (match_operand:QI 0 "register_operand" "=r,r")
18992	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18993				[(match_operand 4 "flags_reg_operand" "")
18994				 (const_int 0)])
18995		      (match_operand:QI 2 "register_operand" "r,0")
18996		      (match_operand:QI 3 "register_operand" "0,r")))]
18997  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18998  "#"
18999  "&& reload_completed"
19000  [(set (match_dup 0)
19001	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19002		      (match_dup 2)
19003		      (match_dup 3)))]
19004  "operands[0] = gen_lowpart (SImode, operands[0]);
19005   operands[2] = gen_lowpart (SImode, operands[2]);
19006   operands[3] = gen_lowpart (SImode, operands[3]);"
19007  [(set_attr "type" "icmov")
19008   (set_attr "mode" "SI")])
19009
19010(define_expand "movsfcc"
19011  [(set (match_operand:SF 0 "register_operand" "")
19012	(if_then_else:SF (match_operand 1 "comparison_operator" "")
19013			 (match_operand:SF 2 "register_operand" "")
19014			 (match_operand:SF 3 "register_operand" "")))]
19015  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19016  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19017
19018(define_insn "*movsfcc_1_387"
19019  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19020	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19021				[(reg FLAGS_REG) (const_int 0)])
19022		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19023		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19024  "TARGET_80387 && TARGET_CMOVE
19025   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19026  "@
19027   fcmov%F1\t{%2, %0|%0, %2}
19028   fcmov%f1\t{%3, %0|%0, %3}
19029   cmov%O2%C1\t{%2, %0|%0, %2}
19030   cmov%O2%c1\t{%3, %0|%0, %3}"
19031  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19032   (set_attr "mode" "SF,SF,SI,SI")])
19033
19034(define_expand "movdfcc"
19035  [(set (match_operand:DF 0 "register_operand" "")
19036	(if_then_else:DF (match_operand 1 "comparison_operator" "")
19037			 (match_operand:DF 2 "register_operand" "")
19038			 (match_operand:DF 3 "register_operand" "")))]
19039  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19040  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19041
19042(define_insn "*movdfcc_1"
19043  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19044	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19045				[(reg FLAGS_REG) (const_int 0)])
19046		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19047		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19048  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19049   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19050  "@
19051   fcmov%F1\t{%2, %0|%0, %2}
19052   fcmov%f1\t{%3, %0|%0, %3}
19053   #
19054   #"
19055  [(set_attr "type" "fcmov,fcmov,multi,multi")
19056   (set_attr "mode" "DF")])
19057
19058(define_insn "*movdfcc_1_rex64"
19059  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19060	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19061				[(reg FLAGS_REG) (const_int 0)])
19062		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19063		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19064  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19065   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19066  "@
19067   fcmov%F1\t{%2, %0|%0, %2}
19068   fcmov%f1\t{%3, %0|%0, %3}
19069   cmov%O2%C1\t{%2, %0|%0, %2}
19070   cmov%O2%c1\t{%3, %0|%0, %3}"
19071  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19072   (set_attr "mode" "DF")])
19073
19074(define_split
19075  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19076	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19077				[(match_operand 4 "flags_reg_operand" "")
19078				 (const_int 0)])
19079		      (match_operand:DF 2 "nonimmediate_operand" "")
19080		      (match_operand:DF 3 "nonimmediate_operand" "")))]
19081  "!TARGET_64BIT && reload_completed"
19082  [(set (match_dup 2)
19083	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19084		      (match_dup 5)
19085		      (match_dup 7)))
19086   (set (match_dup 3)
19087	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19088		      (match_dup 6)
19089		      (match_dup 8)))]
19090  "split_di (operands+2, 1, operands+5, operands+6);
19091   split_di (operands+3, 1, operands+7, operands+8);
19092   split_di (operands, 1, operands+2, operands+3);")
19093
19094(define_expand "movxfcc"
19095  [(set (match_operand:XF 0 "register_operand" "")
19096	(if_then_else:XF (match_operand 1 "comparison_operator" "")
19097			 (match_operand:XF 2 "register_operand" "")
19098			 (match_operand:XF 3 "register_operand" "")))]
19099  "TARGET_80387 && TARGET_CMOVE"
19100  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19101
19102(define_insn "*movxfcc_1"
19103  [(set (match_operand:XF 0 "register_operand" "=f,f")
19104	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19105				[(reg FLAGS_REG) (const_int 0)])
19106		      (match_operand:XF 2 "register_operand" "f,0")
19107		      (match_operand:XF 3 "register_operand" "0,f")))]
19108  "TARGET_80387 && TARGET_CMOVE"
19109  "@
19110   fcmov%F1\t{%2, %0|%0, %2}
19111   fcmov%f1\t{%3, %0|%0, %3}"
19112  [(set_attr "type" "fcmov")
19113   (set_attr "mode" "XF")])
19114
19115;; These versions of the min/max patterns are intentionally ignorant of
19116;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19117;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19118;; are undefined in this condition, we're certain this is correct.
19119
19120(define_insn "sminsf3"
19121  [(set (match_operand:SF 0 "register_operand" "=x")
19122	(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19123		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19124  "TARGET_SSE_MATH"
19125  "minss\t{%2, %0|%0, %2}"
19126  [(set_attr "type" "sseadd")
19127   (set_attr "mode" "SF")])
19128
19129(define_insn "smaxsf3"
19130  [(set (match_operand:SF 0 "register_operand" "=x")
19131	(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19132		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19133  "TARGET_SSE_MATH"
19134  "maxss\t{%2, %0|%0, %2}"
19135  [(set_attr "type" "sseadd")
19136   (set_attr "mode" "SF")])
19137
19138(define_insn "smindf3"
19139  [(set (match_operand:DF 0 "register_operand" "=x")
19140	(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19141		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19142  "TARGET_SSE2 && TARGET_SSE_MATH"
19143  "minsd\t{%2, %0|%0, %2}"
19144  [(set_attr "type" "sseadd")
19145   (set_attr "mode" "DF")])
19146
19147(define_insn "smaxdf3"
19148  [(set (match_operand:DF 0 "register_operand" "=x")
19149	(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19150		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19151  "TARGET_SSE2 && TARGET_SSE_MATH"
19152  "maxsd\t{%2, %0|%0, %2}"
19153  [(set_attr "type" "sseadd")
19154   (set_attr "mode" "DF")])
19155
19156;; These versions of the min/max patterns implement exactly the operations
19157;;   min = (op1 < op2 ? op1 : op2)
19158;;   max = (!(op1 < op2) ? op1 : op2)
19159;; Their operands are not commutative, and thus they may be used in the
19160;; presence of -0.0 and NaN.
19161
19162(define_insn "*ieee_sminsf3"
19163  [(set (match_operand:SF 0 "register_operand" "=x")
19164	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19165		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19166		   UNSPEC_IEEE_MIN))]
19167  "TARGET_SSE_MATH"
19168  "minss\t{%2, %0|%0, %2}"
19169  [(set_attr "type" "sseadd")
19170   (set_attr "mode" "SF")])
19171
19172(define_insn "*ieee_smaxsf3"
19173  [(set (match_operand:SF 0 "register_operand" "=x")
19174	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19175		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19176		   UNSPEC_IEEE_MAX))]
19177  "TARGET_SSE_MATH"
19178  "maxss\t{%2, %0|%0, %2}"
19179  [(set_attr "type" "sseadd")
19180   (set_attr "mode" "SF")])
19181
19182(define_insn "*ieee_smindf3"
19183  [(set (match_operand:DF 0 "register_operand" "=x")
19184	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19185		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19186		   UNSPEC_IEEE_MIN))]
19187  "TARGET_SSE2 && TARGET_SSE_MATH"
19188  "minsd\t{%2, %0|%0, %2}"
19189  [(set_attr "type" "sseadd")
19190   (set_attr "mode" "DF")])
19191
19192(define_insn "*ieee_smaxdf3"
19193  [(set (match_operand:DF 0 "register_operand" "=x")
19194	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19195		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19196		   UNSPEC_IEEE_MAX))]
19197  "TARGET_SSE2 && TARGET_SSE_MATH"
19198  "maxsd\t{%2, %0|%0, %2}"
19199  [(set_attr "type" "sseadd")
19200   (set_attr "mode" "DF")])
19201
19202;; Make two stack loads independent:
19203;;   fld aa              fld aa
19204;;   fld %st(0)     ->   fld bb
19205;;   fmul bb             fmul %st(1), %st
19206;;
19207;; Actually we only match the last two instructions for simplicity.
19208(define_peephole2
19209  [(set (match_operand 0 "fp_register_operand" "")
19210	(match_operand 1 "fp_register_operand" ""))
19211   (set (match_dup 0)
19212	(match_operator 2 "binary_fp_operator"
19213	   [(match_dup 0)
19214	    (match_operand 3 "memory_operand" "")]))]
19215  "REGNO (operands[0]) != REGNO (operands[1])"
19216  [(set (match_dup 0) (match_dup 3))
19217   (set (match_dup 0) (match_dup 4))]
19218
19219  ;; The % modifier is not operational anymore in peephole2's, so we have to
19220  ;; swap the operands manually in the case of addition and multiplication.
19221  "if (COMMUTATIVE_ARITH_P (operands[2]))
19222     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19223				 operands[0], operands[1]);
19224   else
19225     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19226				 operands[1], operands[0]);")
19227
19228;; Conditional addition patterns
19229(define_expand "addqicc"
19230  [(match_operand:QI 0 "register_operand" "")
19231   (match_operand 1 "comparison_operator" "")
19232   (match_operand:QI 2 "register_operand" "")
19233   (match_operand:QI 3 "const_int_operand" "")]
19234  ""
19235  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19236
19237(define_expand "addhicc"
19238  [(match_operand:HI 0 "register_operand" "")
19239   (match_operand 1 "comparison_operator" "")
19240   (match_operand:HI 2 "register_operand" "")
19241   (match_operand:HI 3 "const_int_operand" "")]
19242  ""
19243  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19244
19245(define_expand "addsicc"
19246  [(match_operand:SI 0 "register_operand" "")
19247   (match_operand 1 "comparison_operator" "")
19248   (match_operand:SI 2 "register_operand" "")
19249   (match_operand:SI 3 "const_int_operand" "")]
19250  ""
19251  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19252
19253(define_expand "adddicc"
19254  [(match_operand:DI 0 "register_operand" "")
19255   (match_operand 1 "comparison_operator" "")
19256   (match_operand:DI 2 "register_operand" "")
19257   (match_operand:DI 3 "const_int_operand" "")]
19258  "TARGET_64BIT"
19259  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19260
19261
19262;; Misc patterns (?)
19263
19264;; This pattern exists to put a dependency on all ebp-based memory accesses.
19265;; Otherwise there will be nothing to keep
19266;; 
19267;; [(set (reg ebp) (reg esp))]
19268;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19269;;  (clobber (eflags)]
19270;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19271;;
19272;; in proper program order.
19273(define_insn "pro_epilogue_adjust_stack_1"
19274  [(set (match_operand:SI 0 "register_operand" "=r,r")
19275	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
19276	         (match_operand:SI 2 "immediate_operand" "i,i")))
19277   (clobber (reg:CC FLAGS_REG))
19278   (clobber (mem:BLK (scratch)))]
19279  "!TARGET_64BIT"
19280{
19281  switch (get_attr_type (insn))
19282    {
19283    case TYPE_IMOV:
19284      return "mov{l}\t{%1, %0|%0, %1}";
19285
19286    case TYPE_ALU:
19287      if (GET_CODE (operands[2]) == CONST_INT
19288          && (INTVAL (operands[2]) == 128
19289	      || (INTVAL (operands[2]) < 0
19290	          && INTVAL (operands[2]) != -128)))
19291	{
19292	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19293	  return "sub{l}\t{%2, %0|%0, %2}";
19294	}
19295      return "add{l}\t{%2, %0|%0, %2}";
19296
19297    case TYPE_LEA:
19298      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19299      return "lea{l}\t{%a2, %0|%0, %a2}";
19300
19301    default:
19302      gcc_unreachable ();
19303    }
19304}
19305  [(set (attr "type")
19306	(cond [(eq_attr "alternative" "0")
19307		 (const_string "alu")
19308	       (match_operand:SI 2 "const0_operand" "")
19309		 (const_string "imov")
19310	      ]
19311	      (const_string "lea")))
19312   (set_attr "mode" "SI")])
19313
19314(define_insn "pro_epilogue_adjust_stack_rex64"
19315  [(set (match_operand:DI 0 "register_operand" "=r,r")
19316	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19317		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19318   (clobber (reg:CC FLAGS_REG))
19319   (clobber (mem:BLK (scratch)))]
19320  "TARGET_64BIT"
19321{
19322  switch (get_attr_type (insn))
19323    {
19324    case TYPE_IMOV:
19325      return "mov{q}\t{%1, %0|%0, %1}";
19326
19327    case TYPE_ALU:
19328      if (GET_CODE (operands[2]) == CONST_INT
19329	  /* Avoid overflows.  */
19330	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19331          && (INTVAL (operands[2]) == 128
19332	      || (INTVAL (operands[2]) < 0
19333	          && INTVAL (operands[2]) != -128)))
19334	{
19335	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19336	  return "sub{q}\t{%2, %0|%0, %2}";
19337	}
19338      return "add{q}\t{%2, %0|%0, %2}";
19339
19340    case TYPE_LEA:
19341      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19342      return "lea{q}\t{%a2, %0|%0, %a2}";
19343
19344    default:
19345      gcc_unreachable ();
19346    }
19347}
19348  [(set (attr "type")
19349	(cond [(eq_attr "alternative" "0")
19350		 (const_string "alu")
19351	       (match_operand:DI 2 "const0_operand" "")
19352		 (const_string "imov")
19353	      ]
19354	      (const_string "lea")))
19355   (set_attr "mode" "DI")])
19356
19357(define_insn "pro_epilogue_adjust_stack_rex64_2"
19358  [(set (match_operand:DI 0 "register_operand" "=r,r")
19359	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19360		 (match_operand:DI 3 "immediate_operand" "i,i")))
19361   (use (match_operand:DI 2 "register_operand" "r,r"))
19362   (clobber (reg:CC FLAGS_REG))
19363   (clobber (mem:BLK (scratch)))]
19364  "TARGET_64BIT"
19365{
19366  switch (get_attr_type (insn))
19367    {
19368    case TYPE_ALU:
19369      return "add{q}\t{%2, %0|%0, %2}";
19370
19371    case TYPE_LEA:
19372      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19373      return "lea{q}\t{%a2, %0|%0, %a2}";
19374
19375    default:
19376      gcc_unreachable ();
19377    }
19378}
19379  [(set_attr "type" "alu,lea")
19380   (set_attr "mode" "DI")])
19381
19382(define_expand "allocate_stack_worker"
19383  [(match_operand:SI 0 "register_operand" "")]
19384  "TARGET_STACK_PROBE"
19385{
19386  if (reload_completed)
19387    {
19388      if (TARGET_64BIT)
19389	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19390      else
19391	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19392    }
19393  else
19394    {
19395      if (TARGET_64BIT)
19396	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19397      else
19398	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19399    }
19400  DONE;
19401})
19402
19403(define_insn "allocate_stack_worker_1"
19404  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19405    UNSPECV_STACK_PROBE)
19406   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19407   (clobber (match_scratch:SI 1 "=0"))
19408   (clobber (reg:CC FLAGS_REG))]
19409  "!TARGET_64BIT && TARGET_STACK_PROBE"
19410  "call\t__alloca"
19411  [(set_attr "type" "multi")
19412   (set_attr "length" "5")])
19413
19414(define_expand "allocate_stack_worker_postreload"
19415  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19416				    UNSPECV_STACK_PROBE)
19417	      (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19418	      (clobber (match_dup 0))
19419	      (clobber (reg:CC FLAGS_REG))])]
19420  ""
19421  "")
19422
19423(define_insn "allocate_stack_worker_rex64"
19424  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19425    UNSPECV_STACK_PROBE)
19426   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19427   (clobber (match_scratch:DI 1 "=0"))
19428   (clobber (reg:CC FLAGS_REG))]
19429  "TARGET_64BIT && TARGET_STACK_PROBE"
19430  "call\t__alloca"
19431  [(set_attr "type" "multi")
19432   (set_attr "length" "5")])
19433
19434(define_expand "allocate_stack_worker_rex64_postreload"
19435  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19436				    UNSPECV_STACK_PROBE)
19437	      (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19438	      (clobber (match_dup 0))
19439	      (clobber (reg:CC FLAGS_REG))])]
19440  ""
19441  "")
19442
19443(define_expand "allocate_stack"
19444  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19445		   (minus:SI (reg:SI SP_REG)
19446			     (match_operand:SI 1 "general_operand" "")))
19447	      (clobber (reg:CC FLAGS_REG))])
19448   (parallel [(set (reg:SI SP_REG)
19449		   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19450	      (clobber (reg:CC FLAGS_REG))])]
19451  "TARGET_STACK_PROBE"
19452{
19453#ifdef CHECK_STACK_LIMIT
19454  if (GET_CODE (operands[1]) == CONST_INT
19455      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19456    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19457			   operands[1]));
19458  else 
19459#endif
19460    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19461							    operands[1])));
19462
19463  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19464  DONE;
19465})
19466
19467(define_expand "builtin_setjmp_receiver"
19468  [(label_ref (match_operand 0 "" ""))]
19469  "!TARGET_64BIT && flag_pic"
19470{
19471  if (TARGET_MACHO)
19472    {
19473      rtx xops[3];
19474      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19475      rtx label_rtx = gen_label_rtx ();
19476      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19477      xops[0] = xops[1] = picreg;
19478      xops[2] = gen_rtx_CONST (SImode,
19479	          gen_rtx_MINUS (SImode,
19480		    gen_rtx_LABEL_REF (SImode, label_rtx),
19481		    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19482      ix86_expand_binary_operator (MINUS, SImode, xops);
19483    }
19484  else
19485    emit_insn (gen_set_got (pic_offset_table_rtx));
19486  DONE;
19487})
19488
19489;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19490
19491(define_split
19492  [(set (match_operand 0 "register_operand" "")
19493	(match_operator 3 "promotable_binary_operator"
19494	   [(match_operand 1 "register_operand" "")
19495	    (match_operand 2 "aligned_operand" "")]))
19496   (clobber (reg:CC FLAGS_REG))]
19497  "! TARGET_PARTIAL_REG_STALL && reload_completed
19498   && ((GET_MODE (operands[0]) == HImode 
19499	&& ((!optimize_size && !TARGET_FAST_PREFIX)
19500            /* ??? next two lines just !satisfies_constraint_K (...) */
19501	    || GET_CODE (operands[2]) != CONST_INT
19502	    || satisfies_constraint_K (operands[2])))
19503       || (GET_MODE (operands[0]) == QImode 
19504	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19505  [(parallel [(set (match_dup 0)
19506		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19507	      (clobber (reg:CC FLAGS_REG))])]
19508  "operands[0] = gen_lowpart (SImode, operands[0]);
19509   operands[1] = gen_lowpart (SImode, operands[1]);
19510   if (GET_CODE (operands[3]) != ASHIFT)
19511     operands[2] = gen_lowpart (SImode, operands[2]);
19512   PUT_MODE (operands[3], SImode);")
19513
19514; Promote the QImode tests, as i386 has encoding of the AND
19515; instruction with 32-bit sign-extended immediate and thus the
19516; instruction size is unchanged, except in the %eax case for
19517; which it is increased by one byte, hence the ! optimize_size.
19518(define_split
19519  [(set (match_operand 0 "flags_reg_operand" "")
19520	(match_operator 2 "compare_operator"
19521	  [(and (match_operand 3 "aligned_operand" "")
19522		(match_operand 4 "const_int_operand" ""))
19523	   (const_int 0)]))
19524   (set (match_operand 1 "register_operand" "")
19525	(and (match_dup 3) (match_dup 4)))]
19526  "! TARGET_PARTIAL_REG_STALL && reload_completed
19527   /* Ensure that the operand will remain sign-extended immediate.  */
19528   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19529   && ! optimize_size
19530   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19531       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19532  [(parallel [(set (match_dup 0)
19533		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19534			            (const_int 0)]))
19535	      (set (match_dup 1)
19536		   (and:SI (match_dup 3) (match_dup 4)))])]
19537{
19538  operands[4]
19539    = gen_int_mode (INTVAL (operands[4])
19540		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19541  operands[1] = gen_lowpart (SImode, operands[1]);
19542  operands[3] = gen_lowpart (SImode, operands[3]);
19543})
19544
19545; Don't promote the QImode tests, as i386 doesn't have encoding of
19546; the TEST instruction with 32-bit sign-extended immediate and thus
19547; the instruction size would at least double, which is not what we
19548; want even with ! optimize_size.
19549(define_split
19550  [(set (match_operand 0 "flags_reg_operand" "")
19551	(match_operator 1 "compare_operator"
19552	  [(and (match_operand:HI 2 "aligned_operand" "")
19553		(match_operand:HI 3 "const_int_operand" ""))
19554	   (const_int 0)]))]
19555  "! TARGET_PARTIAL_REG_STALL && reload_completed
19556   /* Ensure that the operand will remain sign-extended immediate.  */
19557   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19558   && ! TARGET_FAST_PREFIX
19559   && ! optimize_size"
19560  [(set (match_dup 0)
19561	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19562		         (const_int 0)]))]
19563{
19564  operands[3]
19565    = gen_int_mode (INTVAL (operands[3])
19566		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19567  operands[2] = gen_lowpart (SImode, operands[2]);
19568})
19569
19570(define_split
19571  [(set (match_operand 0 "register_operand" "")
19572	(neg (match_operand 1 "register_operand" "")))
19573   (clobber (reg:CC FLAGS_REG))]
19574  "! TARGET_PARTIAL_REG_STALL && reload_completed
19575   && (GET_MODE (operands[0]) == HImode
19576       || (GET_MODE (operands[0]) == QImode 
19577	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19578  [(parallel [(set (match_dup 0)
19579		   (neg:SI (match_dup 1)))
19580	      (clobber (reg:CC FLAGS_REG))])]
19581  "operands[0] = gen_lowpart (SImode, operands[0]);
19582   operands[1] = gen_lowpart (SImode, operands[1]);")
19583
19584(define_split
19585  [(set (match_operand 0 "register_operand" "")
19586	(not (match_operand 1 "register_operand" "")))]
19587  "! TARGET_PARTIAL_REG_STALL && reload_completed
19588   && (GET_MODE (operands[0]) == HImode
19589       || (GET_MODE (operands[0]) == QImode 
19590	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19591  [(set (match_dup 0)
19592	(not:SI (match_dup 1)))]
19593  "operands[0] = gen_lowpart (SImode, operands[0]);
19594   operands[1] = gen_lowpart (SImode, operands[1]);")
19595
19596(define_split 
19597  [(set (match_operand 0 "register_operand" "")
19598	(if_then_else (match_operator 1 "comparison_operator" 
19599				[(reg FLAGS_REG) (const_int 0)])
19600		      (match_operand 2 "register_operand" "")
19601		      (match_operand 3 "register_operand" "")))]
19602  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19603   && (GET_MODE (operands[0]) == HImode
19604       || (GET_MODE (operands[0]) == QImode 
19605	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19606  [(set (match_dup 0)
19607	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19608  "operands[0] = gen_lowpart (SImode, operands[0]);
19609   operands[2] = gen_lowpart (SImode, operands[2]);
19610   operands[3] = gen_lowpart (SImode, operands[3]);")
19611			
19612
19613;; RTL Peephole optimizations, run before sched2.  These primarily look to
19614;; transform a complex memory operation into two memory to register operations.
19615
19616;; Don't push memory operands
19617(define_peephole2
19618  [(set (match_operand:SI 0 "push_operand" "")
19619	(match_operand:SI 1 "memory_operand" ""))
19620   (match_scratch:SI 2 "r")]
19621  "!optimize_size && !TARGET_PUSH_MEMORY
19622   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19623  [(set (match_dup 2) (match_dup 1))
19624   (set (match_dup 0) (match_dup 2))]
19625  "")
19626
19627(define_peephole2
19628  [(set (match_operand:DI 0 "push_operand" "")
19629	(match_operand:DI 1 "memory_operand" ""))
19630   (match_scratch:DI 2 "r")]
19631  "!optimize_size && !TARGET_PUSH_MEMORY
19632   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19633  [(set (match_dup 2) (match_dup 1))
19634   (set (match_dup 0) (match_dup 2))]
19635  "")
19636
19637;; We need to handle SFmode only, because DFmode and XFmode is split to
19638;; SImode pushes.
19639(define_peephole2
19640  [(set (match_operand:SF 0 "push_operand" "")
19641	(match_operand:SF 1 "memory_operand" ""))
19642   (match_scratch:SF 2 "r")]
19643  "!optimize_size && !TARGET_PUSH_MEMORY
19644   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19645  [(set (match_dup 2) (match_dup 1))
19646   (set (match_dup 0) (match_dup 2))]
19647  "")
19648
19649(define_peephole2
19650  [(set (match_operand:HI 0 "push_operand" "")
19651	(match_operand:HI 1 "memory_operand" ""))
19652   (match_scratch:HI 2 "r")]
19653  "!optimize_size && !TARGET_PUSH_MEMORY
19654   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19655  [(set (match_dup 2) (match_dup 1))
19656   (set (match_dup 0) (match_dup 2))]
19657  "")
19658
19659(define_peephole2
19660  [(set (match_operand:QI 0 "push_operand" "")
19661	(match_operand:QI 1 "memory_operand" ""))
19662   (match_scratch:QI 2 "q")]
19663  "!optimize_size && !TARGET_PUSH_MEMORY
19664   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19665  [(set (match_dup 2) (match_dup 1))
19666   (set (match_dup 0) (match_dup 2))]
19667  "")
19668
19669;; Don't move an immediate directly to memory when the instruction
19670;; gets too big.
19671(define_peephole2
19672  [(match_scratch:SI 1 "r")
19673   (set (match_operand:SI 0 "memory_operand" "")
19674        (const_int 0))]
19675  "! optimize_size
19676   && ! TARGET_USE_MOV0
19677   && TARGET_SPLIT_LONG_MOVES
19678   && get_attr_length (insn) >= ix86_cost->large_insn
19679   && peep2_regno_dead_p (0, FLAGS_REG)"
19680  [(parallel [(set (match_dup 1) (const_int 0))
19681	      (clobber (reg:CC FLAGS_REG))])
19682   (set (match_dup 0) (match_dup 1))]
19683  "")
19684
19685(define_peephole2
19686  [(match_scratch:HI 1 "r")
19687   (set (match_operand:HI 0 "memory_operand" "")
19688        (const_int 0))]
19689  "! optimize_size
19690   && ! TARGET_USE_MOV0
19691   && TARGET_SPLIT_LONG_MOVES
19692   && get_attr_length (insn) >= ix86_cost->large_insn
19693   && peep2_regno_dead_p (0, FLAGS_REG)"
19694  [(parallel [(set (match_dup 2) (const_int 0))
19695	      (clobber (reg:CC FLAGS_REG))])
19696   (set (match_dup 0) (match_dup 1))]
19697  "operands[2] = gen_lowpart (SImode, operands[1]);")
19698
19699(define_peephole2
19700  [(match_scratch:QI 1 "q")
19701   (set (match_operand:QI 0 "memory_operand" "")
19702        (const_int 0))]
19703  "! optimize_size
19704   && ! TARGET_USE_MOV0
19705   && TARGET_SPLIT_LONG_MOVES
19706   && get_attr_length (insn) >= ix86_cost->large_insn
19707   && peep2_regno_dead_p (0, FLAGS_REG)"
19708  [(parallel [(set (match_dup 2) (const_int 0))
19709	      (clobber (reg:CC FLAGS_REG))])
19710   (set (match_dup 0) (match_dup 1))]
19711  "operands[2] = gen_lowpart (SImode, operands[1]);")
19712
19713(define_peephole2
19714  [(match_scratch:SI 2 "r")
19715   (set (match_operand:SI 0 "memory_operand" "")
19716        (match_operand:SI 1 "immediate_operand" ""))]
19717  "! optimize_size
19718   && get_attr_length (insn) >= ix86_cost->large_insn
19719   && TARGET_SPLIT_LONG_MOVES"
19720  [(set (match_dup 2) (match_dup 1))
19721   (set (match_dup 0) (match_dup 2))]
19722  "")
19723
19724(define_peephole2
19725  [(match_scratch:HI 2 "r")
19726   (set (match_operand:HI 0 "memory_operand" "")
19727        (match_operand:HI 1 "immediate_operand" ""))]
19728  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19729  && TARGET_SPLIT_LONG_MOVES"
19730  [(set (match_dup 2) (match_dup 1))
19731   (set (match_dup 0) (match_dup 2))]
19732  "")
19733
19734(define_peephole2
19735  [(match_scratch:QI 2 "q")
19736   (set (match_operand:QI 0 "memory_operand" "")
19737        (match_operand:QI 1 "immediate_operand" ""))]
19738  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19739  && TARGET_SPLIT_LONG_MOVES"
19740  [(set (match_dup 2) (match_dup 1))
19741   (set (match_dup 0) (match_dup 2))]
19742  "")
19743
19744;; Don't compare memory with zero, load and use a test instead.
19745(define_peephole2
19746  [(set (match_operand 0 "flags_reg_operand" "")
19747 	(match_operator 1 "compare_operator"
19748	  [(match_operand:SI 2 "memory_operand" "")
19749	   (const_int 0)]))
19750   (match_scratch:SI 3 "r")]
19751  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19752  [(set (match_dup 3) (match_dup 2))
19753   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19754  "")
19755
19756;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19757;; Don't split NOTs with a displacement operand, because resulting XOR
19758;; will not be pairable anyway.
19759;;
19760;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19761;; represented using a modRM byte.  The XOR replacement is long decoded,
19762;; so this split helps here as well.
19763;;
19764;; Note: Can't do this as a regular split because we can't get proper
19765;; lifetime information then.
19766
19767(define_peephole2
19768  [(set (match_operand:SI 0 "nonimmediate_operand" "")
19769	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19770  "!optimize_size
19771   && peep2_regno_dead_p (0, FLAGS_REG)
19772   && ((TARGET_PENTIUM 
19773        && (GET_CODE (operands[0]) != MEM
19774            || !memory_displacement_operand (operands[0], SImode)))
19775       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19776  [(parallel [(set (match_dup 0)
19777		   (xor:SI (match_dup 1) (const_int -1)))
19778	      (clobber (reg:CC FLAGS_REG))])]
19779  "")
19780
19781(define_peephole2
19782  [(set (match_operand:HI 0 "nonimmediate_operand" "")
19783	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19784  "!optimize_size
19785   && peep2_regno_dead_p (0, FLAGS_REG)
19786   && ((TARGET_PENTIUM 
19787        && (GET_CODE (operands[0]) != MEM
19788            || !memory_displacement_operand (operands[0], HImode)))
19789       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19790  [(parallel [(set (match_dup 0)
19791		   (xor:HI (match_dup 1) (const_int -1)))
19792	      (clobber (reg:CC FLAGS_REG))])]
19793  "")
19794
19795(define_peephole2
19796  [(set (match_operand:QI 0 "nonimmediate_operand" "")
19797	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19798  "!optimize_size
19799   && peep2_regno_dead_p (0, FLAGS_REG)
19800   && ((TARGET_PENTIUM 
19801        && (GET_CODE (operands[0]) != MEM
19802            || !memory_displacement_operand (operands[0], QImode)))
19803       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19804  [(parallel [(set (match_dup 0)
19805		   (xor:QI (match_dup 1) (const_int -1)))
19806	      (clobber (reg:CC FLAGS_REG))])]
19807  "")
19808
19809;; Non pairable "test imm, reg" instructions can be translated to
19810;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19811;; byte opcode instead of two, have a short form for byte operands),
19812;; so do it for other CPUs as well.  Given that the value was dead,
19813;; this should not create any new dependencies.  Pass on the sub-word
19814;; versions if we're concerned about partial register stalls.
19815
19816(define_peephole2
19817  [(set (match_operand 0 "flags_reg_operand" "")
19818	(match_operator 1 "compare_operator"
19819	  [(and:SI (match_operand:SI 2 "register_operand" "")
19820		   (match_operand:SI 3 "immediate_operand" ""))
19821	   (const_int 0)]))]
19822  "ix86_match_ccmode (insn, CCNOmode)
19823   && (true_regnum (operands[2]) != 0
19824       || satisfies_constraint_K (operands[3]))
19825   && peep2_reg_dead_p (1, operands[2])"
19826  [(parallel
19827     [(set (match_dup 0)
19828	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19829		            (const_int 0)]))
19830      (set (match_dup 2)
19831	   (and:SI (match_dup 2) (match_dup 3)))])]
19832  "")
19833
19834;; We don't need to handle HImode case, because it will be promoted to SImode
19835;; on ! TARGET_PARTIAL_REG_STALL
19836
19837(define_peephole2
19838  [(set (match_operand 0 "flags_reg_operand" "")
19839	(match_operator 1 "compare_operator"
19840	  [(and:QI (match_operand:QI 2 "register_operand" "")
19841		   (match_operand:QI 3 "immediate_operand" ""))
19842	   (const_int 0)]))]
19843  "! TARGET_PARTIAL_REG_STALL
19844   && ix86_match_ccmode (insn, CCNOmode)
19845   && true_regnum (operands[2]) != 0
19846   && peep2_reg_dead_p (1, operands[2])"
19847  [(parallel
19848     [(set (match_dup 0)
19849	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19850		            (const_int 0)]))
19851      (set (match_dup 2)
19852	   (and:QI (match_dup 2) (match_dup 3)))])]
19853  "")
19854
19855(define_peephole2
19856  [(set (match_operand 0 "flags_reg_operand" "")
19857	(match_operator 1 "compare_operator"
19858	  [(and:SI
19859	     (zero_extract:SI
19860	       (match_operand 2 "ext_register_operand" "")
19861	       (const_int 8)
19862	       (const_int 8))
19863	     (match_operand 3 "const_int_operand" ""))
19864	   (const_int 0)]))]
19865  "! TARGET_PARTIAL_REG_STALL
19866   && ix86_match_ccmode (insn, CCNOmode)
19867   && true_regnum (operands[2]) != 0
19868   && peep2_reg_dead_p (1, operands[2])"
19869  [(parallel [(set (match_dup 0)
19870		   (match_op_dup 1
19871		     [(and:SI
19872			(zero_extract:SI
19873			  (match_dup 2)
19874			  (const_int 8)
19875			  (const_int 8))
19876			(match_dup 3))
19877		      (const_int 0)]))
19878	      (set (zero_extract:SI (match_dup 2)
19879				    (const_int 8)
19880				    (const_int 8))
19881		   (and:SI 
19882		     (zero_extract:SI
19883		       (match_dup 2)
19884		       (const_int 8)
19885		       (const_int 8))
19886		     (match_dup 3)))])]
19887  "")
19888
19889;; Don't do logical operations with memory inputs.
19890(define_peephole2
19891  [(match_scratch:SI 2 "r")
19892   (parallel [(set (match_operand:SI 0 "register_operand" "")
19893                   (match_operator:SI 3 "arith_or_logical_operator"
19894                     [(match_dup 0)
19895                      (match_operand:SI 1 "memory_operand" "")]))
19896              (clobber (reg:CC FLAGS_REG))])]
19897  "! optimize_size && ! TARGET_READ_MODIFY"
19898  [(set (match_dup 2) (match_dup 1))
19899   (parallel [(set (match_dup 0)
19900                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19901              (clobber (reg:CC FLAGS_REG))])]
19902  "")
19903
19904(define_peephole2
19905  [(match_scratch:SI 2 "r")
19906   (parallel [(set (match_operand:SI 0 "register_operand" "")
19907                   (match_operator:SI 3 "arith_or_logical_operator"
19908                     [(match_operand:SI 1 "memory_operand" "")
19909                      (match_dup 0)]))
19910              (clobber (reg:CC FLAGS_REG))])]
19911  "! optimize_size && ! TARGET_READ_MODIFY"
19912  [(set (match_dup 2) (match_dup 1))
19913   (parallel [(set (match_dup 0)
19914                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19915              (clobber (reg:CC FLAGS_REG))])]
19916  "")
19917
19918; Don't do logical operations with memory outputs
19919;
19920; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19921; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19922; the same decoder scheduling characteristics as the original.
19923
19924(define_peephole2
19925  [(match_scratch:SI 2 "r")
19926   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19927                   (match_operator:SI 3 "arith_or_logical_operator"
19928                     [(match_dup 0)
19929                      (match_operand:SI 1 "nonmemory_operand" "")]))
19930              (clobber (reg:CC FLAGS_REG))])]
19931  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19932  [(set (match_dup 2) (match_dup 0))
19933   (parallel [(set (match_dup 2)
19934                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19935              (clobber (reg:CC FLAGS_REG))])
19936   (set (match_dup 0) (match_dup 2))]
19937  "")
19938
19939(define_peephole2
19940  [(match_scratch:SI 2 "r")
19941   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19942                   (match_operator:SI 3 "arith_or_logical_operator"
19943                     [(match_operand:SI 1 "nonmemory_operand" "")
19944                      (match_dup 0)]))
19945              (clobber (reg:CC FLAGS_REG))])]
19946  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19947  [(set (match_dup 2) (match_dup 0))
19948   (parallel [(set (match_dup 2)
19949                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19950              (clobber (reg:CC FLAGS_REG))])
19951   (set (match_dup 0) (match_dup 2))]
19952  "")
19953
19954;; Attempt to always use XOR for zeroing registers.
19955(define_peephole2
19956  [(set (match_operand 0 "register_operand" "")
19957	(match_operand 1 "const0_operand" ""))]
19958  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19959   && (! TARGET_USE_MOV0 || optimize_size)
19960   && GENERAL_REG_P (operands[0])
19961   && peep2_regno_dead_p (0, FLAGS_REG)"
19962  [(parallel [(set (match_dup 0) (const_int 0))
19963	      (clobber (reg:CC FLAGS_REG))])]
19964{
19965  operands[0] = gen_lowpart (word_mode, operands[0]);
19966})
19967
19968(define_peephole2
19969  [(set (strict_low_part (match_operand 0 "register_operand" ""))
19970	(const_int 0))]
19971  "(GET_MODE (operands[0]) == QImode
19972    || GET_MODE (operands[0]) == HImode)
19973   && (! TARGET_USE_MOV0 || optimize_size)
19974   && peep2_regno_dead_p (0, FLAGS_REG)"
19975  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19976	      (clobber (reg:CC FLAGS_REG))])])
19977
19978;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19979(define_peephole2
19980  [(set (match_operand 0 "register_operand" "")
19981	(const_int -1))]
19982  "(GET_MODE (operands[0]) == HImode
19983    || GET_MODE (operands[0]) == SImode 
19984    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19985   && (optimize_size || TARGET_PENTIUM)
19986   && peep2_regno_dead_p (0, FLAGS_REG)"
19987  [(parallel [(set (match_dup 0) (const_int -1))
19988	      (clobber (reg:CC FLAGS_REG))])]
19989  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19990			      operands[0]);")
19991
19992;; Attempt to convert simple leas to adds. These can be created by
19993;; move expanders.
19994(define_peephole2
19995  [(set (match_operand:SI 0 "register_operand" "")
19996  	(plus:SI (match_dup 0)
19997		 (match_operand:SI 1 "nonmemory_operand" "")))]
19998  "peep2_regno_dead_p (0, FLAGS_REG)"
19999  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20000	      (clobber (reg:CC FLAGS_REG))])]
20001  "")
20002
20003(define_peephole2
20004  [(set (match_operand:SI 0 "register_operand" "")
20005  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20006			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20007  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20008  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20009	      (clobber (reg:CC FLAGS_REG))])]
20010  "operands[2] = gen_lowpart (SImode, operands[2]);")
20011
20012(define_peephole2
20013  [(set (match_operand:DI 0 "register_operand" "")
20014  	(plus:DI (match_dup 0)
20015		 (match_operand:DI 1 "x86_64_general_operand" "")))]
20016  "peep2_regno_dead_p (0, FLAGS_REG)"
20017  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20018	      (clobber (reg:CC FLAGS_REG))])]
20019  "")
20020
20021(define_peephole2
20022  [(set (match_operand:SI 0 "register_operand" "")
20023  	(mult:SI (match_dup 0)
20024		 (match_operand:SI 1 "const_int_operand" "")))]
20025  "exact_log2 (INTVAL (operands[1])) >= 0
20026   && peep2_regno_dead_p (0, FLAGS_REG)"
20027  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20028	      (clobber (reg:CC FLAGS_REG))])]
20029  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20030
20031(define_peephole2
20032  [(set (match_operand:DI 0 "register_operand" "")
20033  	(mult:DI (match_dup 0)
20034		 (match_operand:DI 1 "const_int_operand" "")))]
20035  "exact_log2 (INTVAL (operands[1])) >= 0
20036   && peep2_regno_dead_p (0, FLAGS_REG)"
20037  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20038	      (clobber (reg:CC FLAGS_REG))])]
20039  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20040
20041(define_peephole2
20042  [(set (match_operand:SI 0 "register_operand" "")
20043  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20044		   (match_operand:DI 2 "const_int_operand" "")) 0))]
20045  "exact_log2 (INTVAL (operands[2])) >= 0
20046   && REGNO (operands[0]) == REGNO (operands[1])
20047   && peep2_regno_dead_p (0, FLAGS_REG)"
20048  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20049	      (clobber (reg:CC FLAGS_REG))])]
20050  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20051
20052;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20053;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20054;; many CPUs it is also faster, since special hardware to avoid esp
20055;; dependencies is present.
20056
20057;; While some of these conversions may be done using splitters, we use peepholes
20058;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20059
20060;; Convert prologue esp subtractions to push.
20061;; We need register to push.  In order to keep verify_flow_info happy we have
20062;; two choices
20063;; - use scratch and clobber it in order to avoid dependencies
20064;; - use already live register
20065;; We can't use the second way right now, since there is no reliable way how to
20066;; verify that given register is live.  First choice will also most likely in
20067;; fewer dependencies.  On the place of esp adjustments it is very likely that
20068;; call clobbered registers are dead.  We may want to use base pointer as an
20069;; alternative when no register is available later.
20070
20071(define_peephole2
20072  [(match_scratch:SI 0 "r")
20073   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20074	      (clobber (reg:CC FLAGS_REG))
20075	      (clobber (mem:BLK (scratch)))])]
20076  "optimize_size || !TARGET_SUB_ESP_4"
20077  [(clobber (match_dup 0))
20078   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20079	      (clobber (mem:BLK (scratch)))])])
20080
20081(define_peephole2
20082  [(match_scratch:SI 0 "r")
20083   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20084	      (clobber (reg:CC FLAGS_REG))
20085	      (clobber (mem:BLK (scratch)))])]
20086  "optimize_size || !TARGET_SUB_ESP_8"
20087  [(clobber (match_dup 0))
20088   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20089   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20090	      (clobber (mem:BLK (scratch)))])])
20091
20092;; Convert esp subtractions to push.
20093(define_peephole2
20094  [(match_scratch:SI 0 "r")
20095   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20096	      (clobber (reg:CC FLAGS_REG))])]
20097  "optimize_size || !TARGET_SUB_ESP_4"
20098  [(clobber (match_dup 0))
20099   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20100
20101(define_peephole2
20102  [(match_scratch:SI 0 "r")
20103   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20104	      (clobber (reg:CC FLAGS_REG))])]
20105  "optimize_size || !TARGET_SUB_ESP_8"
20106  [(clobber (match_dup 0))
20107   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20108   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20109
20110;; Convert epilogue deallocator to pop.
20111(define_peephole2
20112  [(match_scratch:SI 0 "r")
20113   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20114	      (clobber (reg:CC FLAGS_REG))
20115	      (clobber (mem:BLK (scratch)))])]
20116  "optimize_size || !TARGET_ADD_ESP_4"
20117  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20118	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20119	      (clobber (mem:BLK (scratch)))])]
20120  "")
20121
20122;; Two pops case is tricky, since pop causes dependency on destination register.
20123;; We use two registers if available.
20124(define_peephole2
20125  [(match_scratch:SI 0 "r")
20126   (match_scratch:SI 1 "r")
20127   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20128	      (clobber (reg:CC FLAGS_REG))
20129	      (clobber (mem:BLK (scratch)))])]
20130  "optimize_size || !TARGET_ADD_ESP_8"
20131  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20132	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20133	      (clobber (mem:BLK (scratch)))])
20134   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20135	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20136  "")
20137
20138(define_peephole2
20139  [(match_scratch:SI 0 "r")
20140   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20141	      (clobber (reg:CC FLAGS_REG))
20142	      (clobber (mem:BLK (scratch)))])]
20143  "optimize_size"
20144  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20145	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20146	      (clobber (mem:BLK (scratch)))])
20147   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20148	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20149  "")
20150
20151;; Convert esp additions to pop.
20152(define_peephole2
20153  [(match_scratch:SI 0 "r")
20154   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20155	      (clobber (reg:CC FLAGS_REG))])]
20156  ""
20157  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20158	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20159  "")
20160
20161;; Two pops case is tricky, since pop causes dependency on destination register.
20162;; We use two registers if available.
20163(define_peephole2
20164  [(match_scratch:SI 0 "r")
20165   (match_scratch:SI 1 "r")
20166   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20167	      (clobber (reg:CC FLAGS_REG))])]
20168  ""
20169  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20170	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20171   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20172	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20173  "")
20174
20175(define_peephole2
20176  [(match_scratch:SI 0 "r")
20177   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20178	      (clobber (reg:CC FLAGS_REG))])]
20179  "optimize_size"
20180  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20181	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20182   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20183	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20184  "")
20185
20186;; Convert compares with 1 to shorter inc/dec operations when CF is not
20187;; required and register dies.  Similarly for 128 to plus -128.
20188(define_peephole2
20189  [(set (match_operand 0 "flags_reg_operand" "")
20190	(match_operator 1 "compare_operator"
20191	  [(match_operand 2 "register_operand" "")
20192	   (match_operand 3 "const_int_operand" "")]))]
20193  "(INTVAL (operands[3]) == -1
20194    || INTVAL (operands[3]) == 1
20195    || INTVAL (operands[3]) == 128)
20196   && ix86_match_ccmode (insn, CCGCmode)
20197   && peep2_reg_dead_p (1, operands[2])"
20198  [(parallel [(set (match_dup 0)
20199		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20200	      (clobber (match_dup 2))])]
20201  "")
20202
20203(define_peephole2
20204  [(match_scratch:DI 0 "r")
20205   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20206	      (clobber (reg:CC FLAGS_REG))
20207	      (clobber (mem:BLK (scratch)))])]
20208  "optimize_size || !TARGET_SUB_ESP_4"
20209  [(clobber (match_dup 0))
20210   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20211	      (clobber (mem:BLK (scratch)))])])
20212
20213(define_peephole2
20214  [(match_scratch:DI 0 "r")
20215   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20216	      (clobber (reg:CC FLAGS_REG))
20217	      (clobber (mem:BLK (scratch)))])]
20218  "optimize_size || !TARGET_SUB_ESP_8"
20219  [(clobber (match_dup 0))
20220   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20221   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20222	      (clobber (mem:BLK (scratch)))])])
20223
20224;; Convert esp subtractions to push.
20225(define_peephole2
20226  [(match_scratch:DI 0 "r")
20227   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20228	      (clobber (reg:CC FLAGS_REG))])]
20229  "optimize_size || !TARGET_SUB_ESP_4"
20230  [(clobber (match_dup 0))
20231   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20232
20233(define_peephole2
20234  [(match_scratch:DI 0 "r")
20235   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20236	      (clobber (reg:CC FLAGS_REG))])]
20237  "optimize_size || !TARGET_SUB_ESP_8"
20238  [(clobber (match_dup 0))
20239   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20240   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20241
20242;; Convert epilogue deallocator to pop.
20243(define_peephole2
20244  [(match_scratch:DI 0 "r")
20245   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20246	      (clobber (reg:CC FLAGS_REG))
20247	      (clobber (mem:BLK (scratch)))])]
20248  "optimize_size || !TARGET_ADD_ESP_4"
20249  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20250	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20251	      (clobber (mem:BLK (scratch)))])]
20252  "")
20253
20254;; Two pops case is tricky, since pop causes dependency on destination register.
20255;; We use two registers if available.
20256(define_peephole2
20257  [(match_scratch:DI 0 "r")
20258   (match_scratch:DI 1 "r")
20259   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20260	      (clobber (reg:CC FLAGS_REG))
20261	      (clobber (mem:BLK (scratch)))])]
20262  "optimize_size || !TARGET_ADD_ESP_8"
20263  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20264	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20265	      (clobber (mem:BLK (scratch)))])
20266   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20267	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20268  "")
20269
20270(define_peephole2
20271  [(match_scratch:DI 0 "r")
20272   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20273	      (clobber (reg:CC FLAGS_REG))
20274	      (clobber (mem:BLK (scratch)))])]
20275  "optimize_size"
20276  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20277	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20278	      (clobber (mem:BLK (scratch)))])
20279   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20280	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20281  "")
20282
20283;; Convert esp additions to pop.
20284(define_peephole2
20285  [(match_scratch:DI 0 "r")
20286   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20287	      (clobber (reg:CC FLAGS_REG))])]
20288  ""
20289  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20290	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20291  "")
20292
20293;; Two pops case is tricky, since pop causes dependency on destination register.
20294;; We use two registers if available.
20295(define_peephole2
20296  [(match_scratch:DI 0 "r")
20297   (match_scratch:DI 1 "r")
20298   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20299	      (clobber (reg:CC FLAGS_REG))])]
20300  ""
20301  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20302	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20303   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20304	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20305  "")
20306
20307(define_peephole2
20308  [(match_scratch:DI 0 "r")
20309   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20310	      (clobber (reg:CC FLAGS_REG))])]
20311  "optimize_size"
20312  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20313	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20314   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20315	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20316  "")
20317
20318;; Convert imul by three, five and nine into lea
20319(define_peephole2
20320  [(parallel
20321    [(set (match_operand:SI 0 "register_operand" "")
20322	  (mult:SI (match_operand:SI 1 "register_operand" "")
20323		   (match_operand:SI 2 "const_int_operand" "")))
20324     (clobber (reg:CC FLAGS_REG))])]
20325  "INTVAL (operands[2]) == 3
20326   || INTVAL (operands[2]) == 5
20327   || INTVAL (operands[2]) == 9"
20328  [(set (match_dup 0)
20329        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20330                 (match_dup 1)))]
20331  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20332
20333(define_peephole2
20334  [(parallel
20335    [(set (match_operand:SI 0 "register_operand" "")
20336          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20337                   (match_operand:SI 2 "const_int_operand" "")))
20338     (clobber (reg:CC FLAGS_REG))])]
20339  "!optimize_size 
20340   && (INTVAL (operands[2]) == 3
20341       || INTVAL (operands[2]) == 5
20342       || INTVAL (operands[2]) == 9)"
20343  [(set (match_dup 0) (match_dup 1))
20344   (set (match_dup 0)
20345        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20346                 (match_dup 0)))]
20347  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20348
20349(define_peephole2
20350  [(parallel
20351    [(set (match_operand:DI 0 "register_operand" "")
20352	  (mult:DI (match_operand:DI 1 "register_operand" "")
20353		   (match_operand:DI 2 "const_int_operand" "")))
20354     (clobber (reg:CC FLAGS_REG))])]
20355  "TARGET_64BIT
20356   && (INTVAL (operands[2]) == 3
20357       || INTVAL (operands[2]) == 5
20358       || INTVAL (operands[2]) == 9)"
20359  [(set (match_dup 0)
20360        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20361                 (match_dup 1)))]
20362  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20363
20364(define_peephole2
20365  [(parallel
20366    [(set (match_operand:DI 0 "register_operand" "")
20367          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20368                   (match_operand:DI 2 "const_int_operand" "")))
20369     (clobber (reg:CC FLAGS_REG))])]
20370  "TARGET_64BIT
20371   && !optimize_size 
20372   && (INTVAL (operands[2]) == 3
20373       || INTVAL (operands[2]) == 5
20374       || INTVAL (operands[2]) == 9)"
20375  [(set (match_dup 0) (match_dup 1))
20376   (set (match_dup 0)
20377        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20378                 (match_dup 0)))]
20379  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20380
20381;; Imul $32bit_imm, mem, reg is vector decoded, while
20382;; imul $32bit_imm, reg, reg is direct decoded.
20383(define_peephole2
20384  [(match_scratch:DI 3 "r")
20385   (parallel [(set (match_operand:DI 0 "register_operand" "")
20386		   (mult:DI (match_operand:DI 1 "memory_operand" "")
20387			    (match_operand:DI 2 "immediate_operand" "")))
20388	      (clobber (reg:CC FLAGS_REG))])]
20389  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20390   && !satisfies_constraint_K (operands[2])"
20391  [(set (match_dup 3) (match_dup 1))
20392   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20393	      (clobber (reg:CC FLAGS_REG))])]
20394"")
20395
20396(define_peephole2
20397  [(match_scratch:SI 3 "r")
20398   (parallel [(set (match_operand:SI 0 "register_operand" "")
20399		   (mult:SI (match_operand:SI 1 "memory_operand" "")
20400			    (match_operand:SI 2 "immediate_operand" "")))
20401	      (clobber (reg:CC FLAGS_REG))])]
20402  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20403   && !satisfies_constraint_K (operands[2])"
20404  [(set (match_dup 3) (match_dup 1))
20405   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20406	      (clobber (reg:CC FLAGS_REG))])]
20407"")
20408
20409(define_peephole2
20410  [(match_scratch:SI 3 "r")
20411   (parallel [(set (match_operand:DI 0 "register_operand" "")
20412		   (zero_extend:DI
20413		     (mult:SI (match_operand:SI 1 "memory_operand" "")
20414			      (match_operand:SI 2 "immediate_operand" ""))))
20415	      (clobber (reg:CC FLAGS_REG))])]
20416  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20417   && !satisfies_constraint_K (operands[2])"
20418  [(set (match_dup 3) (match_dup 1))
20419   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20420	      (clobber (reg:CC FLAGS_REG))])]
20421"")
20422
20423;; imul $8/16bit_imm, regmem, reg is vector decoded.
20424;; Convert it into imul reg, reg
20425;; It would be better to force assembler to encode instruction using long
20426;; immediate, but there is apparently no way to do so.
20427(define_peephole2
20428  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20429		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20430			    (match_operand:DI 2 "const_int_operand" "")))
20431	      (clobber (reg:CC FLAGS_REG))])
20432   (match_scratch:DI 3 "r")]
20433  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20434   && satisfies_constraint_K (operands[2])"
20435  [(set (match_dup 3) (match_dup 2))
20436   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20437	      (clobber (reg:CC FLAGS_REG))])]
20438{
20439  if (!rtx_equal_p (operands[0], operands[1]))
20440    emit_move_insn (operands[0], operands[1]);
20441})
20442
20443(define_peephole2
20444  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20445		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20446			    (match_operand:SI 2 "const_int_operand" "")))
20447	      (clobber (reg:CC FLAGS_REG))])
20448   (match_scratch:SI 3 "r")]
20449  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20450   && satisfies_constraint_K (operands[2])"
20451  [(set (match_dup 3) (match_dup 2))
20452   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20453	      (clobber (reg:CC FLAGS_REG))])]
20454{
20455  if (!rtx_equal_p (operands[0], operands[1]))
20456    emit_move_insn (operands[0], operands[1]);
20457})
20458
20459(define_peephole2
20460  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20461		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20462			    (match_operand:HI 2 "immediate_operand" "")))
20463	      (clobber (reg:CC FLAGS_REG))])
20464   (match_scratch:HI 3 "r")]
20465  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20466  [(set (match_dup 3) (match_dup 2))
20467   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20468	      (clobber (reg:CC FLAGS_REG))])]
20469{
20470  if (!rtx_equal_p (operands[0], operands[1]))
20471    emit_move_insn (operands[0], operands[1]);
20472})
20473
20474;; After splitting up read-modify operations, array accesses with memory
20475;; operands might end up in form:
20476;;  sall    $2, %eax
20477;;  movl    4(%esp), %edx
20478;;  addl    %edx, %eax
20479;; instead of pre-splitting:
20480;;  sall    $2, %eax
20481;;  addl    4(%esp), %eax
20482;; Turn it into:
20483;;  movl    4(%esp), %edx
20484;;  leal    (%edx,%eax,4), %eax
20485
20486(define_peephole2
20487  [(parallel [(set (match_operand 0 "register_operand" "")
20488		   (ashift (match_operand 1 "register_operand" "")
20489			   (match_operand 2 "const_int_operand" "")))
20490	       (clobber (reg:CC FLAGS_REG))])
20491   (set (match_operand 3 "register_operand")
20492        (match_operand 4 "x86_64_general_operand" ""))
20493   (parallel [(set (match_operand 5 "register_operand" "")
20494		   (plus (match_operand 6 "register_operand" "")
20495			 (match_operand 7 "register_operand" "")))
20496		   (clobber (reg:CC FLAGS_REG))])]
20497  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20498   /* Validate MODE for lea.  */
20499   && ((!TARGET_PARTIAL_REG_STALL
20500	&& (GET_MODE (operands[0]) == QImode
20501	    || GET_MODE (operands[0]) == HImode))
20502       || GET_MODE (operands[0]) == SImode 
20503       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20504   /* We reorder load and the shift.  */
20505   && !rtx_equal_p (operands[1], operands[3])
20506   && !reg_overlap_mentioned_p (operands[0], operands[4])
20507   /* Last PLUS must consist of operand 0 and 3.  */
20508   && !rtx_equal_p (operands[0], operands[3])
20509   && (rtx_equal_p (operands[3], operands[6])
20510       || rtx_equal_p (operands[3], operands[7]))
20511   && (rtx_equal_p (operands[0], operands[6])
20512       || rtx_equal_p (operands[0], operands[7]))
20513   /* The intermediate operand 0 must die or be same as output.  */
20514   && (rtx_equal_p (operands[0], operands[5])
20515       || peep2_reg_dead_p (3, operands[0]))"
20516  [(set (match_dup 3) (match_dup 4))
20517   (set (match_dup 0) (match_dup 1))]
20518{
20519  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20520  int scale = 1 << INTVAL (operands[2]);
20521  rtx index = gen_lowpart (Pmode, operands[1]);
20522  rtx base = gen_lowpart (Pmode, operands[3]);
20523  rtx dest = gen_lowpart (mode, operands[5]);
20524
20525  operands[1] = gen_rtx_PLUS (Pmode, base,
20526  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20527  if (mode != Pmode)
20528    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20529  operands[0] = dest;
20530})
20531
20532;; Call-value patterns last so that the wildcard operand does not
20533;; disrupt insn-recog's switch tables.
20534
20535(define_insn "*call_value_pop_0"
20536  [(set (match_operand 0 "" "")
20537	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20538	      (match_operand:SI 2 "" "")))
20539   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20540			    (match_operand:SI 3 "immediate_operand" "")))]
20541  "!TARGET_64BIT"
20542{
20543  if (SIBLING_CALL_P (insn))
20544    return "jmp\t%P1";
20545  else
20546    return "call\t%P1";
20547}
20548  [(set_attr "type" "callv")])
20549
20550(define_insn "*call_value_pop_1"
20551  [(set (match_operand 0 "" "")
20552	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20553	      (match_operand:SI 2 "" "")))
20554   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20555			    (match_operand:SI 3 "immediate_operand" "i")))]
20556  "!TARGET_64BIT"
20557{
20558  if (constant_call_address_operand (operands[1], Pmode))
20559    {
20560      if (SIBLING_CALL_P (insn))
20561	return "jmp\t%P1";
20562      else
20563	return "call\t%P1";
20564    }
20565  if (SIBLING_CALL_P (insn))
20566    return "jmp\t%A1";
20567  else
20568    return "call\t%A1";
20569}
20570  [(set_attr "type" "callv")])
20571
20572(define_insn "*call_value_0"
20573  [(set (match_operand 0 "" "")
20574	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20575	      (match_operand:SI 2 "" "")))]
20576  "!TARGET_64BIT"
20577{
20578  if (SIBLING_CALL_P (insn))
20579    return "jmp\t%P1";
20580  else
20581    return "call\t%P1";
20582}
20583  [(set_attr "type" "callv")])
20584
20585(define_insn "*call_value_0_rex64"
20586  [(set (match_operand 0 "" "")
20587	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20588	      (match_operand:DI 2 "const_int_operand" "")))]
20589  "TARGET_64BIT"
20590{
20591  if (SIBLING_CALL_P (insn))
20592    return "jmp\t%P1";
20593  else
20594    return "call\t%P1";
20595}
20596  [(set_attr "type" "callv")])
20597
20598(define_insn "*call_value_1"
20599  [(set (match_operand 0 "" "")
20600	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20601	      (match_operand:SI 2 "" "")))]
20602  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20603{
20604  if (constant_call_address_operand (operands[1], Pmode))
20605    return "call\t%P1";
20606  return "call\t%A1";
20607}
20608  [(set_attr "type" "callv")])
20609
20610(define_insn "*sibcall_value_1"
20611  [(set (match_operand 0 "" "")
20612	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20613	      (match_operand:SI 2 "" "")))]
20614  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20615{
20616  if (constant_call_address_operand (operands[1], Pmode))
20617    return "jmp\t%P1";
20618  return "jmp\t%A1";
20619}
20620  [(set_attr "type" "callv")])
20621
20622(define_insn "*call_value_1_rex64"
20623  [(set (match_operand 0 "" "")
20624	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20625	      (match_operand:DI 2 "" "")))]
20626  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20627{
20628  if (constant_call_address_operand (operands[1], Pmode))
20629    return "call\t%P1";
20630  return "call\t%A1";
20631}
20632  [(set_attr "type" "callv")])
20633
20634(define_insn "*sibcall_value_1_rex64"
20635  [(set (match_operand 0 "" "")
20636	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20637	      (match_operand:DI 2 "" "")))]
20638  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20639  "jmp\t%P1"
20640  [(set_attr "type" "callv")])
20641
20642(define_insn "*sibcall_value_1_rex64_v"
20643  [(set (match_operand 0 "" "")
20644	(call (mem:QI (reg:DI 40))
20645	      (match_operand:DI 1 "" "")))]
20646  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20647  "jmp\t*%%r11"
20648  [(set_attr "type" "callv")])
20649
20650;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20651;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20652;; caught for use by garbage collectors and the like.  Using an insn that
20653;; maps to SIGILL makes it more likely the program will rightfully die.
20654;; Keeping with tradition, "6" is in honor of #UD.
20655(define_insn "trap"
20656  [(trap_if (const_int 1) (const_int 6))]
20657  ""
20658  { return ASM_SHORT "0x0b0f"; }
20659  [(set_attr "length" "2")])
20660
20661(define_expand "sse_prologue_save"
20662  [(parallel [(set (match_operand:BLK 0 "" "")
20663		   (unspec:BLK [(reg:DI 21)
20664				(reg:DI 22)
20665				(reg:DI 23)
20666				(reg:DI 24)
20667				(reg:DI 25)
20668				(reg:DI 26)
20669				(reg:DI 27)
20670				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20671	      (use (match_operand:DI 1 "register_operand" ""))
20672	      (use (match_operand:DI 2 "immediate_operand" ""))
20673	      (use (label_ref:DI (match_operand 3 "" "")))])]
20674  "TARGET_64BIT"
20675  "")
20676
20677(define_insn "*sse_prologue_save_insn"
20678  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20679			  (match_operand:DI 4 "const_int_operand" "n")))
20680	(unspec:BLK [(reg:DI 21)
20681		     (reg:DI 22)
20682		     (reg:DI 23)
20683		     (reg:DI 24)
20684		     (reg:DI 25)
20685		     (reg:DI 26)
20686		     (reg:DI 27)
20687		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20688   (use (match_operand:DI 1 "register_operand" "r"))
20689   (use (match_operand:DI 2 "const_int_operand" "i"))
20690   (use (label_ref:DI (match_operand 3 "" "X")))]
20691  "TARGET_64BIT
20692   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20693   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20694  "*
20695{
20696  int i;
20697  operands[0] = gen_rtx_MEM (Pmode,
20698			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20699  output_asm_insn (\"jmp\\t%A1\", operands);
20700  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20701    {
20702      operands[4] = adjust_address (operands[0], DImode, i*16);
20703      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20704      PUT_MODE (operands[4], TImode);
20705      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20706        output_asm_insn (\"rex\", operands);
20707      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20708    }
20709  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20710			     CODE_LABEL_NUMBER (operands[3]));
20711  RET;
20712}
20713  "
20714  [(set_attr "type" "other")
20715   (set_attr "length_immediate" "0")
20716   (set_attr "length_address" "0")
20717   (set_attr "length" "135")
20718   (set_attr "memory" "store")
20719   (set_attr "modrm" "0")
20720   (set_attr "mode" "DI")])
20721
20722(define_expand "prefetch"
20723  [(prefetch (match_operand 0 "address_operand" "")
20724	     (match_operand:SI 1 "const_int_operand" "")
20725	     (match_operand:SI 2 "const_int_operand" ""))]
20726  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20727{
20728  int rw = INTVAL (operands[1]);
20729  int locality = INTVAL (operands[2]);
20730
20731  gcc_assert (rw == 0 || rw == 1);
20732  gcc_assert (locality >= 0 && locality <= 3);
20733  gcc_assert (GET_MODE (operands[0]) == Pmode
20734	      || GET_MODE (operands[0]) == VOIDmode);
20735
20736  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20737     supported by SSE counterpart or the SSE prefetch is not available
20738     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20739     of locality.  */
20740  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20741    operands[2] = GEN_INT (3);
20742  else
20743    operands[1] = const0_rtx;
20744})
20745
20746(define_insn "*prefetch_sse"
20747  [(prefetch (match_operand:SI 0 "address_operand" "p")
20748	     (const_int 0)
20749	     (match_operand:SI 1 "const_int_operand" ""))]
20750  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20751{
20752  static const char * const patterns[4] = {
20753   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20754  };
20755
20756  int locality = INTVAL (operands[1]);
20757  gcc_assert (locality >= 0 && locality <= 3);
20758
20759  return patterns[locality];  
20760}
20761  [(set_attr "type" "sse")
20762   (set_attr "memory" "none")])
20763
20764(define_insn "*prefetch_sse_rex"
20765  [(prefetch (match_operand:DI 0 "address_operand" "p")
20766	     (const_int 0)
20767	     (match_operand:SI 1 "const_int_operand" ""))]
20768  "TARGET_PREFETCH_SSE && TARGET_64BIT"
20769{
20770  static const char * const patterns[4] = {
20771   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20772  };
20773
20774  int locality = INTVAL (operands[1]);
20775  gcc_assert (locality >= 0 && locality <= 3);
20776
20777  return patterns[locality];  
20778}
20779  [(set_attr "type" "sse")
20780   (set_attr "memory" "none")])
20781
20782(define_insn "*prefetch_3dnow"
20783  [(prefetch (match_operand:SI 0 "address_operand" "p")
20784	     (match_operand:SI 1 "const_int_operand" "n")
20785	     (const_int 3))]
20786  "TARGET_3DNOW && !TARGET_64BIT"
20787{
20788  if (INTVAL (operands[1]) == 0)
20789    return "prefetch\t%a0";
20790  else
20791    return "prefetchw\t%a0";
20792}
20793  [(set_attr "type" "mmx")
20794   (set_attr "memory" "none")])
20795
20796(define_insn "*prefetch_3dnow_rex"
20797  [(prefetch (match_operand:DI 0 "address_operand" "p")
20798	     (match_operand:SI 1 "const_int_operand" "n")
20799	     (const_int 3))]
20800  "TARGET_3DNOW && TARGET_64BIT"
20801{
20802  if (INTVAL (operands[1]) == 0)
20803    return "prefetch\t%a0";
20804  else
20805    return "prefetchw\t%a0";
20806}
20807  [(set_attr "type" "mmx")
20808   (set_attr "memory" "none")])
20809
20810(define_expand "stack_protect_set"
20811  [(match_operand 0 "memory_operand" "")
20812   (match_operand 1 "memory_operand" "")]
20813  ""
20814{
20815#ifdef TARGET_THREAD_SSP_OFFSET
20816  if (TARGET_64BIT)
20817    emit_insn (gen_stack_tls_protect_set_di (operands[0],
20818					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20819  else
20820    emit_insn (gen_stack_tls_protect_set_si (operands[0],
20821					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20822#else
20823  if (TARGET_64BIT)
20824    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20825  else
20826    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20827#endif
20828  DONE;
20829})
20830
20831(define_insn "stack_protect_set_si"
20832  [(set (match_operand:SI 0 "memory_operand" "=m")
20833	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20834   (set (match_scratch:SI 2 "=&r") (const_int 0))
20835   (clobber (reg:CC FLAGS_REG))]
20836  ""
20837  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20838  [(set_attr "type" "multi")])
20839
20840(define_insn "stack_protect_set_di"
20841  [(set (match_operand:DI 0 "memory_operand" "=m")
20842	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20843   (set (match_scratch:DI 2 "=&r") (const_int 0))
20844   (clobber (reg:CC FLAGS_REG))]
20845  "TARGET_64BIT"
20846  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20847  [(set_attr "type" "multi")])
20848
20849(define_insn "stack_tls_protect_set_si"
20850  [(set (match_operand:SI 0 "memory_operand" "=m")
20851	(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20852   (set (match_scratch:SI 2 "=&r") (const_int 0))
20853   (clobber (reg:CC FLAGS_REG))]
20854  ""
20855  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20856  [(set_attr "type" "multi")])
20857
20858(define_insn "stack_tls_protect_set_di"
20859  [(set (match_operand:DI 0 "memory_operand" "=m")
20860	(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20861   (set (match_scratch:DI 2 "=&r") (const_int 0))
20862   (clobber (reg:CC FLAGS_REG))]
20863  "TARGET_64BIT"
20864  {
20865     /* The kernel uses a different segment register for performance reasons; a
20866        system call would not have to trash the userspace segment register,
20867        which would be expensive */
20868     if (ix86_cmodel != CM_KERNEL)
20869        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20870     else
20871        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20872  }
20873  [(set_attr "type" "multi")])
20874
20875(define_expand "stack_protect_test"
20876  [(match_operand 0 "memory_operand" "")
20877   (match_operand 1 "memory_operand" "")
20878   (match_operand 2 "" "")]
20879  ""
20880{
20881  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20882  ix86_compare_op0 = operands[0];
20883  ix86_compare_op1 = operands[1];
20884  ix86_compare_emitted = flags;
20885
20886#ifdef TARGET_THREAD_SSP_OFFSET
20887  if (TARGET_64BIT)
20888    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20889					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20890  else
20891    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20892					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20893#else
20894  if (TARGET_64BIT)
20895    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20896  else
20897    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20898#endif
20899  emit_jump_insn (gen_beq (operands[2]));
20900  DONE;
20901})
20902
20903(define_insn "stack_protect_test_si"
20904  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20905	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20906		     (match_operand:SI 2 "memory_operand" "m")]
20907		    UNSPEC_SP_TEST))
20908   (clobber (match_scratch:SI 3 "=&r"))]
20909  ""
20910  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20911  [(set_attr "type" "multi")])
20912
20913(define_insn "stack_protect_test_di"
20914  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20915	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20916		     (match_operand:DI 2 "memory_operand" "m")]
20917		    UNSPEC_SP_TEST))
20918   (clobber (match_scratch:DI 3 "=&r"))]
20919  "TARGET_64BIT"
20920  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20921  [(set_attr "type" "multi")])
20922
20923(define_insn "stack_tls_protect_test_si"
20924  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20925	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20926		     (match_operand:SI 2 "const_int_operand" "i")]
20927		    UNSPEC_SP_TLS_TEST))
20928   (clobber (match_scratch:SI 3 "=r"))]
20929  ""
20930  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20931  [(set_attr "type" "multi")])
20932
20933(define_insn "stack_tls_protect_test_di"
20934  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20935	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20936		     (match_operand:DI 2 "const_int_operand" "i")]
20937		    UNSPEC_SP_TLS_TEST))
20938   (clobber (match_scratch:DI 3 "=r"))]
20939  "TARGET_64BIT"
20940  {
20941     /* The kernel uses a different segment register for performance reasons; a
20942        system call would not have to trash the userspace segment register,
20943        which would be expensive */
20944     if (ix86_cmodel != CM_KERNEL)
20945        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20946     else
20947        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20948  }
20949  [(set_attr "type" "multi")])
20950
20951(include "sse.md")
20952(include "mmx.md")
20953(include "sync.md")
20954