i386.md revision 171835
1170231Sgrog;; GCC machine description for IA-32 and x86-64.
2170231Sgrog;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3298107Sgjb;; 2001, 2002, 2003, 2004, 2005, 2006
4298107Sgjb;; Free Software Foundation, Inc.
5298107Sgjb;; Mostly by William Schelter.
6263227Sjmmv;; x86_64 support added by Jan Hubicka
7263227Sjmmv;;
8263227Sjmmv;; This file is part of GCC.
9263227Sjmmv;;
10263227Sjmmv;; GCC is free software; you can redistribute it and/or modify
11263227Sjmmv;; it under the terms of the GNU General Public License as published by
12263227Sjmmv;; the Free Software Foundation; either version 2, or (at your option)
13263227Sjmmv;; any later version.
14263227Sjmmv;;
15263227Sjmmv;; GCC is distributed in the hope that it will be useful,
16263227Sjmmv;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17263227Sjmmv;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18263227Sjmmv;; GNU General Public License for more details.
19263227Sjmmv;;
20263227Sjmmv;; You should have received a copy of the GNU General Public License
21263227Sjmmv;; along with GCC; see the file COPYING.  If not, write to
22263227Sjmmv;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23263227Sjmmv;; Boston, MA 02110-1301, USA.  */
24263227Sjmmv;;
25263227Sjmmv;; The original PO technology requires these to be ordered by speed,
26263227Sjmmv;; so that assigner will pick the fastest.
27263227Sjmmv;;
28263227Sjmmv;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29263227Sjmmv;;
30263227Sjmmv;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31263227Sjmmv;; constraint letters.
32263227Sjmmv;;
33263227Sjmmv;; The special asm out single letter directives following a '%' are:
34263227Sjmmv;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35263227Sjmmv;;     operands[1].
36263227Sjmmv;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37263227Sjmmv;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38263227Sjmmv;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39263227Sjmmv;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40263227Sjmmv;; '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,k6,athlon,pentium4,k8,nocona,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
477
478;; Operand and operator predicates and constraints
479
480(include "predicates.md")
481(include "constraints.md")
482
483
484;; Compare instructions.
485
486;; All compare insns have expanders that save the operands away without
487;; actually generating RTL.  The bCOND or sCOND (emitted immediately
488;; after the cmp) will actually emit the cmpM.
489
490(define_expand "cmpti"
491  [(set (reg:CC FLAGS_REG)
492	(compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493		    (match_operand:TI 1 "x86_64_general_operand" "")))]
494  "TARGET_64BIT"
495{
496  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497    operands[0] = force_reg (TImode, operands[0]);
498  ix86_compare_op0 = operands[0];
499  ix86_compare_op1 = operands[1];
500  DONE;
501})
502
503(define_expand "cmpdi"
504  [(set (reg:CC FLAGS_REG)
505	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506		    (match_operand:DI 1 "x86_64_general_operand" "")))]
507  ""
508{
509  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510    operands[0] = force_reg (DImode, operands[0]);
511  ix86_compare_op0 = operands[0];
512  ix86_compare_op1 = operands[1];
513  DONE;
514})
515
516(define_expand "cmpsi"
517  [(set (reg:CC FLAGS_REG)
518	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519		    (match_operand:SI 1 "general_operand" "")))]
520  ""
521{
522  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523    operands[0] = force_reg (SImode, operands[0]);
524  ix86_compare_op0 = operands[0];
525  ix86_compare_op1 = operands[1];
526  DONE;
527})
528
529(define_expand "cmphi"
530  [(set (reg:CC FLAGS_REG)
531	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532		    (match_operand:HI 1 "general_operand" "")))]
533  ""
534{
535  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536    operands[0] = force_reg (HImode, operands[0]);
537  ix86_compare_op0 = operands[0];
538  ix86_compare_op1 = operands[1];
539  DONE;
540})
541
542(define_expand "cmpqi"
543  [(set (reg:CC FLAGS_REG)
544	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545		    (match_operand:QI 1 "general_operand" "")))]
546  "TARGET_QIMODE_MATH"
547{
548  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549    operands[0] = force_reg (QImode, operands[0]);
550  ix86_compare_op0 = operands[0];
551  ix86_compare_op1 = operands[1];
552  DONE;
553})
554
555(define_insn "cmpdi_ccno_1_rex64"
556  [(set (reg FLAGS_REG)
557	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558		 (match_operand:DI 1 "const0_operand" "n,n")))]
559  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560  "@
561   test{q}\t{%0, %0|%0, %0}
562   cmp{q}\t{%1, %0|%0, %1}"
563  [(set_attr "type" "test,icmp")
564   (set_attr "length_immediate" "0,1")
565   (set_attr "mode" "DI")])
566
567(define_insn "*cmpdi_minus_1_rex64"
568  [(set (reg FLAGS_REG)
569	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571		 (const_int 0)))]
572  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573  "cmp{q}\t{%1, %0|%0, %1}"
574  [(set_attr "type" "icmp")
575   (set_attr "mode" "DI")])
576
577(define_expand "cmpdi_1_rex64"
578  [(set (reg:CC FLAGS_REG)
579	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580		    (match_operand:DI 1 "general_operand" "")))]
581  "TARGET_64BIT"
582  "")
583
584(define_insn "cmpdi_1_insn_rex64"
585  [(set (reg FLAGS_REG)
586	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589  "cmp{q}\t{%1, %0|%0, %1}"
590  [(set_attr "type" "icmp")
591   (set_attr "mode" "DI")])
592
593
594(define_insn "*cmpsi_ccno_1"
595  [(set (reg FLAGS_REG)
596	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597		 (match_operand:SI 1 "const0_operand" "n,n")))]
598  "ix86_match_ccmode (insn, CCNOmode)"
599  "@
600   test{l}\t{%0, %0|%0, %0}
601   cmp{l}\t{%1, %0|%0, %1}"
602  [(set_attr "type" "test,icmp")
603   (set_attr "length_immediate" "0,1")
604   (set_attr "mode" "SI")])
605
606(define_insn "*cmpsi_minus_1"
607  [(set (reg FLAGS_REG)
608	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609			   (match_operand:SI 1 "general_operand" "ri,mr"))
610		 (const_int 0)))]
611  "ix86_match_ccmode (insn, CCGOCmode)"
612  "cmp{l}\t{%1, %0|%0, %1}"
613  [(set_attr "type" "icmp")
614   (set_attr "mode" "SI")])
615
616(define_expand "cmpsi_1"
617  [(set (reg:CC FLAGS_REG)
618	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619		    (match_operand:SI 1 "general_operand" "ri,mr")))]
620  ""
621  "")
622
623(define_insn "*cmpsi_1_insn"
624  [(set (reg FLAGS_REG)
625	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626		 (match_operand:SI 1 "general_operand" "ri,mr")))]
627  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628    && ix86_match_ccmode (insn, CCmode)"
629  "cmp{l}\t{%1, %0|%0, %1}"
630  [(set_attr "type" "icmp")
631   (set_attr "mode" "SI")])
632
633(define_insn "*cmphi_ccno_1"
634  [(set (reg FLAGS_REG)
635	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636		 (match_operand:HI 1 "const0_operand" "n,n")))]
637  "ix86_match_ccmode (insn, CCNOmode)"
638  "@
639   test{w}\t{%0, %0|%0, %0}
640   cmp{w}\t{%1, %0|%0, %1}"
641  [(set_attr "type" "test,icmp")
642   (set_attr "length_immediate" "0,1")
643   (set_attr "mode" "HI")])
644
645(define_insn "*cmphi_minus_1"
646  [(set (reg FLAGS_REG)
647	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648			   (match_operand:HI 1 "general_operand" "ri,mr"))
649		 (const_int 0)))]
650  "ix86_match_ccmode (insn, CCGOCmode)"
651  "cmp{w}\t{%1, %0|%0, %1}"
652  [(set_attr "type" "icmp")
653   (set_attr "mode" "HI")])
654
655(define_insn "*cmphi_1"
656  [(set (reg FLAGS_REG)
657	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658		 (match_operand:HI 1 "general_operand" "ri,mr")))]
659  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660   && ix86_match_ccmode (insn, CCmode)"
661  "cmp{w}\t{%1, %0|%0, %1}"
662  [(set_attr "type" "icmp")
663   (set_attr "mode" "HI")])
664
665(define_insn "*cmpqi_ccno_1"
666  [(set (reg FLAGS_REG)
667	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668		 (match_operand:QI 1 "const0_operand" "n,n")))]
669  "ix86_match_ccmode (insn, CCNOmode)"
670  "@
671   test{b}\t{%0, %0|%0, %0}
672   cmp{b}\t{$0, %0|%0, 0}"
673  [(set_attr "type" "test,icmp")
674   (set_attr "length_immediate" "0,1")
675   (set_attr "mode" "QI")])
676
677(define_insn "*cmpqi_1"
678  [(set (reg FLAGS_REG)
679	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680		 (match_operand:QI 1 "general_operand" "qi,mq")))]
681  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682    && ix86_match_ccmode (insn, CCmode)"
683  "cmp{b}\t{%1, %0|%0, %1}"
684  [(set_attr "type" "icmp")
685   (set_attr "mode" "QI")])
686
687(define_insn "*cmpqi_minus_1"
688  [(set (reg FLAGS_REG)
689	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690			   (match_operand:QI 1 "general_operand" "qi,mq"))
691		 (const_int 0)))]
692  "ix86_match_ccmode (insn, CCGOCmode)"
693  "cmp{b}\t{%1, %0|%0, %1}"
694  [(set_attr "type" "icmp")
695   (set_attr "mode" "QI")])
696
697(define_insn "*cmpqi_ext_1"
698  [(set (reg FLAGS_REG)
699	(compare
700	  (match_operand:QI 0 "general_operand" "Qm")
701	  (subreg:QI
702	    (zero_extract:SI
703	      (match_operand 1 "ext_register_operand" "Q")
704	      (const_int 8)
705	      (const_int 8)) 0)))]
706  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707  "cmp{b}\t{%h1, %0|%0, %h1}"
708  [(set_attr "type" "icmp")
709   (set_attr "mode" "QI")])
710
711(define_insn "*cmpqi_ext_1_rex64"
712  [(set (reg FLAGS_REG)
713	(compare
714	  (match_operand:QI 0 "register_operand" "Q")
715	  (subreg:QI
716	    (zero_extract:SI
717	      (match_operand 1 "ext_register_operand" "Q")
718	      (const_int 8)
719	      (const_int 8)) 0)))]
720  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721  "cmp{b}\t{%h1, %0|%0, %h1}"
722  [(set_attr "type" "icmp")
723   (set_attr "mode" "QI")])
724
725(define_insn "*cmpqi_ext_2"
726  [(set (reg FLAGS_REG)
727	(compare
728	  (subreg:QI
729	    (zero_extract:SI
730	      (match_operand 0 "ext_register_operand" "Q")
731	      (const_int 8)
732	      (const_int 8)) 0)
733	  (match_operand:QI 1 "const0_operand" "n")))]
734  "ix86_match_ccmode (insn, CCNOmode)"
735  "test{b}\t%h0, %h0"
736  [(set_attr "type" "test")
737   (set_attr "length_immediate" "0")
738   (set_attr "mode" "QI")])
739
740(define_expand "cmpqi_ext_3"
741  [(set (reg:CC FLAGS_REG)
742	(compare:CC
743	  (subreg:QI
744	    (zero_extract:SI
745	      (match_operand 0 "ext_register_operand" "")
746	      (const_int 8)
747	      (const_int 8)) 0)
748	  (match_operand:QI 1 "general_operand" "")))]
749  ""
750  "")
751
752(define_insn "cmpqi_ext_3_insn"
753  [(set (reg FLAGS_REG)
754	(compare
755	  (subreg:QI
756	    (zero_extract:SI
757	      (match_operand 0 "ext_register_operand" "Q")
758	      (const_int 8)
759	      (const_int 8)) 0)
760	  (match_operand:QI 1 "general_operand" "Qmn")))]
761  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762  "cmp{b}\t{%1, %h0|%h0, %1}"
763  [(set_attr "type" "icmp")
764   (set_attr "mode" "QI")])
765
766(define_insn "cmpqi_ext_3_insn_rex64"
767  [(set (reg FLAGS_REG)
768	(compare
769	  (subreg:QI
770	    (zero_extract:SI
771	      (match_operand 0 "ext_register_operand" "Q")
772	      (const_int 8)
773	      (const_int 8)) 0)
774	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776  "cmp{b}\t{%1, %h0|%h0, %1}"
777  [(set_attr "type" "icmp")
778   (set_attr "mode" "QI")])
779
780(define_insn "*cmpqi_ext_4"
781  [(set (reg FLAGS_REG)
782	(compare
783	  (subreg:QI
784	    (zero_extract:SI
785	      (match_operand 0 "ext_register_operand" "Q")
786	      (const_int 8)
787	      (const_int 8)) 0)
788	  (subreg:QI
789	    (zero_extract:SI
790	      (match_operand 1 "ext_register_operand" "Q")
791	      (const_int 8)
792	      (const_int 8)) 0)))]
793  "ix86_match_ccmode (insn, CCmode)"
794  "cmp{b}\t{%h1, %h0|%h0, %h1}"
795  [(set_attr "type" "icmp")
796   (set_attr "mode" "QI")])
797
798;; These implement float point compares.
799;; %%% See if we can get away with VOIDmode operands on the actual insns,
800;; which would allow mix and match FP modes on the compares.  Which is what
801;; the old patterns did, but with many more of them.
802
803(define_expand "cmpxf"
804  [(set (reg:CC FLAGS_REG)
805	(compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806		    (match_operand:XF 1 "nonmemory_operand" "")))]
807  "TARGET_80387"
808{
809  ix86_compare_op0 = operands[0];
810  ix86_compare_op1 = operands[1];
811  DONE;
812})
813
814(define_expand "cmpdf"
815  [(set (reg:CC FLAGS_REG)
816	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
819{
820  ix86_compare_op0 = operands[0];
821  ix86_compare_op1 = operands[1];
822  DONE;
823})
824
825(define_expand "cmpsf"
826  [(set (reg:CC FLAGS_REG)
827	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829  "TARGET_80387 || TARGET_SSE_MATH"
830{
831  ix86_compare_op0 = operands[0];
832  ix86_compare_op1 = operands[1];
833  DONE;
834})
835
836;; FP compares, step 1:
837;; Set the FP condition codes.
838;;
839;; CCFPmode	compare with exceptions
840;; CCFPUmode	compare with no exceptions
841
842;; We may not use "#" to split and emit these, since the REG_DEAD notes
843;; used to manage the reg stack popping would not be preserved.
844
845(define_insn "*cmpfp_0"
846  [(set (match_operand:HI 0 "register_operand" "=a")
847	(unspec:HI
848	  [(compare:CCFP
849	     (match_operand 1 "register_operand" "f")
850	     (match_operand 2 "const0_operand" "X"))]
851	UNSPEC_FNSTSW))]
852  "TARGET_80387
853   && FLOAT_MODE_P (GET_MODE (operands[1]))
854   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855  "* return output_fp_compare (insn, operands, 0, 0);"
856  [(set_attr "type" "multi")
857   (set_attr "unit" "i387")
858   (set (attr "mode")
859     (cond [(match_operand:SF 1 "" "")
860	      (const_string "SF")
861	    (match_operand:DF 1 "" "")
862	      (const_string "DF")
863	   ]
864	   (const_string "XF")))])
865
866(define_insn "*cmpfp_sf"
867  [(set (match_operand:HI 0 "register_operand" "=a")
868	(unspec:HI
869	  [(compare:CCFP
870	     (match_operand:SF 1 "register_operand" "f")
871	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
872	  UNSPEC_FNSTSW))]
873  "TARGET_80387"
874  "* return output_fp_compare (insn, operands, 0, 0);"
875  [(set_attr "type" "multi")
876   (set_attr "unit" "i387")
877   (set_attr "mode" "SF")])
878
879(define_insn "*cmpfp_df"
880  [(set (match_operand:HI 0 "register_operand" "=a")
881	(unspec:HI
882	  [(compare:CCFP
883	     (match_operand:DF 1 "register_operand" "f")
884	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
885	  UNSPEC_FNSTSW))]
886  "TARGET_80387"
887  "* return output_fp_compare (insn, operands, 0, 0);"
888  [(set_attr "type" "multi")
889   (set_attr "unit" "i387")
890   (set_attr "mode" "DF")])
891
892(define_insn "*cmpfp_xf"
893  [(set (match_operand:HI 0 "register_operand" "=a")
894	(unspec:HI
895	  [(compare:CCFP
896	     (match_operand:XF 1 "register_operand" "f")
897	     (match_operand:XF 2 "register_operand" "f"))]
898	  UNSPEC_FNSTSW))]
899  "TARGET_80387"
900  "* return output_fp_compare (insn, operands, 0, 0);"
901  [(set_attr "type" "multi")
902   (set_attr "unit" "i387")
903   (set_attr "mode" "XF")])
904
905(define_insn "*cmpfp_u"
906  [(set (match_operand:HI 0 "register_operand" "=a")
907	(unspec:HI
908	  [(compare:CCFPU
909	     (match_operand 1 "register_operand" "f")
910	     (match_operand 2 "register_operand" "f"))]
911	  UNSPEC_FNSTSW))]
912  "TARGET_80387
913   && FLOAT_MODE_P (GET_MODE (operands[1]))
914   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915  "* return output_fp_compare (insn, operands, 0, 1);"
916  [(set_attr "type" "multi")
917   (set_attr "unit" "i387")
918   (set (attr "mode")
919     (cond [(match_operand:SF 1 "" "")
920	      (const_string "SF")
921	    (match_operand:DF 1 "" "")
922	      (const_string "DF")
923	   ]
924	   (const_string "XF")))])
925
926(define_insn "*cmpfp_<mode>"
927  [(set (match_operand:HI 0 "register_operand" "=a")
928	(unspec:HI
929	  [(compare:CCFP
930	     (match_operand 1 "register_operand" "f")
931	     (match_operator 3 "float_operator"
932	       [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933	  UNSPEC_FNSTSW))]
934  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935   && FLOAT_MODE_P (GET_MODE (operands[1]))
936   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937  "* return output_fp_compare (insn, operands, 0, 0);"
938  [(set_attr "type" "multi")
939   (set_attr "unit" "i387")
940   (set_attr "fp_int_src" "true")
941   (set_attr "mode" "<MODE>")])
942
943;; FP compares, step 2
944;; Move the fpsw to ax.
945
946(define_insn "x86_fnstsw_1"
947  [(set (match_operand:HI 0 "register_operand" "=a")
948	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
949  "TARGET_80387"
950  "fnstsw\t%0"
951  [(set_attr "length" "2")
952   (set_attr "mode" "SI")
953   (set_attr "unit" "i387")])
954
955;; FP compares, step 3
956;; Get ax into flags, general case.
957
958(define_insn "x86_sahf_1"
959  [(set (reg:CC FLAGS_REG)
960	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
961  "!TARGET_64BIT"
962  "sahf"
963  [(set_attr "length" "1")
964   (set_attr "athlon_decode" "vector")
965   (set_attr "mode" "SI")])
966
967;; Pentium Pro can do steps 1 through 3 in one go.
968
969(define_insn "*cmpfp_i_mixed"
970  [(set (reg:CCFP FLAGS_REG)
971	(compare:CCFP (match_operand 0 "register_operand" "f,x")
972		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
973  "TARGET_MIX_SSE_I387
974   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976  "* return output_fp_compare (insn, operands, 1, 0);"
977  [(set_attr "type" "fcmp,ssecomi")
978   (set (attr "mode")
979     (if_then_else (match_operand:SF 1 "" "")
980        (const_string "SF")
981        (const_string "DF")))
982   (set_attr "athlon_decode" "vector")])
983
984(define_insn "*cmpfp_i_sse"
985  [(set (reg:CCFP FLAGS_REG)
986	(compare:CCFP (match_operand 0 "register_operand" "x")
987		      (match_operand 1 "nonimmediate_operand" "xm")))]
988  "TARGET_SSE_MATH
989   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991  "* return output_fp_compare (insn, operands, 1, 0);"
992  [(set_attr "type" "ssecomi")
993   (set (attr "mode")
994     (if_then_else (match_operand:SF 1 "" "")
995        (const_string "SF")
996        (const_string "DF")))
997   (set_attr "athlon_decode" "vector")])
998
999(define_insn "*cmpfp_i_i387"
1000  [(set (reg:CCFP FLAGS_REG)
1001	(compare:CCFP (match_operand 0 "register_operand" "f")
1002		      (match_operand 1 "register_operand" "f")))]
1003  "TARGET_80387 && TARGET_CMOVE
1004   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005   && FLOAT_MODE_P (GET_MODE (operands[0]))
1006   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007  "* return output_fp_compare (insn, operands, 1, 0);"
1008  [(set_attr "type" "fcmp")
1009   (set (attr "mode")
1010     (cond [(match_operand:SF 1 "" "")
1011	      (const_string "SF")
1012	    (match_operand:DF 1 "" "")
1013	      (const_string "DF")
1014	   ]
1015	   (const_string "XF")))
1016   (set_attr "athlon_decode" "vector")])
1017
1018(define_insn "*cmpfp_iu_mixed"
1019  [(set (reg:CCFPU FLAGS_REG)
1020	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022  "TARGET_MIX_SSE_I387
1023   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025  "* return output_fp_compare (insn, operands, 1, 1);"
1026  [(set_attr "type" "fcmp,ssecomi")
1027   (set (attr "mode")
1028     (if_then_else (match_operand:SF 1 "" "")
1029        (const_string "SF")
1030        (const_string "DF")))
1031   (set_attr "athlon_decode" "vector")])
1032
1033(define_insn "*cmpfp_iu_sse"
1034  [(set (reg:CCFPU FLAGS_REG)
1035	(compare:CCFPU (match_operand 0 "register_operand" "x")
1036		       (match_operand 1 "nonimmediate_operand" "xm")))]
1037  "TARGET_SSE_MATH
1038   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040  "* return output_fp_compare (insn, operands, 1, 1);"
1041  [(set_attr "type" "ssecomi")
1042   (set (attr "mode")
1043     (if_then_else (match_operand:SF 1 "" "")
1044        (const_string "SF")
1045        (const_string "DF")))
1046   (set_attr "athlon_decode" "vector")])
1047
1048(define_insn "*cmpfp_iu_387"
1049  [(set (reg:CCFPU FLAGS_REG)
1050	(compare:CCFPU (match_operand 0 "register_operand" "f")
1051		       (match_operand 1 "register_operand" "f")))]
1052  "TARGET_80387 && TARGET_CMOVE
1053   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054   && FLOAT_MODE_P (GET_MODE (operands[0]))
1055   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056  "* return output_fp_compare (insn, operands, 1, 1);"
1057  [(set_attr "type" "fcmp")
1058   (set (attr "mode")
1059     (cond [(match_operand:SF 1 "" "")
1060	      (const_string "SF")
1061	    (match_operand:DF 1 "" "")
1062	      (const_string "DF")
1063	   ]
1064	   (const_string "XF")))
1065   (set_attr "athlon_decode" "vector")])
1066
1067;; Move instructions.
1068
1069;; General case of fullword move.
1070
1071(define_expand "movsi"
1072  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073	(match_operand:SI 1 "general_operand" ""))]
1074  ""
1075  "ix86_expand_move (SImode, operands); DONE;")
1076
1077;; Push/pop instructions.  They are separate since autoinc/dec is not a
1078;; general_operand.
1079;;
1080;; %%% We don't use a post-inc memory reference because x86 is not a 
1081;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083;; targets without our curiosities, and it is just as easy to represent
1084;; this differently.
1085
1086(define_insn "*pushsi2"
1087  [(set (match_operand:SI 0 "push_operand" "=<")
1088	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1089  "!TARGET_64BIT"
1090  "push{l}\t%1"
1091  [(set_attr "type" "push")
1092   (set_attr "mode" "SI")])
1093
1094;; For 64BIT abi we always round up to 8 bytes.
1095(define_insn "*pushsi2_rex64"
1096  [(set (match_operand:SI 0 "push_operand" "=X")
1097	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1098  "TARGET_64BIT"
1099  "push{q}\t%q1"
1100  [(set_attr "type" "push")
1101   (set_attr "mode" "SI")])
1102
1103(define_insn "*pushsi2_prologue"
1104  [(set (match_operand:SI 0 "push_operand" "=<")
1105	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106   (clobber (mem:BLK (scratch)))]
1107  "!TARGET_64BIT"
1108  "push{l}\t%1"
1109  [(set_attr "type" "push")
1110   (set_attr "mode" "SI")])
1111
1112(define_insn "*popsi1_epilogue"
1113  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114	(mem:SI (reg:SI SP_REG)))
1115   (set (reg:SI SP_REG)
1116	(plus:SI (reg:SI SP_REG) (const_int 4)))
1117   (clobber (mem:BLK (scratch)))]
1118  "!TARGET_64BIT"
1119  "pop{l}\t%0"
1120  [(set_attr "type" "pop")
1121   (set_attr "mode" "SI")])
1122
1123(define_insn "popsi1"
1124  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125	(mem:SI (reg:SI SP_REG)))
1126   (set (reg:SI SP_REG)
1127	(plus:SI (reg:SI SP_REG) (const_int 4)))]
1128  "!TARGET_64BIT"
1129  "pop{l}\t%0"
1130  [(set_attr "type" "pop")
1131   (set_attr "mode" "SI")])
1132
1133(define_insn "*movsi_xor"
1134  [(set (match_operand:SI 0 "register_operand" "=r")
1135	(match_operand:SI 1 "const0_operand" "i"))
1136   (clobber (reg:CC FLAGS_REG))]
1137  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138  "xor{l}\t{%0, %0|%0, %0}"
1139  [(set_attr "type" "alu1")
1140   (set_attr "mode" "SI")
1141   (set_attr "length_immediate" "0")])
1142 
1143(define_insn "*movsi_or"
1144  [(set (match_operand:SI 0 "register_operand" "=r")
1145	(match_operand:SI 1 "immediate_operand" "i"))
1146   (clobber (reg:CC FLAGS_REG))]
1147  "reload_completed
1148   && operands[1] == constm1_rtx
1149   && (TARGET_PENTIUM || optimize_size)"
1150{
1151  operands[1] = constm1_rtx;
1152  return "or{l}\t{%1, %0|%0, %1}";
1153}
1154  [(set_attr "type" "alu1")
1155   (set_attr "mode" "SI")
1156   (set_attr "length_immediate" "1")])
1157
1158(define_insn "*movsi_1"
1159  [(set (match_operand:SI 0 "nonimmediate_operand"
1160			"=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161	(match_operand:SI 1 "general_operand"
1162			"rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1163  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1164{
1165  switch (get_attr_type (insn))
1166    {
1167    case TYPE_SSELOG1:
1168      if (get_attr_mode (insn) == MODE_TI)
1169        return "pxor\t%0, %0";
1170      return "xorps\t%0, %0";
1171
1172    case TYPE_SSEMOV:
1173      switch (get_attr_mode (insn))
1174	{
1175	case MODE_TI:
1176	  return "movdqa\t{%1, %0|%0, %1}";
1177	case MODE_V4SF:
1178	  return "movaps\t{%1, %0|%0, %1}";
1179	case MODE_SI:
1180          return "movd\t{%1, %0|%0, %1}";
1181	case MODE_SF:
1182          return "movss\t{%1, %0|%0, %1}";
1183	default:
1184	  gcc_unreachable ();
1185	}
1186
1187    case TYPE_MMXADD:
1188      return "pxor\t%0, %0";
1189
1190    case TYPE_MMXMOV:
1191      if (get_attr_mode (insn) == MODE_DI)
1192	return "movq\t{%1, %0|%0, %1}";
1193      return "movd\t{%1, %0|%0, %1}";
1194
1195    case TYPE_LEA:
1196      return "lea{l}\t{%1, %0|%0, %1}";
1197
1198    default:
1199      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200      return "mov{l}\t{%1, %0|%0, %1}";
1201    }
1202}
1203  [(set (attr "type")
1204     (cond [(eq_attr "alternative" "2")
1205	      (const_string "mmxadd")
1206	    (eq_attr "alternative" "3,4,5")
1207	      (const_string "mmxmov")
1208	    (eq_attr "alternative" "6")
1209	      (const_string "sselog1")
1210	    (eq_attr "alternative" "7,8,9,10,11")
1211	      (const_string "ssemov")
1212 	    (match_operand:DI 1 "pic_32bit_operand" "")
1213	      (const_string "lea")
1214	   ]
1215	   (const_string "imov")))
1216   (set (attr "mode")
1217     (cond [(eq_attr "alternative" "2,3")
1218	      (const_string "DI")
1219	    (eq_attr "alternative" "6,7")
1220	      (if_then_else
1221	        (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222	        (const_string "V4SF")
1223	        (const_string "TI"))
1224	    (and (eq_attr "alternative" "8,9,10,11")
1225	         (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1226	      (const_string "SF")
1227	   ]
1228	   (const_string "SI")))])
1229
1230;; Stores and loads of ax to arbitrary constant address.
1231;; We fake an second form of instruction to force reload to load address
1232;; into register when rax is not available
1233(define_insn "*movabssi_1_rex64"
1234  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237  "@
1238   movabs{l}\t{%1, %P0|%P0, %1}
1239   mov{l}\t{%1, %a0|%a0, %1}"
1240  [(set_attr "type" "imov")
1241   (set_attr "modrm" "0,*")
1242   (set_attr "length_address" "8,0")
1243   (set_attr "length_immediate" "0,*")
1244   (set_attr "memory" "store")
1245   (set_attr "mode" "SI")])
1246
1247(define_insn "*movabssi_2_rex64"
1248  [(set (match_operand:SI 0 "register_operand" "=a,r")
1249        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251  "@
1252   movabs{l}\t{%P1, %0|%0, %P1}
1253   mov{l}\t{%a1, %0|%0, %a1}"
1254  [(set_attr "type" "imov")
1255   (set_attr "modrm" "0,*")
1256   (set_attr "length_address" "8,0")
1257   (set_attr "length_immediate" "0")
1258   (set_attr "memory" "load")
1259   (set_attr "mode" "SI")])
1260
1261(define_insn "*swapsi"
1262  [(set (match_operand:SI 0 "register_operand" "+r")
1263	(match_operand:SI 1 "register_operand" "+r"))
1264   (set (match_dup 1)
1265	(match_dup 0))]
1266  ""
1267  "xchg{l}\t%1, %0"
1268  [(set_attr "type" "imov")
1269   (set_attr "mode" "SI")
1270   (set_attr "pent_pair" "np")
1271   (set_attr "athlon_decode" "vector")])
1272
1273(define_expand "movhi"
1274  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275        (match_operand:HI 1 "general_operand" ""))]
1276  ""
1277  "ix86_expand_move (HImode, operands); DONE;")
1278
1279(define_insn "*pushhi2"
1280  [(set (match_operand:HI 0 "push_operand" "=X")
1281	(match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1282  "!TARGET_64BIT"
1283  "push{l}\t%k1"
1284  [(set_attr "type" "push")
1285   (set_attr "mode" "SI")])
1286
1287;; For 64BIT abi we always round up to 8 bytes.
1288(define_insn "*pushhi2_rex64"
1289  [(set (match_operand:HI 0 "push_operand" "=X")
1290	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1291  "TARGET_64BIT"
1292  "push{q}\t%q1"
1293  [(set_attr "type" "push")
1294   (set_attr "mode" "DI")])
1295
1296(define_insn "*movhi_1"
1297  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300{
1301  switch (get_attr_type (insn))
1302    {
1303    case TYPE_IMOVX:
1304      /* movzwl is faster than movw on p2 due to partial word stalls,
1305	 though not as fast as an aligned movl.  */
1306      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307    default:
1308      if (get_attr_mode (insn) == MODE_SI)
1309        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310      else
1311        return "mov{w}\t{%1, %0|%0, %1}";
1312    }
1313}
1314  [(set (attr "type")
1315     (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316	      (const_string "imov")
1317	    (and (eq_attr "alternative" "0")
1318		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319			  (const_int 0))
1320		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1321			  (const_int 0))))
1322	      (const_string "imov")
1323	    (and (eq_attr "alternative" "1,2")
1324		 (match_operand:HI 1 "aligned_operand" ""))
1325	      (const_string "imov")
1326	    (and (ne (symbol_ref "TARGET_MOVX")
1327		     (const_int 0))
1328		 (eq_attr "alternative" "0,2"))
1329	      (const_string "imovx")
1330	   ]
1331	   (const_string "imov")))
1332    (set (attr "mode")
1333      (cond [(eq_attr "type" "imovx")
1334	       (const_string "SI")
1335	     (and (eq_attr "alternative" "1,2")
1336		  (match_operand:HI 1 "aligned_operand" ""))
1337	       (const_string "SI")
1338	     (and (eq_attr "alternative" "0")
1339		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340			   (const_int 0))
1341		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1342			   (const_int 0))))
1343	       (const_string "SI")
1344	    ]
1345	    (const_string "HI")))])
1346
1347;; Stores and loads of ax to arbitrary constant address.
1348;; We fake an second form of instruction to force reload to load address
1349;; into register when rax is not available
1350(define_insn "*movabshi_1_rex64"
1351  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354  "@
1355   movabs{w}\t{%1, %P0|%P0, %1}
1356   mov{w}\t{%1, %a0|%a0, %1}"
1357  [(set_attr "type" "imov")
1358   (set_attr "modrm" "0,*")
1359   (set_attr "length_address" "8,0")
1360   (set_attr "length_immediate" "0,*")
1361   (set_attr "memory" "store")
1362   (set_attr "mode" "HI")])
1363
1364(define_insn "*movabshi_2_rex64"
1365  [(set (match_operand:HI 0 "register_operand" "=a,r")
1366        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368  "@
1369   movabs{w}\t{%P1, %0|%0, %P1}
1370   mov{w}\t{%a1, %0|%0, %a1}"
1371  [(set_attr "type" "imov")
1372   (set_attr "modrm" "0,*")
1373   (set_attr "length_address" "8,0")
1374   (set_attr "length_immediate" "0")
1375   (set_attr "memory" "load")
1376   (set_attr "mode" "HI")])
1377
1378(define_insn "*swaphi_1"
1379  [(set (match_operand:HI 0 "register_operand" "+r")
1380	(match_operand:HI 1 "register_operand" "+r"))
1381   (set (match_dup 1)
1382	(match_dup 0))]
1383  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384  "xchg{l}\t%k1, %k0"
1385  [(set_attr "type" "imov")
1386   (set_attr "mode" "SI")
1387   (set_attr "pent_pair" "np")
1388   (set_attr "athlon_decode" "vector")])
1389
1390(define_insn "*swaphi_2"
1391  [(set (match_operand:HI 0 "register_operand" "+r")
1392	(match_operand:HI 1 "register_operand" "+r"))
1393   (set (match_dup 1)
1394	(match_dup 0))]
1395  "TARGET_PARTIAL_REG_STALL"
1396  "xchg{w}\t%1, %0"
1397  [(set_attr "type" "imov")
1398   (set_attr "mode" "HI")
1399   (set_attr "pent_pair" "np")
1400   (set_attr "athlon_decode" "vector")])
1401
1402(define_expand "movstricthi"
1403  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404	(match_operand:HI 1 "general_operand" ""))]
1405  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406{
1407  /* Don't generate memory->memory moves, go through a register */
1408  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409    operands[1] = force_reg (HImode, operands[1]);
1410})
1411
1412(define_insn "*movstricthi_1"
1413  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414	(match_operand:HI 1 "general_operand" "rn,m"))]
1415  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417  "mov{w}\t{%1, %0|%0, %1}"
1418  [(set_attr "type" "imov")
1419   (set_attr "mode" "HI")])
1420
1421(define_insn "*movstricthi_xor"
1422  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423	(match_operand:HI 1 "const0_operand" "i"))
1424   (clobber (reg:CC FLAGS_REG))]
1425  "reload_completed
1426   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427  "xor{w}\t{%0, %0|%0, %0}"
1428  [(set_attr "type" "alu1")
1429   (set_attr "mode" "HI")
1430   (set_attr "length_immediate" "0")])
1431
1432(define_expand "movqi"
1433  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434	(match_operand:QI 1 "general_operand" ""))]
1435  ""
1436  "ix86_expand_move (QImode, operands); DONE;")
1437
1438;; emit_push_insn when it calls move_by_pieces requires an insn to
1439;; "push a byte".  But actually we use pushl, which has the effect
1440;; of rounding the amount pushed up to a word.
1441
1442(define_insn "*pushqi2"
1443  [(set (match_operand:QI 0 "push_operand" "=X")
1444	(match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1445  "!TARGET_64BIT"
1446  "push{l}\t%k1"
1447  [(set_attr "type" "push")
1448   (set_attr "mode" "SI")])
1449
1450;; For 64BIT abi we always round up to 8 bytes.
1451(define_insn "*pushqi2_rex64"
1452  [(set (match_operand:QI 0 "push_operand" "=X")
1453	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454  "TARGET_64BIT"
1455  "push{q}\t%q1"
1456  [(set_attr "type" "push")
1457   (set_attr "mode" "DI")])
1458
1459;; Situation is quite tricky about when to choose full sized (SImode) move
1460;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1461;; partial register dependency machines (such as AMD Athlon), where QImode
1462;; moves issue extra dependency and for partial register stalls machines
1463;; that don't use QImode patterns (and QImode move cause stall on the next
1464;; instruction).
1465;;
1466;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467;; register stall machines with, where we use QImode instructions, since
1468;; partial register stall can be caused there.  Then we use movzx.
1469(define_insn "*movqi_1"
1470  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1472  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473{
1474  switch (get_attr_type (insn))
1475    {
1476    case TYPE_IMOVX:
1477      gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479    default:
1480      if (get_attr_mode (insn) == MODE_SI)
1481        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482      else
1483        return "mov{b}\t{%1, %0|%0, %1}";
1484    }
1485}
1486  [(set (attr "type")
1487     (cond [(and (eq_attr "alternative" "5")
1488		 (not (match_operand:QI 1 "aligned_operand" "")))
1489	      (const_string "imovx")
1490	    (ne (symbol_ref "optimize_size") (const_int 0))
1491	      (const_string "imov")
1492	    (and (eq_attr "alternative" "3")
1493		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494			  (const_int 0))
1495		      (eq (symbol_ref "TARGET_QIMODE_MATH")
1496			  (const_int 0))))
1497	      (const_string "imov")
1498	    (eq_attr "alternative" "3,5")
1499	      (const_string "imovx")
1500	    (and (ne (symbol_ref "TARGET_MOVX")
1501		     (const_int 0))
1502		 (eq_attr "alternative" "2"))
1503	      (const_string "imovx")
1504	   ]
1505	   (const_string "imov")))
1506   (set (attr "mode")
1507      (cond [(eq_attr "alternative" "3,4,5")
1508	       (const_string "SI")
1509	     (eq_attr "alternative" "6")
1510	       (const_string "QI")
1511	     (eq_attr "type" "imovx")
1512	       (const_string "SI")
1513	     (and (eq_attr "type" "imov")
1514		  (and (eq_attr "alternative" "0,1")
1515		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516				(const_int 0))
1517			    (and (eq (symbol_ref "optimize_size")
1518				     (const_int 0))
1519			    	 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520				     (const_int 0))))))
1521	       (const_string "SI")
1522	     ;; Avoid partial register stalls when not using QImode arithmetic
1523	     (and (eq_attr "type" "imov")
1524		  (and (eq_attr "alternative" "0,1")
1525		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526				(const_int 0))
1527			    (eq (symbol_ref "TARGET_QIMODE_MATH")
1528				(const_int 0)))))
1529	       (const_string "SI")
1530	   ]
1531	   (const_string "QI")))])
1532
1533(define_expand "reload_outqi"
1534  [(parallel [(match_operand:QI 0 "" "=m")
1535              (match_operand:QI 1 "register_operand" "r")
1536              (match_operand:QI 2 "register_operand" "=&q")])]
1537  ""
1538{
1539  rtx op0, op1, op2;
1540  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541
1542  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543  if (! q_regs_operand (op1, QImode))
1544    {
1545      emit_insn (gen_movqi (op2, op1));
1546      op1 = op2;
1547    }
1548  emit_insn (gen_movqi (op0, op1));
1549  DONE;
1550})
1551
1552(define_insn "*swapqi_1"
1553  [(set (match_operand:QI 0 "register_operand" "+r")
1554	(match_operand:QI 1 "register_operand" "+r"))
1555   (set (match_dup 1)
1556	(match_dup 0))]
1557  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558  "xchg{l}\t%k1, %k0"
1559  [(set_attr "type" "imov")
1560   (set_attr "mode" "SI")
1561   (set_attr "pent_pair" "np")
1562   (set_attr "athlon_decode" "vector")])
1563
1564(define_insn "*swapqi_2"
1565  [(set (match_operand:QI 0 "register_operand" "+q")
1566	(match_operand:QI 1 "register_operand" "+q"))
1567   (set (match_dup 1)
1568	(match_dup 0))]
1569  "TARGET_PARTIAL_REG_STALL"
1570  "xchg{b}\t%1, %0"
1571  [(set_attr "type" "imov")
1572   (set_attr "mode" "QI")
1573   (set_attr "pent_pair" "np")
1574   (set_attr "athlon_decode" "vector")])
1575
1576(define_expand "movstrictqi"
1577  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578	(match_operand:QI 1 "general_operand" ""))]
1579  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1580{
1581  /* Don't generate memory->memory moves, go through a register.  */
1582  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583    operands[1] = force_reg (QImode, operands[1]);
1584})
1585
1586(define_insn "*movstrictqi_1"
1587  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588	(match_operand:QI 1 "general_operand" "*qn,m"))]
1589  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591  "mov{b}\t{%1, %0|%0, %1}"
1592  [(set_attr "type" "imov")
1593   (set_attr "mode" "QI")])
1594
1595(define_insn "*movstrictqi_xor"
1596  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597	(match_operand:QI 1 "const0_operand" "i"))
1598   (clobber (reg:CC FLAGS_REG))]
1599  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600  "xor{b}\t{%0, %0|%0, %0}"
1601  [(set_attr "type" "alu1")
1602   (set_attr "mode" "QI")
1603   (set_attr "length_immediate" "0")])
1604
1605(define_insn "*movsi_extv_1"
1606  [(set (match_operand:SI 0 "register_operand" "=R")
1607	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608			 (const_int 8)
1609			 (const_int 8)))]
1610  ""
1611  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612  [(set_attr "type" "imovx")
1613   (set_attr "mode" "SI")])
1614
1615(define_insn "*movhi_extv_1"
1616  [(set (match_operand:HI 0 "register_operand" "=R")
1617	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618			 (const_int 8)
1619			 (const_int 8)))]
1620  ""
1621  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622  [(set_attr "type" "imovx")
1623   (set_attr "mode" "SI")])
1624
1625(define_insn "*movqi_extv_1"
1626  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1628                         (const_int 8)
1629                         (const_int 8)))]
1630  "!TARGET_64BIT"
1631{
1632  switch (get_attr_type (insn))
1633    {
1634    case TYPE_IMOVX:
1635      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636    default:
1637      return "mov{b}\t{%h1, %0|%0, %h1}";
1638    }
1639}
1640  [(set (attr "type")
1641     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643			     (ne (symbol_ref "TARGET_MOVX")
1644				 (const_int 0))))
1645	(const_string "imovx")
1646	(const_string "imov")))
1647   (set (attr "mode")
1648     (if_then_else (eq_attr "type" "imovx")
1649	(const_string "SI")
1650	(const_string "QI")))])
1651
1652(define_insn "*movqi_extv_1_rex64"
1653  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655                         (const_int 8)
1656                         (const_int 8)))]
1657  "TARGET_64BIT"
1658{
1659  switch (get_attr_type (insn))
1660    {
1661    case TYPE_IMOVX:
1662      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663    default:
1664      return "mov{b}\t{%h1, %0|%0, %h1}";
1665    }
1666}
1667  [(set (attr "type")
1668     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670			     (ne (symbol_ref "TARGET_MOVX")
1671				 (const_int 0))))
1672	(const_string "imovx")
1673	(const_string "imov")))
1674   (set (attr "mode")
1675     (if_then_else (eq_attr "type" "imovx")
1676	(const_string "SI")
1677	(const_string "QI")))])
1678
1679;; Stores and loads of ax to arbitrary constant address.
1680;; We fake an second form of instruction to force reload to load address
1681;; into register when rax is not available
1682(define_insn "*movabsqi_1_rex64"
1683  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686  "@
1687   movabs{b}\t{%1, %P0|%P0, %1}
1688   mov{b}\t{%1, %a0|%a0, %1}"
1689  [(set_attr "type" "imov")
1690   (set_attr "modrm" "0,*")
1691   (set_attr "length_address" "8,0")
1692   (set_attr "length_immediate" "0,*")
1693   (set_attr "memory" "store")
1694   (set_attr "mode" "QI")])
1695
1696(define_insn "*movabsqi_2_rex64"
1697  [(set (match_operand:QI 0 "register_operand" "=a,r")
1698        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700  "@
1701   movabs{b}\t{%P1, %0|%0, %P1}
1702   mov{b}\t{%a1, %0|%0, %a1}"
1703  [(set_attr "type" "imov")
1704   (set_attr "modrm" "0,*")
1705   (set_attr "length_address" "8,0")
1706   (set_attr "length_immediate" "0")
1707   (set_attr "memory" "load")
1708   (set_attr "mode" "QI")])
1709
1710(define_insn "*movdi_extzv_1"
1711  [(set (match_operand:DI 0 "register_operand" "=R")
1712	(zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713			 (const_int 8)
1714			 (const_int 8)))]
1715  "TARGET_64BIT"
1716  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717  [(set_attr "type" "imovx")
1718   (set_attr "mode" "DI")])
1719
1720(define_insn "*movsi_extzv_1"
1721  [(set (match_operand:SI 0 "register_operand" "=R")
1722	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723			 (const_int 8)
1724			 (const_int 8)))]
1725  ""
1726  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727  [(set_attr "type" "imovx")
1728   (set_attr "mode" "SI")])
1729
1730(define_insn "*movqi_extzv_2"
1731  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733				    (const_int 8)
1734				    (const_int 8)) 0))]
1735  "!TARGET_64BIT"
1736{
1737  switch (get_attr_type (insn))
1738    {
1739    case TYPE_IMOVX:
1740      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741    default:
1742      return "mov{b}\t{%h1, %0|%0, %h1}";
1743    }
1744}
1745  [(set (attr "type")
1746     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748			     (ne (symbol_ref "TARGET_MOVX")
1749				 (const_int 0))))
1750	(const_string "imovx")
1751	(const_string "imov")))
1752   (set (attr "mode")
1753     (if_then_else (eq_attr "type" "imovx")
1754	(const_string "SI")
1755	(const_string "QI")))])
1756
1757(define_insn "*movqi_extzv_2_rex64"
1758  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760				    (const_int 8)
1761				    (const_int 8)) 0))]
1762  "TARGET_64BIT"
1763{
1764  switch (get_attr_type (insn))
1765    {
1766    case TYPE_IMOVX:
1767      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768    default:
1769      return "mov{b}\t{%h1, %0|%0, %h1}";
1770    }
1771}
1772  [(set (attr "type")
1773     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774			(ne (symbol_ref "TARGET_MOVX")
1775			    (const_int 0)))
1776	(const_string "imovx")
1777	(const_string "imov")))
1778   (set (attr "mode")
1779     (if_then_else (eq_attr "type" "imovx")
1780	(const_string "SI")
1781	(const_string "QI")))])
1782
1783(define_insn "movsi_insv_1"
1784  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785			 (const_int 8)
1786			 (const_int 8))
1787	(match_operand:SI 1 "general_operand" "Qmn"))]
1788  "!TARGET_64BIT"
1789  "mov{b}\t{%b1, %h0|%h0, %b1}"
1790  [(set_attr "type" "imov")
1791   (set_attr "mode" "QI")])
1792
1793(define_insn "movdi_insv_1_rex64"
1794  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1795			 (const_int 8)
1796			 (const_int 8))
1797	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798  "TARGET_64BIT"
1799  "mov{b}\t{%b1, %h0|%h0, %b1}"
1800  [(set_attr "type" "imov")
1801   (set_attr "mode" "QI")])
1802
1803(define_insn "*movqi_insv_2"
1804  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805			 (const_int 8)
1806			 (const_int 8))
1807	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808		     (const_int 8)))]
1809  ""
1810  "mov{b}\t{%h1, %h0|%h0, %h1}"
1811  [(set_attr "type" "imov")
1812   (set_attr "mode" "QI")])
1813
1814(define_expand "movdi"
1815  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816	(match_operand:DI 1 "general_operand" ""))]
1817  ""
1818  "ix86_expand_move (DImode, operands); DONE;")
1819
1820(define_insn "*pushdi"
1821  [(set (match_operand:DI 0 "push_operand" "=<")
1822	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823  "!TARGET_64BIT"
1824  "#")
1825
1826(define_insn "*pushdi2_rex64"
1827  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1829  "TARGET_64BIT"
1830  "@
1831   push{q}\t%1
1832   #"
1833  [(set_attr "type" "push,multi")
1834   (set_attr "mode" "DI")])
1835
1836;; Convert impossible pushes of immediate to existing instructions.
1837;; First try to get scratch register and go through it.  In case this
1838;; fails, push sign extended lower part first and then overwrite
1839;; upper part by 32bit move.
1840(define_peephole2
1841  [(match_scratch:DI 2 "r")
1842   (set (match_operand:DI 0 "push_operand" "")
1843        (match_operand:DI 1 "immediate_operand" ""))]
1844  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845   && !x86_64_immediate_operand (operands[1], DImode)"
1846  [(set (match_dup 2) (match_dup 1))
1847   (set (match_dup 0) (match_dup 2))]
1848  "")
1849
1850;; We need to define this as both peepholer and splitter for case
1851;; peephole2 pass is not run.
1852;; "&& 1" is needed to keep it from matching the previous pattern.
1853(define_peephole2
1854  [(set (match_operand:DI 0 "push_operand" "")
1855        (match_operand:DI 1 "immediate_operand" ""))]
1856  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858  [(set (match_dup 0) (match_dup 1))
1859   (set (match_dup 2) (match_dup 3))]
1860  "split_di (operands + 1, 1, operands + 2, operands + 3);
1861   operands[1] = gen_lowpart (DImode, operands[2]);
1862   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863						    GEN_INT (4)));
1864  ")
1865
1866(define_split
1867  [(set (match_operand:DI 0 "push_operand" "")
1868        (match_operand:DI 1 "immediate_operand" ""))]
1869  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870		    ? flow2_completed : reload_completed)
1871   && !symbolic_operand (operands[1], DImode)
1872   && !x86_64_immediate_operand (operands[1], DImode)"
1873  [(set (match_dup 0) (match_dup 1))
1874   (set (match_dup 2) (match_dup 3))]
1875  "split_di (operands + 1, 1, operands + 2, operands + 3);
1876   operands[1] = gen_lowpart (DImode, operands[2]);
1877   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878						    GEN_INT (4)));
1879  ")
1880
1881(define_insn "*pushdi2_prologue_rex64"
1882  [(set (match_operand:DI 0 "push_operand" "=<")
1883	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884   (clobber (mem:BLK (scratch)))]
1885  "TARGET_64BIT"
1886  "push{q}\t%1"
1887  [(set_attr "type" "push")
1888   (set_attr "mode" "DI")])
1889
1890(define_insn "*popdi1_epilogue_rex64"
1891  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892	(mem:DI (reg:DI SP_REG)))
1893   (set (reg:DI SP_REG)
1894	(plus:DI (reg:DI SP_REG) (const_int 8)))
1895   (clobber (mem:BLK (scratch)))]
1896  "TARGET_64BIT"
1897  "pop{q}\t%0"
1898  [(set_attr "type" "pop")
1899   (set_attr "mode" "DI")])
1900
1901(define_insn "popdi1"
1902  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903	(mem:DI (reg:DI SP_REG)))
1904   (set (reg:DI SP_REG)
1905	(plus:DI (reg:DI SP_REG) (const_int 8)))]
1906  "TARGET_64BIT"
1907  "pop{q}\t%0"
1908  [(set_attr "type" "pop")
1909   (set_attr "mode" "DI")])
1910
1911(define_insn "*movdi_xor_rex64"
1912  [(set (match_operand:DI 0 "register_operand" "=r")
1913	(match_operand:DI 1 "const0_operand" "i"))
1914   (clobber (reg:CC FLAGS_REG))]
1915  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916   && reload_completed"
1917  "xor{l}\t{%k0, %k0|%k0, %k0}"
1918  [(set_attr "type" "alu1")
1919   (set_attr "mode" "SI")
1920   (set_attr "length_immediate" "0")])
1921
1922(define_insn "*movdi_or_rex64"
1923  [(set (match_operand:DI 0 "register_operand" "=r")
1924	(match_operand:DI 1 "const_int_operand" "i"))
1925   (clobber (reg:CC FLAGS_REG))]
1926  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927   && reload_completed
1928   && operands[1] == constm1_rtx"
1929{
1930  operands[1] = constm1_rtx;
1931  return "or{q}\t{%1, %0|%0, %1}";
1932}
1933  [(set_attr "type" "alu1")
1934   (set_attr "mode" "DI")
1935   (set_attr "length_immediate" "1")])
1936
1937(define_insn "*movdi_2"
1938  [(set (match_operand:DI 0 "nonimmediate_operand"
1939				"=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940	(match_operand:DI 1 "general_operand"
1941				"riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943  "@
1944   #
1945   #
1946   pxor\t%0, %0
1947   movq\t{%1, %0|%0, %1}
1948   movq\t{%1, %0|%0, %1}
1949   pxor\t%0, %0
1950   movq\t{%1, %0|%0, %1}
1951   movdqa\t{%1, %0|%0, %1}
1952   movq\t{%1, %0|%0, %1}
1953   xorps\t%0, %0
1954   movlps\t{%1, %0|%0, %1}
1955   movaps\t{%1, %0|%0, %1}
1956   movlps\t{%1, %0|%0, %1}"
1957  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1959
1960(define_split
1961  [(set (match_operand:DI 0 "push_operand" "")
1962        (match_operand:DI 1 "general_operand" ""))]
1963  "!TARGET_64BIT && reload_completed
1964   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965  [(const_int 0)]
1966  "ix86_split_long_move (operands); DONE;")
1967
1968;; %%% This multiword shite has got to go.
1969(define_split
1970  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971        (match_operand:DI 1 "general_operand" ""))]
1972  "!TARGET_64BIT && reload_completed
1973   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975  [(const_int 0)]
1976  "ix86_split_long_move (operands); DONE;")
1977
1978(define_insn "*movdi_1_rex64"
1979  [(set (match_operand:DI 0 "nonimmediate_operand"
1980		"=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981	(match_operand:DI 1 "general_operand"
1982		"Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984{
1985  switch (get_attr_type (insn))
1986    {
1987    case TYPE_SSECVT:
1988      if (which_alternative == 13)
1989	return "movq2dq\t{%1, %0|%0, %1}";
1990      else
1991	return "movdq2q\t{%1, %0|%0, %1}";
1992    case TYPE_SSEMOV:
1993      if (get_attr_mode (insn) == MODE_TI)
1994	  return "movdqa\t{%1, %0|%0, %1}";
1995      /* FALLTHRU */
1996    case TYPE_MMXMOV:
1997      /* Moves from and into integer register is done using movd opcode with
1998 	 REX prefix.  */
1999      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000	  return "movd\t{%1, %0|%0, %1}";
2001      return "movq\t{%1, %0|%0, %1}";
2002    case TYPE_SSELOG1:
2003    case TYPE_MMXADD:
2004      return "pxor\t%0, %0";
2005    case TYPE_MULTI:
2006      return "#";
2007    case TYPE_LEA:
2008      return "lea{q}\t{%a1, %0|%0, %a1}";
2009    default:
2010      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011      if (get_attr_mode (insn) == MODE_SI)
2012	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013      else if (which_alternative == 2)
2014	return "movabs{q}\t{%1, %0|%0, %1}";
2015      else
2016	return "mov{q}\t{%1, %0|%0, %1}";
2017    }
2018}
2019  [(set (attr "type")
2020     (cond [(eq_attr "alternative" "5")
2021	      (const_string "mmxadd")
2022	    (eq_attr "alternative" "6,7,8")
2023	      (const_string "mmxmov")
2024	    (eq_attr "alternative" "9")
2025	      (const_string "sselog1")
2026	    (eq_attr "alternative" "10,11,12")
2027	      (const_string "ssemov")
2028	    (eq_attr "alternative" "13,14")
2029	      (const_string "ssecvt")
2030	    (eq_attr "alternative" "4")
2031	      (const_string "multi")
2032 	    (match_operand:DI 1 "pic_32bit_operand" "")
2033	      (const_string "lea")
2034	   ]
2035	   (const_string "imov")))
2036   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2039
2040;; Stores and loads of ax to arbitrary constant address.
2041;; We fake an second form of instruction to force reload to load address
2042;; into register when rax is not available
2043(define_insn "*movabsdi_1_rex64"
2044  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047  "@
2048   movabs{q}\t{%1, %P0|%P0, %1}
2049   mov{q}\t{%1, %a0|%a0, %1}"
2050  [(set_attr "type" "imov")
2051   (set_attr "modrm" "0,*")
2052   (set_attr "length_address" "8,0")
2053   (set_attr "length_immediate" "0,*")
2054   (set_attr "memory" "store")
2055   (set_attr "mode" "DI")])
2056
2057(define_insn "*movabsdi_2_rex64"
2058  [(set (match_operand:DI 0 "register_operand" "=a,r")
2059        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061  "@
2062   movabs{q}\t{%P1, %0|%0, %P1}
2063   mov{q}\t{%a1, %0|%0, %a1}"
2064  [(set_attr "type" "imov")
2065   (set_attr "modrm" "0,*")
2066   (set_attr "length_address" "8,0")
2067   (set_attr "length_immediate" "0")
2068   (set_attr "memory" "load")
2069   (set_attr "mode" "DI")])
2070
2071;; Convert impossible stores of immediate to existing instructions.
2072;; First try to get scratch register and go through it.  In case this
2073;; fails, move by 32bit parts.
2074(define_peephole2
2075  [(match_scratch:DI 2 "r")
2076   (set (match_operand:DI 0 "memory_operand" "")
2077        (match_operand:DI 1 "immediate_operand" ""))]
2078  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079   && !x86_64_immediate_operand (operands[1], DImode)"
2080  [(set (match_dup 2) (match_dup 1))
2081   (set (match_dup 0) (match_dup 2))]
2082  "")
2083
2084;; We need to define this as both peepholer and splitter for case
2085;; peephole2 pass is not run.
2086;; "&& 1" is needed to keep it from matching the previous pattern.
2087(define_peephole2
2088  [(set (match_operand:DI 0 "memory_operand" "")
2089        (match_operand:DI 1 "immediate_operand" ""))]
2090  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092  [(set (match_dup 2) (match_dup 3))
2093   (set (match_dup 4) (match_dup 5))]
2094  "split_di (operands, 2, operands + 2, operands + 4);")
2095
2096(define_split
2097  [(set (match_operand:DI 0 "memory_operand" "")
2098        (match_operand:DI 1 "immediate_operand" ""))]
2099  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100		    ? flow2_completed : reload_completed)
2101   && !symbolic_operand (operands[1], DImode)
2102   && !x86_64_immediate_operand (operands[1], DImode)"
2103  [(set (match_dup 2) (match_dup 3))
2104   (set (match_dup 4) (match_dup 5))]
2105  "split_di (operands, 2, operands + 2, operands + 4);")
2106
2107(define_insn "*swapdi_rex64"
2108  [(set (match_operand:DI 0 "register_operand" "+r")
2109	(match_operand:DI 1 "register_operand" "+r"))
2110   (set (match_dup 1)
2111	(match_dup 0))]
2112  "TARGET_64BIT"
2113  "xchg{q}\t%1, %0"
2114  [(set_attr "type" "imov")
2115   (set_attr "mode" "DI")
2116   (set_attr "pent_pair" "np")
2117   (set_attr "athlon_decode" "vector")])
2118
2119(define_expand "movti"
2120  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121	(match_operand:TI 1 "nonimmediate_operand" ""))]
2122  "TARGET_SSE || TARGET_64BIT"
2123{
2124  if (TARGET_64BIT)
2125    ix86_expand_move (TImode, operands);
2126  else
2127    ix86_expand_vector_move (TImode, operands);
2128  DONE;
2129})
2130
2131(define_insn "*movti_internal"
2132  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134  "TARGET_SSE && !TARGET_64BIT
2135   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2136{
2137  switch (which_alternative)
2138    {
2139    case 0:
2140      if (get_attr_mode (insn) == MODE_V4SF)
2141	return "xorps\t%0, %0";
2142      else
2143	return "pxor\t%0, %0";
2144    case 1:
2145    case 2:
2146      if (get_attr_mode (insn) == MODE_V4SF)
2147	return "movaps\t{%1, %0|%0, %1}";
2148      else
2149	return "movdqa\t{%1, %0|%0, %1}";
2150    default:
2151      gcc_unreachable ();
2152    }
2153}
2154  [(set_attr "type" "sselog1,ssemov,ssemov")
2155   (set (attr "mode")
2156	(cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157		    (ne (symbol_ref "optimize_size") (const_int 0)))
2158		 (const_string "V4SF")
2159	       (and (eq_attr "alternative" "2")
2160		    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161			(const_int 0)))
2162		 (const_string "V4SF")]
2163	      (const_string "TI")))])
2164
2165(define_insn "*movti_rex64"
2166  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168  "TARGET_64BIT
2169   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170{
2171  switch (which_alternative)
2172    {
2173    case 0:
2174    case 1:
2175      return "#";
2176    case 2:
2177      if (get_attr_mode (insn) == MODE_V4SF)
2178	return "xorps\t%0, %0";
2179      else
2180	return "pxor\t%0, %0";
2181    case 3:
2182    case 4:
2183      if (get_attr_mode (insn) == MODE_V4SF)
2184	return "movaps\t{%1, %0|%0, %1}";
2185      else
2186	return "movdqa\t{%1, %0|%0, %1}";
2187    default:
2188      gcc_unreachable ();
2189    }
2190}
2191  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192   (set (attr "mode")
2193        (cond [(eq_attr "alternative" "2,3")
2194		 (if_then_else
2195		   (ne (symbol_ref "optimize_size")
2196		       (const_int 0))
2197		   (const_string "V4SF")
2198		   (const_string "TI"))
2199	       (eq_attr "alternative" "4")
2200		 (if_then_else
2201		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202			    (const_int 0))
2203			(ne (symbol_ref "optimize_size")
2204			    (const_int 0)))
2205		   (const_string "V4SF")
2206		   (const_string "TI"))]
2207	       (const_string "DI")))])
2208
2209(define_split
2210  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211        (match_operand:TI 1 "general_operand" ""))]
2212  "reload_completed && !SSE_REG_P (operands[0])
2213   && !SSE_REG_P (operands[1])"
2214  [(const_int 0)]
2215  "ix86_split_long_move (operands); DONE;")
2216
2217(define_expand "movsf"
2218  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219	(match_operand:SF 1 "general_operand" ""))]
2220  ""
2221  "ix86_expand_move (SFmode, operands); DONE;")
2222
2223(define_insn "*pushsf"
2224  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2226  "!TARGET_64BIT"
2227{
2228  /* Anything else should be already split before reg-stack.  */
2229  gcc_assert (which_alternative == 1);
2230  return "push{l}\t%1";
2231}
2232  [(set_attr "type" "multi,push,multi")
2233   (set_attr "unit" "i387,*,*")
2234   (set_attr "mode" "SF,SI,SF")])
2235
2236(define_insn "*pushsf_rex64"
2237  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2239  "TARGET_64BIT"
2240{
2241  /* Anything else should be already split before reg-stack.  */
2242  gcc_assert (which_alternative == 1);
2243  return "push{q}\t%q1";
2244}
2245  [(set_attr "type" "multi,push,multi")
2246   (set_attr "unit" "i387,*,*")
2247   (set_attr "mode" "SF,DI,SF")])
2248
2249(define_split
2250  [(set (match_operand:SF 0 "push_operand" "")
2251	(match_operand:SF 1 "memory_operand" ""))]
2252  "reload_completed
2253   && GET_CODE (operands[1]) == MEM
2254   && constant_pool_reference_p (operands[1])"
2255  [(set (match_dup 0)
2256	(match_dup 1))]
2257  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2258
2259
2260;; %%% Kill this when call knows how to work this out.
2261(define_split
2262  [(set (match_operand:SF 0 "push_operand" "")
2263	(match_operand:SF 1 "any_fp_register_operand" ""))]
2264  "!TARGET_64BIT"
2265  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2267
2268(define_split
2269  [(set (match_operand:SF 0 "push_operand" "")
2270	(match_operand:SF 1 "any_fp_register_operand" ""))]
2271  "TARGET_64BIT"
2272  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274
2275(define_insn "*movsf_1"
2276  [(set (match_operand:SF 0 "nonimmediate_operand"
2277	  "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2278	(match_operand:SF 1 "general_operand"
2279	  "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2280  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281   && (reload_in_progress || reload_completed
2282       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283       || GET_CODE (operands[1]) != CONST_DOUBLE
2284       || memory_operand (operands[0], SFmode))" 
2285{
2286  switch (which_alternative)
2287    {
2288    case 0:
2289      return output_387_reg_move (insn, operands);
2290
2291    case 1:
2292      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293        return "fstp%z0\t%y0";
2294      else
2295        return "fst%z0\t%y0";
2296
2297    case 2:
2298      return standard_80387_constant_opcode (operands[1]);
2299
2300    case 3:
2301    case 4:
2302      return "mov{l}\t{%1, %0|%0, %1}";
2303    case 5:
2304      if (get_attr_mode (insn) == MODE_TI)
2305	return "pxor\t%0, %0";
2306      else
2307	return "xorps\t%0, %0";
2308    case 6:
2309      if (get_attr_mode (insn) == MODE_V4SF)
2310	return "movaps\t{%1, %0|%0, %1}";
2311      else
2312	return "movss\t{%1, %0|%0, %1}";
2313    case 7:
2314    case 8:
2315      return "movss\t{%1, %0|%0, %1}";
2316
2317    case 9:
2318    case 10:
2319      return "movd\t{%1, %0|%0, %1}";
2320
2321    case 11:
2322      return "movq\t{%1, %0|%0, %1}";
2323
2324    default:
2325      gcc_unreachable ();
2326    }
2327}
2328  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329   (set (attr "mode")
2330        (cond [(eq_attr "alternative" "3,4,9,10")
2331		 (const_string "SI")
2332	       (eq_attr "alternative" "5")
2333		 (if_then_else
2334		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335			    	 (const_int 0))
2336			     (ne (symbol_ref "TARGET_SSE2")
2337				 (const_int 0)))
2338			(eq (symbol_ref "optimize_size")
2339			    (const_int 0)))
2340		   (const_string "TI")
2341		   (const_string "V4SF"))
2342	       /* For architectures resolving dependencies on
2343		  whole SSE registers use APS move to break dependency
2344		  chains, otherwise use short move to avoid extra work. 
2345
2346		  Do the same for architectures resolving dependencies on
2347		  the parts.  While in DF mode it is better to always handle
2348		  just register parts, the SF mode is different due to lack
2349		  of instructions to load just part of the register.  It is
2350		  better to maintain the whole registers in single format
2351		  to avoid problems on using packed logical operations.  */
2352	       (eq_attr "alternative" "6")
2353		 (if_then_else
2354		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355			    (const_int 0))
2356			(ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357			    (const_int 0)))
2358		   (const_string "V4SF")
2359		   (const_string "SF"))
2360	       (eq_attr "alternative" "11")
2361		 (const_string "DI")]
2362	       (const_string "SF")))])
2363
2364(define_insn "*swapsf"
2365  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366	(match_operand:SF 1 "fp_register_operand" "+f"))
2367   (set (match_dup 1)
2368	(match_dup 0))]
2369  "reload_completed || TARGET_80387"
2370{
2371  if (STACK_TOP_P (operands[0]))
2372    return "fxch\t%1";
2373  else
2374    return "fxch\t%0";
2375}
2376  [(set_attr "type" "fxch")
2377   (set_attr "mode" "SF")])
2378
2379(define_expand "movdf"
2380  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381	(match_operand:DF 1 "general_operand" ""))]
2382  ""
2383  "ix86_expand_move (DFmode, operands); DONE;")
2384
2385;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386;; Size of pushdf using integer instructions is 2+2*memory operand size
2387;; On the average, pushdf using integers can be still shorter.  Allow this
2388;; pattern for optimize_size too.
2389
2390(define_insn "*pushdf_nointeger"
2391  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392	(match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394{
2395  /* This insn should be already split before reg-stack.  */
2396  gcc_unreachable ();
2397}
2398  [(set_attr "type" "multi")
2399   (set_attr "unit" "i387,*,*,*")
2400   (set_attr "mode" "DF,SI,SI,DF")])
2401
2402(define_insn "*pushdf_integer"
2403  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404	(match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406{
2407  /* This insn should be already split before reg-stack.  */
2408  gcc_unreachable ();
2409}
2410  [(set_attr "type" "multi")
2411   (set_attr "unit" "i387,*,*")
2412   (set_attr "mode" "DF,SI,DF")])
2413
2414;; %%% Kill this when call knows how to work this out.
2415(define_split
2416  [(set (match_operand:DF 0 "push_operand" "")
2417	(match_operand:DF 1 "any_fp_register_operand" ""))]
2418  "!TARGET_64BIT && reload_completed"
2419  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420   (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421  "")
2422
2423(define_split
2424  [(set (match_operand:DF 0 "push_operand" "")
2425	(match_operand:DF 1 "any_fp_register_operand" ""))]
2426  "TARGET_64BIT && reload_completed"
2427  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428   (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429  "")
2430
2431(define_split
2432  [(set (match_operand:DF 0 "push_operand" "")
2433	(match_operand:DF 1 "general_operand" ""))]
2434  "reload_completed"
2435  [(const_int 0)]
2436  "ix86_split_long_move (operands); DONE;")
2437
2438;; Moving is usually shorter when only FP registers are used. This separate
2439;; movdf pattern avoids the use of integer registers for FP operations
2440;; when optimizing for size.
2441
2442(define_insn "*movdf_nointeger"
2443  [(set (match_operand:DF 0 "nonimmediate_operand"
2444			"=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2445	(match_operand:DF 1 "general_operand"
2446			"fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2447  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449   && (reload_in_progress || reload_completed
2450       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451       || GET_CODE (operands[1]) != CONST_DOUBLE
2452       || memory_operand (operands[0], DFmode))" 
2453{
2454  switch (which_alternative)
2455    {
2456    case 0:
2457      return output_387_reg_move (insn, operands);
2458
2459    case 1:
2460      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461        return "fstp%z0\t%y0";
2462      else
2463        return "fst%z0\t%y0";
2464
2465    case 2:
2466      return standard_80387_constant_opcode (operands[1]);
2467
2468    case 3:
2469    case 4:
2470      return "#";
2471    case 5:
2472      switch (get_attr_mode (insn))
2473	{
2474	case MODE_V4SF:
2475	  return "xorps\t%0, %0";
2476	case MODE_V2DF:
2477	  return "xorpd\t%0, %0";
2478	case MODE_TI:
2479	  return "pxor\t%0, %0";
2480	default:
2481	  gcc_unreachable ();
2482	}
2483    case 6:
2484    case 7:
2485    case 8:
2486      switch (get_attr_mode (insn))
2487	{
2488	case MODE_V4SF:
2489	  return "movaps\t{%1, %0|%0, %1}";
2490	case MODE_V2DF:
2491	  return "movapd\t{%1, %0|%0, %1}";
2492	case MODE_TI:
2493	  return "movdqa\t{%1, %0|%0, %1}";
2494	case MODE_DI:
2495	  return "movq\t{%1, %0|%0, %1}";
2496	case MODE_DF:
2497	  return "movsd\t{%1, %0|%0, %1}";
2498	case MODE_V1DF:
2499	  return "movlpd\t{%1, %0|%0, %1}";
2500	case MODE_V2SF:
2501	  return "movlps\t{%1, %0|%0, %1}";
2502	default:
2503	  gcc_unreachable ();
2504	}
2505
2506    default:
2507      gcc_unreachable ();
2508    }
2509}
2510  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511   (set (attr "mode")
2512        (cond [(eq_attr "alternative" "0,1,2")
2513		 (const_string "DF")
2514	       (eq_attr "alternative" "3,4")
2515		 (const_string "SI")
2516
2517	       /* For SSE1, we have many fewer alternatives.  */
2518	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519		 (cond [(eq_attr "alternative" "5,6")
2520			  (const_string "V4SF")
2521		       ]
2522		   (const_string "V2SF"))
2523
2524	       /* xorps is one byte shorter.  */
2525	       (eq_attr "alternative" "5")
2526		 (cond [(ne (symbol_ref "optimize_size")
2527			    (const_int 0))
2528			  (const_string "V4SF")
2529			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530			    (const_int 0))
2531			  (const_string "TI")
2532		       ]
2533		       (const_string "V2DF"))
2534
2535	       /* For architectures resolving dependencies on
2536		  whole SSE registers use APD move to break dependency
2537		  chains, otherwise use short move to avoid extra work.
2538
2539		  movaps encodes one byte shorter.  */
2540	       (eq_attr "alternative" "6")
2541		 (cond
2542		   [(ne (symbol_ref "optimize_size")
2543		        (const_int 0))
2544		      (const_string "V4SF")
2545		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546		        (const_int 0))
2547		      (const_string "V2DF")
2548		   ]
2549		   (const_string "DF"))
2550	       /* For architectures resolving dependencies on register
2551		  parts we may avoid extra work to zero out upper part
2552		  of register.  */
2553	       (eq_attr "alternative" "7")
2554		 (if_then_else
2555		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556		       (const_int 0))
2557		   (const_string "V1DF")
2558		   (const_string "DF"))
2559	      ]
2560	      (const_string "DF")))])
2561
2562(define_insn "*movdf_integer"
2563  [(set (match_operand:DF 0 "nonimmediate_operand"
2564		"=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2565	(match_operand:DF 1 "general_operand"
2566		"fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2567  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569   && (reload_in_progress || reload_completed
2570       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571       || GET_CODE (operands[1]) != CONST_DOUBLE
2572       || memory_operand (operands[0], DFmode))" 
2573{
2574  switch (which_alternative)
2575    {
2576    case 0:
2577      return output_387_reg_move (insn, operands);
2578
2579    case 1:
2580      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581        return "fstp%z0\t%y0";
2582      else
2583        return "fst%z0\t%y0";
2584
2585    case 2:
2586      return standard_80387_constant_opcode (operands[1]);
2587
2588    case 3:
2589    case 4:
2590      return "#";
2591
2592    case 5:
2593      switch (get_attr_mode (insn))
2594	{
2595	case MODE_V4SF:
2596	  return "xorps\t%0, %0";
2597	case MODE_V2DF:
2598	  return "xorpd\t%0, %0";
2599	case MODE_TI:
2600	  return "pxor\t%0, %0";
2601	default:
2602	  gcc_unreachable ();
2603	}
2604    case 6:
2605    case 7:
2606    case 8:
2607      switch (get_attr_mode (insn))
2608	{
2609	case MODE_V4SF:
2610	  return "movaps\t{%1, %0|%0, %1}";
2611	case MODE_V2DF:
2612	  return "movapd\t{%1, %0|%0, %1}";
2613	case MODE_TI:
2614	  return "movdqa\t{%1, %0|%0, %1}";
2615	case MODE_DI:
2616	  return "movq\t{%1, %0|%0, %1}";
2617	case MODE_DF:
2618	  return "movsd\t{%1, %0|%0, %1}";
2619	case MODE_V1DF:
2620	  return "movlpd\t{%1, %0|%0, %1}";
2621	case MODE_V2SF:
2622	  return "movlps\t{%1, %0|%0, %1}";
2623	default:
2624	  gcc_unreachable ();
2625	}
2626
2627    default:
2628      gcc_unreachable();
2629    }
2630}
2631  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632   (set (attr "mode")
2633        (cond [(eq_attr "alternative" "0,1,2")
2634		 (const_string "DF")
2635	       (eq_attr "alternative" "3,4")
2636		 (const_string "SI")
2637
2638	       /* For SSE1, we have many fewer alternatives.  */
2639	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640		 (cond [(eq_attr "alternative" "5,6")
2641			  (const_string "V4SF")
2642		       ]
2643		   (const_string "V2SF"))
2644
2645	       /* xorps is one byte shorter.  */
2646	       (eq_attr "alternative" "5")
2647		 (cond [(ne (symbol_ref "optimize_size")
2648			    (const_int 0))
2649			  (const_string "V4SF")
2650			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651			    (const_int 0))
2652			  (const_string "TI")
2653		       ]
2654		       (const_string "V2DF"))
2655
2656	       /* For architectures resolving dependencies on
2657		  whole SSE registers use APD move to break dependency
2658		  chains, otherwise use short move to avoid extra work.
2659
2660		  movaps encodes one byte shorter.  */
2661	       (eq_attr "alternative" "6")
2662		 (cond
2663		   [(ne (symbol_ref "optimize_size")
2664		        (const_int 0))
2665		      (const_string "V4SF")
2666		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667		        (const_int 0))
2668		      (const_string "V2DF")
2669		   ]
2670		   (const_string "DF"))
2671	       /* For architectures resolving dependencies on register
2672		  parts we may avoid extra work to zero out upper part
2673		  of register.  */
2674	       (eq_attr "alternative" "7")
2675		 (if_then_else
2676		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677		       (const_int 0))
2678		   (const_string "V1DF")
2679		   (const_string "DF"))
2680	      ]
2681	      (const_string "DF")))])
2682
2683(define_split
2684  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685	(match_operand:DF 1 "general_operand" ""))]
2686  "reload_completed
2687   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688   && ! (ANY_FP_REG_P (operands[0]) || 
2689	 (GET_CODE (operands[0]) == SUBREG
2690	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691   && ! (ANY_FP_REG_P (operands[1]) || 
2692	 (GET_CODE (operands[1]) == SUBREG
2693	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694  [(const_int 0)]
2695  "ix86_split_long_move (operands); DONE;")
2696
2697(define_insn "*swapdf"
2698  [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699	(match_operand:DF 1 "fp_register_operand" "+f"))
2700   (set (match_dup 1)
2701	(match_dup 0))]
2702  "reload_completed || TARGET_80387"
2703{
2704  if (STACK_TOP_P (operands[0]))
2705    return "fxch\t%1";
2706  else
2707    return "fxch\t%0";
2708}
2709  [(set_attr "type" "fxch")
2710   (set_attr "mode" "DF")])
2711
2712(define_expand "movxf"
2713  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714	(match_operand:XF 1 "general_operand" ""))]
2715  ""
2716  "ix86_expand_move (XFmode, operands); DONE;")
2717
2718;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719;; Size of pushdf using integer instructions is 3+3*memory operand size
2720;; Pushing using integer instructions is longer except for constants
2721;; and direct memory references.
2722;; (assuming that any given constant is pushed only once, but this ought to be
2723;;  handled elsewhere).
2724
2725(define_insn "*pushxf_nointeger"
2726  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2728  "optimize_size"
2729{
2730  /* This insn should be already split before reg-stack.  */
2731  gcc_unreachable ();
2732}
2733  [(set_attr "type" "multi")
2734   (set_attr "unit" "i387,*,*")
2735   (set_attr "mode" "XF,SI,SI")])
2736
2737(define_insn "*pushxf_integer"
2738  [(set (match_operand:XF 0 "push_operand" "=<,<")
2739	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740  "!optimize_size"
2741{
2742  /* This insn should be already split before reg-stack.  */
2743  gcc_unreachable ();
2744}
2745  [(set_attr "type" "multi")
2746   (set_attr "unit" "i387,*")
2747   (set_attr "mode" "XF,SI")])
2748
2749(define_split
2750  [(set (match_operand 0 "push_operand" "")
2751	(match_operand 1 "general_operand" ""))]
2752  "reload_completed
2753   && (GET_MODE (operands[0]) == XFmode
2754       || GET_MODE (operands[0]) == DFmode)
2755   && !ANY_FP_REG_P (operands[1])"
2756  [(const_int 0)]
2757  "ix86_split_long_move (operands); DONE;")
2758
2759(define_split
2760  [(set (match_operand:XF 0 "push_operand" "")
2761	(match_operand:XF 1 "any_fp_register_operand" ""))]
2762  "!TARGET_64BIT"
2763  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764   (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766
2767(define_split
2768  [(set (match_operand:XF 0 "push_operand" "")
2769	(match_operand:XF 1 "any_fp_register_operand" ""))]
2770  "TARGET_64BIT"
2771  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772   (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775;; Do not use integer registers when optimizing for size
2776(define_insn "*movxf_nointeger"
2777  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779  "optimize_size
2780   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781   && (reload_in_progress || reload_completed
2782       || GET_CODE (operands[1]) != CONST_DOUBLE
2783       || memory_operand (operands[0], XFmode))" 
2784{
2785  switch (which_alternative)
2786    {
2787    case 0:
2788      return output_387_reg_move (insn, operands);
2789
2790    case 1:
2791      /* There is no non-popping store to memory for XFmode.  So if
2792	 we need one, follow the store with a load.  */
2793      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794        return "fstp%z0\t%y0\;fld%z0\t%y0";
2795      else
2796        return "fstp%z0\t%y0";
2797
2798    case 2:
2799      return standard_80387_constant_opcode (operands[1]);
2800
2801    case 3: case 4:
2802      return "#";
2803    default:
2804      gcc_unreachable ();
2805    }
2806}
2807  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808   (set_attr "mode" "XF,XF,XF,SI,SI")])
2809
2810(define_insn "*movxf_integer"
2811  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812	(match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813  "!optimize_size
2814   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815   && (reload_in_progress || reload_completed
2816       || GET_CODE (operands[1]) != CONST_DOUBLE
2817       || memory_operand (operands[0], XFmode))" 
2818{
2819  switch (which_alternative)
2820    {
2821    case 0:
2822      return output_387_reg_move (insn, operands);
2823
2824    case 1:
2825      /* There is no non-popping store to memory for XFmode.  So if
2826	 we need one, follow the store with a load.  */
2827      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828        return "fstp%z0\t%y0\;fld%z0\t%y0";
2829      else
2830        return "fstp%z0\t%y0";
2831
2832    case 2:
2833      return standard_80387_constant_opcode (operands[1]);
2834
2835    case 3: case 4:
2836      return "#";
2837
2838    default:
2839      gcc_unreachable ();
2840    }
2841}
2842  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843   (set_attr "mode" "XF,XF,XF,SI,SI")])
2844
2845(define_split
2846  [(set (match_operand 0 "nonimmediate_operand" "")
2847	(match_operand 1 "general_operand" ""))]
2848  "reload_completed
2849   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850   && GET_MODE (operands[0]) == XFmode
2851   && ! (ANY_FP_REG_P (operands[0]) || 
2852	 (GET_CODE (operands[0]) == SUBREG
2853	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854   && ! (ANY_FP_REG_P (operands[1]) || 
2855	 (GET_CODE (operands[1]) == SUBREG
2856	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857  [(const_int 0)]
2858  "ix86_split_long_move (operands); DONE;")
2859
2860(define_split
2861  [(set (match_operand 0 "register_operand" "")
2862	(match_operand 1 "memory_operand" ""))]
2863  "reload_completed
2864   && GET_CODE (operands[1]) == MEM
2865   && (GET_MODE (operands[0]) == XFmode
2866       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867   && constant_pool_reference_p (operands[1])"
2868  [(set (match_dup 0) (match_dup 1))]
2869{
2870  rtx c = avoid_constant_pool_reference (operands[1]);
2871  rtx r = operands[0];
2872
2873  if (GET_CODE (r) == SUBREG)
2874    r = SUBREG_REG (r);
2875
2876  if (SSE_REG_P (r))
2877    {
2878      if (!standard_sse_constant_p (c))
2879	FAIL;
2880    }
2881  else if (FP_REG_P (r))
2882    {
2883      if (!standard_80387_constant_p (c))
2884	FAIL;
2885    }
2886  else if (MMX_REG_P (r))
2887    FAIL;
2888
2889  operands[1] = c;
2890})
2891
2892(define_insn "swapxf"
2893  [(set (match_operand:XF 0 "register_operand" "+f")
2894	(match_operand:XF 1 "register_operand" "+f"))
2895   (set (match_dup 1)
2896	(match_dup 0))]
2897  "TARGET_80387"
2898{
2899  if (STACK_TOP_P (operands[0]))
2900    return "fxch\t%1";
2901  else
2902    return "fxch\t%0";
2903}
2904  [(set_attr "type" "fxch")
2905   (set_attr "mode" "XF")])
2906
2907(define_expand "movtf"
2908  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909	(match_operand:TF 1 "nonimmediate_operand" ""))]
2910  "TARGET_64BIT"
2911{
2912  ix86_expand_move (TFmode, operands);
2913  DONE;
2914})
2915
2916(define_insn "*movtf_internal"
2917  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919  "TARGET_64BIT
2920   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921{
2922  switch (which_alternative)
2923    {
2924    case 0:
2925    case 1:
2926      return "#";
2927    case 2:
2928      if (get_attr_mode (insn) == MODE_V4SF)
2929	return "xorps\t%0, %0";
2930      else
2931	return "pxor\t%0, %0";
2932    case 3:
2933    case 4:
2934      if (get_attr_mode (insn) == MODE_V4SF)
2935	return "movaps\t{%1, %0|%0, %1}";
2936      else
2937	return "movdqa\t{%1, %0|%0, %1}";
2938    default:
2939      gcc_unreachable ();
2940    }
2941}
2942  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2943   (set (attr "mode")
2944        (cond [(eq_attr "alternative" "2,3")
2945		 (if_then_else
2946		   (ne (symbol_ref "optimize_size")
2947		       (const_int 0))
2948		   (const_string "V4SF")
2949		   (const_string "TI"))
2950	       (eq_attr "alternative" "4")
2951		 (if_then_else
2952		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953			    (const_int 0))
2954			(ne (symbol_ref "optimize_size")
2955			    (const_int 0)))
2956		   (const_string "V4SF")
2957		   (const_string "TI"))]
2958	       (const_string "DI")))])
2959
2960(define_split
2961  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962        (match_operand:TF 1 "general_operand" ""))]
2963  "reload_completed && !SSE_REG_P (operands[0])
2964   && !SSE_REG_P (operands[1])"
2965  [(const_int 0)]
2966  "ix86_split_long_move (operands); DONE;")
2967
2968;; Zero extension instructions
2969
2970(define_expand "zero_extendhisi2"
2971  [(set (match_operand:SI 0 "register_operand" "")
2972     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973  ""
2974{
2975  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976    {
2977      operands[1] = force_reg (HImode, operands[1]);
2978      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979      DONE;
2980    }
2981})
2982
2983(define_insn "zero_extendhisi2_and"
2984  [(set (match_operand:SI 0 "register_operand" "=r")
2985     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986   (clobber (reg:CC FLAGS_REG))]
2987  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988  "#"
2989  [(set_attr "type" "alu1")
2990   (set_attr "mode" "SI")])
2991
2992(define_split
2993  [(set (match_operand:SI 0 "register_operand" "")
2994	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995   (clobber (reg:CC FLAGS_REG))]
2996  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998	      (clobber (reg:CC FLAGS_REG))])]
2999  "")
3000
3001(define_insn "*zero_extendhisi2_movzwl"
3002  [(set (match_operand:SI 0 "register_operand" "=r")
3003     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005  "movz{wl|x}\t{%1, %0|%0, %1}"
3006  [(set_attr "type" "imovx")
3007   (set_attr "mode" "SI")])
3008
3009(define_expand "zero_extendqihi2"
3010  [(parallel
3011    [(set (match_operand:HI 0 "register_operand" "")
3012       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013     (clobber (reg:CC FLAGS_REG))])]
3014  ""
3015  "")
3016
3017(define_insn "*zero_extendqihi2_and"
3018  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020   (clobber (reg:CC FLAGS_REG))]
3021  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022  "#"
3023  [(set_attr "type" "alu1")
3024   (set_attr "mode" "HI")])
3025
3026(define_insn "*zero_extendqihi2_movzbw_and"
3027  [(set (match_operand:HI 0 "register_operand" "=r,r")
3028     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029   (clobber (reg:CC FLAGS_REG))]
3030  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031  "#"
3032  [(set_attr "type" "imovx,alu1")
3033   (set_attr "mode" "HI")])
3034
3035; zero extend to SImode here to avoid partial register stalls
3036(define_insn "*zero_extendqihi2_movzbl"
3037  [(set (match_operand:HI 0 "register_operand" "=r")
3038     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040  "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041  [(set_attr "type" "imovx")
3042   (set_attr "mode" "SI")])
3043
3044;; For the movzbw case strip only the clobber
3045(define_split
3046  [(set (match_operand:HI 0 "register_operand" "")
3047	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048   (clobber (reg:CC FLAGS_REG))]
3049  "reload_completed 
3050   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052  [(set (match_operand:HI 0 "register_operand" "")
3053	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054
3055;; When source and destination does not overlap, clear destination
3056;; first and then do the movb
3057(define_split
3058  [(set (match_operand:HI 0 "register_operand" "")
3059	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060   (clobber (reg:CC FLAGS_REG))]
3061  "reload_completed
3062   && ANY_QI_REG_P (operands[0])
3063   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065  [(set (match_dup 0) (const_int 0))
3066   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067  "operands[2] = gen_lowpart (QImode, operands[0]);")
3068
3069;; Rest is handled by single and.
3070(define_split
3071  [(set (match_operand:HI 0 "register_operand" "")
3072	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073   (clobber (reg:CC FLAGS_REG))]
3074  "reload_completed
3075   && true_regnum (operands[0]) == true_regnum (operands[1])"
3076  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077	      (clobber (reg:CC FLAGS_REG))])]
3078  "")
3079
3080(define_expand "zero_extendqisi2"
3081  [(parallel
3082    [(set (match_operand:SI 0 "register_operand" "")
3083       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084     (clobber (reg:CC FLAGS_REG))])]
3085  ""
3086  "")
3087
3088(define_insn "*zero_extendqisi2_and"
3089  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091   (clobber (reg:CC FLAGS_REG))]
3092  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093  "#"
3094  [(set_attr "type" "alu1")
3095   (set_attr "mode" "SI")])
3096
3097(define_insn "*zero_extendqisi2_movzbw_and"
3098  [(set (match_operand:SI 0 "register_operand" "=r,r")
3099     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100   (clobber (reg:CC FLAGS_REG))]
3101  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102  "#"
3103  [(set_attr "type" "imovx,alu1")
3104   (set_attr "mode" "SI")])
3105
3106(define_insn "*zero_extendqisi2_movzbw"
3107  [(set (match_operand:SI 0 "register_operand" "=r")
3108     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110  "movz{bl|x}\t{%1, %0|%0, %1}"
3111  [(set_attr "type" "imovx")
3112   (set_attr "mode" "SI")])
3113
3114;; For the movzbl case strip only the clobber
3115(define_split
3116  [(set (match_operand:SI 0 "register_operand" "")
3117	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118   (clobber (reg:CC FLAGS_REG))]
3119  "reload_completed 
3120   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122  [(set (match_dup 0)
3123	(zero_extend:SI (match_dup 1)))])
3124
3125;; When source and destination does not overlap, clear destination
3126;; first and then do the movb
3127(define_split
3128  [(set (match_operand:SI 0 "register_operand" "")
3129	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130   (clobber (reg:CC FLAGS_REG))]
3131  "reload_completed
3132   && ANY_QI_REG_P (operands[0])
3133   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136  [(set (match_dup 0) (const_int 0))
3137   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138  "operands[2] = gen_lowpart (QImode, operands[0]);")
3139
3140;; Rest is handled by single and.
3141(define_split
3142  [(set (match_operand:SI 0 "register_operand" "")
3143	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144   (clobber (reg:CC FLAGS_REG))]
3145  "reload_completed
3146   && true_regnum (operands[0]) == true_regnum (operands[1])"
3147  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148	      (clobber (reg:CC FLAGS_REG))])]
3149  "")
3150
3151;; %%% Kill me once multi-word ops are sane.
3152(define_expand "zero_extendsidi2"
3153  [(set (match_operand:DI 0 "register_operand" "=r")
3154     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3155  ""
3156  "if (!TARGET_64BIT)
3157     {
3158       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3159       DONE;
3160     }
3161  ")
3162
3163(define_insn "zero_extendsidi2_32"
3164  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166   (clobber (reg:CC FLAGS_REG))]
3167  "!TARGET_64BIT"
3168  "@
3169   #
3170   #
3171   #
3172   movd\t{%1, %0|%0, %1}
3173   movd\t{%1, %0|%0, %1}"
3174  [(set_attr "mode" "SI,SI,SI,DI,TI")
3175   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176
3177(define_insn "zero_extendsidi2_rex64"
3178  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3180  "TARGET_64BIT"
3181  "@
3182   mov\t{%k1, %k0|%k0, %k1}
3183   #
3184   movd\t{%1, %0|%0, %1}
3185   movd\t{%1, %0|%0, %1}"
3186  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187   (set_attr "mode" "SI,DI,SI,SI")])
3188
3189(define_split
3190  [(set (match_operand:DI 0 "memory_operand" "")
3191     (zero_extend:DI (match_dup 0)))]
3192  "TARGET_64BIT"
3193  [(set (match_dup 4) (const_int 0))]
3194  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195
3196(define_split 
3197  [(set (match_operand:DI 0 "register_operand" "")
3198	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199   (clobber (reg:CC FLAGS_REG))]
3200  "!TARGET_64BIT && reload_completed
3201   && true_regnum (operands[0]) == true_regnum (operands[1])"
3202  [(set (match_dup 4) (const_int 0))]
3203  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204
3205(define_split 
3206  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208   (clobber (reg:CC FLAGS_REG))]
3209  "!TARGET_64BIT && reload_completed
3210   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211  [(set (match_dup 3) (match_dup 1))
3212   (set (match_dup 4) (const_int 0))]
3213  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214
3215(define_insn "zero_extendhidi2"
3216  [(set (match_operand:DI 0 "register_operand" "=r")
3217     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218  "TARGET_64BIT"
3219  "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220  [(set_attr "type" "imovx")
3221   (set_attr "mode" "DI")])
3222
3223(define_insn "zero_extendqidi2"
3224  [(set (match_operand:DI 0 "register_operand" "=r")
3225     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226  "TARGET_64BIT"
3227  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228  [(set_attr "type" "imovx")
3229   (set_attr "mode" "DI")])
3230
3231;; Sign extension instructions
3232
3233(define_expand "extendsidi2"
3234  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236	      (clobber (reg:CC FLAGS_REG))
3237	      (clobber (match_scratch:SI 2 ""))])]
3238  ""
3239{
3240  if (TARGET_64BIT)
3241    {
3242      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3243      DONE;
3244    }
3245})
3246
3247(define_insn "*extendsidi2_1"
3248  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250   (clobber (reg:CC FLAGS_REG))
3251   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252  "!TARGET_64BIT"
3253  "#")
3254
3255(define_insn "extendsidi2_rex64"
3256  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258  "TARGET_64BIT"
3259  "@
3260   {cltq|cdqe}
3261   movs{lq|x}\t{%1,%0|%0, %1}"
3262  [(set_attr "type" "imovx")
3263   (set_attr "mode" "DI")
3264   (set_attr "prefix_0f" "0")
3265   (set_attr "modrm" "0,1")])
3266
3267(define_insn "extendhidi2"
3268  [(set (match_operand:DI 0 "register_operand" "=r")
3269	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270  "TARGET_64BIT"
3271  "movs{wq|x}\t{%1,%0|%0, %1}"
3272  [(set_attr "type" "imovx")
3273   (set_attr "mode" "DI")])
3274
3275(define_insn "extendqidi2"
3276  [(set (match_operand:DI 0 "register_operand" "=r")
3277	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278  "TARGET_64BIT"
3279  "movs{bq|x}\t{%1,%0|%0, %1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "DI")])
3282
3283;; Extend to memory case when source register does die.
3284(define_split 
3285  [(set (match_operand:DI 0 "memory_operand" "")
3286	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287   (clobber (reg:CC FLAGS_REG))
3288   (clobber (match_operand:SI 2 "register_operand" ""))]
3289  "(reload_completed
3290    && dead_or_set_p (insn, operands[1])
3291    && !reg_mentioned_p (operands[1], operands[0]))"
3292  [(set (match_dup 3) (match_dup 1))
3293   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294	      (clobber (reg:CC FLAGS_REG))])
3295   (set (match_dup 4) (match_dup 1))]
3296  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297
3298;; Extend to memory case when source register does not die.
3299(define_split 
3300  [(set (match_operand:DI 0 "memory_operand" "")
3301	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302   (clobber (reg:CC FLAGS_REG))
3303   (clobber (match_operand:SI 2 "register_operand" ""))]
3304  "reload_completed"
3305  [(const_int 0)]
3306{
3307  split_di (&operands[0], 1, &operands[3], &operands[4]);
3308
3309  emit_move_insn (operands[3], operands[1]);
3310
3311  /* Generate a cltd if possible and doing so it profitable.  */
3312  if (true_regnum (operands[1]) == 0
3313      && true_regnum (operands[2]) == 1
3314      && (optimize_size || TARGET_USE_CLTD))
3315    {
3316      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317    }
3318  else
3319    {
3320      emit_move_insn (operands[2], operands[1]);
3321      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322    }
3323  emit_move_insn (operands[4], operands[2]);
3324  DONE;
3325})
3326
3327;; Extend to register case.  Optimize case where source and destination
3328;; registers match and cases where we can use cltd.
3329(define_split 
3330  [(set (match_operand:DI 0 "register_operand" "")
3331	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332   (clobber (reg:CC FLAGS_REG))
3333   (clobber (match_scratch:SI 2 ""))]
3334  "reload_completed"
3335  [(const_int 0)]
3336{
3337  split_di (&operands[0], 1, &operands[3], &operands[4]);
3338
3339  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340    emit_move_insn (operands[3], operands[1]);
3341
3342  /* Generate a cltd if possible and doing so it profitable.  */
3343  if (true_regnum (operands[3]) == 0
3344      && (optimize_size || TARGET_USE_CLTD))
3345    {
3346      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347      DONE;
3348    }
3349
3350  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351    emit_move_insn (operands[4], operands[1]);
3352
3353  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354  DONE;
3355})
3356
3357(define_insn "extendhisi2"
3358  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3360  ""
3361{
3362  switch (get_attr_prefix_0f (insn))
3363    {
3364    case 0:
3365      return "{cwtl|cwde}";
3366    default:
3367      return "movs{wl|x}\t{%1,%0|%0, %1}";
3368    }
3369}
3370  [(set_attr "type" "imovx")
3371   (set_attr "mode" "SI")
3372   (set (attr "prefix_0f")
3373     ;; movsx is short decodable while cwtl is vector decoded.
3374     (if_then_else (and (eq_attr "cpu" "!k6")
3375			(eq_attr "alternative" "0"))
3376	(const_string "0")
3377	(const_string "1")))
3378   (set (attr "modrm")
3379     (if_then_else (eq_attr "prefix_0f" "0")
3380	(const_string "0")
3381	(const_string "1")))])
3382
3383(define_insn "*extendhisi2_zext"
3384  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385	(zero_extend:DI
3386	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3387  "TARGET_64BIT"
3388{
3389  switch (get_attr_prefix_0f (insn))
3390    {
3391    case 0:
3392      return "{cwtl|cwde}";
3393    default:
3394      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3395    }
3396}
3397  [(set_attr "type" "imovx")
3398   (set_attr "mode" "SI")
3399   (set (attr "prefix_0f")
3400     ;; movsx is short decodable while cwtl is vector decoded.
3401     (if_then_else (and (eq_attr "cpu" "!k6")
3402			(eq_attr "alternative" "0"))
3403	(const_string "0")
3404	(const_string "1")))
3405   (set (attr "modrm")
3406     (if_then_else (eq_attr "prefix_0f" "0")
3407	(const_string "0")
3408	(const_string "1")))])
3409
3410(define_insn "extendqihi2"
3411  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3413  ""
3414{
3415  switch (get_attr_prefix_0f (insn))
3416    {
3417    case 0:
3418      return "{cbtw|cbw}";
3419    default:
3420      return "movs{bw|x}\t{%1,%0|%0, %1}";
3421    }
3422}
3423  [(set_attr "type" "imovx")
3424   (set_attr "mode" "HI")
3425   (set (attr "prefix_0f")
3426     ;; movsx is short decodable while cwtl is vector decoded.
3427     (if_then_else (and (eq_attr "cpu" "!k6")
3428			(eq_attr "alternative" "0"))
3429	(const_string "0")
3430	(const_string "1")))
3431   (set (attr "modrm")
3432     (if_then_else (eq_attr "prefix_0f" "0")
3433	(const_string "0")
3434	(const_string "1")))])
3435
3436(define_insn "extendqisi2"
3437  [(set (match_operand:SI 0 "register_operand" "=r")
3438	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439  ""
3440  "movs{bl|x}\t{%1,%0|%0, %1}"
3441   [(set_attr "type" "imovx")
3442    (set_attr "mode" "SI")])
3443
3444(define_insn "*extendqisi2_zext"
3445  [(set (match_operand:DI 0 "register_operand" "=r")
3446	(zero_extend:DI
3447	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448  "TARGET_64BIT"
3449  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450   [(set_attr "type" "imovx")
3451    (set_attr "mode" "SI")])
3452
3453;; Conversions between float and double.
3454
3455;; These are all no-ops in the model used for the 80387.  So just
3456;; emit moves.
3457
3458;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3459(define_insn "*dummy_extendsfdf2"
3460  [(set (match_operand:DF 0 "push_operand" "=<")
3461	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3462  "0"
3463  "#")
3464
3465(define_split
3466  [(set (match_operand:DF 0 "push_operand" "")
3467	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468  "!TARGET_64BIT"
3469  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470   (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3471
3472(define_split
3473  [(set (match_operand:DF 0 "push_operand" "")
3474	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475  "TARGET_64BIT"
3476  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477   (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3478
3479(define_insn "*dummy_extendsfxf2"
3480  [(set (match_operand:XF 0 "push_operand" "=<")
3481	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3482  "0"
3483  "#")
3484
3485(define_split
3486  [(set (match_operand:XF 0 "push_operand" "")
3487	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488  ""
3489  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490   (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492
3493(define_split
3494  [(set (match_operand:XF 0 "push_operand" "")
3495	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496  "TARGET_64BIT"
3497  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498   (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501(define_split
3502  [(set (match_operand:XF 0 "push_operand" "")
3503	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504  ""
3505  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506   (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508
3509(define_split
3510  [(set (match_operand:XF 0 "push_operand" "")
3511	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512  "TARGET_64BIT"
3513  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514   (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516
3517(define_expand "extendsfdf2"
3518  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3521{
3522  /* ??? Needed for compress_float_constant since all fp constants
3523     are LEGITIMATE_CONSTANT_P.  */
3524  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3525    {
3526      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527	  && standard_80387_constant_p (operands[1]) > 0)
3528	{
3529	  operands[1] = simplify_const_unary_operation
3530	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531	  emit_move_insn_1 (operands[0], operands[1]);
3532	  DONE;
3533	}
3534      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3535    }
3536  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3537    operands[1] = force_reg (SFmode, operands[1]);
3538})
3539
3540(define_insn "*extendsfdf2_mixed"
3541  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3542        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3543  "TARGET_SSE2 && TARGET_MIX_SSE_I387
3544   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3545{
3546  switch (which_alternative)
3547    {
3548    case 0:
3549      return output_387_reg_move (insn, operands);
3550
3551    case 1:
3552      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553        return "fstp%z0\t%y0";
3554      else
3555        return "fst%z0\t%y0";
3556
3557    case 2:
3558      return "cvtss2sd\t{%1, %0|%0, %1}";
3559
3560    default:
3561      gcc_unreachable ();
3562    }
3563}
3564  [(set_attr "type" "fmov,fmov,ssecvt")
3565   (set_attr "mode" "SF,XF,DF")])
3566
3567(define_insn "*extendsfdf2_sse"
3568  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3569        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3570  "TARGET_SSE2 && TARGET_SSE_MATH
3571   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572  "cvtss2sd\t{%1, %0|%0, %1}"
3573  [(set_attr "type" "ssecvt")
3574   (set_attr "mode" "DF")])
3575
3576(define_insn "*extendsfdf2_i387"
3577  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3578        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3579  "TARGET_80387
3580   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3581{
3582  switch (which_alternative)
3583    {
3584    case 0:
3585      return output_387_reg_move (insn, operands);
3586
3587    case 1:
3588      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589        return "fstp%z0\t%y0";
3590      else
3591        return "fst%z0\t%y0";
3592
3593    default:
3594      gcc_unreachable ();
3595    }
3596}
3597  [(set_attr "type" "fmov")
3598   (set_attr "mode" "SF,XF")])
3599
3600(define_expand "extendsfxf2"
3601  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3603  "TARGET_80387"
3604{
3605  /* ??? Needed for compress_float_constant since all fp constants
3606     are LEGITIMATE_CONSTANT_P.  */
3607  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608    {
3609      if (standard_80387_constant_p (operands[1]) > 0)
3610	{
3611	  operands[1] = simplify_const_unary_operation
3612	    (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613	  emit_move_insn_1 (operands[0], operands[1]);
3614	  DONE;
3615	}
3616      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3617    }
3618  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619    operands[1] = force_reg (SFmode, operands[1]);
3620})
3621
3622(define_insn "*extendsfxf2_i387"
3623  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3625  "TARGET_80387
3626   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3627{
3628  switch (which_alternative)
3629    {
3630    case 0:
3631      return output_387_reg_move (insn, operands);
3632
3633    case 1:
3634      /* There is no non-popping store to memory for XFmode.  So if
3635	 we need one, follow the store with a load.  */
3636      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637        return "fstp%z0\t%y0";
3638      else
3639        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640
3641    default:
3642      gcc_unreachable ();
3643    }
3644}
3645  [(set_attr "type" "fmov")
3646   (set_attr "mode" "SF,XF")])
3647
3648(define_expand "extenddfxf2"
3649  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651  "TARGET_80387"
3652{
3653  /* ??? Needed for compress_float_constant since all fp constants
3654     are LEGITIMATE_CONSTANT_P.  */
3655  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656    {
3657      if (standard_80387_constant_p (operands[1]) > 0)
3658	{
3659	  operands[1] = simplify_const_unary_operation
3660	    (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661	  emit_move_insn_1 (operands[0], operands[1]);
3662	  DONE;
3663	}
3664      operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665    }
3666  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667    operands[1] = force_reg (DFmode, operands[1]);
3668})
3669
3670(define_insn "*extenddfxf2_i387"
3671  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3672        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3673  "TARGET_80387
3674   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3675{
3676  switch (which_alternative)
3677    {
3678    case 0:
3679      return output_387_reg_move (insn, operands);
3680
3681    case 1:
3682      /* There is no non-popping store to memory for XFmode.  So if
3683	 we need one, follow the store with a load.  */
3684      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3686      else
3687        return "fstp%z0\t%y0";
3688
3689    default:
3690      gcc_unreachable ();
3691    }
3692}
3693  [(set_attr "type" "fmov")
3694   (set_attr "mode" "DF,XF")])
3695
3696;; %%% This seems bad bad news.
3697;; This cannot output into an f-reg because there is no way to be sure
3698;; of truncating in that case.  Otherwise this is just like a simple move
3699;; insn.  So we pretend we can output to a reg in order to get better
3700;; register preferencing, but we really use a stack slot.
3701
3702;; Conversion from DFmode to SFmode.
3703
3704(define_expand "truncdfsf2"
3705  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3706	(float_truncate:SF
3707	  (match_operand:DF 1 "nonimmediate_operand" "")))]
3708  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3709{
3710  if (MEM_P (operands[0]) && MEM_P (operands[1]))
3711    operands[1] = force_reg (DFmode, operands[1]);
3712
3713  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3714    ;
3715  else if (flag_unsafe_math_optimizations)
3716    ;
3717  else
3718    {
3719      rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3720      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3721      DONE;
3722    }
3723})
3724
3725(define_expand "truncdfsf2_with_temp"
3726  [(parallel [(set (match_operand:SF 0 "" "")
3727		   (float_truncate:SF (match_operand:DF 1 "" "")))
3728	      (clobber (match_operand:SF 2 "" ""))])]
3729  "")
3730
3731(define_insn "*truncdfsf_fast_mixed"
3732  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3733        (float_truncate:SF
3734          (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3735  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3736{
3737  switch (which_alternative)
3738    {
3739    case 0:
3740      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741	return "fstp%z0\t%y0";
3742      else
3743	return "fst%z0\t%y0";
3744    case 1:
3745      return output_387_reg_move (insn, operands);
3746    case 2:
3747      return "cvtsd2ss\t{%1, %0|%0, %1}";
3748    default:
3749      gcc_unreachable ();
3750    }
3751}
3752  [(set_attr "type" "fmov,fmov,ssecvt")
3753   (set_attr "mode" "SF")])
3754
3755;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3756;; because nothing we do here is unsafe.
3757(define_insn "*truncdfsf_fast_sse"
3758  [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3759        (float_truncate:SF
3760          (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3761  "TARGET_SSE2 && TARGET_SSE_MATH"
3762  "cvtsd2ss\t{%1, %0|%0, %1}"
3763  [(set_attr "type" "ssecvt")
3764   (set_attr "mode" "SF")])
3765
3766(define_insn "*truncdfsf_fast_i387"
3767  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3768        (float_truncate:SF
3769          (match_operand:DF 1 "nonimmediate_operand" "f")))]
3770  "TARGET_80387 && flag_unsafe_math_optimizations"
3771  "* return output_387_reg_move (insn, operands);"
3772  [(set_attr "type" "fmov")
3773   (set_attr "mode" "SF")])
3774
3775(define_insn "*truncdfsf_mixed"
3776  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3777	(float_truncate:SF
3778	  (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3779   (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3780  "TARGET_MIX_SSE_I387"
3781{
3782  switch (which_alternative)
3783    {
3784    case 0:
3785      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786	return "fstp%z0\t%y0";
3787      else
3788	return "fst%z0\t%y0";
3789    case 1:
3790      return "#";
3791    case 2:
3792      return "cvtsd2ss\t{%1, %0|%0, %1}";
3793    default:
3794      gcc_unreachable ();
3795    }
3796}
3797  [(set_attr "type" "fmov,multi,ssecvt")
3798   (set_attr "unit" "*,i387,*")
3799   (set_attr "mode" "SF")])
3800
3801(define_insn "*truncdfsf_i387"
3802  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3803	(float_truncate:SF
3804	  (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3805   (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3806  "TARGET_80387"
3807{
3808  switch (which_alternative)
3809    {
3810    case 0:
3811      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812	return "fstp%z0\t%y0";
3813      else
3814	return "fst%z0\t%y0";
3815    case 1:
3816      return "#";
3817    default:
3818      gcc_unreachable ();
3819    }
3820}
3821  [(set_attr "type" "fmov,multi")
3822   (set_attr "unit" "*,i387")
3823   (set_attr "mode" "SF")])
3824
3825(define_insn "*truncdfsf2_i387_1"
3826  [(set (match_operand:SF 0 "memory_operand" "=m")
3827	(float_truncate:SF
3828	  (match_operand:DF 1 "register_operand" "f")))]
3829  "TARGET_80387
3830   && !(TARGET_SSE2 && TARGET_SSE_MATH)
3831   && !TARGET_MIX_SSE_I387"
3832{
3833  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834    return "fstp%z0\t%y0";
3835  else
3836    return "fst%z0\t%y0";
3837}
3838  [(set_attr "type" "fmov")
3839   (set_attr "mode" "SF")])
3840
3841(define_split
3842  [(set (match_operand:SF 0 "register_operand" "")
3843	(float_truncate:SF
3844	 (match_operand:DF 1 "fp_register_operand" "")))
3845   (clobber (match_operand 2 "" ""))]
3846  "reload_completed"
3847  [(set (match_dup 2) (match_dup 1))
3848   (set (match_dup 0) (match_dup 2))]
3849{
3850  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3851})
3852
3853;; Conversion from XFmode to SFmode.
3854
3855(define_expand "truncxfsf2"
3856  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3857		   (float_truncate:SF
3858		    (match_operand:XF 1 "register_operand" "")))
3859	      (clobber (match_dup 2))])]
3860  "TARGET_80387"
3861{
3862  if (flag_unsafe_math_optimizations)
3863    {
3864      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3865      emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3866      if (reg != operands[0])
3867	emit_move_insn (operands[0], reg);
3868      DONE;
3869    }
3870  else
3871    operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3872})
3873
3874(define_insn "*truncxfsf2_mixed"
3875  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3876	(float_truncate:SF
3877	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3878   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3879  "TARGET_MIX_SSE_I387"
3880{
3881  gcc_assert (!which_alternative);
3882  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883    return "fstp%z0\t%y0";
3884  else
3885    return "fst%z0\t%y0";
3886}
3887  [(set_attr "type" "fmov,multi,multi,multi")
3888   (set_attr "unit" "*,i387,i387,i387")
3889   (set_attr "mode" "SF")])
3890
3891(define_insn "truncxfsf2_i387_noop"
3892  [(set (match_operand:SF 0 "register_operand" "=f")
3893	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3894  "TARGET_80387 && flag_unsafe_math_optimizations"
3895{
3896  return output_387_reg_move (insn, operands);
3897}
3898  [(set_attr "type" "fmov")
3899   (set_attr "mode" "SF")])
3900
3901(define_insn "*truncxfsf2_i387"
3902  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3903	(float_truncate:SF
3904	 (match_operand:XF 1 "register_operand" "f,f,f")))
3905   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3906  "TARGET_80387"
3907{
3908  gcc_assert (!which_alternative);
3909  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910    return "fstp%z0\t%y0";
3911   else
3912     return "fst%z0\t%y0";
3913}
3914  [(set_attr "type" "fmov,multi,multi")
3915   (set_attr "unit" "*,i387,i387")
3916   (set_attr "mode" "SF")])
3917
3918(define_insn "*truncxfsf2_i387_1"
3919  [(set (match_operand:SF 0 "memory_operand" "=m")
3920	(float_truncate:SF
3921	 (match_operand:XF 1 "register_operand" "f")))]
3922  "TARGET_80387"
3923{
3924  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925    return "fstp%z0\t%y0";
3926  else
3927    return "fst%z0\t%y0";
3928}
3929  [(set_attr "type" "fmov")
3930   (set_attr "mode" "SF")])
3931
3932(define_split
3933  [(set (match_operand:SF 0 "register_operand" "")
3934	(float_truncate:SF
3935	 (match_operand:XF 1 "register_operand" "")))
3936   (clobber (match_operand:SF 2 "memory_operand" ""))]
3937  "TARGET_80387 && reload_completed"
3938  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3939   (set (match_dup 0) (match_dup 2))]
3940  "")
3941
3942(define_split
3943  [(set (match_operand:SF 0 "memory_operand" "")
3944	(float_truncate:SF
3945	 (match_operand:XF 1 "register_operand" "")))
3946   (clobber (match_operand:SF 2 "memory_operand" ""))]
3947  "TARGET_80387"
3948  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3949  "")
3950
3951;; Conversion from XFmode to DFmode.
3952
3953(define_expand "truncxfdf2"
3954  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3955		   (float_truncate:DF
3956		    (match_operand:XF 1 "register_operand" "")))
3957	      (clobber (match_dup 2))])]
3958  "TARGET_80387"
3959{
3960  if (flag_unsafe_math_optimizations)
3961    {
3962      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3963      emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3964      if (reg != operands[0])
3965	emit_move_insn (operands[0], reg);
3966      DONE;
3967    }
3968  else
3969    operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3970})
3971
3972(define_insn "*truncxfdf2_mixed"
3973  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3974	(float_truncate:DF
3975	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3976   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3977  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3978{
3979  gcc_assert (!which_alternative);
3980  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981    return "fstp%z0\t%y0";
3982  else
3983    return "fst%z0\t%y0";
3984}
3985  [(set_attr "type" "fmov,multi,multi,multi")
3986   (set_attr "unit" "*,i387,i387,i387")
3987   (set_attr "mode" "DF")])
3988
3989(define_insn "truncxfdf2_i387_noop"
3990  [(set (match_operand:DF 0 "register_operand" "=f")
3991	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3992  "TARGET_80387 && flag_unsafe_math_optimizations"
3993{
3994  return output_387_reg_move (insn, operands);
3995}
3996  [(set_attr "type" "fmov")
3997   (set_attr "mode" "DF")])
3998
3999(define_insn "*truncxfdf2_i387"
4000  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4001	(float_truncate:DF
4002	 (match_operand:XF 1 "register_operand" "f,f,f")))
4003   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4004  "TARGET_80387"
4005{
4006  gcc_assert (!which_alternative);
4007  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008    return "fstp%z0\t%y0";
4009  else
4010    return "fst%z0\t%y0";
4011}
4012  [(set_attr "type" "fmov,multi,multi")
4013   (set_attr "unit" "*,i387,i387")
4014   (set_attr "mode" "DF")])
4015
4016(define_insn "*truncxfdf2_i387_1"
4017  [(set (match_operand:DF 0 "memory_operand" "=m")
4018	(float_truncate:DF
4019	  (match_operand:XF 1 "register_operand" "f")))]
4020  "TARGET_80387"
4021{
4022  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023    return "fstp%z0\t%y0";
4024  else
4025    return "fst%z0\t%y0";
4026}
4027  [(set_attr "type" "fmov")
4028   (set_attr "mode" "DF")])
4029
4030(define_split
4031  [(set (match_operand:DF 0 "register_operand" "")
4032	(float_truncate:DF
4033	 (match_operand:XF 1 "register_operand" "")))
4034   (clobber (match_operand:DF 2 "memory_operand" ""))]
4035  "TARGET_80387 && reload_completed"
4036  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4037   (set (match_dup 0) (match_dup 2))]
4038  "")
4039
4040(define_split
4041  [(set (match_operand:DF 0 "memory_operand" "")
4042	(float_truncate:DF
4043	 (match_operand:XF 1 "register_operand" "")))
4044   (clobber (match_operand:DF 2 "memory_operand" ""))]
4045  "TARGET_80387"
4046  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4047  "")
4048
4049;; Signed conversion to DImode.
4050
4051(define_expand "fix_truncxfdi2"
4052  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4053                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4054	      (clobber (reg:CC FLAGS_REG))])]
4055  "TARGET_80387"
4056{
4057  if (TARGET_FISTTP)
4058   {
4059     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4060     DONE;
4061   }
4062})
4063
4064(define_expand "fix_trunc<mode>di2"
4065  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4066                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4067              (clobber (reg:CC FLAGS_REG))])]
4068  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4069{
4070  if (TARGET_FISTTP
4071      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4072   {
4073     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4074     DONE;
4075   }
4076  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4077   {
4078     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4080     if (out != operands[0])
4081	emit_move_insn (operands[0], out);
4082     DONE;
4083   }
4084})
4085
4086;; Signed conversion to SImode.
4087
4088(define_expand "fix_truncxfsi2"
4089  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4091	      (clobber (reg:CC FLAGS_REG))])]
4092  "TARGET_80387"
4093{
4094  if (TARGET_FISTTP)
4095   {
4096     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4097     DONE;
4098   }
4099})
4100
4101(define_expand "fix_trunc<mode>si2"
4102  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4103	           (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4104	      (clobber (reg:CC FLAGS_REG))])]
4105  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4106{
4107  if (TARGET_FISTTP
4108      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4109   {
4110     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4111     DONE;
4112   }
4113  if (SSE_FLOAT_MODE_P (<MODE>mode))
4114   {
4115     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4116     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4117     if (out != operands[0])
4118	emit_move_insn (operands[0], out);
4119     DONE;
4120   }
4121})
4122
4123;; Signed conversion to HImode.
4124
4125(define_expand "fix_trunc<mode>hi2"
4126  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4127	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4128              (clobber (reg:CC FLAGS_REG))])]
4129  "TARGET_80387
4130   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4131{
4132  if (TARGET_FISTTP)
4133   {
4134     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4135     DONE;
4136   }
4137})
4138
4139;; When SSE is available, it is always faster to use it!
4140(define_insn "fix_truncsfdi_sse"
4141  [(set (match_operand:DI 0 "register_operand" "=r,r")
4142	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143  "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144  "cvttss2si{q}\t{%1, %0|%0, %1}"
4145  [(set_attr "type" "sseicvt")
4146   (set_attr "mode" "SF")
4147   (set_attr "athlon_decode" "double,vector")])
4148
4149(define_insn "fix_truncdfdi_sse"
4150  [(set (match_operand:DI 0 "register_operand" "=r,r")
4151	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152  "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154  [(set_attr "type" "sseicvt")
4155   (set_attr "mode" "DF")
4156   (set_attr "athlon_decode" "double,vector")])
4157
4158(define_insn "fix_truncsfsi_sse"
4159  [(set (match_operand:SI 0 "register_operand" "=r,r")
4160	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161  "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162  "cvttss2si\t{%1, %0|%0, %1}"
4163  [(set_attr "type" "sseicvt")
4164   (set_attr "mode" "DF")
4165   (set_attr "athlon_decode" "double,vector")])
4166
4167(define_insn "fix_truncdfsi_sse"
4168  [(set (match_operand:SI 0 "register_operand" "=r,r")
4169	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4170  "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171  "cvttsd2si\t{%1, %0|%0, %1}"
4172  [(set_attr "type" "sseicvt")
4173   (set_attr "mode" "DF")
4174   (set_attr "athlon_decode" "double,vector")])
4175
4176;; Avoid vector decoded forms of the instruction.
4177(define_peephole2
4178  [(match_scratch:DF 2 "Y")
4179   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4180	(fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4181  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4182  [(set (match_dup 2) (match_dup 1))
4183   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4184  "")
4185
4186(define_peephole2
4187  [(match_scratch:SF 2 "x")
4188   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4189	(fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4190  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4191  [(set (match_dup 2) (match_dup 1))
4192   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4193  "")
4194
4195(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4196  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4197	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4198  "TARGET_FISTTP
4199   && FLOAT_MODE_P (GET_MODE (operands[1]))
4200   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201	 && (TARGET_64BIT || <MODE>mode != DImode))
4202	&& TARGET_SSE_MATH)
4203   && !(reload_completed || reload_in_progress)"
4204  "#"
4205  "&& 1"
4206  [(const_int 0)]
4207{
4208  if (memory_operand (operands[0], VOIDmode))
4209    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4210  else
4211    {
4212      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4213      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4214							    operands[1],
4215							    operands[2]));
4216    }
4217  DONE;
4218}
4219  [(set_attr "type" "fisttp")
4220   (set_attr "mode" "<MODE>")])
4221
4222(define_insn "fix_trunc<mode>_i387_fisttp"
4223  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4224	(fix:X87MODEI (match_operand 1 "register_operand" "f")))
4225   (clobber (match_scratch:XF 2 "=&1f"))]
4226  "TARGET_FISTTP
4227   && FLOAT_MODE_P (GET_MODE (operands[1]))
4228   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229	 && (TARGET_64BIT || <MODE>mode != DImode))
4230	&& TARGET_SSE_MATH)"
4231  "* return output_fix_trunc (insn, operands, 1);"
4232  [(set_attr "type" "fisttp")
4233   (set_attr "mode" "<MODE>")])
4234
4235(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4236  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4238   (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4239   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4240  "TARGET_FISTTP
4241   && FLOAT_MODE_P (GET_MODE (operands[1]))
4242   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4243	&& (TARGET_64BIT || <MODE>mode != DImode))
4244	&& TARGET_SSE_MATH)"
4245  "#"
4246  [(set_attr "type" "fisttp")
4247   (set_attr "mode" "<MODE>")])
4248
4249(define_split
4250  [(set (match_operand:X87MODEI 0 "register_operand" "")
4251	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4252   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4253   (clobber (match_scratch 3 ""))]
4254  "reload_completed"
4255  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4256	      (clobber (match_dup 3))])
4257   (set (match_dup 0) (match_dup 2))]
4258  "")
4259
4260(define_split
4261  [(set (match_operand:X87MODEI 0 "memory_operand" "")
4262	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4263   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4264   (clobber (match_scratch 3 ""))]
4265  "reload_completed"
4266  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4267	      (clobber (match_dup 3))])]
4268  "")
4269
4270;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4272;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4273;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4274;; function in i386.c.
4275(define_insn_and_split "*fix_trunc<mode>_i387_1"
4276  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278   (clobber (reg:CC FLAGS_REG))]
4279  "TARGET_80387 && !TARGET_FISTTP
4280   && FLOAT_MODE_P (GET_MODE (operands[1]))
4281   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282	 && (TARGET_64BIT || <MODE>mode != DImode))
4283   && !(reload_completed || reload_in_progress)"
4284  "#"
4285  "&& 1"
4286  [(const_int 0)]
4287{
4288  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4289
4290  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4291  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4292  if (memory_operand (operands[0], VOIDmode))
4293    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4294					 operands[2], operands[3]));
4295  else
4296    {
4297      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4298      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4299						     operands[2], operands[3],
4300						     operands[4]));
4301    }
4302  DONE;
4303}
4304  [(set_attr "type" "fistp")
4305   (set_attr "i387_cw" "trunc")
4306   (set_attr "mode" "<MODE>")])
4307
4308(define_insn "fix_truncdi_i387"
4309  [(set (match_operand:DI 0 "memory_operand" "=m")
4310	(fix:DI (match_operand 1 "register_operand" "f")))
4311   (use (match_operand:HI 2 "memory_operand" "m"))
4312   (use (match_operand:HI 3 "memory_operand" "m"))
4313   (clobber (match_scratch:XF 4 "=&1f"))]
4314  "TARGET_80387 && !TARGET_FISTTP
4315   && FLOAT_MODE_P (GET_MODE (operands[1]))
4316   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4317  "* return output_fix_trunc (insn, operands, 0);"
4318  [(set_attr "type" "fistp")
4319   (set_attr "i387_cw" "trunc")
4320   (set_attr "mode" "DI")])
4321
4322(define_insn "fix_truncdi_i387_with_temp"
4323  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4324	(fix:DI (match_operand 1 "register_operand" "f,f")))
4325   (use (match_operand:HI 2 "memory_operand" "m,m"))
4326   (use (match_operand:HI 3 "memory_operand" "m,m"))
4327   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4328   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4329  "TARGET_80387 && !TARGET_FISTTP
4330   && FLOAT_MODE_P (GET_MODE (operands[1]))
4331   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332  "#"
4333  [(set_attr "type" "fistp")
4334   (set_attr "i387_cw" "trunc")
4335   (set_attr "mode" "DI")])
4336
4337(define_split 
4338  [(set (match_operand:DI 0 "register_operand" "")
4339	(fix:DI (match_operand 1 "register_operand" "")))
4340   (use (match_operand:HI 2 "memory_operand" ""))
4341   (use (match_operand:HI 3 "memory_operand" ""))
4342   (clobber (match_operand:DI 4 "memory_operand" ""))
4343   (clobber (match_scratch 5 ""))]
4344  "reload_completed"
4345  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4346	      (use (match_dup 2))
4347	      (use (match_dup 3))
4348	      (clobber (match_dup 5))])
4349   (set (match_dup 0) (match_dup 4))]
4350  "")
4351
4352(define_split 
4353  [(set (match_operand:DI 0 "memory_operand" "")
4354	(fix:DI (match_operand 1 "register_operand" "")))
4355   (use (match_operand:HI 2 "memory_operand" ""))
4356   (use (match_operand:HI 3 "memory_operand" ""))
4357   (clobber (match_operand:DI 4 "memory_operand" ""))
4358   (clobber (match_scratch 5 ""))]
4359  "reload_completed"
4360  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4361	      (use (match_dup 2))
4362	      (use (match_dup 3))
4363	      (clobber (match_dup 5))])]
4364  "")
4365
4366(define_insn "fix_trunc<mode>_i387"
4367  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4368	(fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4369   (use (match_operand:HI 2 "memory_operand" "m"))
4370   (use (match_operand:HI 3 "memory_operand" "m"))]
4371  "TARGET_80387 && !TARGET_FISTTP
4372   && FLOAT_MODE_P (GET_MODE (operands[1]))
4373   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374  "* return output_fix_trunc (insn, operands, 0);"
4375  [(set_attr "type" "fistp")
4376   (set_attr "i387_cw" "trunc")
4377   (set_attr "mode" "<MODE>")])
4378
4379(define_insn "fix_trunc<mode>_i387_with_temp"
4380  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4381	(fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4382   (use (match_operand:HI 2 "memory_operand" "m,m"))
4383   (use (match_operand:HI 3 "memory_operand" "m,m"))
4384   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4385  "TARGET_80387 && !TARGET_FISTTP
4386   && FLOAT_MODE_P (GET_MODE (operands[1]))
4387   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388  "#"
4389  [(set_attr "type" "fistp")
4390   (set_attr "i387_cw" "trunc")
4391   (set_attr "mode" "<MODE>")])
4392
4393(define_split 
4394  [(set (match_operand:X87MODEI12 0 "register_operand" "")
4395	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4396   (use (match_operand:HI 2 "memory_operand" ""))
4397   (use (match_operand:HI 3 "memory_operand" ""))
4398   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4399  "reload_completed"
4400  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4401	      (use (match_dup 2))
4402	      (use (match_dup 3))])
4403   (set (match_dup 0) (match_dup 4))]
4404  "")
4405
4406(define_split 
4407  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4408	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4409   (use (match_operand:HI 2 "memory_operand" ""))
4410   (use (match_operand:HI 3 "memory_operand" ""))
4411   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4412  "reload_completed"
4413  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4414	      (use (match_dup 2))
4415	      (use (match_dup 3))])]
4416  "")
4417
4418(define_insn "x86_fnstcw_1"
4419  [(set (match_operand:HI 0 "memory_operand" "=m")
4420	(unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4421  "TARGET_80387"
4422  "fnstcw\t%0"
4423  [(set_attr "length" "2")
4424   (set_attr "mode" "HI")
4425   (set_attr "unit" "i387")])
4426
4427(define_insn "x86_fldcw_1"
4428  [(set (reg:HI FPSR_REG)
4429	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4430  "TARGET_80387"
4431  "fldcw\t%0"
4432  [(set_attr "length" "2")
4433   (set_attr "mode" "HI")
4434   (set_attr "unit" "i387")
4435   (set_attr "athlon_decode" "vector")])
4436
4437;; Conversion between fixed point and floating point.
4438
4439;; Even though we only accept memory inputs, the backend _really_
4440;; wants to be able to do this between registers.
4441
4442(define_expand "floathisf2"
4443  [(set (match_operand:SF 0 "register_operand" "")
4444	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4445  "TARGET_80387 || TARGET_SSE_MATH"
4446{
4447  if (TARGET_SSE_MATH)
4448    {
4449      emit_insn (gen_floatsisf2 (operands[0],
4450				 convert_to_mode (SImode, operands[1], 0)));
4451      DONE;
4452    }
4453})
4454
4455(define_insn "*floathisf2_i387"
4456  [(set (match_operand:SF 0 "register_operand" "=f,f")
4457	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4458  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4459  "@
4460   fild%z1\t%1
4461   #"
4462  [(set_attr "type" "fmov,multi")
4463   (set_attr "mode" "SF")
4464   (set_attr "unit" "*,i387")
4465   (set_attr "fp_int_src" "true")])
4466
4467(define_expand "floatsisf2"
4468  [(set (match_operand:SF 0 "register_operand" "")
4469	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4470  "TARGET_80387 || TARGET_SSE_MATH"
4471  "")
4472
4473(define_insn "*floatsisf2_mixed"
4474  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4475	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4476  "TARGET_MIX_SSE_I387"
4477  "@
4478   fild%z1\t%1
4479   #
4480   cvtsi2ss\t{%1, %0|%0, %1}
4481   cvtsi2ss\t{%1, %0|%0, %1}"
4482  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4483   (set_attr "mode" "SF")
4484   (set_attr "unit" "*,i387,*,*")
4485   (set_attr "athlon_decode" "*,*,vector,double")
4486   (set_attr "fp_int_src" "true")])
4487
4488(define_insn "*floatsisf2_sse"
4489  [(set (match_operand:SF 0 "register_operand" "=x,x")
4490	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4491  "TARGET_SSE_MATH"
4492  "cvtsi2ss\t{%1, %0|%0, %1}"
4493  [(set_attr "type" "sseicvt")
4494   (set_attr "mode" "SF")
4495   (set_attr "athlon_decode" "vector,double")
4496   (set_attr "fp_int_src" "true")])
4497
4498(define_insn "*floatsisf2_i387"
4499  [(set (match_operand:SF 0 "register_operand" "=f,f")
4500	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4501  "TARGET_80387"
4502  "@
4503   fild%z1\t%1
4504   #"
4505  [(set_attr "type" "fmov,multi")
4506   (set_attr "mode" "SF")
4507   (set_attr "unit" "*,i387")
4508   (set_attr "fp_int_src" "true")])
4509
4510(define_expand "floatdisf2"
4511  [(set (match_operand:SF 0 "register_operand" "")
4512	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4514  "")
4515
4516(define_insn "*floatdisf2_mixed"
4517  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4518	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4519  "TARGET_64BIT && TARGET_MIX_SSE_I387"
4520  "@
4521   fild%z1\t%1
4522   #
4523   cvtsi2ss{q}\t{%1, %0|%0, %1}
4524   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4525  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4526   (set_attr "mode" "SF")
4527   (set_attr "unit" "*,i387,*,*")
4528   (set_attr "athlon_decode" "*,*,vector,double")
4529   (set_attr "fp_int_src" "true")])
4530
4531(define_insn "*floatdisf2_sse"
4532  [(set (match_operand:SF 0 "register_operand" "=x,x")
4533	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534  "TARGET_64BIT && TARGET_SSE_MATH"
4535  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536  [(set_attr "type" "sseicvt")
4537   (set_attr "mode" "SF")
4538   (set_attr "athlon_decode" "vector,double")
4539   (set_attr "fp_int_src" "true")])
4540
4541(define_insn "*floatdisf2_i387"
4542  [(set (match_operand:SF 0 "register_operand" "=f,f")
4543	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4544  "TARGET_80387"
4545  "@
4546   fild%z1\t%1
4547   #"
4548  [(set_attr "type" "fmov,multi")
4549   (set_attr "mode" "SF")
4550   (set_attr "unit" "*,i387")
4551   (set_attr "fp_int_src" "true")])
4552
4553(define_expand "floathidf2"
4554  [(set (match_operand:DF 0 "register_operand" "")
4555	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557{
4558  if (TARGET_SSE2 && TARGET_SSE_MATH)
4559    {
4560      emit_insn (gen_floatsidf2 (operands[0],
4561				 convert_to_mode (SImode, operands[1], 0)));
4562      DONE;
4563    }
4564})
4565
4566(define_insn "*floathidf2_i387"
4567  [(set (match_operand:DF 0 "register_operand" "=f,f")
4568	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569  "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570  "@
4571   fild%z1\t%1
4572   #"
4573  [(set_attr "type" "fmov,multi")
4574   (set_attr "mode" "DF")
4575   (set_attr "unit" "*,i387")
4576   (set_attr "fp_int_src" "true")])
4577
4578(define_expand "floatsidf2"
4579  [(set (match_operand:DF 0 "register_operand" "")
4580	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4581  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4582  "")
4583
4584(define_insn "*floatsidf2_mixed"
4585  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4586	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4587  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4588  "@
4589   fild%z1\t%1
4590   #
4591   cvtsi2sd\t{%1, %0|%0, %1}
4592   cvtsi2sd\t{%1, %0|%0, %1}"
4593  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4594   (set_attr "mode" "DF")
4595   (set_attr "unit" "*,i387,*,*")
4596   (set_attr "athlon_decode" "*,*,double,direct")
4597   (set_attr "fp_int_src" "true")])
4598
4599(define_insn "*floatsidf2_sse"
4600  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4601	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4602  "TARGET_SSE2 && TARGET_SSE_MATH"
4603  "cvtsi2sd\t{%1, %0|%0, %1}"
4604  [(set_attr "type" "sseicvt")
4605   (set_attr "mode" "DF")
4606   (set_attr "athlon_decode" "double,direct")
4607   (set_attr "fp_int_src" "true")])
4608
4609(define_insn "*floatsidf2_i387"
4610  [(set (match_operand:DF 0 "register_operand" "=f,f")
4611	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4612  "TARGET_80387"
4613  "@
4614   fild%z1\t%1
4615   #"
4616  [(set_attr "type" "fmov,multi")
4617   (set_attr "mode" "DF")
4618   (set_attr "unit" "*,i387")
4619   (set_attr "fp_int_src" "true")])
4620
4621(define_expand "floatdidf2"
4622  [(set (match_operand:DF 0 "register_operand" "")
4623	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4625  "")
4626
4627(define_insn "*floatdidf2_mixed"
4628  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4629	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4630  "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4631  "@
4632   fild%z1\t%1
4633   #
4634   cvtsi2sd{q}\t{%1, %0|%0, %1}
4635   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4636  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4637   (set_attr "mode" "DF")
4638   (set_attr "unit" "*,i387,*,*")
4639   (set_attr "athlon_decode" "*,*,double,direct")
4640   (set_attr "fp_int_src" "true")])
4641
4642(define_insn "*floatdidf2_sse"
4643  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4644	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4645  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4646  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647  [(set_attr "type" "sseicvt")
4648   (set_attr "mode" "DF")
4649   (set_attr "athlon_decode" "double,direct")
4650   (set_attr "fp_int_src" "true")])
4651
4652(define_insn "*floatdidf2_i387"
4653  [(set (match_operand:DF 0 "register_operand" "=f,f")
4654	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4655  "TARGET_80387"
4656  "@
4657   fild%z1\t%1
4658   #"
4659  [(set_attr "type" "fmov,multi")
4660   (set_attr "mode" "DF")
4661   (set_attr "unit" "*,i387")
4662   (set_attr "fp_int_src" "true")])
4663
4664(define_insn "floathixf2"
4665  [(set (match_operand:XF 0 "register_operand" "=f,f")
4666	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4667  "TARGET_80387"
4668  "@
4669   fild%z1\t%1
4670   #"
4671  [(set_attr "type" "fmov,multi")
4672   (set_attr "mode" "XF")
4673   (set_attr "unit" "*,i387")
4674   (set_attr "fp_int_src" "true")])
4675
4676(define_insn "floatsixf2"
4677  [(set (match_operand:XF 0 "register_operand" "=f,f")
4678	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4679  "TARGET_80387"
4680  "@
4681   fild%z1\t%1
4682   #"
4683  [(set_attr "type" "fmov,multi")
4684   (set_attr "mode" "XF")
4685   (set_attr "unit" "*,i387")
4686   (set_attr "fp_int_src" "true")])
4687
4688(define_insn "floatdixf2"
4689  [(set (match_operand:XF 0 "register_operand" "=f,f")
4690	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4691  "TARGET_80387"
4692  "@
4693   fild%z1\t%1
4694   #"
4695  [(set_attr "type" "fmov,multi")
4696   (set_attr "mode" "XF")
4697   (set_attr "unit" "*,i387")
4698   (set_attr "fp_int_src" "true")])
4699
4700;; %%% Kill these when reload knows how to do it.
4701(define_split
4702  [(set (match_operand 0 "fp_register_operand" "")
4703	(float (match_operand 1 "register_operand" "")))]
4704  "reload_completed
4705   && TARGET_80387
4706   && FLOAT_MODE_P (GET_MODE (operands[0]))"
4707  [(const_int 0)]
4708{
4709  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4710  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4711  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4712  ix86_free_from_memory (GET_MODE (operands[1]));
4713  DONE;
4714})
4715
4716(define_expand "floatunssisf2"
4717  [(use (match_operand:SF 0 "register_operand" ""))
4718   (use (match_operand:SI 1 "register_operand" ""))]
4719  "!TARGET_64BIT && TARGET_SSE_MATH"
4720  "x86_emit_floatuns (operands); DONE;")
4721
4722(define_expand "floatunsdisf2"
4723  [(use (match_operand:SF 0 "register_operand" ""))
4724   (use (match_operand:DI 1 "register_operand" ""))]
4725  "TARGET_64BIT && TARGET_SSE_MATH"
4726  "x86_emit_floatuns (operands); DONE;")
4727
4728(define_expand "floatunsdidf2"
4729  [(use (match_operand:DF 0 "register_operand" ""))
4730   (use (match_operand:DI 1 "register_operand" ""))]
4731  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4732  "x86_emit_floatuns (operands); DONE;")
4733
4734;; SSE extract/set expanders
4735
4736
4737;; Add instructions
4738
4739;; %%% splits for addditi3
4740
4741(define_expand "addti3"
4742  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4743	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4744		 (match_operand:TI 2 "x86_64_general_operand" "")))
4745   (clobber (reg:CC FLAGS_REG))]
4746  "TARGET_64BIT"
4747  "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4748
4749(define_insn "*addti3_1"
4750  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4751	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4752		 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4753   (clobber (reg:CC FLAGS_REG))]
4754  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4755  "#")
4756
4757(define_split
4758  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4759	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4760		 (match_operand:TI 2 "x86_64_general_operand" "")))
4761   (clobber (reg:CC FLAGS_REG))]
4762  "TARGET_64BIT && reload_completed"
4763  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4764					  UNSPEC_ADD_CARRY))
4765	      (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4766   (parallel [(set (match_dup 3)
4767		   (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4768				     (match_dup 4))
4769			    (match_dup 5)))
4770	      (clobber (reg:CC FLAGS_REG))])]
4771  "split_ti (operands+0, 1, operands+0, operands+3);
4772   split_ti (operands+1, 1, operands+1, operands+4);
4773   split_ti (operands+2, 1, operands+2, operands+5);")
4774
4775;; %%% splits for addsidi3
4776;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4777;	(plus:DI (match_operand:DI 1 "general_operand" "")
4778;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4779
4780(define_expand "adddi3"
4781  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4782	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4783		 (match_operand:DI 2 "x86_64_general_operand" "")))
4784   (clobber (reg:CC FLAGS_REG))]
4785  ""
4786  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4787
4788(define_insn "*adddi3_1"
4789  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4790	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4791		 (match_operand:DI 2 "general_operand" "roiF,riF")))
4792   (clobber (reg:CC FLAGS_REG))]
4793  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4794  "#")
4795
4796(define_split
4797  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4799		 (match_operand:DI 2 "general_operand" "")))
4800   (clobber (reg:CC FLAGS_REG))]
4801  "!TARGET_64BIT && reload_completed"
4802  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4803					  UNSPEC_ADD_CARRY))
4804	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4805   (parallel [(set (match_dup 3)
4806		   (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4807				     (match_dup 4))
4808			    (match_dup 5)))
4809	      (clobber (reg:CC FLAGS_REG))])]
4810  "split_di (operands+0, 1, operands+0, operands+3);
4811   split_di (operands+1, 1, operands+1, operands+4);
4812   split_di (operands+2, 1, operands+2, operands+5);")
4813
4814(define_insn "adddi3_carry_rex64"
4815  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4816	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4817			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4818		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4819   (clobber (reg:CC FLAGS_REG))]
4820  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4821  "adc{q}\t{%2, %0|%0, %2}"
4822  [(set_attr "type" "alu")
4823   (set_attr "pent_pair" "pu")
4824   (set_attr "mode" "DI")])
4825
4826(define_insn "*adddi3_cc_rex64"
4827  [(set (reg:CC FLAGS_REG)
4828	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4829		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4830		   UNSPEC_ADD_CARRY))
4831   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4832	(plus:DI (match_dup 1) (match_dup 2)))]
4833  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834  "add{q}\t{%2, %0|%0, %2}"
4835  [(set_attr "type" "alu")
4836   (set_attr "mode" "DI")])
4837
4838(define_insn "addqi3_carry"
4839  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4840	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4841			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4842		   (match_operand:QI 2 "general_operand" "qi,qm")))
4843   (clobber (reg:CC FLAGS_REG))]
4844  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4845  "adc{b}\t{%2, %0|%0, %2}"
4846  [(set_attr "type" "alu")
4847   (set_attr "pent_pair" "pu")
4848   (set_attr "mode" "QI")])
4849
4850(define_insn "addhi3_carry"
4851  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4852	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4853			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4854		   (match_operand:HI 2 "general_operand" "ri,rm")))
4855   (clobber (reg:CC FLAGS_REG))]
4856  "ix86_binary_operator_ok (PLUS, HImode, operands)"
4857  "adc{w}\t{%2, %0|%0, %2}"
4858  [(set_attr "type" "alu")
4859   (set_attr "pent_pair" "pu")
4860   (set_attr "mode" "HI")])
4861
4862(define_insn "addsi3_carry"
4863  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4865			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4866		   (match_operand:SI 2 "general_operand" "ri,rm")))
4867   (clobber (reg:CC FLAGS_REG))]
4868  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4869  "adc{l}\t{%2, %0|%0, %2}"
4870  [(set_attr "type" "alu")
4871   (set_attr "pent_pair" "pu")
4872   (set_attr "mode" "SI")])
4873
4874(define_insn "*addsi3_carry_zext"
4875  [(set (match_operand:DI 0 "register_operand" "=r")
4876	  (zero_extend:DI 
4877	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4878			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
4879		     (match_operand:SI 2 "general_operand" "rim"))))
4880   (clobber (reg:CC FLAGS_REG))]
4881  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4882  "adc{l}\t{%2, %k0|%k0, %2}"
4883  [(set_attr "type" "alu")
4884   (set_attr "pent_pair" "pu")
4885   (set_attr "mode" "SI")])
4886
4887(define_insn "*addsi3_cc"
4888  [(set (reg:CC FLAGS_REG)
4889	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4890		    (match_operand:SI 2 "general_operand" "ri,rm")]
4891		   UNSPEC_ADD_CARRY))
4892   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4893	(plus:SI (match_dup 1) (match_dup 2)))]
4894  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4895  "add{l}\t{%2, %0|%0, %2}"
4896  [(set_attr "type" "alu")
4897   (set_attr "mode" "SI")])
4898
4899(define_insn "addqi3_cc"
4900  [(set (reg:CC FLAGS_REG)
4901	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4902		    (match_operand:QI 2 "general_operand" "qi,qm")]
4903		   UNSPEC_ADD_CARRY))
4904   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4905	(plus:QI (match_dup 1) (match_dup 2)))]
4906  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4907  "add{b}\t{%2, %0|%0, %2}"
4908  [(set_attr "type" "alu")
4909   (set_attr "mode" "QI")])
4910
4911(define_expand "addsi3"
4912  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4913		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4914			    (match_operand:SI 2 "general_operand" "")))
4915	      (clobber (reg:CC FLAGS_REG))])]
4916  ""
4917  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4918
4919(define_insn "*lea_1"
4920  [(set (match_operand:SI 0 "register_operand" "=r")
4921	(match_operand:SI 1 "no_seg_address_operand" "p"))]
4922  "!TARGET_64BIT"
4923  "lea{l}\t{%a1, %0|%0, %a1}"
4924  [(set_attr "type" "lea")
4925   (set_attr "mode" "SI")])
4926
4927(define_insn "*lea_1_rex64"
4928  [(set (match_operand:SI 0 "register_operand" "=r")
4929	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4930  "TARGET_64BIT"
4931  "lea{l}\t{%a1, %0|%0, %a1}"
4932  [(set_attr "type" "lea")
4933   (set_attr "mode" "SI")])
4934
4935(define_insn "*lea_1_zext"
4936  [(set (match_operand:DI 0 "register_operand" "=r")
4937	(zero_extend:DI
4938	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4939  "TARGET_64BIT"
4940  "lea{l}\t{%a1, %k0|%k0, %a1}"
4941  [(set_attr "type" "lea")
4942   (set_attr "mode" "SI")])
4943
4944(define_insn "*lea_2_rex64"
4945  [(set (match_operand:DI 0 "register_operand" "=r")
4946	(match_operand:DI 1 "no_seg_address_operand" "p"))]
4947  "TARGET_64BIT"
4948  "lea{q}\t{%a1, %0|%0, %a1}"
4949  [(set_attr "type" "lea")
4950   (set_attr "mode" "DI")])
4951
4952;; The lea patterns for non-Pmodes needs to be matched by several
4953;; insns converted to real lea by splitters.
4954
4955(define_insn_and_split "*lea_general_1"
4956  [(set (match_operand 0 "register_operand" "=r")
4957	(plus (plus (match_operand 1 "index_register_operand" "l")
4958		    (match_operand 2 "register_operand" "r"))
4959	      (match_operand 3 "immediate_operand" "i")))]
4960  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4961    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4962   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4963   && GET_MODE (operands[0]) == GET_MODE (operands[1])
4964   && GET_MODE (operands[0]) == GET_MODE (operands[2])
4965   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4966       || GET_MODE (operands[3]) == VOIDmode)"
4967  "#"
4968  "&& reload_completed"
4969  [(const_int 0)]
4970{
4971  rtx pat;
4972  operands[0] = gen_lowpart (SImode, operands[0]);
4973  operands[1] = gen_lowpart (Pmode, operands[1]);
4974  operands[2] = gen_lowpart (Pmode, operands[2]);
4975  operands[3] = gen_lowpart (Pmode, operands[3]);
4976  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4977  		      operands[3]);
4978  if (Pmode != SImode)
4979    pat = gen_rtx_SUBREG (SImode, pat, 0);
4980  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4981  DONE;
4982}
4983  [(set_attr "type" "lea")
4984   (set_attr "mode" "SI")])
4985
4986(define_insn_and_split "*lea_general_1_zext"
4987  [(set (match_operand:DI 0 "register_operand" "=r")
4988	(zero_extend:DI
4989	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4990			    (match_operand:SI 2 "register_operand" "r"))
4991		   (match_operand:SI 3 "immediate_operand" "i"))))]
4992  "TARGET_64BIT"
4993  "#"
4994  "&& reload_completed"
4995  [(set (match_dup 0)
4996	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4997						     (match_dup 2))
4998					    (match_dup 3)) 0)))]
4999{
5000  operands[1] = gen_lowpart (Pmode, operands[1]);
5001  operands[2] = gen_lowpart (Pmode, operands[2]);
5002  operands[3] = gen_lowpart (Pmode, operands[3]);
5003}
5004  [(set_attr "type" "lea")
5005   (set_attr "mode" "SI")])
5006
5007(define_insn_and_split "*lea_general_2"
5008  [(set (match_operand 0 "register_operand" "=r")
5009	(plus (mult (match_operand 1 "index_register_operand" "l")
5010		    (match_operand 2 "const248_operand" "i"))
5011	      (match_operand 3 "nonmemory_operand" "ri")))]
5012  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5013    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5014   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5015   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5016   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5017       || GET_MODE (operands[3]) == VOIDmode)"
5018  "#"
5019  "&& reload_completed"
5020  [(const_int 0)]
5021{
5022  rtx pat;
5023  operands[0] = gen_lowpart (SImode, operands[0]);
5024  operands[1] = gen_lowpart (Pmode, operands[1]);
5025  operands[3] = gen_lowpart (Pmode, operands[3]);
5026  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5027  		      operands[3]);
5028  if (Pmode != SImode)
5029    pat = gen_rtx_SUBREG (SImode, pat, 0);
5030  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5031  DONE;
5032}
5033  [(set_attr "type" "lea")
5034   (set_attr "mode" "SI")])
5035
5036(define_insn_and_split "*lea_general_2_zext"
5037  [(set (match_operand:DI 0 "register_operand" "=r")
5038	(zero_extend:DI
5039	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5040			    (match_operand:SI 2 "const248_operand" "n"))
5041		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5042  "TARGET_64BIT"
5043  "#"
5044  "&& reload_completed"
5045  [(set (match_dup 0)
5046	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5047						     (match_dup 2))
5048					    (match_dup 3)) 0)))]
5049{
5050  operands[1] = gen_lowpart (Pmode, operands[1]);
5051  operands[3] = gen_lowpart (Pmode, operands[3]);
5052}
5053  [(set_attr "type" "lea")
5054   (set_attr "mode" "SI")])
5055
5056(define_insn_and_split "*lea_general_3"
5057  [(set (match_operand 0 "register_operand" "=r")
5058	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
5059			  (match_operand 2 "const248_operand" "i"))
5060		    (match_operand 3 "register_operand" "r"))
5061	      (match_operand 4 "immediate_operand" "i")))]
5062  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5063    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5064   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5065   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5066   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5067  "#"
5068  "&& reload_completed"
5069  [(const_int 0)]
5070{
5071  rtx pat;
5072  operands[0] = gen_lowpart (SImode, operands[0]);
5073  operands[1] = gen_lowpart (Pmode, operands[1]);
5074  operands[3] = gen_lowpart (Pmode, operands[3]);
5075  operands[4] = gen_lowpart (Pmode, operands[4]);
5076  pat = gen_rtx_PLUS (Pmode,
5077  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5078		      					 operands[2]),
5079				    operands[3]),
5080  		      operands[4]);
5081  if (Pmode != SImode)
5082    pat = gen_rtx_SUBREG (SImode, pat, 0);
5083  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5084  DONE;
5085}
5086  [(set_attr "type" "lea")
5087   (set_attr "mode" "SI")])
5088
5089(define_insn_and_split "*lea_general_3_zext"
5090  [(set (match_operand:DI 0 "register_operand" "=r")
5091	(zero_extend:DI
5092	  (plus:SI (plus:SI (mult:SI
5093			      (match_operand:SI 1 "index_register_operand" "l")
5094			      (match_operand:SI 2 "const248_operand" "n"))
5095			    (match_operand:SI 3 "register_operand" "r"))
5096		   (match_operand:SI 4 "immediate_operand" "i"))))]
5097  "TARGET_64BIT"
5098  "#"
5099  "&& reload_completed"
5100  [(set (match_dup 0)
5101	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5102							      (match_dup 2))
5103						     (match_dup 3))
5104					    (match_dup 4)) 0)))]
5105{
5106  operands[1] = gen_lowpart (Pmode, operands[1]);
5107  operands[3] = gen_lowpart (Pmode, operands[3]);
5108  operands[4] = gen_lowpart (Pmode, operands[4]);
5109}
5110  [(set_attr "type" "lea")
5111   (set_attr "mode" "SI")])
5112
5113(define_insn "*adddi_1_rex64"
5114  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5115	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5116		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5117   (clobber (reg:CC FLAGS_REG))]
5118  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5119{
5120  switch (get_attr_type (insn))
5121    {
5122    case TYPE_LEA:
5123      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5124      return "lea{q}\t{%a2, %0|%0, %a2}";
5125
5126    case TYPE_INCDEC:
5127      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5128      if (operands[2] == const1_rtx)
5129        return "inc{q}\t%0";
5130      else
5131        {
5132	  gcc_assert (operands[2] == constm1_rtx);
5133          return "dec{q}\t%0";
5134	}
5135
5136    default:
5137      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5138
5139      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5140	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5141      if (GET_CODE (operands[2]) == CONST_INT
5142	  /* Avoid overflows.  */
5143	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5144          && (INTVAL (operands[2]) == 128
5145	      || (INTVAL (operands[2]) < 0
5146		  && INTVAL (operands[2]) != -128)))
5147        {
5148          operands[2] = GEN_INT (-INTVAL (operands[2]));
5149          return "sub{q}\t{%2, %0|%0, %2}";
5150        }
5151      return "add{q}\t{%2, %0|%0, %2}";
5152    }
5153}
5154  [(set (attr "type")
5155     (cond [(eq_attr "alternative" "2")
5156	      (const_string "lea")
5157	    ; Current assemblers are broken and do not allow @GOTOFF in
5158	    ; ought but a memory context.
5159	    (match_operand:DI 2 "pic_symbolic_operand" "")
5160	      (const_string "lea")
5161	    (match_operand:DI 2 "incdec_operand" "")
5162	      (const_string "incdec")
5163	   ]
5164	   (const_string "alu")))
5165   (set_attr "mode" "DI")])
5166
5167;; Convert lea to the lea pattern to avoid flags dependency.
5168(define_split
5169  [(set (match_operand:DI 0 "register_operand" "")
5170	(plus:DI (match_operand:DI 1 "register_operand" "")
5171		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5172   (clobber (reg:CC FLAGS_REG))]
5173  "TARGET_64BIT && reload_completed
5174   && true_regnum (operands[0]) != true_regnum (operands[1])"
5175  [(set (match_dup 0)
5176	(plus:DI (match_dup 1)
5177		 (match_dup 2)))]
5178  "")
5179
5180(define_insn "*adddi_2_rex64"
5181  [(set (reg FLAGS_REG)
5182	(compare
5183	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5184		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5185	  (const_int 0)))			
5186   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5187	(plus:DI (match_dup 1) (match_dup 2)))]
5188  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5189   && ix86_binary_operator_ok (PLUS, DImode, operands)
5190   /* Current assemblers are broken and do not allow @GOTOFF in
5191      ought but a memory context.  */
5192   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5193{
5194  switch (get_attr_type (insn))
5195    {
5196    case TYPE_INCDEC:
5197      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5198      if (operands[2] == const1_rtx)
5199        return "inc{q}\t%0";
5200      else
5201        {
5202	  gcc_assert (operands[2] == constm1_rtx);
5203          return "dec{q}\t%0";
5204	}
5205
5206    default:
5207      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208      /* ???? We ought to handle there the 32bit case too
5209	 - do we need new constraint?  */
5210      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5212      if (GET_CODE (operands[2]) == CONST_INT
5213	  /* Avoid overflows.  */
5214	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5215          && (INTVAL (operands[2]) == 128
5216	      || (INTVAL (operands[2]) < 0
5217		  && INTVAL (operands[2]) != -128)))
5218        {
5219          operands[2] = GEN_INT (-INTVAL (operands[2]));
5220          return "sub{q}\t{%2, %0|%0, %2}";
5221        }
5222      return "add{q}\t{%2, %0|%0, %2}";
5223    }
5224}
5225  [(set (attr "type")
5226     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5227	(const_string "incdec")
5228	(const_string "alu")))
5229   (set_attr "mode" "DI")])
5230
5231(define_insn "*adddi_3_rex64"
5232  [(set (reg FLAGS_REG)
5233	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5234		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5235   (clobber (match_scratch:DI 0 "=r"))]
5236  "TARGET_64BIT
5237   && ix86_match_ccmode (insn, CCZmode)
5238   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5239   /* Current assemblers are broken and do not allow @GOTOFF in
5240      ought but a memory context.  */
5241   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5242{
5243  switch (get_attr_type (insn))
5244    {
5245    case TYPE_INCDEC:
5246      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247      if (operands[2] == const1_rtx)
5248        return "inc{q}\t%0";
5249      else
5250        {
5251	  gcc_assert (operands[2] == constm1_rtx);
5252          return "dec{q}\t%0";
5253	}
5254
5255    default:
5256      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5257      /* ???? We ought to handle there the 32bit case too
5258	 - do we need new constraint?  */
5259      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5261      if (GET_CODE (operands[2]) == CONST_INT
5262	  /* Avoid overflows.  */
5263	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264          && (INTVAL (operands[2]) == 128
5265	      || (INTVAL (operands[2]) < 0
5266		  && INTVAL (operands[2]) != -128)))
5267        {
5268          operands[2] = GEN_INT (-INTVAL (operands[2]));
5269          return "sub{q}\t{%2, %0|%0, %2}";
5270        }
5271      return "add{q}\t{%2, %0|%0, %2}";
5272    }
5273}
5274  [(set (attr "type")
5275     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5276	(const_string "incdec")
5277	(const_string "alu")))
5278   (set_attr "mode" "DI")])
5279
5280; For comparisons against 1, -1 and 128, we may generate better code
5281; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5282; is matched then.  We can't accept general immediate, because for
5283; case of overflows,  the result is messed up.
5284; This pattern also don't hold of 0x8000000000000000, since the value overflows
5285; when negated.
5286; Also carry flag is reversed compared to cmp, so this conversion is valid
5287; only for comparisons not depending on it.
5288(define_insn "*adddi_4_rex64"
5289  [(set (reg FLAGS_REG)
5290	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5291		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5292   (clobber (match_scratch:DI 0 "=rm"))]
5293  "TARGET_64BIT
5294   &&  ix86_match_ccmode (insn, CCGCmode)"
5295{
5296  switch (get_attr_type (insn))
5297    {
5298    case TYPE_INCDEC:
5299      if (operands[2] == constm1_rtx)
5300        return "inc{q}\t%0";
5301      else
5302        {
5303	  gcc_assert (operands[2] == const1_rtx);
5304          return "dec{q}\t%0";
5305	}
5306
5307    default:
5308      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5309      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5310	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5311      if ((INTVAL (operands[2]) == -128
5312	   || (INTVAL (operands[2]) > 0
5313	       && INTVAL (operands[2]) != 128))
5314	  /* Avoid overflows.  */
5315	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5316	return "sub{q}\t{%2, %0|%0, %2}";
5317      operands[2] = GEN_INT (-INTVAL (operands[2]));
5318      return "add{q}\t{%2, %0|%0, %2}";
5319    }
5320}
5321  [(set (attr "type")
5322     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5323	(const_string "incdec")
5324	(const_string "alu")))
5325   (set_attr "mode" "DI")])
5326
5327(define_insn "*adddi_5_rex64"
5328  [(set (reg FLAGS_REG)
5329	(compare
5330	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5331		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5332	  (const_int 0)))			
5333   (clobber (match_scratch:DI 0 "=r"))]
5334  "TARGET_64BIT
5335   && ix86_match_ccmode (insn, CCGOCmode)
5336   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5337   /* Current assemblers are broken and do not allow @GOTOFF in
5338      ought but a memory context.  */
5339   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5340{
5341  switch (get_attr_type (insn))
5342    {
5343    case TYPE_INCDEC:
5344      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5345      if (operands[2] == const1_rtx)
5346        return "inc{q}\t%0";
5347      else
5348        {
5349          gcc_assert (operands[2] == constm1_rtx);
5350          return "dec{q}\t%0";
5351	}
5352
5353    default:
5354      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5355      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5356	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5357      if (GET_CODE (operands[2]) == CONST_INT
5358	  /* Avoid overflows.  */
5359	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5360          && (INTVAL (operands[2]) == 128
5361	      || (INTVAL (operands[2]) < 0
5362		  && INTVAL (operands[2]) != -128)))
5363        {
5364          operands[2] = GEN_INT (-INTVAL (operands[2]));
5365          return "sub{q}\t{%2, %0|%0, %2}";
5366        }
5367      return "add{q}\t{%2, %0|%0, %2}";
5368    }
5369}
5370  [(set (attr "type")
5371     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5372	(const_string "incdec")
5373	(const_string "alu")))
5374   (set_attr "mode" "DI")])
5375
5376
5377(define_insn "*addsi_1"
5378  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5379	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5380		 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5381   (clobber (reg:CC FLAGS_REG))]
5382  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5383{
5384  switch (get_attr_type (insn))
5385    {
5386    case TYPE_LEA:
5387      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388      return "lea{l}\t{%a2, %0|%0, %a2}";
5389
5390    case TYPE_INCDEC:
5391      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392      if (operands[2] == const1_rtx)
5393        return "inc{l}\t%0";
5394      else
5395	{
5396  	  gcc_assert (operands[2] == constm1_rtx);
5397          return "dec{l}\t%0";
5398	}
5399
5400    default:
5401      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5402
5403      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5405      if (GET_CODE (operands[2]) == CONST_INT
5406          && (INTVAL (operands[2]) == 128
5407	      || (INTVAL (operands[2]) < 0
5408		  && INTVAL (operands[2]) != -128)))
5409        {
5410          operands[2] = GEN_INT (-INTVAL (operands[2]));
5411          return "sub{l}\t{%2, %0|%0, %2}";
5412        }
5413      return "add{l}\t{%2, %0|%0, %2}";
5414    }
5415}
5416  [(set (attr "type")
5417     (cond [(eq_attr "alternative" "2")
5418	      (const_string "lea")
5419	    ; Current assemblers are broken and do not allow @GOTOFF in
5420	    ; ought but a memory context.
5421	    (match_operand:SI 2 "pic_symbolic_operand" "")
5422	      (const_string "lea")
5423	    (match_operand:SI 2 "incdec_operand" "")
5424	      (const_string "incdec")
5425	   ]
5426	   (const_string "alu")))
5427   (set_attr "mode" "SI")])
5428
5429;; Convert lea to the lea pattern to avoid flags dependency.
5430(define_split
5431  [(set (match_operand 0 "register_operand" "")
5432	(plus (match_operand 1 "register_operand" "")
5433              (match_operand 2 "nonmemory_operand" "")))
5434   (clobber (reg:CC FLAGS_REG))]
5435  "reload_completed
5436   && true_regnum (operands[0]) != true_regnum (operands[1])"
5437  [(const_int 0)]
5438{
5439  rtx pat;
5440  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5441     may confuse gen_lowpart.  */
5442  if (GET_MODE (operands[0]) != Pmode)
5443    {
5444      operands[1] = gen_lowpart (Pmode, operands[1]);
5445      operands[2] = gen_lowpart (Pmode, operands[2]);
5446    }
5447  operands[0] = gen_lowpart (SImode, operands[0]);
5448  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5449  if (Pmode != SImode)
5450    pat = gen_rtx_SUBREG (SImode, pat, 0);
5451  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5452  DONE;
5453})
5454
5455;; It may seem that nonimmediate operand is proper one for operand 1.
5456;; The addsi_1 pattern allows nonimmediate operand at that place and
5457;; we take care in ix86_binary_operator_ok to not allow two memory
5458;; operands so proper swapping will be done in reload.  This allow
5459;; patterns constructed from addsi_1 to match.
5460(define_insn "addsi_1_zext"
5461  [(set (match_operand:DI 0 "register_operand" "=r,r")
5462	(zero_extend:DI
5463	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5464		   (match_operand:SI 2 "general_operand" "rmni,lni"))))
5465   (clobber (reg:CC FLAGS_REG))]
5466  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5467{
5468  switch (get_attr_type (insn))
5469    {
5470    case TYPE_LEA:
5471      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5472      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5473
5474    case TYPE_INCDEC:
5475      if (operands[2] == const1_rtx)
5476        return "inc{l}\t%k0";
5477      else
5478        {
5479	  gcc_assert (operands[2] == constm1_rtx);
5480          return "dec{l}\t%k0";
5481	}
5482
5483    default:
5484      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5485	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5486      if (GET_CODE (operands[2]) == CONST_INT
5487          && (INTVAL (operands[2]) == 128
5488	      || (INTVAL (operands[2]) < 0
5489		  && INTVAL (operands[2]) != -128)))
5490        {
5491          operands[2] = GEN_INT (-INTVAL (operands[2]));
5492          return "sub{l}\t{%2, %k0|%k0, %2}";
5493        }
5494      return "add{l}\t{%2, %k0|%k0, %2}";
5495    }
5496}
5497  [(set (attr "type")
5498     (cond [(eq_attr "alternative" "1")
5499	      (const_string "lea")
5500	    ; Current assemblers are broken and do not allow @GOTOFF in
5501	    ; ought but a memory context.
5502	    (match_operand:SI 2 "pic_symbolic_operand" "")
5503	      (const_string "lea")
5504	    (match_operand:SI 2 "incdec_operand" "")
5505	      (const_string "incdec")
5506	   ]
5507	   (const_string "alu")))
5508   (set_attr "mode" "SI")])
5509
5510;; Convert lea to the lea pattern to avoid flags dependency.
5511(define_split
5512  [(set (match_operand:DI 0 "register_operand" "")
5513	(zero_extend:DI
5514	  (plus:SI (match_operand:SI 1 "register_operand" "")
5515		   (match_operand:SI 2 "nonmemory_operand" ""))))
5516   (clobber (reg:CC FLAGS_REG))]
5517  "TARGET_64BIT && reload_completed
5518   && true_regnum (operands[0]) != true_regnum (operands[1])"
5519  [(set (match_dup 0)
5520	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5521{
5522  operands[1] = gen_lowpart (Pmode, operands[1]);
5523  operands[2] = gen_lowpart (Pmode, operands[2]);
5524})
5525
5526(define_insn "*addsi_2"
5527  [(set (reg FLAGS_REG)
5528	(compare
5529	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5530		   (match_operand:SI 2 "general_operand" "rmni,rni"))
5531	  (const_int 0)))			
5532   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5533	(plus:SI (match_dup 1) (match_dup 2)))]
5534  "ix86_match_ccmode (insn, CCGOCmode)
5535   && ix86_binary_operator_ok (PLUS, SImode, operands)
5536   /* Current assemblers are broken and do not allow @GOTOFF in
5537      ought but a memory context.  */
5538   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5539{
5540  switch (get_attr_type (insn))
5541    {
5542    case TYPE_INCDEC:
5543      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544      if (operands[2] == const1_rtx)
5545        return "inc{l}\t%0";
5546      else
5547        {
5548	  gcc_assert (operands[2] == constm1_rtx);
5549          return "dec{l}\t%0";
5550	}
5551
5552    default:
5553      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5556      if (GET_CODE (operands[2]) == CONST_INT
5557          && (INTVAL (operands[2]) == 128
5558	      || (INTVAL (operands[2]) < 0
5559		  && INTVAL (operands[2]) != -128)))
5560        {
5561          operands[2] = GEN_INT (-INTVAL (operands[2]));
5562          return "sub{l}\t{%2, %0|%0, %2}";
5563        }
5564      return "add{l}\t{%2, %0|%0, %2}";
5565    }
5566}
5567  [(set (attr "type")
5568     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569	(const_string "incdec")
5570	(const_string "alu")))
5571   (set_attr "mode" "SI")])
5572
5573;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574(define_insn "*addsi_2_zext"
5575  [(set (reg FLAGS_REG)
5576	(compare
5577	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5578		   (match_operand:SI 2 "general_operand" "rmni"))
5579	  (const_int 0)))			
5580   (set (match_operand:DI 0 "register_operand" "=r")
5581	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5582  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583   && ix86_binary_operator_ok (PLUS, SImode, operands)
5584   /* Current assemblers are broken and do not allow @GOTOFF in
5585      ought but a memory context.  */
5586   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5587{
5588  switch (get_attr_type (insn))
5589    {
5590    case TYPE_INCDEC:
5591      if (operands[2] == const1_rtx)
5592        return "inc{l}\t%k0";
5593      else
5594	{
5595	  gcc_assert (operands[2] == constm1_rtx);
5596          return "dec{l}\t%k0";
5597	}
5598
5599    default:
5600      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5602      if (GET_CODE (operands[2]) == CONST_INT
5603          && (INTVAL (operands[2]) == 128
5604	      || (INTVAL (operands[2]) < 0
5605		  && INTVAL (operands[2]) != -128)))
5606        {
5607          operands[2] = GEN_INT (-INTVAL (operands[2]));
5608          return "sub{l}\t{%2, %k0|%k0, %2}";
5609        }
5610      return "add{l}\t{%2, %k0|%k0, %2}";
5611    }
5612}
5613  [(set (attr "type")
5614     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5615	(const_string "incdec")
5616	(const_string "alu")))
5617   (set_attr "mode" "SI")])
5618
5619(define_insn "*addsi_3"
5620  [(set (reg FLAGS_REG)
5621	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5622		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5623   (clobber (match_scratch:SI 0 "=r"))]
5624  "ix86_match_ccmode (insn, CCZmode)
5625   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626   /* Current assemblers are broken and do not allow @GOTOFF in
5627      ought but a memory context.  */
5628   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629{
5630  switch (get_attr_type (insn))
5631    {
5632    case TYPE_INCDEC:
5633      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634      if (operands[2] == const1_rtx)
5635        return "inc{l}\t%0";
5636      else
5637        {
5638	  gcc_assert (operands[2] == constm1_rtx);
5639          return "dec{l}\t%0";
5640	}
5641
5642    default:
5643      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5646      if (GET_CODE (operands[2]) == CONST_INT
5647          && (INTVAL (operands[2]) == 128
5648	      || (INTVAL (operands[2]) < 0
5649		  && INTVAL (operands[2]) != -128)))
5650        {
5651          operands[2] = GEN_INT (-INTVAL (operands[2]));
5652          return "sub{l}\t{%2, %0|%0, %2}";
5653        }
5654      return "add{l}\t{%2, %0|%0, %2}";
5655    }
5656}
5657  [(set (attr "type")
5658     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659	(const_string "incdec")
5660	(const_string "alu")))
5661   (set_attr "mode" "SI")])
5662
5663;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664(define_insn "*addsi_3_zext"
5665  [(set (reg FLAGS_REG)
5666	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5667		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5668   (set (match_operand:DI 0 "register_operand" "=r")
5669	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5670  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5671   && ix86_binary_operator_ok (PLUS, SImode, operands)
5672   /* Current assemblers are broken and do not allow @GOTOFF in
5673      ought but a memory context.  */
5674   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5675{
5676  switch (get_attr_type (insn))
5677    {
5678    case TYPE_INCDEC:
5679      if (operands[2] == const1_rtx)
5680        return "inc{l}\t%k0";
5681      else
5682        {
5683	  gcc_assert (operands[2] == constm1_rtx);
5684          return "dec{l}\t%k0";
5685	}
5686
5687    default:
5688      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5689	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5690      if (GET_CODE (operands[2]) == CONST_INT
5691          && (INTVAL (operands[2]) == 128
5692	      || (INTVAL (operands[2]) < 0
5693		  && INTVAL (operands[2]) != -128)))
5694        {
5695          operands[2] = GEN_INT (-INTVAL (operands[2]));
5696          return "sub{l}\t{%2, %k0|%k0, %2}";
5697        }
5698      return "add{l}\t{%2, %k0|%k0, %2}";
5699    }
5700}
5701  [(set (attr "type")
5702     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5703	(const_string "incdec")
5704	(const_string "alu")))
5705   (set_attr "mode" "SI")])
5706
5707; For comparisons against 1, -1 and 128, we may generate better code
5708; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5709; is matched then.  We can't accept general immediate, because for
5710; case of overflows,  the result is messed up.
5711; This pattern also don't hold of 0x80000000, since the value overflows
5712; when negated.
5713; Also carry flag is reversed compared to cmp, so this conversion is valid
5714; only for comparisons not depending on it.
5715(define_insn "*addsi_4"
5716  [(set (reg FLAGS_REG)
5717	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
5718		 (match_operand:SI 2 "const_int_operand" "n")))
5719   (clobber (match_scratch:SI 0 "=rm"))]
5720  "ix86_match_ccmode (insn, CCGCmode)
5721   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5722{
5723  switch (get_attr_type (insn))
5724    {
5725    case TYPE_INCDEC:
5726      if (operands[2] == constm1_rtx)
5727        return "inc{l}\t%0";
5728      else
5729        {
5730	  gcc_assert (operands[2] == const1_rtx);
5731          return "dec{l}\t%0";
5732	}
5733
5734    default:
5735      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5737	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5738      if ((INTVAL (operands[2]) == -128
5739	   || (INTVAL (operands[2]) > 0
5740	       && INTVAL (operands[2]) != 128)))
5741	return "sub{l}\t{%2, %0|%0, %2}";
5742      operands[2] = GEN_INT (-INTVAL (operands[2]));
5743      return "add{l}\t{%2, %0|%0, %2}";
5744    }
5745}
5746  [(set (attr "type")
5747     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5748	(const_string "incdec")
5749	(const_string "alu")))
5750   (set_attr "mode" "SI")])
5751
5752(define_insn "*addsi_5"
5753  [(set (reg FLAGS_REG)
5754	(compare
5755	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5756		   (match_operand:SI 2 "general_operand" "rmni"))
5757	  (const_int 0)))			
5758   (clobber (match_scratch:SI 0 "=r"))]
5759  "ix86_match_ccmode (insn, CCGOCmode)
5760   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761   /* Current assemblers are broken and do not allow @GOTOFF in
5762      ought but a memory context.  */
5763   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764{
5765  switch (get_attr_type (insn))
5766    {
5767    case TYPE_INCDEC:
5768      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5769      if (operands[2] == const1_rtx)
5770        return "inc{l}\t%0";
5771      else
5772        {
5773	  gcc_assert (operands[2] == constm1_rtx);
5774          return "dec{l}\t%0";
5775	}
5776
5777    default:
5778      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5781      if (GET_CODE (operands[2]) == CONST_INT
5782          && (INTVAL (operands[2]) == 128
5783	      || (INTVAL (operands[2]) < 0
5784		  && INTVAL (operands[2]) != -128)))
5785        {
5786          operands[2] = GEN_INT (-INTVAL (operands[2]));
5787          return "sub{l}\t{%2, %0|%0, %2}";
5788        }
5789      return "add{l}\t{%2, %0|%0, %2}";
5790    }
5791}
5792  [(set (attr "type")
5793     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794	(const_string "incdec")
5795	(const_string "alu")))
5796   (set_attr "mode" "SI")])
5797
5798(define_expand "addhi3"
5799  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5800		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5801			    (match_operand:HI 2 "general_operand" "")))
5802	      (clobber (reg:CC FLAGS_REG))])]
5803  "TARGET_HIMODE_MATH"
5804  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5805
5806;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5807;; type optimizations enabled by define-splits.  This is not important
5808;; for PII, and in fact harmful because of partial register stalls.
5809
5810(define_insn "*addhi_1_lea"
5811  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5812	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5813		 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5814   (clobber (reg:CC FLAGS_REG))]
5815  "!TARGET_PARTIAL_REG_STALL
5816   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5817{
5818  switch (get_attr_type (insn))
5819    {
5820    case TYPE_LEA:
5821      return "#";
5822    case TYPE_INCDEC:
5823      if (operands[2] == const1_rtx)
5824	return "inc{w}\t%0";
5825      else
5826	{
5827	  gcc_assert (operands[2] == constm1_rtx);
5828	  return "dec{w}\t%0";
5829	}
5830
5831    default:
5832      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5834      if (GET_CODE (operands[2]) == CONST_INT
5835          && (INTVAL (operands[2]) == 128
5836	      || (INTVAL (operands[2]) < 0
5837		  && INTVAL (operands[2]) != -128)))
5838	{
5839	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5840	  return "sub{w}\t{%2, %0|%0, %2}";
5841	}
5842      return "add{w}\t{%2, %0|%0, %2}";
5843    }
5844}
5845  [(set (attr "type")
5846     (if_then_else (eq_attr "alternative" "2")
5847	(const_string "lea")
5848	(if_then_else (match_operand:HI 2 "incdec_operand" "")
5849	   (const_string "incdec")
5850	   (const_string "alu"))))
5851   (set_attr "mode" "HI,HI,SI")])
5852
5853(define_insn "*addhi_1"
5854  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5855	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5856		 (match_operand:HI 2 "general_operand" "ri,rm")))
5857   (clobber (reg:CC FLAGS_REG))]
5858  "TARGET_PARTIAL_REG_STALL
5859   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5860{
5861  switch (get_attr_type (insn))
5862    {
5863    case TYPE_INCDEC:
5864      if (operands[2] == const1_rtx)
5865	return "inc{w}\t%0";
5866      else
5867        {
5868	  gcc_assert (operands[2] == constm1_rtx);
5869	  return "dec{w}\t%0";
5870	}
5871
5872    default:
5873      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5875      if (GET_CODE (operands[2]) == CONST_INT
5876          && (INTVAL (operands[2]) == 128
5877	      || (INTVAL (operands[2]) < 0
5878		  && INTVAL (operands[2]) != -128)))
5879	{
5880	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5881	  return "sub{w}\t{%2, %0|%0, %2}";
5882	}
5883      return "add{w}\t{%2, %0|%0, %2}";
5884    }
5885}
5886  [(set (attr "type")
5887     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888	(const_string "incdec")
5889	(const_string "alu")))
5890   (set_attr "mode" "HI")])
5891
5892(define_insn "*addhi_2"
5893  [(set (reg FLAGS_REG)
5894	(compare
5895	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896		   (match_operand:HI 2 "general_operand" "rmni,rni"))
5897	  (const_int 0)))			
5898   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5899	(plus:HI (match_dup 1) (match_dup 2)))]
5900  "ix86_match_ccmode (insn, CCGOCmode)
5901   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5902{
5903  switch (get_attr_type (insn))
5904    {
5905    case TYPE_INCDEC:
5906      if (operands[2] == const1_rtx)
5907	return "inc{w}\t%0";
5908      else
5909        {
5910	  gcc_assert (operands[2] == constm1_rtx);
5911	  return "dec{w}\t%0";
5912	}
5913
5914    default:
5915      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5917      if (GET_CODE (operands[2]) == CONST_INT
5918          && (INTVAL (operands[2]) == 128
5919	      || (INTVAL (operands[2]) < 0
5920		  && INTVAL (operands[2]) != -128)))
5921	{
5922	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5923	  return "sub{w}\t{%2, %0|%0, %2}";
5924	}
5925      return "add{w}\t{%2, %0|%0, %2}";
5926    }
5927}
5928  [(set (attr "type")
5929     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930	(const_string "incdec")
5931	(const_string "alu")))
5932   (set_attr "mode" "HI")])
5933
5934(define_insn "*addhi_3"
5935  [(set (reg FLAGS_REG)
5936	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5937		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5938   (clobber (match_scratch:HI 0 "=r"))]
5939  "ix86_match_ccmode (insn, CCZmode)
5940   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5941{
5942  switch (get_attr_type (insn))
5943    {
5944    case TYPE_INCDEC:
5945      if (operands[2] == const1_rtx)
5946	return "inc{w}\t%0";
5947      else
5948        {
5949	  gcc_assert (operands[2] == constm1_rtx);
5950	  return "dec{w}\t%0";
5951	}
5952
5953    default:
5954      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5956      if (GET_CODE (operands[2]) == CONST_INT
5957          && (INTVAL (operands[2]) == 128
5958	      || (INTVAL (operands[2]) < 0
5959		  && INTVAL (operands[2]) != -128)))
5960	{
5961	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5962	  return "sub{w}\t{%2, %0|%0, %2}";
5963	}
5964      return "add{w}\t{%2, %0|%0, %2}";
5965    }
5966}
5967  [(set (attr "type")
5968     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5969	(const_string "incdec")
5970	(const_string "alu")))
5971   (set_attr "mode" "HI")])
5972
5973; See comments above addsi_4 for details.
5974(define_insn "*addhi_4"
5975  [(set (reg FLAGS_REG)
5976	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
5977		 (match_operand:HI 2 "const_int_operand" "n")))
5978   (clobber (match_scratch:HI 0 "=rm"))]
5979  "ix86_match_ccmode (insn, CCGCmode)
5980   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5981{
5982  switch (get_attr_type (insn))
5983    {
5984    case TYPE_INCDEC:
5985      if (operands[2] == constm1_rtx)
5986        return "inc{w}\t%0";
5987      else
5988	{
5989	  gcc_assert (operands[2] == const1_rtx);
5990          return "dec{w}\t%0";
5991	}
5992
5993    default:
5994      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5997      if ((INTVAL (operands[2]) == -128
5998	   || (INTVAL (operands[2]) > 0
5999	       && INTVAL (operands[2]) != 128)))
6000	return "sub{w}\t{%2, %0|%0, %2}";
6001      operands[2] = GEN_INT (-INTVAL (operands[2]));
6002      return "add{w}\t{%2, %0|%0, %2}";
6003    }
6004}
6005  [(set (attr "type")
6006     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007	(const_string "incdec")
6008	(const_string "alu")))
6009   (set_attr "mode" "SI")])
6010
6011
6012(define_insn "*addhi_5"
6013  [(set (reg FLAGS_REG)
6014	(compare
6015	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6016		   (match_operand:HI 2 "general_operand" "rmni"))
6017	  (const_int 0)))			
6018   (clobber (match_scratch:HI 0 "=r"))]
6019  "ix86_match_ccmode (insn, CCGOCmode)
6020   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6021{
6022  switch (get_attr_type (insn))
6023    {
6024    case TYPE_INCDEC:
6025      if (operands[2] == const1_rtx)
6026	return "inc{w}\t%0";
6027      else
6028	{
6029	  gcc_assert (operands[2] == constm1_rtx);
6030	  return "dec{w}\t%0";
6031	}
6032
6033    default:
6034      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6036      if (GET_CODE (operands[2]) == CONST_INT
6037          && (INTVAL (operands[2]) == 128
6038	      || (INTVAL (operands[2]) < 0
6039		  && INTVAL (operands[2]) != -128)))
6040	{
6041	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6042	  return "sub{w}\t{%2, %0|%0, %2}";
6043	}
6044      return "add{w}\t{%2, %0|%0, %2}";
6045    }
6046}
6047  [(set (attr "type")
6048     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049	(const_string "incdec")
6050	(const_string "alu")))
6051   (set_attr "mode" "HI")])
6052
6053(define_expand "addqi3"
6054  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6055		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6056			    (match_operand:QI 2 "general_operand" "")))
6057	      (clobber (reg:CC FLAGS_REG))])]
6058  "TARGET_QIMODE_MATH"
6059  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6060
6061;; %%% Potential partial reg stall on alternative 2.  What to do?
6062(define_insn "*addqi_1_lea"
6063  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6064	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6065		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6066   (clobber (reg:CC FLAGS_REG))]
6067  "!TARGET_PARTIAL_REG_STALL
6068   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6069{
6070  int widen = (which_alternative == 2);
6071  switch (get_attr_type (insn))
6072    {
6073    case TYPE_LEA:
6074      return "#";
6075    case TYPE_INCDEC:
6076      if (operands[2] == const1_rtx)
6077	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6078      else
6079	{
6080	  gcc_assert (operands[2] == constm1_rtx);
6081	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6082	}
6083
6084    default:
6085      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087      if (GET_CODE (operands[2]) == CONST_INT
6088          && (INTVAL (operands[2]) == 128
6089	      || (INTVAL (operands[2]) < 0
6090		  && INTVAL (operands[2]) != -128)))
6091	{
6092	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6093	  if (widen)
6094	    return "sub{l}\t{%2, %k0|%k0, %2}";
6095	  else
6096	    return "sub{b}\t{%2, %0|%0, %2}";
6097	}
6098      if (widen)
6099        return "add{l}\t{%k2, %k0|%k0, %k2}";
6100      else
6101        return "add{b}\t{%2, %0|%0, %2}";
6102    }
6103}
6104  [(set (attr "type")
6105     (if_then_else (eq_attr "alternative" "3")
6106	(const_string "lea")
6107	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6108	   (const_string "incdec")
6109	   (const_string "alu"))))
6110   (set_attr "mode" "QI,QI,SI,SI")])
6111
6112(define_insn "*addqi_1"
6113  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6114	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6115		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6116   (clobber (reg:CC FLAGS_REG))]
6117  "TARGET_PARTIAL_REG_STALL
6118   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119{
6120  int widen = (which_alternative == 2);
6121  switch (get_attr_type (insn))
6122    {
6123    case TYPE_INCDEC:
6124      if (operands[2] == const1_rtx)
6125	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6126      else
6127	{
6128	  gcc_assert (operands[2] == constm1_rtx);
6129	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6130	}
6131
6132    default:
6133      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6135      if (GET_CODE (operands[2]) == CONST_INT
6136          && (INTVAL (operands[2]) == 128
6137	      || (INTVAL (operands[2]) < 0
6138		  && INTVAL (operands[2]) != -128)))
6139	{
6140	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6141	  if (widen)
6142	    return "sub{l}\t{%2, %k0|%k0, %2}";
6143	  else
6144	    return "sub{b}\t{%2, %0|%0, %2}";
6145	}
6146      if (widen)
6147        return "add{l}\t{%k2, %k0|%k0, %k2}";
6148      else
6149        return "add{b}\t{%2, %0|%0, %2}";
6150    }
6151}
6152  [(set (attr "type")
6153     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154	(const_string "incdec")
6155	(const_string "alu")))
6156   (set_attr "mode" "QI,QI,SI")])
6157
6158(define_insn "*addqi_1_slp"
6159  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6160	(plus:QI (match_dup 0)
6161		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6162   (clobber (reg:CC FLAGS_REG))]
6163  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6164   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6165{
6166  switch (get_attr_type (insn))
6167    {
6168    case TYPE_INCDEC:
6169      if (operands[1] == const1_rtx)
6170	return "inc{b}\t%0";
6171      else
6172	{
6173	  gcc_assert (operands[1] == constm1_rtx);
6174	  return "dec{b}\t%0";
6175	}
6176
6177    default:
6178      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6179      if (GET_CODE (operands[1]) == CONST_INT
6180	  && INTVAL (operands[1]) < 0)
6181	{
6182	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6183	  return "sub{b}\t{%1, %0|%0, %1}";
6184	}
6185      return "add{b}\t{%1, %0|%0, %1}";
6186    }
6187}
6188  [(set (attr "type")
6189     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6190	(const_string "incdec")
6191	(const_string "alu1")))
6192   (set (attr "memory")
6193     (if_then_else (match_operand 1 "memory_operand" "")
6194        (const_string "load")
6195        (const_string "none")))
6196   (set_attr "mode" "QI")])
6197
6198(define_insn "*addqi_2"
6199  [(set (reg FLAGS_REG)
6200	(compare
6201	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6202		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6203	  (const_int 0)))
6204   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6205	(plus:QI (match_dup 1) (match_dup 2)))]
6206  "ix86_match_ccmode (insn, CCGOCmode)
6207   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6208{
6209  switch (get_attr_type (insn))
6210    {
6211    case TYPE_INCDEC:
6212      if (operands[2] == const1_rtx)
6213	return "inc{b}\t%0";
6214      else
6215        {
6216	  gcc_assert (operands[2] == constm1_rtx
6217		      || (GET_CODE (operands[2]) == CONST_INT
6218		          && INTVAL (operands[2]) == 255));
6219	  return "dec{b}\t%0";
6220	}
6221
6222    default:
6223      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6224      if (GET_CODE (operands[2]) == CONST_INT
6225          && INTVAL (operands[2]) < 0)
6226	{
6227	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6228	  return "sub{b}\t{%2, %0|%0, %2}";
6229	}
6230      return "add{b}\t{%2, %0|%0, %2}";
6231    }
6232}
6233  [(set (attr "type")
6234     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6235	(const_string "incdec")
6236	(const_string "alu")))
6237   (set_attr "mode" "QI")])
6238
6239(define_insn "*addqi_3"
6240  [(set (reg FLAGS_REG)
6241	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6242		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6243   (clobber (match_scratch:QI 0 "=q"))]
6244  "ix86_match_ccmode (insn, CCZmode)
6245   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6246{
6247  switch (get_attr_type (insn))
6248    {
6249    case TYPE_INCDEC:
6250      if (operands[2] == const1_rtx)
6251	return "inc{b}\t%0";
6252      else
6253        {
6254	  gcc_assert (operands[2] == constm1_rtx
6255		      || (GET_CODE (operands[2]) == CONST_INT
6256			  && INTVAL (operands[2]) == 255));
6257	  return "dec{b}\t%0";
6258	}
6259
6260    default:
6261      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6262      if (GET_CODE (operands[2]) == CONST_INT
6263          && INTVAL (operands[2]) < 0)
6264	{
6265	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6266	  return "sub{b}\t{%2, %0|%0, %2}";
6267	}
6268      return "add{b}\t{%2, %0|%0, %2}";
6269    }
6270}
6271  [(set (attr "type")
6272     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6273	(const_string "incdec")
6274	(const_string "alu")))
6275   (set_attr "mode" "QI")])
6276
6277; See comments above addsi_4 for details.
6278(define_insn "*addqi_4"
6279  [(set (reg FLAGS_REG)
6280	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6281		 (match_operand:QI 2 "const_int_operand" "n")))
6282   (clobber (match_scratch:QI 0 "=qm"))]
6283  "ix86_match_ccmode (insn, CCGCmode)
6284   && (INTVAL (operands[2]) & 0xff) != 0x80"
6285{
6286  switch (get_attr_type (insn))
6287    {
6288    case TYPE_INCDEC:
6289      if (operands[2] == constm1_rtx
6290	  || (GET_CODE (operands[2]) == CONST_INT
6291	      && INTVAL (operands[2]) == 255))
6292        return "inc{b}\t%0";
6293      else
6294	{
6295	  gcc_assert (operands[2] == const1_rtx);
6296          return "dec{b}\t%0";
6297	}
6298
6299    default:
6300      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301      if (INTVAL (operands[2]) < 0)
6302        {
6303          operands[2] = GEN_INT (-INTVAL (operands[2]));
6304          return "add{b}\t{%2, %0|%0, %2}";
6305        }
6306      return "sub{b}\t{%2, %0|%0, %2}";
6307    }
6308}
6309  [(set (attr "type")
6310     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6311	(const_string "incdec")
6312	(const_string "alu")))
6313   (set_attr "mode" "QI")])
6314
6315
6316(define_insn "*addqi_5"
6317  [(set (reg FLAGS_REG)
6318	(compare
6319	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6320		   (match_operand:QI 2 "general_operand" "qmni"))
6321	  (const_int 0)))
6322   (clobber (match_scratch:QI 0 "=q"))]
6323  "ix86_match_ccmode (insn, CCGOCmode)
6324   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6325{
6326  switch (get_attr_type (insn))
6327    {
6328    case TYPE_INCDEC:
6329      if (operands[2] == const1_rtx)
6330	return "inc{b}\t%0";
6331      else
6332        {
6333	  gcc_assert (operands[2] == constm1_rtx
6334		      || (GET_CODE (operands[2]) == CONST_INT
6335			  && INTVAL (operands[2]) == 255));
6336	  return "dec{b}\t%0";
6337	}
6338
6339    default:
6340      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6341      if (GET_CODE (operands[2]) == CONST_INT
6342          && INTVAL (operands[2]) < 0)
6343	{
6344	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6345	  return "sub{b}\t{%2, %0|%0, %2}";
6346	}
6347      return "add{b}\t{%2, %0|%0, %2}";
6348    }
6349}
6350  [(set (attr "type")
6351     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352	(const_string "incdec")
6353	(const_string "alu")))
6354   (set_attr "mode" "QI")])
6355
6356
6357(define_insn "addqi_ext_1"
6358  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359			 (const_int 8)
6360			 (const_int 8))
6361	(plus:SI
6362	  (zero_extract:SI
6363	    (match_operand 1 "ext_register_operand" "0")
6364	    (const_int 8)
6365	    (const_int 8))
6366	  (match_operand:QI 2 "general_operand" "Qmn")))
6367   (clobber (reg:CC FLAGS_REG))]
6368  "!TARGET_64BIT"
6369{
6370  switch (get_attr_type (insn))
6371    {
6372    case TYPE_INCDEC:
6373      if (operands[2] == const1_rtx)
6374	return "inc{b}\t%h0";
6375      else
6376        {
6377	  gcc_assert (operands[2] == constm1_rtx
6378		      || (GET_CODE (operands[2]) == CONST_INT
6379			  && INTVAL (operands[2]) == 255));
6380          return "dec{b}\t%h0";
6381	}
6382
6383    default:
6384      return "add{b}\t{%2, %h0|%h0, %2}";
6385    }
6386}
6387  [(set (attr "type")
6388     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389	(const_string "incdec")
6390	(const_string "alu")))
6391   (set_attr "mode" "QI")])
6392
6393(define_insn "*addqi_ext_1_rex64"
6394  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395			 (const_int 8)
6396			 (const_int 8))
6397	(plus:SI
6398	  (zero_extract:SI
6399	    (match_operand 1 "ext_register_operand" "0")
6400	    (const_int 8)
6401	    (const_int 8))
6402	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6403   (clobber (reg:CC FLAGS_REG))]
6404  "TARGET_64BIT"
6405{
6406  switch (get_attr_type (insn))
6407    {
6408    case TYPE_INCDEC:
6409      if (operands[2] == const1_rtx)
6410	return "inc{b}\t%h0";
6411      else
6412        {
6413	  gcc_assert (operands[2] == constm1_rtx
6414		      || (GET_CODE (operands[2]) == CONST_INT
6415			  && INTVAL (operands[2]) == 255));
6416          return "dec{b}\t%h0";
6417        }
6418
6419    default:
6420      return "add{b}\t{%2, %h0|%h0, %2}";
6421    }
6422}
6423  [(set (attr "type")
6424     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425	(const_string "incdec")
6426	(const_string "alu")))
6427   (set_attr "mode" "QI")])
6428
6429(define_insn "*addqi_ext_2"
6430  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6431			 (const_int 8)
6432			 (const_int 8))
6433	(plus:SI
6434	  (zero_extract:SI
6435	    (match_operand 1 "ext_register_operand" "%0")
6436	    (const_int 8)
6437	    (const_int 8))
6438	  (zero_extract:SI
6439	    (match_operand 2 "ext_register_operand" "Q")
6440	    (const_int 8)
6441	    (const_int 8))))
6442   (clobber (reg:CC FLAGS_REG))]
6443  ""
6444  "add{b}\t{%h2, %h0|%h0, %h2}"
6445  [(set_attr "type" "alu")
6446   (set_attr "mode" "QI")])
6447
6448;; The patterns that match these are at the end of this file.
6449
6450(define_expand "addxf3"
6451  [(set (match_operand:XF 0 "register_operand" "")
6452	(plus:XF (match_operand:XF 1 "register_operand" "")
6453		 (match_operand:XF 2 "register_operand" "")))]
6454  "TARGET_80387"
6455  "")
6456
6457(define_expand "adddf3"
6458  [(set (match_operand:DF 0 "register_operand" "")
6459	(plus:DF (match_operand:DF 1 "register_operand" "")
6460		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6461  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6462  "")
6463
6464(define_expand "addsf3"
6465  [(set (match_operand:SF 0 "register_operand" "")
6466	(plus:SF (match_operand:SF 1 "register_operand" "")
6467		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6468  "TARGET_80387 || TARGET_SSE_MATH"
6469  "")
6470
6471;; Subtract instructions
6472
6473;; %%% splits for subditi3
6474
6475(define_expand "subti3"
6476  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6477		   (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6478			     (match_operand:TI 2 "x86_64_general_operand" "")))
6479	      (clobber (reg:CC FLAGS_REG))])]
6480  "TARGET_64BIT"
6481  "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6482
6483(define_insn "*subti3_1"
6484  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6485	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6486		  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6487   (clobber (reg:CC FLAGS_REG))]
6488  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6489  "#")
6490
6491(define_split
6492  [(set (match_operand:TI 0 "nonimmediate_operand" "")
6493	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6494		  (match_operand:TI 2 "x86_64_general_operand" "")))
6495   (clobber (reg:CC FLAGS_REG))]
6496  "TARGET_64BIT && reload_completed"
6497  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498	      (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6499   (parallel [(set (match_dup 3)
6500		   (minus:DI (match_dup 4)
6501			     (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6502				      (match_dup 5))))
6503	      (clobber (reg:CC FLAGS_REG))])]
6504  "split_ti (operands+0, 1, operands+0, operands+3);
6505   split_ti (operands+1, 1, operands+1, operands+4);
6506   split_ti (operands+2, 1, operands+2, operands+5);")
6507
6508;; %%% splits for subsidi3
6509
6510(define_expand "subdi3"
6511  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6512		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6513			     (match_operand:DI 2 "x86_64_general_operand" "")))
6514	      (clobber (reg:CC FLAGS_REG))])]
6515  ""
6516  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6517
6518(define_insn "*subdi3_1"
6519  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6520	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6522   (clobber (reg:CC FLAGS_REG))]
6523  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6524  "#")
6525
6526(define_split
6527  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6528	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6529		  (match_operand:DI 2 "general_operand" "")))
6530   (clobber (reg:CC FLAGS_REG))]
6531  "!TARGET_64BIT && reload_completed"
6532  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6533	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6534   (parallel [(set (match_dup 3)
6535		   (minus:SI (match_dup 4)
6536			     (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6537				      (match_dup 5))))
6538	      (clobber (reg:CC FLAGS_REG))])]
6539  "split_di (operands+0, 1, operands+0, operands+3);
6540   split_di (operands+1, 1, operands+1, operands+4);
6541   split_di (operands+2, 1, operands+2, operands+5);")
6542
6543(define_insn "subdi3_carry_rex64"
6544  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6545	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6547	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6548   (clobber (reg:CC FLAGS_REG))]
6549  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550  "sbb{q}\t{%2, %0|%0, %2}"
6551  [(set_attr "type" "alu")
6552   (set_attr "pent_pair" "pu")
6553   (set_attr "mode" "DI")])
6554
6555(define_insn "*subdi_1_rex64"
6556  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559   (clobber (reg:CC FLAGS_REG))]
6560  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561  "sub{q}\t{%2, %0|%0, %2}"
6562  [(set_attr "type" "alu")
6563   (set_attr "mode" "DI")])
6564
6565(define_insn "*subdi_2_rex64"
6566  [(set (reg FLAGS_REG)
6567	(compare
6568	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6569		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6570	  (const_int 0)))
6571   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572	(minus:DI (match_dup 1) (match_dup 2)))]
6573  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6574   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575  "sub{q}\t{%2, %0|%0, %2}"
6576  [(set_attr "type" "alu")
6577   (set_attr "mode" "DI")])
6578
6579(define_insn "*subdi_3_rex63"
6580  [(set (reg FLAGS_REG)
6581	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6582		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6583   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584	(minus:DI (match_dup 1) (match_dup 2)))]
6585  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587  "sub{q}\t{%2, %0|%0, %2}"
6588  [(set_attr "type" "alu")
6589   (set_attr "mode" "DI")])
6590
6591(define_insn "subqi3_carry"
6592  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6593	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6594	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6595	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6596   (clobber (reg:CC FLAGS_REG))]
6597  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6598  "sbb{b}\t{%2, %0|%0, %2}"
6599  [(set_attr "type" "alu")
6600   (set_attr "pent_pair" "pu")
6601   (set_attr "mode" "QI")])
6602
6603(define_insn "subhi3_carry"
6604  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6605	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6607	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6608   (clobber (reg:CC FLAGS_REG))]
6609  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6610  "sbb{w}\t{%2, %0|%0, %2}"
6611  [(set_attr "type" "alu")
6612   (set_attr "pent_pair" "pu")
6613   (set_attr "mode" "HI")])
6614
6615(define_insn "subsi3_carry"
6616  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6619	       (match_operand:SI 2 "general_operand" "ri,rm"))))
6620   (clobber (reg:CC FLAGS_REG))]
6621  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622  "sbb{l}\t{%2, %0|%0, %2}"
6623  [(set_attr "type" "alu")
6624   (set_attr "pent_pair" "pu")
6625   (set_attr "mode" "SI")])
6626
6627(define_insn "subsi3_carry_zext"
6628  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6629	  (zero_extend:DI
6630	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6631	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6632		 (match_operand:SI 2 "general_operand" "ri,rm")))))
6633   (clobber (reg:CC FLAGS_REG))]
6634  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635  "sbb{l}\t{%2, %k0|%k0, %2}"
6636  [(set_attr "type" "alu")
6637   (set_attr "pent_pair" "pu")
6638   (set_attr "mode" "SI")])
6639
6640(define_expand "subsi3"
6641  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6642		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6643			     (match_operand:SI 2 "general_operand" "")))
6644	      (clobber (reg:CC FLAGS_REG))])]
6645  ""
6646  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6647
6648(define_insn "*subsi_1"
6649  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6650	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6651		  (match_operand:SI 2 "general_operand" "ri,rm")))
6652   (clobber (reg:CC FLAGS_REG))]
6653  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6654  "sub{l}\t{%2, %0|%0, %2}"
6655  [(set_attr "type" "alu")
6656   (set_attr "mode" "SI")])
6657
6658(define_insn "*subsi_1_zext"
6659  [(set (match_operand:DI 0 "register_operand" "=r")
6660	(zero_extend:DI
6661	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6662		    (match_operand:SI 2 "general_operand" "rim"))))
6663   (clobber (reg:CC FLAGS_REG))]
6664  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665  "sub{l}\t{%2, %k0|%k0, %2}"
6666  [(set_attr "type" "alu")
6667   (set_attr "mode" "SI")])
6668
6669(define_insn "*subsi_2"
6670  [(set (reg FLAGS_REG)
6671	(compare
6672	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673		    (match_operand:SI 2 "general_operand" "ri,rm"))
6674	  (const_int 0)))
6675   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6676	(minus:SI (match_dup 1) (match_dup 2)))]
6677  "ix86_match_ccmode (insn, CCGOCmode)
6678   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679  "sub{l}\t{%2, %0|%0, %2}"
6680  [(set_attr "type" "alu")
6681   (set_attr "mode" "SI")])
6682
6683(define_insn "*subsi_2_zext"
6684  [(set (reg FLAGS_REG)
6685	(compare
6686	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6687		    (match_operand:SI 2 "general_operand" "rim"))
6688	  (const_int 0)))
6689   (set (match_operand:DI 0 "register_operand" "=r")
6690	(zero_extend:DI
6691	  (minus:SI (match_dup 1)
6692		    (match_dup 2))))]
6693  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695  "sub{l}\t{%2, %k0|%k0, %2}"
6696  [(set_attr "type" "alu")
6697   (set_attr "mode" "SI")])
6698
6699(define_insn "*subsi_3"
6700  [(set (reg FLAGS_REG)
6701	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6702		 (match_operand:SI 2 "general_operand" "ri,rm")))
6703   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704	(minus:SI (match_dup 1) (match_dup 2)))]
6705  "ix86_match_ccmode (insn, CCmode)
6706   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707  "sub{l}\t{%2, %0|%0, %2}"
6708  [(set_attr "type" "alu")
6709   (set_attr "mode" "SI")])
6710
6711(define_insn "*subsi_3_zext"
6712  [(set (reg FLAGS_REG)
6713	(compare (match_operand:SI 1 "register_operand" "0")
6714		 (match_operand:SI 2 "general_operand" "rim")))
6715   (set (match_operand:DI 0 "register_operand" "=r")
6716	(zero_extend:DI
6717	  (minus:SI (match_dup 1)
6718		    (match_dup 2))))]
6719  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721  "sub{l}\t{%2, %1|%1, %2}"
6722  [(set_attr "type" "alu")
6723   (set_attr "mode" "DI")])
6724
6725(define_expand "subhi3"
6726  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6727		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6728			     (match_operand:HI 2 "general_operand" "")))
6729	      (clobber (reg:CC FLAGS_REG))])]
6730  "TARGET_HIMODE_MATH"
6731  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6732
6733(define_insn "*subhi_1"
6734  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6735	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6736		  (match_operand:HI 2 "general_operand" "ri,rm")))
6737   (clobber (reg:CC FLAGS_REG))]
6738  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6739  "sub{w}\t{%2, %0|%0, %2}"
6740  [(set_attr "type" "alu")
6741   (set_attr "mode" "HI")])
6742
6743(define_insn "*subhi_2"
6744  [(set (reg FLAGS_REG)
6745	(compare
6746	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6747		    (match_operand:HI 2 "general_operand" "ri,rm"))
6748	  (const_int 0)))
6749   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750	(minus:HI (match_dup 1) (match_dup 2)))]
6751  "ix86_match_ccmode (insn, CCGOCmode)
6752   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6753  "sub{w}\t{%2, %0|%0, %2}"
6754  [(set_attr "type" "alu")
6755   (set_attr "mode" "HI")])
6756
6757(define_insn "*subhi_3"
6758  [(set (reg FLAGS_REG)
6759	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6760		 (match_operand:HI 2 "general_operand" "ri,rm")))
6761   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6762	(minus:HI (match_dup 1) (match_dup 2)))]
6763  "ix86_match_ccmode (insn, CCmode)
6764   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6765  "sub{w}\t{%2, %0|%0, %2}"
6766  [(set_attr "type" "alu")
6767   (set_attr "mode" "HI")])
6768
6769(define_expand "subqi3"
6770  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6771		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6772			     (match_operand:QI 2 "general_operand" "")))
6773	      (clobber (reg:CC FLAGS_REG))])]
6774  "TARGET_QIMODE_MATH"
6775  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6776
6777(define_insn "*subqi_1"
6778  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6779	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780		  (match_operand:QI 2 "general_operand" "qn,qmn")))
6781   (clobber (reg:CC FLAGS_REG))]
6782  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6783  "sub{b}\t{%2, %0|%0, %2}"
6784  [(set_attr "type" "alu")
6785   (set_attr "mode" "QI")])
6786
6787(define_insn "*subqi_1_slp"
6788  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6789	(minus:QI (match_dup 0)
6790		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6791   (clobber (reg:CC FLAGS_REG))]
6792  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6793   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6794  "sub{b}\t{%1, %0|%0, %1}"
6795  [(set_attr "type" "alu1")
6796   (set_attr "mode" "QI")])
6797
6798(define_insn "*subqi_2"
6799  [(set (reg FLAGS_REG)
6800	(compare
6801	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6802		    (match_operand:QI 2 "general_operand" "qi,qm"))
6803	  (const_int 0)))
6804   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6805	(minus:HI (match_dup 1) (match_dup 2)))]
6806  "ix86_match_ccmode (insn, CCGOCmode)
6807   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6808  "sub{b}\t{%2, %0|%0, %2}"
6809  [(set_attr "type" "alu")
6810   (set_attr "mode" "QI")])
6811
6812(define_insn "*subqi_3"
6813  [(set (reg FLAGS_REG)
6814	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6815		 (match_operand:QI 2 "general_operand" "qi,qm")))
6816   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6817	(minus:HI (match_dup 1) (match_dup 2)))]
6818  "ix86_match_ccmode (insn, CCmode)
6819   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6820  "sub{b}\t{%2, %0|%0, %2}"
6821  [(set_attr "type" "alu")
6822   (set_attr "mode" "QI")])
6823
6824;; The patterns that match these are at the end of this file.
6825
6826(define_expand "subxf3"
6827  [(set (match_operand:XF 0 "register_operand" "")
6828	(minus:XF (match_operand:XF 1 "register_operand" "")
6829		  (match_operand:XF 2 "register_operand" "")))]
6830  "TARGET_80387"
6831  "")
6832
6833(define_expand "subdf3"
6834  [(set (match_operand:DF 0 "register_operand" "")
6835	(minus:DF (match_operand:DF 1 "register_operand" "")
6836		  (match_operand:DF 2 "nonimmediate_operand" "")))]
6837  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6838  "")
6839
6840(define_expand "subsf3"
6841  [(set (match_operand:SF 0 "register_operand" "")
6842	(minus:SF (match_operand:SF 1 "register_operand" "")
6843		  (match_operand:SF 2 "nonimmediate_operand" "")))]
6844  "TARGET_80387 || TARGET_SSE_MATH"
6845  "")
6846
6847;; Multiply instructions
6848
6849(define_expand "muldi3"
6850  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6851		   (mult:DI (match_operand:DI 1 "register_operand" "")
6852			    (match_operand:DI 2 "x86_64_general_operand" "")))
6853	      (clobber (reg:CC FLAGS_REG))])]
6854  "TARGET_64BIT"
6855  "")
6856
6857(define_insn "*muldi3_1_rex64"
6858  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6859	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6860		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6861   (clobber (reg:CC FLAGS_REG))]
6862  "TARGET_64BIT
6863   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6864  "@
6865   imul{q}\t{%2, %1, %0|%0, %1, %2}
6866   imul{q}\t{%2, %1, %0|%0, %1, %2}
6867   imul{q}\t{%2, %0|%0, %2}"
6868  [(set_attr "type" "imul")
6869   (set_attr "prefix_0f" "0,0,1")
6870   (set (attr "athlon_decode")
6871	(cond [(eq_attr "cpu" "athlon")
6872		  (const_string "vector")
6873	       (eq_attr "alternative" "1")
6874		  (const_string "vector")
6875	       (and (eq_attr "alternative" "2")
6876		    (match_operand 1 "memory_operand" ""))
6877		  (const_string "vector")]
6878	      (const_string "direct")))
6879   (set_attr "mode" "DI")])
6880
6881(define_expand "mulsi3"
6882  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6883		   (mult:SI (match_operand:SI 1 "register_operand" "")
6884			    (match_operand:SI 2 "general_operand" "")))
6885	      (clobber (reg:CC FLAGS_REG))])]
6886  ""
6887  "")
6888
6889(define_insn "*mulsi3_1"
6890  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6891	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6892		 (match_operand:SI 2 "general_operand" "K,i,mr")))
6893   (clobber (reg:CC FLAGS_REG))]
6894  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6895  "@
6896   imul{l}\t{%2, %1, %0|%0, %1, %2}
6897   imul{l}\t{%2, %1, %0|%0, %1, %2}
6898   imul{l}\t{%2, %0|%0, %2}"
6899  [(set_attr "type" "imul")
6900   (set_attr "prefix_0f" "0,0,1")
6901   (set (attr "athlon_decode")
6902	(cond [(eq_attr "cpu" "athlon")
6903		  (const_string "vector")
6904	       (eq_attr "alternative" "1")
6905		  (const_string "vector")
6906	       (and (eq_attr "alternative" "2")
6907		    (match_operand 1 "memory_operand" ""))
6908		  (const_string "vector")]
6909	      (const_string "direct")))
6910   (set_attr "mode" "SI")])
6911
6912(define_insn "*mulsi3_1_zext"
6913  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914	(zero_extend:DI
6915	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6916		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
6917   (clobber (reg:CC FLAGS_REG))]
6918  "TARGET_64BIT
6919   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6920  "@
6921   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923   imul{l}\t{%2, %k0|%k0, %2}"
6924  [(set_attr "type" "imul")
6925   (set_attr "prefix_0f" "0,0,1")
6926   (set (attr "athlon_decode")
6927	(cond [(eq_attr "cpu" "athlon")
6928		  (const_string "vector")
6929	       (eq_attr "alternative" "1")
6930		  (const_string "vector")
6931	       (and (eq_attr "alternative" "2")
6932		    (match_operand 1 "memory_operand" ""))
6933		  (const_string "vector")]
6934	      (const_string "direct")))
6935   (set_attr "mode" "SI")])
6936
6937(define_expand "mulhi3"
6938  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6939		   (mult:HI (match_operand:HI 1 "register_operand" "")
6940			    (match_operand:HI 2 "general_operand" "")))
6941	      (clobber (reg:CC FLAGS_REG))])]
6942  "TARGET_HIMODE_MATH"
6943  "")
6944
6945(define_insn "*mulhi3_1"
6946  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948		 (match_operand:HI 2 "general_operand" "K,i,mr")))
6949   (clobber (reg:CC FLAGS_REG))]
6950  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6951  "@
6952   imul{w}\t{%2, %1, %0|%0, %1, %2}
6953   imul{w}\t{%2, %1, %0|%0, %1, %2}
6954   imul{w}\t{%2, %0|%0, %2}"
6955  [(set_attr "type" "imul")
6956   (set_attr "prefix_0f" "0,0,1")
6957   (set (attr "athlon_decode")
6958	(cond [(eq_attr "cpu" "athlon")
6959		  (const_string "vector")
6960	       (eq_attr "alternative" "1,2")
6961		  (const_string "vector")]
6962	      (const_string "direct")))
6963   (set_attr "mode" "HI")])
6964
6965(define_expand "mulqi3"
6966  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6967		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6968			    (match_operand:QI 2 "register_operand" "")))
6969	      (clobber (reg:CC FLAGS_REG))])]
6970  "TARGET_QIMODE_MATH"
6971  "")
6972
6973(define_insn "*mulqi3_1"
6974  [(set (match_operand:QI 0 "register_operand" "=a")
6975	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6977   (clobber (reg:CC FLAGS_REG))]
6978  "TARGET_QIMODE_MATH
6979   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6980  "mul{b}\t%2"
6981  [(set_attr "type" "imul")
6982   (set_attr "length_immediate" "0")
6983   (set (attr "athlon_decode")
6984     (if_then_else (eq_attr "cpu" "athlon")
6985        (const_string "vector")
6986        (const_string "direct")))
6987   (set_attr "mode" "QI")])
6988
6989(define_expand "umulqihi3"
6990  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991		   (mult:HI (zero_extend:HI
6992			      (match_operand:QI 1 "nonimmediate_operand" ""))
6993			    (zero_extend:HI
6994			      (match_operand:QI 2 "register_operand" ""))))
6995	      (clobber (reg:CC FLAGS_REG))])]
6996  "TARGET_QIMODE_MATH"
6997  "")
6998
6999(define_insn "*umulqihi3_1"
7000  [(set (match_operand:HI 0 "register_operand" "=a")
7001	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7002		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7003   (clobber (reg:CC FLAGS_REG))]
7004  "TARGET_QIMODE_MATH
7005   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7006  "mul{b}\t%2"
7007  [(set_attr "type" "imul")
7008   (set_attr "length_immediate" "0")
7009   (set (attr "athlon_decode")
7010     (if_then_else (eq_attr "cpu" "athlon")
7011        (const_string "vector")
7012        (const_string "direct")))
7013   (set_attr "mode" "QI")])
7014
7015(define_expand "mulqihi3"
7016  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7017		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7018			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7019	      (clobber (reg:CC FLAGS_REG))])]
7020  "TARGET_QIMODE_MATH"
7021  "")
7022
7023(define_insn "*mulqihi3_insn"
7024  [(set (match_operand:HI 0 "register_operand" "=a")
7025	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7026		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7027   (clobber (reg:CC FLAGS_REG))]
7028  "TARGET_QIMODE_MATH
7029   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7030  "imul{b}\t%2"
7031  [(set_attr "type" "imul")
7032   (set_attr "length_immediate" "0")
7033   (set (attr "athlon_decode")
7034     (if_then_else (eq_attr "cpu" "athlon")
7035        (const_string "vector")
7036        (const_string "direct")))
7037   (set_attr "mode" "QI")])
7038
7039(define_expand "umulditi3"
7040  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7041		   (mult:TI (zero_extend:TI
7042			      (match_operand:DI 1 "nonimmediate_operand" ""))
7043			    (zero_extend:TI
7044			      (match_operand:DI 2 "register_operand" ""))))
7045	      (clobber (reg:CC FLAGS_REG))])]
7046  "TARGET_64BIT"
7047  "")
7048
7049(define_insn "*umulditi3_insn"
7050  [(set (match_operand:TI 0 "register_operand" "=A")
7051	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7052		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7053   (clobber (reg:CC FLAGS_REG))]
7054  "TARGET_64BIT
7055   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7056  "mul{q}\t%2"
7057  [(set_attr "type" "imul")
7058   (set_attr "length_immediate" "0")
7059   (set (attr "athlon_decode")
7060     (if_then_else (eq_attr "cpu" "athlon")
7061        (const_string "vector")
7062        (const_string "double")))
7063   (set_attr "mode" "DI")])
7064
7065;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7066(define_expand "umulsidi3"
7067  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7068		   (mult:DI (zero_extend:DI
7069			      (match_operand:SI 1 "nonimmediate_operand" ""))
7070			    (zero_extend:DI
7071			      (match_operand:SI 2 "register_operand" ""))))
7072	      (clobber (reg:CC FLAGS_REG))])]
7073  "!TARGET_64BIT"
7074  "")
7075
7076(define_insn "*umulsidi3_insn"
7077  [(set (match_operand:DI 0 "register_operand" "=A")
7078	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7079		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7080   (clobber (reg:CC FLAGS_REG))]
7081  "!TARGET_64BIT
7082   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083  "mul{l}\t%2"
7084  [(set_attr "type" "imul")
7085   (set_attr "length_immediate" "0")
7086   (set (attr "athlon_decode")
7087     (if_then_else (eq_attr "cpu" "athlon")
7088        (const_string "vector")
7089        (const_string "double")))
7090   (set_attr "mode" "SI")])
7091
7092(define_expand "mulditi3"
7093  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094		   (mult:TI (sign_extend:TI
7095			      (match_operand:DI 1 "nonimmediate_operand" ""))
7096			    (sign_extend:TI
7097			      (match_operand:DI 2 "register_operand" ""))))
7098	      (clobber (reg:CC FLAGS_REG))])]
7099  "TARGET_64BIT"
7100  "")
7101
7102(define_insn "*mulditi3_insn"
7103  [(set (match_operand:TI 0 "register_operand" "=A")
7104	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106   (clobber (reg:CC FLAGS_REG))]
7107  "TARGET_64BIT
7108   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109  "imul{q}\t%2"
7110  [(set_attr "type" "imul")
7111   (set_attr "length_immediate" "0")
7112   (set (attr "athlon_decode")
7113     (if_then_else (eq_attr "cpu" "athlon")
7114        (const_string "vector")
7115        (const_string "double")))
7116   (set_attr "mode" "DI")])
7117
7118(define_expand "mulsidi3"
7119  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120		   (mult:DI (sign_extend:DI
7121			      (match_operand:SI 1 "nonimmediate_operand" ""))
7122			    (sign_extend:DI
7123			      (match_operand:SI 2 "register_operand" ""))))
7124	      (clobber (reg:CC FLAGS_REG))])]
7125  "!TARGET_64BIT"
7126  "")
7127
7128(define_insn "*mulsidi3_insn"
7129  [(set (match_operand:DI 0 "register_operand" "=A")
7130	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132   (clobber (reg:CC FLAGS_REG))]
7133  "!TARGET_64BIT
7134   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135  "imul{l}\t%2"
7136  [(set_attr "type" "imul")
7137   (set_attr "length_immediate" "0")
7138   (set (attr "athlon_decode")
7139     (if_then_else (eq_attr "cpu" "athlon")
7140        (const_string "vector")
7141        (const_string "double")))
7142   (set_attr "mode" "SI")])
7143
7144(define_expand "umuldi3_highpart"
7145  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7146		   (truncate:DI
7147		     (lshiftrt:TI
7148		       (mult:TI (zero_extend:TI
7149				  (match_operand:DI 1 "nonimmediate_operand" ""))
7150				(zero_extend:TI
7151				  (match_operand:DI 2 "register_operand" "")))
7152		       (const_int 64))))
7153	      (clobber (match_scratch:DI 3 ""))
7154	      (clobber (reg:CC FLAGS_REG))])]
7155  "TARGET_64BIT"
7156  "")
7157
7158(define_insn "*umuldi3_highpart_rex64"
7159  [(set (match_operand:DI 0 "register_operand" "=d")
7160	(truncate:DI
7161	  (lshiftrt:TI
7162	    (mult:TI (zero_extend:TI
7163		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7164		     (zero_extend:TI
7165		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7166	    (const_int 64))))
7167   (clobber (match_scratch:DI 3 "=1"))
7168   (clobber (reg:CC FLAGS_REG))]
7169  "TARGET_64BIT
7170   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7171  "mul{q}\t%2"
7172  [(set_attr "type" "imul")
7173   (set_attr "length_immediate" "0")
7174   (set (attr "athlon_decode")
7175     (if_then_else (eq_attr "cpu" "athlon")
7176        (const_string "vector")
7177        (const_string "double")))
7178   (set_attr "mode" "DI")])
7179
7180(define_expand "umulsi3_highpart"
7181  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182		   (truncate:SI
7183		     (lshiftrt:DI
7184		       (mult:DI (zero_extend:DI
7185				  (match_operand:SI 1 "nonimmediate_operand" ""))
7186				(zero_extend:DI
7187				  (match_operand:SI 2 "register_operand" "")))
7188		       (const_int 32))))
7189	      (clobber (match_scratch:SI 3 ""))
7190	      (clobber (reg:CC FLAGS_REG))])]
7191  ""
7192  "")
7193
7194(define_insn "*umulsi3_highpart_insn"
7195  [(set (match_operand:SI 0 "register_operand" "=d")
7196	(truncate:SI
7197	  (lshiftrt:DI
7198	    (mult:DI (zero_extend:DI
7199		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7200		     (zero_extend:DI
7201		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7202	    (const_int 32))))
7203   (clobber (match_scratch:SI 3 "=1"))
7204   (clobber (reg:CC FLAGS_REG))]
7205  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7206  "mul{l}\t%2"
7207  [(set_attr "type" "imul")
7208   (set_attr "length_immediate" "0")
7209   (set (attr "athlon_decode")
7210     (if_then_else (eq_attr "cpu" "athlon")
7211        (const_string "vector")
7212        (const_string "double")))
7213   (set_attr "mode" "SI")])
7214
7215(define_insn "*umulsi3_highpart_zext"
7216  [(set (match_operand:DI 0 "register_operand" "=d")
7217	(zero_extend:DI (truncate:SI
7218	  (lshiftrt:DI
7219	    (mult:DI (zero_extend:DI
7220		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7221		     (zero_extend:DI
7222		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7223	    (const_int 32)))))
7224   (clobber (match_scratch:SI 3 "=1"))
7225   (clobber (reg:CC FLAGS_REG))]
7226  "TARGET_64BIT
7227   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228  "mul{l}\t%2"
7229  [(set_attr "type" "imul")
7230   (set_attr "length_immediate" "0")
7231   (set (attr "athlon_decode")
7232     (if_then_else (eq_attr "cpu" "athlon")
7233        (const_string "vector")
7234        (const_string "double")))
7235   (set_attr "mode" "SI")])
7236
7237(define_expand "smuldi3_highpart"
7238  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7239		   (truncate:DI
7240		     (lshiftrt:TI
7241		       (mult:TI (sign_extend:TI
7242				  (match_operand:DI 1 "nonimmediate_operand" ""))
7243				(sign_extend:TI
7244				  (match_operand:DI 2 "register_operand" "")))
7245		       (const_int 64))))
7246	      (clobber (match_scratch:DI 3 ""))
7247	      (clobber (reg:CC FLAGS_REG))])]
7248  "TARGET_64BIT"
7249  "")
7250
7251(define_insn "*smuldi3_highpart_rex64"
7252  [(set (match_operand:DI 0 "register_operand" "=d")
7253	(truncate:DI
7254	  (lshiftrt:TI
7255	    (mult:TI (sign_extend:TI
7256		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257		     (sign_extend:TI
7258		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259	    (const_int 64))))
7260   (clobber (match_scratch:DI 3 "=1"))
7261   (clobber (reg:CC FLAGS_REG))]
7262  "TARGET_64BIT
7263   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264  "imul{q}\t%2"
7265  [(set_attr "type" "imul")
7266   (set (attr "athlon_decode")
7267     (if_then_else (eq_attr "cpu" "athlon")
7268        (const_string "vector")
7269        (const_string "double")))
7270   (set_attr "mode" "DI")])
7271
7272(define_expand "smulsi3_highpart"
7273  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7274		   (truncate:SI
7275		     (lshiftrt:DI
7276		       (mult:DI (sign_extend:DI
7277				  (match_operand:SI 1 "nonimmediate_operand" ""))
7278				(sign_extend:DI
7279				  (match_operand:SI 2 "register_operand" "")))
7280		       (const_int 32))))
7281	      (clobber (match_scratch:SI 3 ""))
7282	      (clobber (reg:CC FLAGS_REG))])]
7283  ""
7284  "")
7285
7286(define_insn "*smulsi3_highpart_insn"
7287  [(set (match_operand:SI 0 "register_operand" "=d")
7288	(truncate:SI
7289	  (lshiftrt:DI
7290	    (mult:DI (sign_extend:DI
7291		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7292		     (sign_extend:DI
7293		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7294	    (const_int 32))))
7295   (clobber (match_scratch:SI 3 "=1"))
7296   (clobber (reg:CC FLAGS_REG))]
7297  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7298  "imul{l}\t%2"
7299  [(set_attr "type" "imul")
7300   (set (attr "athlon_decode")
7301     (if_then_else (eq_attr "cpu" "athlon")
7302        (const_string "vector")
7303        (const_string "double")))
7304   (set_attr "mode" "SI")])
7305
7306(define_insn "*smulsi3_highpart_zext"
7307  [(set (match_operand:DI 0 "register_operand" "=d")
7308	(zero_extend:DI (truncate:SI
7309	  (lshiftrt:DI
7310	    (mult:DI (sign_extend:DI
7311		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7312		     (sign_extend:DI
7313		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7314	    (const_int 32)))))
7315   (clobber (match_scratch:SI 3 "=1"))
7316   (clobber (reg:CC FLAGS_REG))]
7317  "TARGET_64BIT
7318   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7319  "imul{l}\t%2"
7320  [(set_attr "type" "imul")
7321   (set (attr "athlon_decode")
7322     (if_then_else (eq_attr "cpu" "athlon")
7323        (const_string "vector")
7324        (const_string "double")))
7325   (set_attr "mode" "SI")])
7326
7327;; The patterns that match these are at the end of this file.
7328
7329(define_expand "mulxf3"
7330  [(set (match_operand:XF 0 "register_operand" "")
7331	(mult:XF (match_operand:XF 1 "register_operand" "")
7332		 (match_operand:XF 2 "register_operand" "")))]
7333  "TARGET_80387"
7334  "")
7335
7336(define_expand "muldf3"
7337  [(set (match_operand:DF 0 "register_operand" "")
7338	(mult:DF (match_operand:DF 1 "register_operand" "")
7339		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7340  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7341  "")
7342
7343(define_expand "mulsf3"
7344  [(set (match_operand:SF 0 "register_operand" "")
7345	(mult:SF (match_operand:SF 1 "register_operand" "")
7346		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7347  "TARGET_80387 || TARGET_SSE_MATH"
7348  "")
7349
7350;; Divide instructions
7351
7352(define_insn "divqi3"
7353  [(set (match_operand:QI 0 "register_operand" "=a")
7354	(div:QI (match_operand:HI 1 "register_operand" "0")
7355		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7356   (clobber (reg:CC FLAGS_REG))]
7357  "TARGET_QIMODE_MATH"
7358  "idiv{b}\t%2"
7359  [(set_attr "type" "idiv")
7360   (set_attr "mode" "QI")])
7361
7362(define_insn "udivqi3"
7363  [(set (match_operand:QI 0 "register_operand" "=a")
7364	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7365		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7366   (clobber (reg:CC FLAGS_REG))]
7367  "TARGET_QIMODE_MATH"
7368  "div{b}\t%2"
7369  [(set_attr "type" "idiv")
7370   (set_attr "mode" "QI")])
7371
7372;; The patterns that match these are at the end of this file.
7373
7374(define_expand "divxf3"
7375  [(set (match_operand:XF 0 "register_operand" "")
7376	(div:XF (match_operand:XF 1 "register_operand" "")
7377		(match_operand:XF 2 "register_operand" "")))]
7378  "TARGET_80387"
7379  "")
7380
7381(define_expand "divdf3"
7382  [(set (match_operand:DF 0 "register_operand" "")
7383 	(div:DF (match_operand:DF 1 "register_operand" "")
7384 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7385   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7386   "")
7387 
7388(define_expand "divsf3"
7389  [(set (match_operand:SF 0 "register_operand" "")
7390	(div:SF (match_operand:SF 1 "register_operand" "")
7391		(match_operand:SF 2 "nonimmediate_operand" "")))]
7392  "TARGET_80387 || TARGET_SSE_MATH"
7393  "")
7394
7395;; Remainder instructions.
7396
7397(define_expand "divmoddi4"
7398  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7399		   (div:DI (match_operand:DI 1 "register_operand" "")
7400			   (match_operand:DI 2 "nonimmediate_operand" "")))
7401	      (set (match_operand:DI 3 "register_operand" "")
7402		   (mod:DI (match_dup 1) (match_dup 2)))
7403	      (clobber (reg:CC FLAGS_REG))])]
7404  "TARGET_64BIT"
7405  "")
7406
7407;; Allow to come the parameter in eax or edx to avoid extra moves.
7408;; Penalize eax case slightly because it results in worse scheduling
7409;; of code.
7410(define_insn "*divmoddi4_nocltd_rex64"
7411  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7412	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7413		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7414   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7415	(mod:DI (match_dup 2) (match_dup 3)))
7416   (clobber (reg:CC FLAGS_REG))]
7417  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7418  "#"
7419  [(set_attr "type" "multi")])
7420
7421(define_insn "*divmoddi4_cltd_rex64"
7422  [(set (match_operand:DI 0 "register_operand" "=a")
7423	(div:DI (match_operand:DI 2 "register_operand" "a")
7424		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7425   (set (match_operand:DI 1 "register_operand" "=&d")
7426	(mod:DI (match_dup 2) (match_dup 3)))
7427   (clobber (reg:CC FLAGS_REG))]
7428  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7429  "#"
7430  [(set_attr "type" "multi")])
7431
7432(define_insn "*divmoddi_noext_rex64"
7433  [(set (match_operand:DI 0 "register_operand" "=a")
7434	(div:DI (match_operand:DI 1 "register_operand" "0")
7435		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7436   (set (match_operand:DI 3 "register_operand" "=d")
7437	(mod:DI (match_dup 1) (match_dup 2)))
7438   (use (match_operand:DI 4 "register_operand" "3"))
7439   (clobber (reg:CC FLAGS_REG))]
7440  "TARGET_64BIT"
7441  "idiv{q}\t%2"
7442  [(set_attr "type" "idiv")
7443   (set_attr "mode" "DI")])
7444
7445(define_split
7446  [(set (match_operand:DI 0 "register_operand" "")
7447	(div:DI (match_operand:DI 1 "register_operand" "")
7448		(match_operand:DI 2 "nonimmediate_operand" "")))
7449   (set (match_operand:DI 3 "register_operand" "")
7450	(mod:DI (match_dup 1) (match_dup 2)))
7451   (clobber (reg:CC FLAGS_REG))]
7452  "TARGET_64BIT && reload_completed"
7453  [(parallel [(set (match_dup 3)
7454		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7455	      (clobber (reg:CC FLAGS_REG))])
7456   (parallel [(set (match_dup 0)
7457	           (div:DI (reg:DI 0) (match_dup 2)))
7458	      (set (match_dup 3)
7459		   (mod:DI (reg:DI 0) (match_dup 2)))
7460	      (use (match_dup 3))
7461	      (clobber (reg:CC FLAGS_REG))])]
7462{
7463  /* Avoid use of cltd in favor of a mov+shift.  */
7464  if (!TARGET_USE_CLTD && !optimize_size)
7465    {
7466      if (true_regnum (operands[1]))
7467        emit_move_insn (operands[0], operands[1]);
7468      else
7469	emit_move_insn (operands[3], operands[1]);
7470      operands[4] = operands[3];
7471    }
7472  else
7473    {
7474      gcc_assert (!true_regnum (operands[1]));
7475      operands[4] = operands[1];
7476    }
7477})
7478
7479
7480(define_expand "divmodsi4"
7481  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7482		   (div:SI (match_operand:SI 1 "register_operand" "")
7483			   (match_operand:SI 2 "nonimmediate_operand" "")))
7484	      (set (match_operand:SI 3 "register_operand" "")
7485		   (mod:SI (match_dup 1) (match_dup 2)))
7486	      (clobber (reg:CC FLAGS_REG))])]
7487  ""
7488  "")
7489
7490;; Allow to come the parameter in eax or edx to avoid extra moves.
7491;; Penalize eax case slightly because it results in worse scheduling
7492;; of code.
7493(define_insn "*divmodsi4_nocltd"
7494  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7495	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7496		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7497   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7498	(mod:SI (match_dup 2) (match_dup 3)))
7499   (clobber (reg:CC FLAGS_REG))]
7500  "!optimize_size && !TARGET_USE_CLTD"
7501  "#"
7502  [(set_attr "type" "multi")])
7503
7504(define_insn "*divmodsi4_cltd"
7505  [(set (match_operand:SI 0 "register_operand" "=a")
7506	(div:SI (match_operand:SI 2 "register_operand" "a")
7507		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7508   (set (match_operand:SI 1 "register_operand" "=&d")
7509	(mod:SI (match_dup 2) (match_dup 3)))
7510   (clobber (reg:CC FLAGS_REG))]
7511  "optimize_size || TARGET_USE_CLTD"
7512  "#"
7513  [(set_attr "type" "multi")])
7514
7515(define_insn "*divmodsi_noext"
7516  [(set (match_operand:SI 0 "register_operand" "=a")
7517	(div:SI (match_operand:SI 1 "register_operand" "0")
7518		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7519   (set (match_operand:SI 3 "register_operand" "=d")
7520	(mod:SI (match_dup 1) (match_dup 2)))
7521   (use (match_operand:SI 4 "register_operand" "3"))
7522   (clobber (reg:CC FLAGS_REG))]
7523  ""
7524  "idiv{l}\t%2"
7525  [(set_attr "type" "idiv")
7526   (set_attr "mode" "SI")])
7527
7528(define_split
7529  [(set (match_operand:SI 0 "register_operand" "")
7530	(div:SI (match_operand:SI 1 "register_operand" "")
7531		(match_operand:SI 2 "nonimmediate_operand" "")))
7532   (set (match_operand:SI 3 "register_operand" "")
7533	(mod:SI (match_dup 1) (match_dup 2)))
7534   (clobber (reg:CC FLAGS_REG))]
7535  "reload_completed"
7536  [(parallel [(set (match_dup 3)
7537		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7538	      (clobber (reg:CC FLAGS_REG))])
7539   (parallel [(set (match_dup 0)
7540	           (div:SI (reg:SI 0) (match_dup 2)))
7541	      (set (match_dup 3)
7542		   (mod:SI (reg:SI 0) (match_dup 2)))
7543	      (use (match_dup 3))
7544	      (clobber (reg:CC FLAGS_REG))])]
7545{
7546  /* Avoid use of cltd in favor of a mov+shift.  */
7547  if (!TARGET_USE_CLTD && !optimize_size)
7548    {
7549      if (true_regnum (operands[1]))
7550        emit_move_insn (operands[0], operands[1]);
7551      else
7552	emit_move_insn (operands[3], operands[1]);
7553      operands[4] = operands[3];
7554    }
7555  else
7556    {
7557      gcc_assert (!true_regnum (operands[1]));
7558      operands[4] = operands[1];
7559    }
7560})
7561;; %%% Split me.
7562(define_insn "divmodhi4"
7563  [(set (match_operand:HI 0 "register_operand" "=a")
7564	(div:HI (match_operand:HI 1 "register_operand" "0")
7565		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7566   (set (match_operand:HI 3 "register_operand" "=&d")
7567	(mod:HI (match_dup 1) (match_dup 2)))
7568   (clobber (reg:CC FLAGS_REG))]
7569  "TARGET_HIMODE_MATH"
7570  "cwtd\;idiv{w}\t%2"
7571  [(set_attr "type" "multi")
7572   (set_attr "length_immediate" "0")
7573   (set_attr "mode" "SI")])
7574
7575(define_insn "udivmoddi4"
7576  [(set (match_operand:DI 0 "register_operand" "=a")
7577	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7578		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7579   (set (match_operand:DI 3 "register_operand" "=&d")
7580	(umod:DI (match_dup 1) (match_dup 2)))
7581   (clobber (reg:CC FLAGS_REG))]
7582  "TARGET_64BIT"
7583  "xor{q}\t%3, %3\;div{q}\t%2"
7584  [(set_attr "type" "multi")
7585   (set_attr "length_immediate" "0")
7586   (set_attr "mode" "DI")])
7587
7588(define_insn "*udivmoddi4_noext"
7589  [(set (match_operand:DI 0 "register_operand" "=a")
7590	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7591		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7592   (set (match_operand:DI 3 "register_operand" "=d")
7593	(umod:DI (match_dup 1) (match_dup 2)))
7594   (use (match_dup 3))
7595   (clobber (reg:CC FLAGS_REG))]
7596  "TARGET_64BIT"
7597  "div{q}\t%2"
7598  [(set_attr "type" "idiv")
7599   (set_attr "mode" "DI")])
7600
7601(define_split
7602  [(set (match_operand:DI 0 "register_operand" "")
7603	(udiv:DI (match_operand:DI 1 "register_operand" "")
7604		 (match_operand:DI 2 "nonimmediate_operand" "")))
7605   (set (match_operand:DI 3 "register_operand" "")
7606	(umod:DI (match_dup 1) (match_dup 2)))
7607   (clobber (reg:CC FLAGS_REG))]
7608  "TARGET_64BIT && reload_completed"
7609  [(set (match_dup 3) (const_int 0))
7610   (parallel [(set (match_dup 0)
7611		   (udiv:DI (match_dup 1) (match_dup 2)))
7612	      (set (match_dup 3)
7613		   (umod:DI (match_dup 1) (match_dup 2)))
7614	      (use (match_dup 3))
7615	      (clobber (reg:CC FLAGS_REG))])]
7616  "")
7617
7618(define_insn "udivmodsi4"
7619  [(set (match_operand:SI 0 "register_operand" "=a")
7620	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7621		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7622   (set (match_operand:SI 3 "register_operand" "=&d")
7623	(umod:SI (match_dup 1) (match_dup 2)))
7624   (clobber (reg:CC FLAGS_REG))]
7625  ""
7626  "xor{l}\t%3, %3\;div{l}\t%2"
7627  [(set_attr "type" "multi")
7628   (set_attr "length_immediate" "0")
7629   (set_attr "mode" "SI")])
7630
7631(define_insn "*udivmodsi4_noext"
7632  [(set (match_operand:SI 0 "register_operand" "=a")
7633	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7634		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7635   (set (match_operand:SI 3 "register_operand" "=d")
7636	(umod:SI (match_dup 1) (match_dup 2)))
7637   (use (match_dup 3))
7638   (clobber (reg:CC FLAGS_REG))]
7639  ""
7640  "div{l}\t%2"
7641  [(set_attr "type" "idiv")
7642   (set_attr "mode" "SI")])
7643
7644(define_split
7645  [(set (match_operand:SI 0 "register_operand" "")
7646	(udiv:SI (match_operand:SI 1 "register_operand" "")
7647		 (match_operand:SI 2 "nonimmediate_operand" "")))
7648   (set (match_operand:SI 3 "register_operand" "")
7649	(umod:SI (match_dup 1) (match_dup 2)))
7650   (clobber (reg:CC FLAGS_REG))]
7651  "reload_completed"
7652  [(set (match_dup 3) (const_int 0))
7653   (parallel [(set (match_dup 0)
7654		   (udiv:SI (match_dup 1) (match_dup 2)))
7655	      (set (match_dup 3)
7656		   (umod:SI (match_dup 1) (match_dup 2)))
7657	      (use (match_dup 3))
7658	      (clobber (reg:CC FLAGS_REG))])]
7659  "")
7660
7661(define_expand "udivmodhi4"
7662  [(set (match_dup 4) (const_int 0))
7663   (parallel [(set (match_operand:HI 0 "register_operand" "")
7664		   (udiv:HI (match_operand:HI 1 "register_operand" "")
7665		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
7666	      (set (match_operand:HI 3 "register_operand" "")
7667	   	   (umod:HI (match_dup 1) (match_dup 2)))
7668	      (use (match_dup 4))
7669	      (clobber (reg:CC FLAGS_REG))])]
7670  "TARGET_HIMODE_MATH"
7671  "operands[4] = gen_reg_rtx (HImode);")
7672
7673(define_insn "*udivmodhi_noext"
7674  [(set (match_operand:HI 0 "register_operand" "=a")
7675	(udiv:HI (match_operand:HI 1 "register_operand" "0")
7676		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7677   (set (match_operand:HI 3 "register_operand" "=d")
7678	(umod:HI (match_dup 1) (match_dup 2)))
7679   (use (match_operand:HI 4 "register_operand" "3"))
7680   (clobber (reg:CC FLAGS_REG))]
7681  ""
7682  "div{w}\t%2"
7683  [(set_attr "type" "idiv")
7684   (set_attr "mode" "HI")])
7685
7686;; We cannot use div/idiv for double division, because it causes
7687;; "division by zero" on the overflow and that's not what we expect
7688;; from truncate.  Because true (non truncating) double division is
7689;; never generated, we can't create this insn anyway.
7690;
7691;(define_insn ""
7692;  [(set (match_operand:SI 0 "register_operand" "=a")
7693;	(truncate:SI
7694;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7695;		   (zero_extend:DI
7696;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7697;   (set (match_operand:SI 3 "register_operand" "=d")
7698;	(truncate:SI
7699;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7700;   (clobber (reg:CC FLAGS_REG))]
7701;  ""
7702;  "div{l}\t{%2, %0|%0, %2}"
7703;  [(set_attr "type" "idiv")])
7704
7705;;- Logical AND instructions
7706
7707;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7708;; Note that this excludes ah.
7709
7710(define_insn "*testdi_1_rex64"
7711  [(set (reg FLAGS_REG)
7712	(compare
7713	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7714		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7715	  (const_int 0)))]
7716  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7717   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7718  "@
7719   test{l}\t{%k1, %k0|%k0, %k1}
7720   test{l}\t{%k1, %k0|%k0, %k1}
7721   test{q}\t{%1, %0|%0, %1}
7722   test{q}\t{%1, %0|%0, %1}
7723   test{q}\t{%1, %0|%0, %1}"
7724  [(set_attr "type" "test")
7725   (set_attr "modrm" "0,1,0,1,1")
7726   (set_attr "mode" "SI,SI,DI,DI,DI")
7727   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7728
7729(define_insn "testsi_1"
7730  [(set (reg FLAGS_REG)
7731	(compare
7732	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7733		  (match_operand:SI 1 "general_operand" "in,in,rin"))
7734	  (const_int 0)))]
7735  "ix86_match_ccmode (insn, CCNOmode)
7736   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737  "test{l}\t{%1, %0|%0, %1}"
7738  [(set_attr "type" "test")
7739   (set_attr "modrm" "0,1,1")
7740   (set_attr "mode" "SI")
7741   (set_attr "pent_pair" "uv,np,uv")])
7742
7743(define_expand "testsi_ccno_1"
7744  [(set (reg:CCNO FLAGS_REG)
7745	(compare:CCNO
7746	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7747		  (match_operand:SI 1 "nonmemory_operand" ""))
7748	  (const_int 0)))]
7749  ""
7750  "")
7751
7752(define_insn "*testhi_1"
7753  [(set (reg FLAGS_REG)
7754        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7755			 (match_operand:HI 1 "general_operand" "n,n,rn"))
7756		 (const_int 0)))]
7757  "ix86_match_ccmode (insn, CCNOmode)
7758   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7759  "test{w}\t{%1, %0|%0, %1}"
7760  [(set_attr "type" "test")
7761   (set_attr "modrm" "0,1,1")
7762   (set_attr "mode" "HI")
7763   (set_attr "pent_pair" "uv,np,uv")])
7764
7765(define_expand "testqi_ccz_1"
7766  [(set (reg:CCZ FLAGS_REG)
7767        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7768			     (match_operand:QI 1 "nonmemory_operand" ""))
7769		 (const_int 0)))]
7770  ""
7771  "")
7772
7773(define_insn "*testqi_1_maybe_si"
7774  [(set (reg FLAGS_REG)
7775        (compare
7776	  (and:QI
7777	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7778	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7779	  (const_int 0)))]
7780   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781    && ix86_match_ccmode (insn,
7782 			 GET_CODE (operands[1]) == CONST_INT
7783 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7784{
7785  if (which_alternative == 3)
7786    {
7787      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7788	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7789      return "test{l}\t{%1, %k0|%k0, %1}";
7790    }
7791  return "test{b}\t{%1, %0|%0, %1}";
7792}
7793  [(set_attr "type" "test")
7794   (set_attr "modrm" "0,1,1,1")
7795   (set_attr "mode" "QI,QI,QI,SI")
7796   (set_attr "pent_pair" "uv,np,uv,np")])
7797
7798(define_insn "*testqi_1"
7799  [(set (reg FLAGS_REG)
7800        (compare
7801	  (and:QI
7802	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7803	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7804	  (const_int 0)))]
7805  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7806   && ix86_match_ccmode (insn, CCNOmode)"
7807  "test{b}\t{%1, %0|%0, %1}"
7808  [(set_attr "type" "test")
7809   (set_attr "modrm" "0,1,1")
7810   (set_attr "mode" "QI")
7811   (set_attr "pent_pair" "uv,np,uv")])
7812
7813(define_expand "testqi_ext_ccno_0"
7814  [(set (reg:CCNO FLAGS_REG)
7815	(compare:CCNO
7816	  (and:SI
7817	    (zero_extract:SI
7818	      (match_operand 0 "ext_register_operand" "")
7819	      (const_int 8)
7820	      (const_int 8))
7821	    (match_operand 1 "const_int_operand" ""))
7822	  (const_int 0)))]
7823  ""
7824  "")
7825
7826(define_insn "*testqi_ext_0"
7827  [(set (reg FLAGS_REG)
7828	(compare
7829	  (and:SI
7830	    (zero_extract:SI
7831	      (match_operand 0 "ext_register_operand" "Q")
7832	      (const_int 8)
7833	      (const_int 8))
7834	    (match_operand 1 "const_int_operand" "n"))
7835	  (const_int 0)))]
7836  "ix86_match_ccmode (insn, CCNOmode)"
7837  "test{b}\t{%1, %h0|%h0, %1}"
7838  [(set_attr "type" "test")
7839   (set_attr "mode" "QI")
7840   (set_attr "length_immediate" "1")
7841   (set_attr "pent_pair" "np")])
7842
7843(define_insn "*testqi_ext_1"
7844  [(set (reg FLAGS_REG)
7845	(compare
7846	  (and:SI
7847	    (zero_extract:SI
7848	      (match_operand 0 "ext_register_operand" "Q")
7849	      (const_int 8)
7850	      (const_int 8))
7851	    (zero_extend:SI
7852	      (match_operand:QI 1 "general_operand" "Qm")))
7853	  (const_int 0)))]
7854  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7855   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7856  "test{b}\t{%1, %h0|%h0, %1}"
7857  [(set_attr "type" "test")
7858   (set_attr "mode" "QI")])
7859
7860(define_insn "*testqi_ext_1_rex64"
7861  [(set (reg FLAGS_REG)
7862	(compare
7863	  (and:SI
7864	    (zero_extract:SI
7865	      (match_operand 0 "ext_register_operand" "Q")
7866	      (const_int 8)
7867	      (const_int 8))
7868	    (zero_extend:SI
7869	      (match_operand:QI 1 "register_operand" "Q")))
7870	  (const_int 0)))]
7871  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7872  "test{b}\t{%1, %h0|%h0, %1}"
7873  [(set_attr "type" "test")
7874   (set_attr "mode" "QI")])
7875
7876(define_insn "*testqi_ext_2"
7877  [(set (reg FLAGS_REG)
7878	(compare
7879	  (and:SI
7880	    (zero_extract:SI
7881	      (match_operand 0 "ext_register_operand" "Q")
7882	      (const_int 8)
7883	      (const_int 8))
7884	    (zero_extract:SI
7885	      (match_operand 1 "ext_register_operand" "Q")
7886	      (const_int 8)
7887	      (const_int 8)))
7888	  (const_int 0)))]
7889  "ix86_match_ccmode (insn, CCNOmode)"
7890  "test{b}\t{%h1, %h0|%h0, %h1}"
7891  [(set_attr "type" "test")
7892   (set_attr "mode" "QI")])
7893
7894;; Combine likes to form bit extractions for some tests.  Humor it.
7895(define_insn "*testqi_ext_3"
7896  [(set (reg FLAGS_REG)
7897        (compare (zero_extract:SI
7898		   (match_operand 0 "nonimmediate_operand" "rm")
7899		   (match_operand:SI 1 "const_int_operand" "")
7900		   (match_operand:SI 2 "const_int_operand" ""))
7901		 (const_int 0)))]
7902  "ix86_match_ccmode (insn, CCNOmode)
7903   && INTVAL (operands[1]) > 0
7904   && INTVAL (operands[2]) >= 0
7905   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7906   && (GET_MODE (operands[0]) == SImode
7907       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7908       || GET_MODE (operands[0]) == HImode
7909       || GET_MODE (operands[0]) == QImode)"
7910  "#")
7911
7912(define_insn "*testqi_ext_3_rex64"
7913  [(set (reg FLAGS_REG)
7914        (compare (zero_extract:DI
7915		   (match_operand 0 "nonimmediate_operand" "rm")
7916		   (match_operand:DI 1 "const_int_operand" "")
7917		   (match_operand:DI 2 "const_int_operand" ""))
7918		 (const_int 0)))]
7919  "TARGET_64BIT
7920   && ix86_match_ccmode (insn, CCNOmode)
7921   && INTVAL (operands[1]) > 0
7922   && INTVAL (operands[2]) >= 0
7923   /* Ensure that resulting mask is zero or sign extended operand.  */
7924   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7925       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7926	   && INTVAL (operands[1]) > 32))
7927   && (GET_MODE (operands[0]) == SImode
7928       || GET_MODE (operands[0]) == DImode
7929       || GET_MODE (operands[0]) == HImode
7930       || GET_MODE (operands[0]) == QImode)"
7931  "#")
7932
7933(define_split
7934  [(set (match_operand 0 "flags_reg_operand" "")
7935        (match_operator 1 "compare_operator"
7936	  [(zero_extract
7937	     (match_operand 2 "nonimmediate_operand" "")
7938	     (match_operand 3 "const_int_operand" "")
7939	     (match_operand 4 "const_int_operand" ""))
7940	   (const_int 0)]))]
7941  "ix86_match_ccmode (insn, CCNOmode)"
7942  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7943{
7944  rtx val = operands[2];
7945  HOST_WIDE_INT len = INTVAL (operands[3]);
7946  HOST_WIDE_INT pos = INTVAL (operands[4]);
7947  HOST_WIDE_INT mask;
7948  enum machine_mode mode, submode;
7949
7950  mode = GET_MODE (val);
7951  if (GET_CODE (val) == MEM)
7952    {
7953      /* ??? Combine likes to put non-volatile mem extractions in QImode
7954	 no matter the size of the test.  So find a mode that works.  */
7955      if (! MEM_VOLATILE_P (val))
7956	{
7957	  mode = smallest_mode_for_size (pos + len, MODE_INT);
7958	  val = adjust_address (val, mode, 0);
7959	}
7960    }
7961  else if (GET_CODE (val) == SUBREG
7962	   && (submode = GET_MODE (SUBREG_REG (val)),
7963	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7964	   && pos + len <= GET_MODE_BITSIZE (submode))
7965    {
7966      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7967      mode = submode;
7968      val = SUBREG_REG (val);
7969    }
7970  else if (mode == HImode && pos + len <= 8)
7971    {
7972      /* Small HImode tests can be converted to QImode.  */
7973      mode = QImode;
7974      val = gen_lowpart (QImode, val);
7975    }
7976
7977  if (len == HOST_BITS_PER_WIDE_INT)
7978    mask = -1;
7979  else
7980    mask = ((HOST_WIDE_INT)1 << len) - 1;
7981  mask <<= pos;
7982
7983  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7984})
7985
7986;; Convert HImode/SImode test instructions with immediate to QImode ones.
7987;; i386 does not allow to encode test with 8bit sign extended immediate, so
7988;; this is relatively important trick.
7989;; Do the conversion only post-reload to avoid limiting of the register class
7990;; to QI regs.
7991(define_split
7992  [(set (match_operand 0 "flags_reg_operand" "")
7993	(match_operator 1 "compare_operator"
7994	  [(and (match_operand 2 "register_operand" "")
7995	        (match_operand 3 "const_int_operand" ""))
7996	   (const_int 0)]))]
7997   "reload_completed
7998    && QI_REG_P (operands[2])
7999    && GET_MODE (operands[2]) != QImode
8000    && ((ix86_match_ccmode (insn, CCZmode)
8001    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8002	|| (ix86_match_ccmode (insn, CCNOmode)
8003	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8004  [(set (match_dup 0)
8005	(match_op_dup 1
8006	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8007		   (match_dup 3))
8008	   (const_int 0)]))]
8009  "operands[2] = gen_lowpart (SImode, operands[2]);
8010   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8011
8012(define_split
8013  [(set (match_operand 0 "flags_reg_operand" "")
8014	(match_operator 1 "compare_operator"
8015	  [(and (match_operand 2 "nonimmediate_operand" "")
8016	        (match_operand 3 "const_int_operand" ""))
8017	   (const_int 0)]))]
8018   "reload_completed
8019    && GET_MODE (operands[2]) != QImode
8020    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8021    && ((ix86_match_ccmode (insn, CCZmode)
8022	 && !(INTVAL (operands[3]) & ~255))
8023	|| (ix86_match_ccmode (insn, CCNOmode)
8024	    && !(INTVAL (operands[3]) & ~127)))"
8025  [(set (match_dup 0)
8026	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8027			 (const_int 0)]))]
8028  "operands[2] = gen_lowpart (QImode, operands[2]);
8029   operands[3] = gen_lowpart (QImode, operands[3]);")
8030
8031
8032;; %%% This used to optimize known byte-wide and operations to memory,
8033;; and sometimes to QImode registers.  If this is considered useful,
8034;; it should be done with splitters.
8035
8036(define_expand "anddi3"
8037  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8038	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8039		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8040   (clobber (reg:CC FLAGS_REG))]
8041  "TARGET_64BIT"
8042  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8043
8044(define_insn "*anddi_1_rex64"
8045  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8046	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8047		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8048   (clobber (reg:CC FLAGS_REG))]
8049  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8050{
8051  switch (get_attr_type (insn))
8052    {
8053    case TYPE_IMOVX:
8054      {
8055	enum machine_mode mode;
8056
8057	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8058        if (INTVAL (operands[2]) == 0xff)
8059	  mode = QImode;
8060	else
8061	  {
8062	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8063	    mode = HImode;
8064	  }
8065	
8066	operands[1] = gen_lowpart (mode, operands[1]);
8067	if (mode == QImode)
8068	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8069	else
8070	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8071      }
8072
8073    default:
8074      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8075      if (get_attr_mode (insn) == MODE_SI)
8076	return "and{l}\t{%k2, %k0|%k0, %k2}";
8077      else
8078	return "and{q}\t{%2, %0|%0, %2}";
8079    }
8080}
8081  [(set_attr "type" "alu,alu,alu,imovx")
8082   (set_attr "length_immediate" "*,*,*,0")
8083   (set_attr "mode" "SI,DI,DI,DI")])
8084
8085(define_insn "*anddi_2"
8086  [(set (reg FLAGS_REG)
8087	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8088			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8089		 (const_int 0)))
8090   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8091	(and:DI (match_dup 1) (match_dup 2)))]
8092  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093   && ix86_binary_operator_ok (AND, DImode, operands)"
8094  "@
8095   and{l}\t{%k2, %k0|%k0, %k2}
8096   and{q}\t{%2, %0|%0, %2}
8097   and{q}\t{%2, %0|%0, %2}"
8098  [(set_attr "type" "alu")
8099   (set_attr "mode" "SI,DI,DI")])
8100
8101(define_expand "andsi3"
8102  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8103	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8104		(match_operand:SI 2 "general_operand" "")))
8105   (clobber (reg:CC FLAGS_REG))]
8106  ""
8107  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8108
8109(define_insn "*andsi_1"
8110  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8111	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8112		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8113   (clobber (reg:CC FLAGS_REG))]
8114  "ix86_binary_operator_ok (AND, SImode, operands)"
8115{
8116  switch (get_attr_type (insn))
8117    {
8118    case TYPE_IMOVX:
8119      {
8120	enum machine_mode mode;
8121
8122	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123        if (INTVAL (operands[2]) == 0xff)
8124	  mode = QImode;
8125	else
8126	  {
8127	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8128	    mode = HImode;
8129	  }
8130	
8131	operands[1] = gen_lowpart (mode, operands[1]);
8132	if (mode == QImode)
8133	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8134	else
8135	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8136      }
8137
8138    default:
8139      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8140      return "and{l}\t{%2, %0|%0, %2}";
8141    }
8142}
8143  [(set_attr "type" "alu,alu,imovx")
8144   (set_attr "length_immediate" "*,*,0")
8145   (set_attr "mode" "SI")])
8146
8147(define_split
8148  [(set (match_operand 0 "register_operand" "")
8149	(and (match_dup 0)
8150	     (const_int -65536)))
8151   (clobber (reg:CC FLAGS_REG))]
8152  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8153  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8154  "operands[1] = gen_lowpart (HImode, operands[0]);")
8155
8156(define_split
8157  [(set (match_operand 0 "ext_register_operand" "")
8158	(and (match_dup 0)
8159	     (const_int -256)))
8160   (clobber (reg:CC FLAGS_REG))]
8161  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8162  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8163  "operands[1] = gen_lowpart (QImode, operands[0]);")
8164
8165(define_split
8166  [(set (match_operand 0 "ext_register_operand" "")
8167	(and (match_dup 0)
8168	     (const_int -65281)))
8169   (clobber (reg:CC FLAGS_REG))]
8170  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8171  [(parallel [(set (zero_extract:SI (match_dup 0)
8172				    (const_int 8)
8173				    (const_int 8))
8174		   (xor:SI 
8175		     (zero_extract:SI (match_dup 0)
8176				      (const_int 8)
8177				      (const_int 8))
8178		     (zero_extract:SI (match_dup 0)
8179				      (const_int 8)
8180				      (const_int 8))))
8181	      (clobber (reg:CC FLAGS_REG))])]
8182  "operands[0] = gen_lowpart (SImode, operands[0]);")
8183
8184;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185(define_insn "*andsi_1_zext"
8186  [(set (match_operand:DI 0 "register_operand" "=r")
8187	(zero_extend:DI
8188	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189		  (match_operand:SI 2 "general_operand" "rim"))))
8190   (clobber (reg:CC FLAGS_REG))]
8191  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8192  "and{l}\t{%2, %k0|%k0, %2}"
8193  [(set_attr "type" "alu")
8194   (set_attr "mode" "SI")])
8195
8196(define_insn "*andsi_2"
8197  [(set (reg FLAGS_REG)
8198	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8199			 (match_operand:SI 2 "general_operand" "rim,ri"))
8200		 (const_int 0)))
8201   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8202	(and:SI (match_dup 1) (match_dup 2)))]
8203  "ix86_match_ccmode (insn, CCNOmode)
8204   && ix86_binary_operator_ok (AND, SImode, operands)"
8205  "and{l}\t{%2, %0|%0, %2}"
8206  [(set_attr "type" "alu")
8207   (set_attr "mode" "SI")])
8208
8209;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210(define_insn "*andsi_2_zext"
8211  [(set (reg FLAGS_REG)
8212	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8213			 (match_operand:SI 2 "general_operand" "rim"))
8214		 (const_int 0)))
8215   (set (match_operand:DI 0 "register_operand" "=r")
8216	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8217  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8218   && ix86_binary_operator_ok (AND, SImode, operands)"
8219  "and{l}\t{%2, %k0|%k0, %2}"
8220  [(set_attr "type" "alu")
8221   (set_attr "mode" "SI")])
8222
8223(define_expand "andhi3"
8224  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8225	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8226		(match_operand:HI 2 "general_operand" "")))
8227   (clobber (reg:CC FLAGS_REG))]
8228  "TARGET_HIMODE_MATH"
8229  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8230
8231(define_insn "*andhi_1"
8232  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8233	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8234		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8235   (clobber (reg:CC FLAGS_REG))]
8236  "ix86_binary_operator_ok (AND, HImode, operands)"
8237{
8238  switch (get_attr_type (insn))
8239    {
8240    case TYPE_IMOVX:
8241      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8242      gcc_assert (INTVAL (operands[2]) == 0xff);
8243      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8244
8245    default:
8246      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8247
8248      return "and{w}\t{%2, %0|%0, %2}";
8249    }
8250}
8251  [(set_attr "type" "alu,alu,imovx")
8252   (set_attr "length_immediate" "*,*,0")
8253   (set_attr "mode" "HI,HI,SI")])
8254
8255(define_insn "*andhi_2"
8256  [(set (reg FLAGS_REG)
8257	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8258			 (match_operand:HI 2 "general_operand" "rim,ri"))
8259		 (const_int 0)))
8260   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8261	(and:HI (match_dup 1) (match_dup 2)))]
8262  "ix86_match_ccmode (insn, CCNOmode)
8263   && ix86_binary_operator_ok (AND, HImode, operands)"
8264  "and{w}\t{%2, %0|%0, %2}"
8265  [(set_attr "type" "alu")
8266   (set_attr "mode" "HI")])
8267
8268(define_expand "andqi3"
8269  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8270	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8271		(match_operand:QI 2 "general_operand" "")))
8272   (clobber (reg:CC FLAGS_REG))]
8273  "TARGET_QIMODE_MATH"
8274  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8275
8276;; %%% Potential partial reg stall on alternative 2.  What to do?
8277(define_insn "*andqi_1"
8278  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8279	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8280		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8281   (clobber (reg:CC FLAGS_REG))]
8282  "ix86_binary_operator_ok (AND, QImode, operands)"
8283  "@
8284   and{b}\t{%2, %0|%0, %2}
8285   and{b}\t{%2, %0|%0, %2}
8286   and{l}\t{%k2, %k0|%k0, %k2}"
8287  [(set_attr "type" "alu")
8288   (set_attr "mode" "QI,QI,SI")])
8289
8290(define_insn "*andqi_1_slp"
8291  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8292	(and:QI (match_dup 0)
8293		(match_operand:QI 1 "general_operand" "qi,qmi")))
8294   (clobber (reg:CC FLAGS_REG))]
8295  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8296   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8297  "and{b}\t{%1, %0|%0, %1}"
8298  [(set_attr "type" "alu1")
8299   (set_attr "mode" "QI")])
8300
8301(define_insn "*andqi_2_maybe_si"
8302  [(set (reg FLAGS_REG)
8303	(compare (and:QI
8304		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8305		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8306		 (const_int 0)))
8307   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8308	(and:QI (match_dup 1) (match_dup 2)))]
8309  "ix86_binary_operator_ok (AND, QImode, operands)
8310   && ix86_match_ccmode (insn,
8311			 GET_CODE (operands[2]) == CONST_INT
8312			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8313{
8314  if (which_alternative == 2)
8315    {
8316      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8317        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8318      return "and{l}\t{%2, %k0|%k0, %2}";
8319    }
8320  return "and{b}\t{%2, %0|%0, %2}";
8321}
8322  [(set_attr "type" "alu")
8323   (set_attr "mode" "QI,QI,SI")])
8324
8325(define_insn "*andqi_2"
8326  [(set (reg FLAGS_REG)
8327	(compare (and:QI
8328		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8329		   (match_operand:QI 2 "general_operand" "qim,qi"))
8330		 (const_int 0)))
8331   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8332	(and:QI (match_dup 1) (match_dup 2)))]
8333  "ix86_match_ccmode (insn, CCNOmode)
8334   && ix86_binary_operator_ok (AND, QImode, operands)"
8335  "and{b}\t{%2, %0|%0, %2}"
8336  [(set_attr "type" "alu")
8337   (set_attr "mode" "QI")])
8338
8339(define_insn "*andqi_2_slp"
8340  [(set (reg FLAGS_REG)
8341	(compare (and:QI
8342		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8343		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8344		 (const_int 0)))
8345   (set (strict_low_part (match_dup 0))
8346	(and:QI (match_dup 0) (match_dup 1)))]
8347  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8348   && ix86_match_ccmode (insn, CCNOmode)
8349   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350  "and{b}\t{%1, %0|%0, %1}"
8351  [(set_attr "type" "alu1")
8352   (set_attr "mode" "QI")])
8353
8354;; ??? A bug in recog prevents it from recognizing a const_int as an
8355;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8356;; for a QImode operand, which of course failed.
8357
8358(define_insn "andqi_ext_0"
8359  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8360			 (const_int 8)
8361			 (const_int 8))
8362	(and:SI 
8363	  (zero_extract:SI
8364	    (match_operand 1 "ext_register_operand" "0")
8365	    (const_int 8)
8366	    (const_int 8))
8367	  (match_operand 2 "const_int_operand" "n")))
8368   (clobber (reg:CC FLAGS_REG))]
8369  ""
8370  "and{b}\t{%2, %h0|%h0, %2}"
8371  [(set_attr "type" "alu")
8372   (set_attr "length_immediate" "1")
8373   (set_attr "mode" "QI")])
8374
8375;; Generated by peephole translating test to and.  This shows up
8376;; often in fp comparisons.
8377
8378(define_insn "*andqi_ext_0_cc"
8379  [(set (reg FLAGS_REG)
8380	(compare
8381	  (and:SI
8382	    (zero_extract:SI
8383	      (match_operand 1 "ext_register_operand" "0")
8384	      (const_int 8)
8385	      (const_int 8))
8386	    (match_operand 2 "const_int_operand" "n"))
8387	  (const_int 0)))
8388   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8389			 (const_int 8)
8390			 (const_int 8))
8391	(and:SI 
8392	  (zero_extract:SI
8393	    (match_dup 1)
8394	    (const_int 8)
8395	    (const_int 8))
8396	  (match_dup 2)))]
8397  "ix86_match_ccmode (insn, CCNOmode)"
8398  "and{b}\t{%2, %h0|%h0, %2}"
8399  [(set_attr "type" "alu")
8400   (set_attr "length_immediate" "1")
8401   (set_attr "mode" "QI")])
8402
8403(define_insn "*andqi_ext_1"
8404  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405			 (const_int 8)
8406			 (const_int 8))
8407	(and:SI 
8408	  (zero_extract:SI
8409	    (match_operand 1 "ext_register_operand" "0")
8410	    (const_int 8)
8411	    (const_int 8))
8412	  (zero_extend:SI
8413	    (match_operand:QI 2 "general_operand" "Qm"))))
8414   (clobber (reg:CC FLAGS_REG))]
8415  "!TARGET_64BIT"
8416  "and{b}\t{%2, %h0|%h0, %2}"
8417  [(set_attr "type" "alu")
8418   (set_attr "length_immediate" "0")
8419   (set_attr "mode" "QI")])
8420
8421(define_insn "*andqi_ext_1_rex64"
8422  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423			 (const_int 8)
8424			 (const_int 8))
8425	(and:SI 
8426	  (zero_extract:SI
8427	    (match_operand 1 "ext_register_operand" "0")
8428	    (const_int 8)
8429	    (const_int 8))
8430	  (zero_extend:SI
8431	    (match_operand 2 "ext_register_operand" "Q"))))
8432   (clobber (reg:CC FLAGS_REG))]
8433  "TARGET_64BIT"
8434  "and{b}\t{%2, %h0|%h0, %2}"
8435  [(set_attr "type" "alu")
8436   (set_attr "length_immediate" "0")
8437   (set_attr "mode" "QI")])
8438
8439(define_insn "*andqi_ext_2"
8440  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441			 (const_int 8)
8442			 (const_int 8))
8443	(and:SI
8444	  (zero_extract:SI
8445	    (match_operand 1 "ext_register_operand" "%0")
8446	    (const_int 8)
8447	    (const_int 8))
8448	  (zero_extract:SI
8449	    (match_operand 2 "ext_register_operand" "Q")
8450	    (const_int 8)
8451	    (const_int 8))))
8452   (clobber (reg:CC FLAGS_REG))]
8453  ""
8454  "and{b}\t{%h2, %h0|%h0, %h2}"
8455  [(set_attr "type" "alu")
8456   (set_attr "length_immediate" "0")
8457   (set_attr "mode" "QI")])
8458
8459;; Convert wide AND instructions with immediate operand to shorter QImode
8460;; equivalents when possible.
8461;; Don't do the splitting with memory operands, since it introduces risk
8462;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8463;; for size, but that can (should?) be handled by generic code instead.
8464(define_split
8465  [(set (match_operand 0 "register_operand" "")
8466	(and (match_operand 1 "register_operand" "")
8467	     (match_operand 2 "const_int_operand" "")))
8468   (clobber (reg:CC FLAGS_REG))]
8469   "reload_completed
8470    && QI_REG_P (operands[0])
8471    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8472    && !(~INTVAL (operands[2]) & ~(255 << 8))
8473    && GET_MODE (operands[0]) != QImode"
8474  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8475		   (and:SI (zero_extract:SI (match_dup 1)
8476					    (const_int 8) (const_int 8))
8477			   (match_dup 2)))
8478	      (clobber (reg:CC FLAGS_REG))])]
8479  "operands[0] = gen_lowpart (SImode, operands[0]);
8480   operands[1] = gen_lowpart (SImode, operands[1]);
8481   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8482
8483;; Since AND can be encoded with sign extended immediate, this is only
8484;; profitable when 7th bit is not set.
8485(define_split
8486  [(set (match_operand 0 "register_operand" "")
8487	(and (match_operand 1 "general_operand" "")
8488	     (match_operand 2 "const_int_operand" "")))
8489   (clobber (reg:CC FLAGS_REG))]
8490   "reload_completed
8491    && ANY_QI_REG_P (operands[0])
8492    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8493    && !(~INTVAL (operands[2]) & ~255)
8494    && !(INTVAL (operands[2]) & 128)
8495    && GET_MODE (operands[0]) != QImode"
8496  [(parallel [(set (strict_low_part (match_dup 0))
8497		   (and:QI (match_dup 1)
8498			   (match_dup 2)))
8499	      (clobber (reg:CC FLAGS_REG))])]
8500  "operands[0] = gen_lowpart (QImode, operands[0]);
8501   operands[1] = gen_lowpart (QImode, operands[1]);
8502   operands[2] = gen_lowpart (QImode, operands[2]);")
8503
8504;; Logical inclusive OR instructions
8505
8506;; %%% This used to optimize known byte-wide and operations to memory.
8507;; If this is considered useful, it should be done with splitters.
8508
8509(define_expand "iordi3"
8510  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8511	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8512		(match_operand:DI 2 "x86_64_general_operand" "")))
8513   (clobber (reg:CC FLAGS_REG))]
8514  "TARGET_64BIT"
8515  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8516
8517(define_insn "*iordi_1_rex64"
8518  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8519	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8520		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8521   (clobber (reg:CC FLAGS_REG))]
8522  "TARGET_64BIT
8523   && ix86_binary_operator_ok (IOR, DImode, operands)"
8524  "or{q}\t{%2, %0|%0, %2}"
8525  [(set_attr "type" "alu")
8526   (set_attr "mode" "DI")])
8527
8528(define_insn "*iordi_2_rex64"
8529  [(set (reg FLAGS_REG)
8530	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8531			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8532		 (const_int 0)))
8533   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8534	(ior:DI (match_dup 1) (match_dup 2)))]
8535  "TARGET_64BIT
8536   && ix86_match_ccmode (insn, CCNOmode)
8537   && ix86_binary_operator_ok (IOR, DImode, operands)"
8538  "or{q}\t{%2, %0|%0, %2}"
8539  [(set_attr "type" "alu")
8540   (set_attr "mode" "DI")])
8541
8542(define_insn "*iordi_3_rex64"
8543  [(set (reg FLAGS_REG)
8544	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8545			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8546		 (const_int 0)))
8547   (clobber (match_scratch:DI 0 "=r"))]
8548  "TARGET_64BIT
8549   && ix86_match_ccmode (insn, CCNOmode)
8550   && ix86_binary_operator_ok (IOR, DImode, operands)"
8551  "or{q}\t{%2, %0|%0, %2}"
8552  [(set_attr "type" "alu")
8553   (set_attr "mode" "DI")])
8554
8555
8556(define_expand "iorsi3"
8557  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8558	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8559		(match_operand:SI 2 "general_operand" "")))
8560   (clobber (reg:CC FLAGS_REG))]
8561  ""
8562  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8563
8564(define_insn "*iorsi_1"
8565  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8566	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567		(match_operand:SI 2 "general_operand" "ri,rmi")))
8568   (clobber (reg:CC FLAGS_REG))]
8569  "ix86_binary_operator_ok (IOR, SImode, operands)"
8570  "or{l}\t{%2, %0|%0, %2}"
8571  [(set_attr "type" "alu")
8572   (set_attr "mode" "SI")])
8573
8574;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575(define_insn "*iorsi_1_zext"
8576  [(set (match_operand:DI 0 "register_operand" "=rm")
8577	(zero_extend:DI
8578	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579		  (match_operand:SI 2 "general_operand" "rim"))))
8580   (clobber (reg:CC FLAGS_REG))]
8581  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8582  "or{l}\t{%2, %k0|%k0, %2}"
8583  [(set_attr "type" "alu")
8584   (set_attr "mode" "SI")])
8585
8586(define_insn "*iorsi_1_zext_imm"
8587  [(set (match_operand:DI 0 "register_operand" "=rm")
8588	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8589		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8590   (clobber (reg:CC FLAGS_REG))]
8591  "TARGET_64BIT"
8592  "or{l}\t{%2, %k0|%k0, %2}"
8593  [(set_attr "type" "alu")
8594   (set_attr "mode" "SI")])
8595
8596(define_insn "*iorsi_2"
8597  [(set (reg FLAGS_REG)
8598	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8599			 (match_operand:SI 2 "general_operand" "rim,ri"))
8600		 (const_int 0)))
8601   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8602	(ior:SI (match_dup 1) (match_dup 2)))]
8603  "ix86_match_ccmode (insn, CCNOmode)
8604   && ix86_binary_operator_ok (IOR, SImode, operands)"
8605  "or{l}\t{%2, %0|%0, %2}"
8606  [(set_attr "type" "alu")
8607   (set_attr "mode" "SI")])
8608
8609;; See comment for addsi_1_zext why we do use nonimmediate_operand
8610;; ??? Special case for immediate operand is missing - it is tricky.
8611(define_insn "*iorsi_2_zext"
8612  [(set (reg FLAGS_REG)
8613	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8614			 (match_operand:SI 2 "general_operand" "rim"))
8615		 (const_int 0)))
8616   (set (match_operand:DI 0 "register_operand" "=r")
8617	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8618  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8619   && ix86_binary_operator_ok (IOR, SImode, operands)"
8620  "or{l}\t{%2, %k0|%k0, %2}"
8621  [(set_attr "type" "alu")
8622   (set_attr "mode" "SI")])
8623
8624(define_insn "*iorsi_2_zext_imm"
8625  [(set (reg FLAGS_REG)
8626	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8627			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8628		 (const_int 0)))
8629   (set (match_operand:DI 0 "register_operand" "=r")
8630	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8631  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8632   && ix86_binary_operator_ok (IOR, SImode, operands)"
8633  "or{l}\t{%2, %k0|%k0, %2}"
8634  [(set_attr "type" "alu")
8635   (set_attr "mode" "SI")])
8636
8637(define_insn "*iorsi_3"
8638  [(set (reg FLAGS_REG)
8639	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8640			 (match_operand:SI 2 "general_operand" "rim"))
8641		 (const_int 0)))
8642   (clobber (match_scratch:SI 0 "=r"))]
8643  "ix86_match_ccmode (insn, CCNOmode)
8644   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8645  "or{l}\t{%2, %0|%0, %2}"
8646  [(set_attr "type" "alu")
8647   (set_attr "mode" "SI")])
8648
8649(define_expand "iorhi3"
8650  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8651	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8652		(match_operand:HI 2 "general_operand" "")))
8653   (clobber (reg:CC FLAGS_REG))]
8654  "TARGET_HIMODE_MATH"
8655  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8656
8657(define_insn "*iorhi_1"
8658  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8659	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8660		(match_operand:HI 2 "general_operand" "rmi,ri")))
8661   (clobber (reg:CC FLAGS_REG))]
8662  "ix86_binary_operator_ok (IOR, HImode, operands)"
8663  "or{w}\t{%2, %0|%0, %2}"
8664  [(set_attr "type" "alu")
8665   (set_attr "mode" "HI")])
8666
8667(define_insn "*iorhi_2"
8668  [(set (reg FLAGS_REG)
8669	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8670			 (match_operand:HI 2 "general_operand" "rim,ri"))
8671		 (const_int 0)))
8672   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8673	(ior:HI (match_dup 1) (match_dup 2)))]
8674  "ix86_match_ccmode (insn, CCNOmode)
8675   && ix86_binary_operator_ok (IOR, HImode, operands)"
8676  "or{w}\t{%2, %0|%0, %2}"
8677  [(set_attr "type" "alu")
8678   (set_attr "mode" "HI")])
8679
8680(define_insn "*iorhi_3"
8681  [(set (reg FLAGS_REG)
8682	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8683			 (match_operand:HI 2 "general_operand" "rim"))
8684		 (const_int 0)))
8685   (clobber (match_scratch:HI 0 "=r"))]
8686  "ix86_match_ccmode (insn, CCNOmode)
8687   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8688  "or{w}\t{%2, %0|%0, %2}"
8689  [(set_attr "type" "alu")
8690   (set_attr "mode" "HI")])
8691
8692(define_expand "iorqi3"
8693  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8694	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8695		(match_operand:QI 2 "general_operand" "")))
8696   (clobber (reg:CC FLAGS_REG))]
8697  "TARGET_QIMODE_MATH"
8698  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8699
8700;; %%% Potential partial reg stall on alternative 2.  What to do?
8701(define_insn "*iorqi_1"
8702  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8703	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8704		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8705   (clobber (reg:CC FLAGS_REG))]
8706  "ix86_binary_operator_ok (IOR, QImode, operands)"
8707  "@
8708   or{b}\t{%2, %0|%0, %2}
8709   or{b}\t{%2, %0|%0, %2}
8710   or{l}\t{%k2, %k0|%k0, %k2}"
8711  [(set_attr "type" "alu")
8712   (set_attr "mode" "QI,QI,SI")])
8713
8714(define_insn "*iorqi_1_slp"
8715  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8716	(ior:QI (match_dup 0)
8717		(match_operand:QI 1 "general_operand" "qmi,qi")))
8718   (clobber (reg:CC FLAGS_REG))]
8719  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8721  "or{b}\t{%1, %0|%0, %1}"
8722  [(set_attr "type" "alu1")
8723   (set_attr "mode" "QI")])
8724
8725(define_insn "*iorqi_2"
8726  [(set (reg FLAGS_REG)
8727	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8728			 (match_operand:QI 2 "general_operand" "qim,qi"))
8729		 (const_int 0)))
8730   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8731	(ior:QI (match_dup 1) (match_dup 2)))]
8732  "ix86_match_ccmode (insn, CCNOmode)
8733   && ix86_binary_operator_ok (IOR, QImode, operands)"
8734  "or{b}\t{%2, %0|%0, %2}"
8735  [(set_attr "type" "alu")
8736   (set_attr "mode" "QI")])
8737
8738(define_insn "*iorqi_2_slp"
8739  [(set (reg FLAGS_REG)
8740	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8741			 (match_operand:QI 1 "general_operand" "qim,qi"))
8742		 (const_int 0)))
8743   (set (strict_low_part (match_dup 0))
8744	(ior:QI (match_dup 0) (match_dup 1)))]
8745  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8746   && ix86_match_ccmode (insn, CCNOmode)
8747   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8748  "or{b}\t{%1, %0|%0, %1}"
8749  [(set_attr "type" "alu1")
8750   (set_attr "mode" "QI")])
8751
8752(define_insn "*iorqi_3"
8753  [(set (reg FLAGS_REG)
8754	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8755			 (match_operand:QI 2 "general_operand" "qim"))
8756		 (const_int 0)))
8757   (clobber (match_scratch:QI 0 "=q"))]
8758  "ix86_match_ccmode (insn, CCNOmode)
8759   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760  "or{b}\t{%2, %0|%0, %2}"
8761  [(set_attr "type" "alu")
8762   (set_attr "mode" "QI")])
8763
8764(define_insn "iorqi_ext_0"
8765  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8766			 (const_int 8)
8767			 (const_int 8))
8768	(ior:SI 
8769	  (zero_extract:SI
8770	    (match_operand 1 "ext_register_operand" "0")
8771	    (const_int 8)
8772	    (const_int 8))
8773	  (match_operand 2 "const_int_operand" "n")))
8774   (clobber (reg:CC FLAGS_REG))]
8775  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8776  "or{b}\t{%2, %h0|%h0, %2}"
8777  [(set_attr "type" "alu")
8778   (set_attr "length_immediate" "1")
8779   (set_attr "mode" "QI")])
8780
8781(define_insn "*iorqi_ext_1"
8782  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783			 (const_int 8)
8784			 (const_int 8))
8785	(ior:SI 
8786	  (zero_extract:SI
8787	    (match_operand 1 "ext_register_operand" "0")
8788	    (const_int 8)
8789	    (const_int 8))
8790	  (zero_extend:SI
8791	    (match_operand:QI 2 "general_operand" "Qm"))))
8792   (clobber (reg:CC FLAGS_REG))]
8793  "!TARGET_64BIT
8794   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8795  "or{b}\t{%2, %h0|%h0, %2}"
8796  [(set_attr "type" "alu")
8797   (set_attr "length_immediate" "0")
8798   (set_attr "mode" "QI")])
8799
8800(define_insn "*iorqi_ext_1_rex64"
8801  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8802			 (const_int 8)
8803			 (const_int 8))
8804	(ior:SI 
8805	  (zero_extract:SI
8806	    (match_operand 1 "ext_register_operand" "0")
8807	    (const_int 8)
8808	    (const_int 8))
8809	  (zero_extend:SI
8810	    (match_operand 2 "ext_register_operand" "Q"))))
8811   (clobber (reg:CC FLAGS_REG))]
8812  "TARGET_64BIT
8813   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8814  "or{b}\t{%2, %h0|%h0, %2}"
8815  [(set_attr "type" "alu")
8816   (set_attr "length_immediate" "0")
8817   (set_attr "mode" "QI")])
8818
8819(define_insn "*iorqi_ext_2"
8820  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821			 (const_int 8)
8822			 (const_int 8))
8823	(ior:SI 
8824	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8825	  		   (const_int 8)
8826			   (const_int 8))
8827	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8828	  		   (const_int 8)
8829			   (const_int 8))))
8830   (clobber (reg:CC FLAGS_REG))]
8831  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832  "ior{b}\t{%h2, %h0|%h0, %h2}"
8833  [(set_attr "type" "alu")
8834   (set_attr "length_immediate" "0")
8835   (set_attr "mode" "QI")])
8836
8837(define_split
8838  [(set (match_operand 0 "register_operand" "")
8839	(ior (match_operand 1 "register_operand" "")
8840	     (match_operand 2 "const_int_operand" "")))
8841   (clobber (reg:CC FLAGS_REG))]
8842   "reload_completed
8843    && QI_REG_P (operands[0])
8844    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8845    && !(INTVAL (operands[2]) & ~(255 << 8))
8846    && GET_MODE (operands[0]) != QImode"
8847  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8848		   (ior:SI (zero_extract:SI (match_dup 1)
8849					    (const_int 8) (const_int 8))
8850			   (match_dup 2)))
8851	      (clobber (reg:CC FLAGS_REG))])]
8852  "operands[0] = gen_lowpart (SImode, operands[0]);
8853   operands[1] = gen_lowpart (SImode, operands[1]);
8854   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8855
8856;; Since OR can be encoded with sign extended immediate, this is only
8857;; profitable when 7th bit is set.
8858(define_split
8859  [(set (match_operand 0 "register_operand" "")
8860	(ior (match_operand 1 "general_operand" "")
8861	     (match_operand 2 "const_int_operand" "")))
8862   (clobber (reg:CC FLAGS_REG))]
8863   "reload_completed
8864    && ANY_QI_REG_P (operands[0])
8865    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8866    && !(INTVAL (operands[2]) & ~255)
8867    && (INTVAL (operands[2]) & 128)
8868    && GET_MODE (operands[0]) != QImode"
8869  [(parallel [(set (strict_low_part (match_dup 0))
8870		   (ior:QI (match_dup 1)
8871			   (match_dup 2)))
8872	      (clobber (reg:CC FLAGS_REG))])]
8873  "operands[0] = gen_lowpart (QImode, operands[0]);
8874   operands[1] = gen_lowpart (QImode, operands[1]);
8875   operands[2] = gen_lowpart (QImode, operands[2]);")
8876
8877;; Logical XOR instructions
8878
8879;; %%% This used to optimize known byte-wide and operations to memory.
8880;; If this is considered useful, it should be done with splitters.
8881
8882(define_expand "xordi3"
8883  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885		(match_operand:DI 2 "x86_64_general_operand" "")))
8886   (clobber (reg:CC FLAGS_REG))]
8887  "TARGET_64BIT"
8888  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8889
8890(define_insn "*xordi_1_rex64"
8891  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8892	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8894   (clobber (reg:CC FLAGS_REG))]
8895  "TARGET_64BIT
8896   && ix86_binary_operator_ok (XOR, DImode, operands)"
8897  "@
8898   xor{q}\t{%2, %0|%0, %2}
8899   xor{q}\t{%2, %0|%0, %2}"
8900  [(set_attr "type" "alu")
8901   (set_attr "mode" "DI,DI")])
8902
8903(define_insn "*xordi_2_rex64"
8904  [(set (reg FLAGS_REG)
8905	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8907		 (const_int 0)))
8908   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909	(xor:DI (match_dup 1) (match_dup 2)))]
8910  "TARGET_64BIT
8911   && ix86_match_ccmode (insn, CCNOmode)
8912   && ix86_binary_operator_ok (XOR, DImode, operands)"
8913  "@
8914   xor{q}\t{%2, %0|%0, %2}
8915   xor{q}\t{%2, %0|%0, %2}"
8916  [(set_attr "type" "alu")
8917   (set_attr "mode" "DI,DI")])
8918
8919(define_insn "*xordi_3_rex64"
8920  [(set (reg FLAGS_REG)
8921	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8922			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8923		 (const_int 0)))
8924   (clobber (match_scratch:DI 0 "=r"))]
8925  "TARGET_64BIT
8926   && ix86_match_ccmode (insn, CCNOmode)
8927   && ix86_binary_operator_ok (XOR, DImode, operands)"
8928  "xor{q}\t{%2, %0|%0, %2}"
8929  [(set_attr "type" "alu")
8930   (set_attr "mode" "DI")])
8931
8932(define_expand "xorsi3"
8933  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8934	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8935		(match_operand:SI 2 "general_operand" "")))
8936   (clobber (reg:CC FLAGS_REG))]
8937  ""
8938  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8939
8940(define_insn "*xorsi_1"
8941  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8942	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943		(match_operand:SI 2 "general_operand" "ri,rm")))
8944   (clobber (reg:CC FLAGS_REG))]
8945  "ix86_binary_operator_ok (XOR, SImode, operands)"
8946  "xor{l}\t{%2, %0|%0, %2}"
8947  [(set_attr "type" "alu")
8948   (set_attr "mode" "SI")])
8949
8950;; See comment for addsi_1_zext why we do use nonimmediate_operand
8951;; Add speccase for immediates
8952(define_insn "*xorsi_1_zext"
8953  [(set (match_operand:DI 0 "register_operand" "=r")
8954	(zero_extend:DI
8955	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956		  (match_operand:SI 2 "general_operand" "rim"))))
8957   (clobber (reg:CC FLAGS_REG))]
8958  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8959  "xor{l}\t{%2, %k0|%k0, %2}"
8960  [(set_attr "type" "alu")
8961   (set_attr "mode" "SI")])
8962
8963(define_insn "*xorsi_1_zext_imm"
8964  [(set (match_operand:DI 0 "register_operand" "=r")
8965	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8966		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8967   (clobber (reg:CC FLAGS_REG))]
8968  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8969  "xor{l}\t{%2, %k0|%k0, %2}"
8970  [(set_attr "type" "alu")
8971   (set_attr "mode" "SI")])
8972
8973(define_insn "*xorsi_2"
8974  [(set (reg FLAGS_REG)
8975	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8976			 (match_operand:SI 2 "general_operand" "rim,ri"))
8977		 (const_int 0)))
8978   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8979	(xor:SI (match_dup 1) (match_dup 2)))]
8980  "ix86_match_ccmode (insn, CCNOmode)
8981   && ix86_binary_operator_ok (XOR, SImode, operands)"
8982  "xor{l}\t{%2, %0|%0, %2}"
8983  [(set_attr "type" "alu")
8984   (set_attr "mode" "SI")])
8985
8986;; See comment for addsi_1_zext why we do use nonimmediate_operand
8987;; ??? Special case for immediate operand is missing - it is tricky.
8988(define_insn "*xorsi_2_zext"
8989  [(set (reg FLAGS_REG)
8990	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8991			 (match_operand:SI 2 "general_operand" "rim"))
8992		 (const_int 0)))
8993   (set (match_operand:DI 0 "register_operand" "=r")
8994	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8995  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8996   && ix86_binary_operator_ok (XOR, SImode, operands)"
8997  "xor{l}\t{%2, %k0|%k0, %2}"
8998  [(set_attr "type" "alu")
8999   (set_attr "mode" "SI")])
9000
9001(define_insn "*xorsi_2_zext_imm"
9002  [(set (reg FLAGS_REG)
9003	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9004			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9005		 (const_int 0)))
9006   (set (match_operand:DI 0 "register_operand" "=r")
9007	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9008  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9009   && ix86_binary_operator_ok (XOR, SImode, operands)"
9010  "xor{l}\t{%2, %k0|%k0, %2}"
9011  [(set_attr "type" "alu")
9012   (set_attr "mode" "SI")])
9013
9014(define_insn "*xorsi_3"
9015  [(set (reg FLAGS_REG)
9016	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9017			 (match_operand:SI 2 "general_operand" "rim"))
9018		 (const_int 0)))
9019   (clobber (match_scratch:SI 0 "=r"))]
9020  "ix86_match_ccmode (insn, CCNOmode)
9021   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9022  "xor{l}\t{%2, %0|%0, %2}"
9023  [(set_attr "type" "alu")
9024   (set_attr "mode" "SI")])
9025
9026(define_expand "xorhi3"
9027  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9028	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9029		(match_operand:HI 2 "general_operand" "")))
9030   (clobber (reg:CC FLAGS_REG))]
9031  "TARGET_HIMODE_MATH"
9032  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9033
9034(define_insn "*xorhi_1"
9035  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9036	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9037		(match_operand:HI 2 "general_operand" "rmi,ri")))
9038   (clobber (reg:CC FLAGS_REG))]
9039  "ix86_binary_operator_ok (XOR, HImode, operands)"
9040  "xor{w}\t{%2, %0|%0, %2}"
9041  [(set_attr "type" "alu")
9042   (set_attr "mode" "HI")])
9043
9044(define_insn "*xorhi_2"
9045  [(set (reg FLAGS_REG)
9046	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9047			 (match_operand:HI 2 "general_operand" "rim,ri"))
9048		 (const_int 0)))
9049   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9050	(xor:HI (match_dup 1) (match_dup 2)))]
9051  "ix86_match_ccmode (insn, CCNOmode)
9052   && ix86_binary_operator_ok (XOR, HImode, operands)"
9053  "xor{w}\t{%2, %0|%0, %2}"
9054  [(set_attr "type" "alu")
9055   (set_attr "mode" "HI")])
9056
9057(define_insn "*xorhi_3"
9058  [(set (reg FLAGS_REG)
9059	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9060			 (match_operand:HI 2 "general_operand" "rim"))
9061		 (const_int 0)))
9062   (clobber (match_scratch:HI 0 "=r"))]
9063  "ix86_match_ccmode (insn, CCNOmode)
9064   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9065  "xor{w}\t{%2, %0|%0, %2}"
9066  [(set_attr "type" "alu")
9067   (set_attr "mode" "HI")])
9068
9069(define_expand "xorqi3"
9070  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9071	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9072		(match_operand:QI 2 "general_operand" "")))
9073   (clobber (reg:CC FLAGS_REG))]
9074  "TARGET_QIMODE_MATH"
9075  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9076
9077;; %%% Potential partial reg stall on alternative 2.  What to do?
9078(define_insn "*xorqi_1"
9079  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9082   (clobber (reg:CC FLAGS_REG))]
9083  "ix86_binary_operator_ok (XOR, QImode, operands)"
9084  "@
9085   xor{b}\t{%2, %0|%0, %2}
9086   xor{b}\t{%2, %0|%0, %2}
9087   xor{l}\t{%k2, %k0|%k0, %k2}"
9088  [(set_attr "type" "alu")
9089   (set_attr "mode" "QI,QI,SI")])
9090
9091(define_insn "*xorqi_1_slp"
9092  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9093	(xor:QI (match_dup 0)
9094		(match_operand:QI 1 "general_operand" "qi,qmi")))
9095   (clobber (reg:CC FLAGS_REG))]
9096  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9097   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9098  "xor{b}\t{%1, %0|%0, %1}"
9099  [(set_attr "type" "alu1")
9100   (set_attr "mode" "QI")])
9101
9102(define_insn "xorqi_ext_0"
9103  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9104			 (const_int 8)
9105			 (const_int 8))
9106	(xor:SI 
9107	  (zero_extract:SI
9108	    (match_operand 1 "ext_register_operand" "0")
9109	    (const_int 8)
9110	    (const_int 8))
9111	  (match_operand 2 "const_int_operand" "n")))
9112   (clobber (reg:CC FLAGS_REG))]
9113  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9114  "xor{b}\t{%2, %h0|%h0, %2}"
9115  [(set_attr "type" "alu")
9116   (set_attr "length_immediate" "1")
9117   (set_attr "mode" "QI")])
9118
9119(define_insn "*xorqi_ext_1"
9120  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9121			 (const_int 8)
9122			 (const_int 8))
9123	(xor:SI 
9124	  (zero_extract:SI
9125	    (match_operand 1 "ext_register_operand" "0")
9126	    (const_int 8)
9127	    (const_int 8))
9128	  (zero_extend:SI
9129	    (match_operand:QI 2 "general_operand" "Qm"))))
9130   (clobber (reg:CC FLAGS_REG))]
9131  "!TARGET_64BIT
9132   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9133  "xor{b}\t{%2, %h0|%h0, %2}"
9134  [(set_attr "type" "alu")
9135   (set_attr "length_immediate" "0")
9136   (set_attr "mode" "QI")])
9137
9138(define_insn "*xorqi_ext_1_rex64"
9139  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9140			 (const_int 8)
9141			 (const_int 8))
9142	(xor:SI 
9143	  (zero_extract:SI
9144	    (match_operand 1 "ext_register_operand" "0")
9145	    (const_int 8)
9146	    (const_int 8))
9147	  (zero_extend:SI
9148	    (match_operand 2 "ext_register_operand" "Q"))))
9149   (clobber (reg:CC FLAGS_REG))]
9150  "TARGET_64BIT
9151   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9152  "xor{b}\t{%2, %h0|%h0, %2}"
9153  [(set_attr "type" "alu")
9154   (set_attr "length_immediate" "0")
9155   (set_attr "mode" "QI")])
9156
9157(define_insn "*xorqi_ext_2"
9158  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159			 (const_int 8)
9160			 (const_int 8))
9161	(xor:SI 
9162	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9163	  		   (const_int 8)
9164			   (const_int 8))
9165	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9166	  		   (const_int 8)
9167			   (const_int 8))))
9168   (clobber (reg:CC FLAGS_REG))]
9169  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170  "xor{b}\t{%h2, %h0|%h0, %h2}"
9171  [(set_attr "type" "alu")
9172   (set_attr "length_immediate" "0")
9173   (set_attr "mode" "QI")])
9174
9175(define_insn "*xorqi_cc_1"
9176  [(set (reg FLAGS_REG)
9177	(compare
9178	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9179		  (match_operand:QI 2 "general_operand" "qim,qi"))
9180	  (const_int 0)))
9181   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9182	(xor:QI (match_dup 1) (match_dup 2)))]
9183  "ix86_match_ccmode (insn, CCNOmode)
9184   && ix86_binary_operator_ok (XOR, QImode, operands)"
9185  "xor{b}\t{%2, %0|%0, %2}"
9186  [(set_attr "type" "alu")
9187   (set_attr "mode" "QI")])
9188
9189(define_insn "*xorqi_2_slp"
9190  [(set (reg FLAGS_REG)
9191	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9192			 (match_operand:QI 1 "general_operand" "qim,qi"))
9193		 (const_int 0)))
9194   (set (strict_low_part (match_dup 0))
9195	(xor:QI (match_dup 0) (match_dup 1)))]
9196  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9197   && ix86_match_ccmode (insn, CCNOmode)
9198   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9199  "xor{b}\t{%1, %0|%0, %1}"
9200  [(set_attr "type" "alu1")
9201   (set_attr "mode" "QI")])
9202
9203(define_insn "*xorqi_cc_2"
9204  [(set (reg FLAGS_REG)
9205	(compare
9206	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9207		  (match_operand:QI 2 "general_operand" "qim"))
9208	  (const_int 0)))
9209   (clobber (match_scratch:QI 0 "=q"))]
9210  "ix86_match_ccmode (insn, CCNOmode)
9211   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9212  "xor{b}\t{%2, %0|%0, %2}"
9213  [(set_attr "type" "alu")
9214   (set_attr "mode" "QI")])
9215
9216(define_insn "*xorqi_cc_ext_1"
9217  [(set (reg FLAGS_REG)
9218	(compare
9219	  (xor:SI
9220	    (zero_extract:SI
9221	      (match_operand 1 "ext_register_operand" "0")
9222	      (const_int 8)
9223	      (const_int 8))
9224	    (match_operand:QI 2 "general_operand" "qmn"))
9225	  (const_int 0)))
9226   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9227			 (const_int 8)
9228			 (const_int 8))
9229	(xor:SI 
9230	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9231	  (match_dup 2)))]
9232  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9233  "xor{b}\t{%2, %h0|%h0, %2}"
9234  [(set_attr "type" "alu")
9235   (set_attr "mode" "QI")])
9236
9237(define_insn "*xorqi_cc_ext_1_rex64"
9238  [(set (reg FLAGS_REG)
9239	(compare
9240	  (xor:SI
9241	    (zero_extract:SI
9242	      (match_operand 1 "ext_register_operand" "0")
9243	      (const_int 8)
9244	      (const_int 8))
9245	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9246	  (const_int 0)))
9247   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9248			 (const_int 8)
9249			 (const_int 8))
9250	(xor:SI 
9251	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9252	  (match_dup 2)))]
9253  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9254  "xor{b}\t{%2, %h0|%h0, %2}"
9255  [(set_attr "type" "alu")
9256   (set_attr "mode" "QI")])
9257
9258(define_expand "xorqi_cc_ext_1"
9259  [(parallel [
9260     (set (reg:CCNO FLAGS_REG)
9261	  (compare:CCNO
9262	    (xor:SI
9263	      (zero_extract:SI
9264		(match_operand 1 "ext_register_operand" "")
9265		(const_int 8)
9266		(const_int 8))
9267	      (match_operand:QI 2 "general_operand" ""))
9268	    (const_int 0)))
9269     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9270			   (const_int 8)
9271			   (const_int 8))
9272	  (xor:SI 
9273	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9274	    (match_dup 2)))])]
9275  ""
9276  "")
9277
9278(define_split
9279  [(set (match_operand 0 "register_operand" "")
9280	(xor (match_operand 1 "register_operand" "")
9281	     (match_operand 2 "const_int_operand" "")))
9282   (clobber (reg:CC FLAGS_REG))]
9283   "reload_completed
9284    && QI_REG_P (operands[0])
9285    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9286    && !(INTVAL (operands[2]) & ~(255 << 8))
9287    && GET_MODE (operands[0]) != QImode"
9288  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9289		   (xor:SI (zero_extract:SI (match_dup 1)
9290					    (const_int 8) (const_int 8))
9291			   (match_dup 2)))
9292	      (clobber (reg:CC FLAGS_REG))])]
9293  "operands[0] = gen_lowpart (SImode, operands[0]);
9294   operands[1] = gen_lowpart (SImode, operands[1]);
9295   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9296
9297;; Since XOR can be encoded with sign extended immediate, this is only
9298;; profitable when 7th bit is set.
9299(define_split
9300  [(set (match_operand 0 "register_operand" "")
9301	(xor (match_operand 1 "general_operand" "")
9302	     (match_operand 2 "const_int_operand" "")))
9303   (clobber (reg:CC FLAGS_REG))]
9304   "reload_completed
9305    && ANY_QI_REG_P (operands[0])
9306    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9307    && !(INTVAL (operands[2]) & ~255)
9308    && (INTVAL (operands[2]) & 128)
9309    && GET_MODE (operands[0]) != QImode"
9310  [(parallel [(set (strict_low_part (match_dup 0))
9311		   (xor:QI (match_dup 1)
9312			   (match_dup 2)))
9313	      (clobber (reg:CC FLAGS_REG))])]
9314  "operands[0] = gen_lowpart (QImode, operands[0]);
9315   operands[1] = gen_lowpart (QImode, operands[1]);
9316   operands[2] = gen_lowpart (QImode, operands[2]);")
9317
9318;; Negation instructions
9319
9320(define_expand "negti2"
9321  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9322		   (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9323	      (clobber (reg:CC FLAGS_REG))])]
9324  "TARGET_64BIT"
9325  "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9326
9327(define_insn "*negti2_1"
9328  [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9329	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9330   (clobber (reg:CC FLAGS_REG))]
9331  "TARGET_64BIT
9332   && ix86_unary_operator_ok (NEG, TImode, operands)"
9333  "#")
9334
9335(define_split
9336  [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9338   (clobber (reg:CC FLAGS_REG))]
9339  "TARGET_64BIT && reload_completed"
9340  [(parallel
9341    [(set (reg:CCZ FLAGS_REG)
9342	  (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9343     (set (match_dup 0) (neg:DI (match_dup 2)))])
9344   (parallel
9345    [(set (match_dup 1)
9346	  (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9347			    (match_dup 3))
9348		   (const_int 0)))
9349     (clobber (reg:CC FLAGS_REG))])
9350   (parallel
9351    [(set (match_dup 1)
9352	  (neg:DI (match_dup 1)))
9353     (clobber (reg:CC FLAGS_REG))])]
9354  "split_ti (operands+1, 1, operands+2, operands+3);
9355   split_ti (operands+0, 1, operands+0, operands+1);")
9356
9357(define_expand "negdi2"
9358  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9359		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9360	      (clobber (reg:CC FLAGS_REG))])]
9361  ""
9362  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9363
9364(define_insn "*negdi2_1"
9365  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9366	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9367   (clobber (reg:CC FLAGS_REG))]
9368  "!TARGET_64BIT
9369   && ix86_unary_operator_ok (NEG, DImode, operands)"
9370  "#")
9371
9372(define_split
9373  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374	(neg:DI (match_operand:DI 1 "general_operand" "")))
9375   (clobber (reg:CC FLAGS_REG))]
9376  "!TARGET_64BIT && reload_completed"
9377  [(parallel
9378    [(set (reg:CCZ FLAGS_REG)
9379	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9380     (set (match_dup 0) (neg:SI (match_dup 2)))])
9381   (parallel
9382    [(set (match_dup 1)
9383	  (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9384			    (match_dup 3))
9385		   (const_int 0)))
9386     (clobber (reg:CC FLAGS_REG))])
9387   (parallel
9388    [(set (match_dup 1)
9389	  (neg:SI (match_dup 1)))
9390     (clobber (reg:CC FLAGS_REG))])]
9391  "split_di (operands+1, 1, operands+2, operands+3);
9392   split_di (operands+0, 1, operands+0, operands+1);")
9393
9394(define_insn "*negdi2_1_rex64"
9395  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9396	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9397   (clobber (reg:CC FLAGS_REG))]
9398  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9399  "neg{q}\t%0"
9400  [(set_attr "type" "negnot")
9401   (set_attr "mode" "DI")])
9402
9403;; The problem with neg is that it does not perform (compare x 0),
9404;; it really performs (compare 0 x), which leaves us with the zero
9405;; flag being the only useful item.
9406
9407(define_insn "*negdi2_cmpz_rex64"
9408  [(set (reg:CCZ FLAGS_REG)
9409	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9410		     (const_int 0)))
9411   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412	(neg:DI (match_dup 1)))]
9413  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414  "neg{q}\t%0"
9415  [(set_attr "type" "negnot")
9416   (set_attr "mode" "DI")])
9417
9418
9419(define_expand "negsi2"
9420  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9421		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9422	      (clobber (reg:CC FLAGS_REG))])]
9423  ""
9424  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9425
9426(define_insn "*negsi2_1"
9427  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9428	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9429   (clobber (reg:CC FLAGS_REG))]
9430  "ix86_unary_operator_ok (NEG, SImode, operands)"
9431  "neg{l}\t%0"
9432  [(set_attr "type" "negnot")
9433   (set_attr "mode" "SI")])
9434
9435;; Combine is quite creative about this pattern.
9436(define_insn "*negsi2_1_zext"
9437  [(set (match_operand:DI 0 "register_operand" "=r")
9438	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9439					(const_int 32)))
9440		     (const_int 32)))
9441   (clobber (reg:CC FLAGS_REG))]
9442  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443  "neg{l}\t%k0"
9444  [(set_attr "type" "negnot")
9445   (set_attr "mode" "SI")])
9446
9447;; The problem with neg is that it does not perform (compare x 0),
9448;; it really performs (compare 0 x), which leaves us with the zero
9449;; flag being the only useful item.
9450
9451(define_insn "*negsi2_cmpz"
9452  [(set (reg:CCZ FLAGS_REG)
9453	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9454		     (const_int 0)))
9455   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9456	(neg:SI (match_dup 1)))]
9457  "ix86_unary_operator_ok (NEG, SImode, operands)"
9458  "neg{l}\t%0"
9459  [(set_attr "type" "negnot")
9460   (set_attr "mode" "SI")])
9461
9462(define_insn "*negsi2_cmpz_zext"
9463  [(set (reg:CCZ FLAGS_REG)
9464	(compare:CCZ (lshiftrt:DI
9465		       (neg:DI (ashift:DI
9466				 (match_operand:DI 1 "register_operand" "0")
9467				 (const_int 32)))
9468		       (const_int 32))
9469		     (const_int 0)))
9470   (set (match_operand:DI 0 "register_operand" "=r")
9471	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9472					(const_int 32)))
9473		     (const_int 32)))]
9474  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9475  "neg{l}\t%k0"
9476  [(set_attr "type" "negnot")
9477   (set_attr "mode" "SI")])
9478
9479(define_expand "neghi2"
9480  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9481		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9482	      (clobber (reg:CC FLAGS_REG))])]
9483  "TARGET_HIMODE_MATH"
9484  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9485
9486(define_insn "*neghi2_1"
9487  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9488	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9489   (clobber (reg:CC FLAGS_REG))]
9490  "ix86_unary_operator_ok (NEG, HImode, operands)"
9491  "neg{w}\t%0"
9492  [(set_attr "type" "negnot")
9493   (set_attr "mode" "HI")])
9494
9495(define_insn "*neghi2_cmpz"
9496  [(set (reg:CCZ FLAGS_REG)
9497	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9498		     (const_int 0)))
9499   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500	(neg:HI (match_dup 1)))]
9501  "ix86_unary_operator_ok (NEG, HImode, operands)"
9502  "neg{w}\t%0"
9503  [(set_attr "type" "negnot")
9504   (set_attr "mode" "HI")])
9505
9506(define_expand "negqi2"
9507  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9508		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9509	      (clobber (reg:CC FLAGS_REG))])]
9510  "TARGET_QIMODE_MATH"
9511  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9512
9513(define_insn "*negqi2_1"
9514  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9515	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9516   (clobber (reg:CC FLAGS_REG))]
9517  "ix86_unary_operator_ok (NEG, QImode, operands)"
9518  "neg{b}\t%0"
9519  [(set_attr "type" "negnot")
9520   (set_attr "mode" "QI")])
9521
9522(define_insn "*negqi2_cmpz"
9523  [(set (reg:CCZ FLAGS_REG)
9524	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9525		     (const_int 0)))
9526   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527	(neg:QI (match_dup 1)))]
9528  "ix86_unary_operator_ok (NEG, QImode, operands)"
9529  "neg{b}\t%0"
9530  [(set_attr "type" "negnot")
9531   (set_attr "mode" "QI")])
9532
9533;; Changing of sign for FP values is doable using integer unit too.
9534
9535(define_expand "negsf2"
9536  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9537	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9538  "TARGET_80387 || TARGET_SSE_MATH"
9539  "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9540
9541(define_expand "abssf2"
9542  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544  "TARGET_80387 || TARGET_SSE_MATH"
9545  "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9546
9547(define_insn "*absnegsf2_mixed"
9548  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9549	(match_operator:SF 3 "absneg_operator"
9550	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9551   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9552   (clobber (reg:CC FLAGS_REG))]
9553  "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9554   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9555  "#")
9556
9557(define_insn "*absnegsf2_sse"
9558  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9559	(match_operator:SF 3 "absneg_operator"
9560	  [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9561   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9562   (clobber (reg:CC FLAGS_REG))]
9563  "TARGET_SSE_MATH
9564   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9565  "#")
9566
9567(define_insn "*absnegsf2_i387"
9568  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9569	(match_operator:SF 3 "absneg_operator"
9570	  [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9571   (use (match_operand 2 "" ""))
9572   (clobber (reg:CC FLAGS_REG))]
9573  "TARGET_80387 && !TARGET_SSE_MATH
9574   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9575  "#")
9576
9577(define_expand "copysignsf3"
9578  [(match_operand:SF 0 "register_operand" "")
9579   (match_operand:SF 1 "nonmemory_operand" "")
9580   (match_operand:SF 2 "register_operand" "")]
9581  "TARGET_SSE_MATH"
9582{
9583  ix86_expand_copysign (operands);
9584  DONE;
9585})
9586
9587(define_insn_and_split "copysignsf3_const"
9588  [(set (match_operand:SF 0 "register_operand"          "=x")
9589	(unspec:SF
9590	  [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9591	   (match_operand:SF 2 "register_operand"       "0")
9592	   (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9593	  UNSPEC_COPYSIGN))]
9594  "TARGET_SSE_MATH"
9595  "#"
9596  "&& reload_completed"
9597  [(const_int 0)]
9598{
9599  ix86_split_copysign_const (operands);
9600  DONE;
9601})
9602
9603(define_insn "copysignsf3_var"
9604  [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9605	(unspec:SF
9606	  [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9607	   (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9608	   (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9609	   (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9610	  UNSPEC_COPYSIGN))
9611   (clobber (match_scratch:V4SF 1			"=x, x, x, x,x"))]
9612  "TARGET_SSE_MATH"
9613  "#")
9614
9615(define_split
9616  [(set (match_operand:SF 0 "register_operand" "")
9617	(unspec:SF
9618	  [(match_operand:SF 2 "register_operand" "")
9619	   (match_operand:SF 3 "register_operand" "")
9620	   (match_operand:V4SF 4 "" "")
9621	   (match_operand:V4SF 5 "" "")]
9622	  UNSPEC_COPYSIGN))
9623   (clobber (match_scratch:V4SF 1 ""))]
9624  "TARGET_SSE_MATH && reload_completed"
9625  [(const_int 0)]
9626{
9627  ix86_split_copysign_var (operands);
9628  DONE;
9629})
9630
9631(define_expand "negdf2"
9632  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9633	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9634  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9635  "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9636
9637(define_expand "absdf2"
9638  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641  "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9642
9643(define_insn "*absnegdf2_mixed"
9644  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9645	(match_operator:DF 3 "absneg_operator"
9646	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9647   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9648   (clobber (reg:CC FLAGS_REG))]
9649  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9650   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9651  "#")
9652
9653(define_insn "*absnegdf2_sse"
9654  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9655	(match_operator:DF 3 "absneg_operator"
9656	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9657   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9658   (clobber (reg:CC FLAGS_REG))]
9659  "TARGET_SSE2 && TARGET_SSE_MATH
9660   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9661  "#")
9662
9663(define_insn "*absnegdf2_i387"
9664  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9665	(match_operator:DF 3 "absneg_operator"
9666	  [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9667   (use (match_operand 2 "" ""))
9668   (clobber (reg:CC FLAGS_REG))]
9669  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9670   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9671  "#")
9672
9673(define_expand "copysigndf3"
9674  [(match_operand:DF 0 "register_operand" "")
9675   (match_operand:DF 1 "nonmemory_operand" "")
9676   (match_operand:DF 2 "register_operand" "")]
9677  "TARGET_SSE2 && TARGET_SSE_MATH"
9678{
9679  ix86_expand_copysign (operands);
9680  DONE;
9681})
9682
9683(define_insn_and_split "copysigndf3_const"
9684  [(set (match_operand:DF 0 "register_operand"          "=x")
9685	(unspec:DF
9686	  [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9687	   (match_operand:DF 2 "register_operand"       "0")
9688	   (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9689	  UNSPEC_COPYSIGN))]
9690  "TARGET_SSE2 && TARGET_SSE_MATH"
9691  "#"
9692  "&& reload_completed"
9693  [(const_int 0)]
9694{
9695  ix86_split_copysign_const (operands);
9696  DONE;
9697})
9698
9699(define_insn "copysigndf3_var"
9700  [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9701	(unspec:DF
9702	  [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9703	   (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9704	   (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9705	   (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9706	  UNSPEC_COPYSIGN))
9707   (clobber (match_scratch:V2DF 1			"=x, x, x, x,x"))]
9708  "TARGET_SSE2 && TARGET_SSE_MATH"
9709  "#")
9710
9711(define_split
9712  [(set (match_operand:DF 0 "register_operand" "")
9713	(unspec:DF
9714	  [(match_operand:DF 2 "register_operand" "")
9715	   (match_operand:DF 3 "register_operand" "")
9716	   (match_operand:V2DF 4 "" "")
9717	   (match_operand:V2DF 5 "" "")]
9718	  UNSPEC_COPYSIGN))
9719   (clobber (match_scratch:V2DF 1 ""))]
9720  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9721  [(const_int 0)]
9722{
9723  ix86_split_copysign_var (operands);
9724  DONE;
9725})
9726
9727(define_expand "negxf2"
9728  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9729	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9730  "TARGET_80387"
9731  "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9732
9733(define_expand "absxf2"
9734  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736  "TARGET_80387"
9737  "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9738
9739(define_insn "*absnegxf2_i387"
9740  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9741	(match_operator:XF 3 "absneg_operator"
9742	  [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9743   (use (match_operand 2 "" ""))
9744   (clobber (reg:CC FLAGS_REG))]
9745  "TARGET_80387
9746   && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9747  "#")
9748
9749;; Splitters for fp abs and neg.
9750
9751(define_split
9752  [(set (match_operand 0 "fp_register_operand" "")
9753	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9754   (use (match_operand 2 "" ""))
9755   (clobber (reg:CC FLAGS_REG))]
9756  "reload_completed"
9757  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9758
9759(define_split
9760  [(set (match_operand 0 "register_operand" "")
9761	(match_operator 3 "absneg_operator"
9762	  [(match_operand 1 "register_operand" "")]))
9763   (use (match_operand 2 "nonimmediate_operand" ""))
9764   (clobber (reg:CC FLAGS_REG))]
9765  "reload_completed && SSE_REG_P (operands[0])"
9766  [(set (match_dup 0) (match_dup 3))]
9767{
9768  enum machine_mode mode = GET_MODE (operands[0]);
9769  enum machine_mode vmode = GET_MODE (operands[2]);
9770  rtx tmp;
9771  
9772  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9773  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9774  if (operands_match_p (operands[0], operands[2]))
9775    {
9776      tmp = operands[1];
9777      operands[1] = operands[2];
9778      operands[2] = tmp;
9779    }
9780  if (GET_CODE (operands[3]) == ABS)
9781    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9782  else
9783    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9784  operands[3] = tmp;
9785})
9786
9787(define_split
9788  [(set (match_operand:SF 0 "register_operand" "")
9789	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9790   (use (match_operand:V4SF 2 "" ""))
9791   (clobber (reg:CC FLAGS_REG))]
9792  "reload_completed"
9793  [(parallel [(set (match_dup 0) (match_dup 1))
9794	      (clobber (reg:CC FLAGS_REG))])]
9795{ 
9796  rtx tmp;
9797  operands[0] = gen_lowpart (SImode, operands[0]);
9798  if (GET_CODE (operands[1]) == ABS)
9799    {
9800      tmp = gen_int_mode (0x7fffffff, SImode);
9801      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9802    }
9803  else
9804    {
9805      tmp = gen_int_mode (0x80000000, SImode);
9806      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9807    }
9808  operands[1] = tmp;
9809})
9810
9811(define_split
9812  [(set (match_operand:DF 0 "register_operand" "")
9813	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9814   (use (match_operand 2 "" ""))
9815   (clobber (reg:CC FLAGS_REG))]
9816  "reload_completed"
9817  [(parallel [(set (match_dup 0) (match_dup 1))
9818	      (clobber (reg:CC FLAGS_REG))])]
9819{
9820  rtx tmp;
9821  if (TARGET_64BIT)
9822    {
9823      tmp = gen_lowpart (DImode, operands[0]);
9824      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9825      operands[0] = tmp;
9826
9827      if (GET_CODE (operands[1]) == ABS)
9828	tmp = const0_rtx;
9829      else
9830	tmp = gen_rtx_NOT (DImode, tmp);
9831    }
9832  else
9833    {
9834      operands[0] = gen_highpart (SImode, operands[0]);
9835      if (GET_CODE (operands[1]) == ABS)
9836	{
9837	  tmp = gen_int_mode (0x7fffffff, SImode);
9838	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
9839	}
9840      else
9841	{
9842	  tmp = gen_int_mode (0x80000000, SImode);
9843	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9844	}
9845    }
9846  operands[1] = tmp;
9847})
9848
9849(define_split
9850  [(set (match_operand:XF 0 "register_operand" "")
9851	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9852   (use (match_operand 2 "" ""))
9853   (clobber (reg:CC FLAGS_REG))]
9854  "reload_completed"
9855  [(parallel [(set (match_dup 0) (match_dup 1))
9856	      (clobber (reg:CC FLAGS_REG))])]
9857{
9858  rtx tmp;
9859  operands[0] = gen_rtx_REG (SImode,
9860			     true_regnum (operands[0])
9861			     + (TARGET_64BIT ? 1 : 2));
9862  if (GET_CODE (operands[1]) == ABS)
9863    {
9864      tmp = GEN_INT (0x7fff);
9865      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9866    }
9867  else
9868    {
9869      tmp = GEN_INT (0x8000);
9870      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9871    }
9872  operands[1] = tmp;
9873})
9874
9875(define_split
9876  [(set (match_operand 0 "memory_operand" "")
9877	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9878   (use (match_operand 2 "" ""))
9879   (clobber (reg:CC FLAGS_REG))]
9880  "reload_completed"
9881  [(parallel [(set (match_dup 0) (match_dup 1))
9882	      (clobber (reg:CC FLAGS_REG))])]
9883{
9884  enum machine_mode mode = GET_MODE (operands[0]);
9885  int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9886  rtx tmp;
9887
9888  operands[0] = adjust_address (operands[0], QImode, size - 1);
9889  if (GET_CODE (operands[1]) == ABS)
9890    {
9891      tmp = gen_int_mode (0x7f, QImode);
9892      tmp = gen_rtx_AND (QImode, operands[0], tmp);
9893    }
9894  else
9895    {
9896      tmp = gen_int_mode (0x80, QImode);
9897      tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9898    }
9899  operands[1] = tmp;
9900})
9901
9902;; Conditionalize these after reload. If they match before reload, we 
9903;; lose the clobber and ability to use integer instructions.
9904
9905(define_insn "*negsf2_1"
9906  [(set (match_operand:SF 0 "register_operand" "=f")
9907	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
9908  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9909  "fchs"
9910  [(set_attr "type" "fsgn")
9911   (set_attr "mode" "SF")])
9912
9913(define_insn "*negdf2_1"
9914  [(set (match_operand:DF 0 "register_operand" "=f")
9915	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
9916  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9917  "fchs"
9918  [(set_attr "type" "fsgn")
9919   (set_attr "mode" "DF")])
9920
9921(define_insn "*negxf2_1"
9922  [(set (match_operand:XF 0 "register_operand" "=f")
9923	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
9924  "TARGET_80387"
9925  "fchs"
9926  [(set_attr "type" "fsgn")
9927   (set_attr "mode" "XF")])
9928
9929(define_insn "*abssf2_1"
9930  [(set (match_operand:SF 0 "register_operand" "=f")
9931	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
9932  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9933  "fabs"
9934  [(set_attr "type" "fsgn")
9935   (set_attr "mode" "SF")])
9936
9937(define_insn "*absdf2_1"
9938  [(set (match_operand:DF 0 "register_operand" "=f")
9939	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
9940  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9941  "fabs"
9942  [(set_attr "type" "fsgn")
9943   (set_attr "mode" "DF")])
9944
9945(define_insn "*absxf2_1"
9946  [(set (match_operand:XF 0 "register_operand" "=f")
9947	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
9948  "TARGET_80387"
9949  "fabs"
9950  [(set_attr "type" "fsgn")
9951   (set_attr "mode" "DF")])
9952
9953(define_insn "*negextendsfdf2"
9954  [(set (match_operand:DF 0 "register_operand" "=f")
9955	(neg:DF (float_extend:DF
9956		  (match_operand:SF 1 "register_operand" "0"))))]
9957  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9958  "fchs"
9959  [(set_attr "type" "fsgn")
9960   (set_attr "mode" "DF")])
9961
9962(define_insn "*negextenddfxf2"
9963  [(set (match_operand:XF 0 "register_operand" "=f")
9964	(neg:XF (float_extend:XF
9965		  (match_operand:DF 1 "register_operand" "0"))))]
9966  "TARGET_80387"
9967  "fchs"
9968  [(set_attr "type" "fsgn")
9969   (set_attr "mode" "XF")])
9970
9971(define_insn "*negextendsfxf2"
9972  [(set (match_operand:XF 0 "register_operand" "=f")
9973	(neg:XF (float_extend:XF
9974		  (match_operand:SF 1 "register_operand" "0"))))]
9975  "TARGET_80387"
9976  "fchs"
9977  [(set_attr "type" "fsgn")
9978   (set_attr "mode" "XF")])
9979
9980(define_insn "*absextendsfdf2"
9981  [(set (match_operand:DF 0 "register_operand" "=f")
9982	(abs:DF (float_extend:DF
9983		  (match_operand:SF 1 "register_operand" "0"))))]
9984  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9985  "fabs"
9986  [(set_attr "type" "fsgn")
9987   (set_attr "mode" "DF")])
9988
9989(define_insn "*absextenddfxf2"
9990  [(set (match_operand:XF 0 "register_operand" "=f")
9991	(abs:XF (float_extend:XF
9992	  (match_operand:DF 1 "register_operand" "0"))))]
9993  "TARGET_80387"
9994  "fabs"
9995  [(set_attr "type" "fsgn")
9996   (set_attr "mode" "XF")])
9997
9998(define_insn "*absextendsfxf2"
9999  [(set (match_operand:XF 0 "register_operand" "=f")
10000	(abs:XF (float_extend:XF
10001	  (match_operand:SF 1 "register_operand" "0"))))]
10002  "TARGET_80387"
10003  "fabs"
10004  [(set_attr "type" "fsgn")
10005   (set_attr "mode" "XF")])
10006
10007;; One complement instructions
10008
10009(define_expand "one_cmpldi2"
10010  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10011	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10012  "TARGET_64BIT"
10013  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10014
10015(define_insn "*one_cmpldi2_1_rex64"
10016  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10017	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10018  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10019  "not{q}\t%0"
10020  [(set_attr "type" "negnot")
10021   (set_attr "mode" "DI")])
10022
10023(define_insn "*one_cmpldi2_2_rex64"
10024  [(set (reg FLAGS_REG)
10025	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10026		 (const_int 0)))
10027   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10028	(not:DI (match_dup 1)))]
10029  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10030   && ix86_unary_operator_ok (NOT, DImode, operands)"
10031  "#"
10032  [(set_attr "type" "alu1")
10033   (set_attr "mode" "DI")])
10034
10035(define_split
10036  [(set (match_operand 0 "flags_reg_operand" "")
10037	(match_operator 2 "compare_operator"
10038	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10039	   (const_int 0)]))
10040   (set (match_operand:DI 1 "nonimmediate_operand" "")
10041	(not:DI (match_dup 3)))]
10042  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10043  [(parallel [(set (match_dup 0)
10044		   (match_op_dup 2
10045		     [(xor:DI (match_dup 3) (const_int -1))
10046		      (const_int 0)]))
10047	      (set (match_dup 1)
10048		   (xor:DI (match_dup 3) (const_int -1)))])]
10049  "")
10050
10051(define_expand "one_cmplsi2"
10052  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10053	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10054  ""
10055  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10056
10057(define_insn "*one_cmplsi2_1"
10058  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10059	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10060  "ix86_unary_operator_ok (NOT, SImode, operands)"
10061  "not{l}\t%0"
10062  [(set_attr "type" "negnot")
10063   (set_attr "mode" "SI")])
10064
10065;; ??? Currently never generated - xor is used instead.
10066(define_insn "*one_cmplsi2_1_zext"
10067  [(set (match_operand:DI 0 "register_operand" "=r")
10068	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10069  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10070  "not{l}\t%k0"
10071  [(set_attr "type" "negnot")
10072   (set_attr "mode" "SI")])
10073
10074(define_insn "*one_cmplsi2_2"
10075  [(set (reg FLAGS_REG)
10076	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10077		 (const_int 0)))
10078   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10079	(not:SI (match_dup 1)))]
10080  "ix86_match_ccmode (insn, CCNOmode)
10081   && ix86_unary_operator_ok (NOT, SImode, operands)"
10082  "#"
10083  [(set_attr "type" "alu1")
10084   (set_attr "mode" "SI")])
10085
10086(define_split
10087  [(set (match_operand 0 "flags_reg_operand" "")
10088	(match_operator 2 "compare_operator"
10089	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10090	   (const_int 0)]))
10091   (set (match_operand:SI 1 "nonimmediate_operand" "")
10092	(not:SI (match_dup 3)))]
10093  "ix86_match_ccmode (insn, CCNOmode)"
10094  [(parallel [(set (match_dup 0)
10095		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10096				    (const_int 0)]))
10097	      (set (match_dup 1)
10098		   (xor:SI (match_dup 3) (const_int -1)))])]
10099  "")
10100
10101;; ??? Currently never generated - xor is used instead.
10102(define_insn "*one_cmplsi2_2_zext"
10103  [(set (reg FLAGS_REG)
10104	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10105		 (const_int 0)))
10106   (set (match_operand:DI 0 "register_operand" "=r")
10107	(zero_extend:DI (not:SI (match_dup 1))))]
10108  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10109   && ix86_unary_operator_ok (NOT, SImode, operands)"
10110  "#"
10111  [(set_attr "type" "alu1")
10112   (set_attr "mode" "SI")])
10113
10114(define_split
10115  [(set (match_operand 0 "flags_reg_operand" "")
10116	(match_operator 2 "compare_operator"
10117	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10118	   (const_int 0)]))
10119   (set (match_operand:DI 1 "register_operand" "")
10120	(zero_extend:DI (not:SI (match_dup 3))))]
10121  "ix86_match_ccmode (insn, CCNOmode)"
10122  [(parallel [(set (match_dup 0)
10123		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10124				    (const_int 0)]))
10125	      (set (match_dup 1)
10126		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10127  "")
10128
10129(define_expand "one_cmplhi2"
10130  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10131	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10132  "TARGET_HIMODE_MATH"
10133  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10134
10135(define_insn "*one_cmplhi2_1"
10136  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10137	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10138  "ix86_unary_operator_ok (NOT, HImode, operands)"
10139  "not{w}\t%0"
10140  [(set_attr "type" "negnot")
10141   (set_attr "mode" "HI")])
10142
10143(define_insn "*one_cmplhi2_2"
10144  [(set (reg FLAGS_REG)
10145	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10146		 (const_int 0)))
10147   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10148	(not:HI (match_dup 1)))]
10149  "ix86_match_ccmode (insn, CCNOmode)
10150   && ix86_unary_operator_ok (NEG, HImode, operands)"
10151  "#"
10152  [(set_attr "type" "alu1")
10153   (set_attr "mode" "HI")])
10154
10155(define_split
10156  [(set (match_operand 0 "flags_reg_operand" "")
10157	(match_operator 2 "compare_operator"
10158	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10159	   (const_int 0)]))
10160   (set (match_operand:HI 1 "nonimmediate_operand" "")
10161	(not:HI (match_dup 3)))]
10162  "ix86_match_ccmode (insn, CCNOmode)"
10163  [(parallel [(set (match_dup 0)
10164		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10165		      		    (const_int 0)]))
10166	      (set (match_dup 1)
10167		   (xor:HI (match_dup 3) (const_int -1)))])]
10168  "")
10169
10170;; %%% Potential partial reg stall on alternative 1.  What to do?
10171(define_expand "one_cmplqi2"
10172  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10173	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10174  "TARGET_QIMODE_MATH"
10175  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10176
10177(define_insn "*one_cmplqi2_1"
10178  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10179	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10180  "ix86_unary_operator_ok (NOT, QImode, operands)"
10181  "@
10182   not{b}\t%0
10183   not{l}\t%k0"
10184  [(set_attr "type" "negnot")
10185   (set_attr "mode" "QI,SI")])
10186
10187(define_insn "*one_cmplqi2_2"
10188  [(set (reg FLAGS_REG)
10189	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10190		 (const_int 0)))
10191   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10192	(not:QI (match_dup 1)))]
10193  "ix86_match_ccmode (insn, CCNOmode)
10194   && ix86_unary_operator_ok (NOT, QImode, operands)"
10195  "#"
10196  [(set_attr "type" "alu1")
10197   (set_attr "mode" "QI")])
10198
10199(define_split
10200  [(set (match_operand 0 "flags_reg_operand" "")
10201	(match_operator 2 "compare_operator"
10202	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10203	   (const_int 0)]))
10204   (set (match_operand:QI 1 "nonimmediate_operand" "")
10205	(not:QI (match_dup 3)))]
10206  "ix86_match_ccmode (insn, CCNOmode)"
10207  [(parallel [(set (match_dup 0)
10208		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10209		      		    (const_int 0)]))
10210	      (set (match_dup 1)
10211		   (xor:QI (match_dup 3) (const_int -1)))])]
10212  "")
10213
10214;; Arithmetic shift instructions
10215
10216;; DImode shifts are implemented using the i386 "shift double" opcode,
10217;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10218;; is variable, then the count is in %cl and the "imm" operand is dropped
10219;; from the assembler input.
10220;;
10221;; This instruction shifts the target reg/mem as usual, but instead of
10222;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10223;; is a left shift double, bits are taken from the high order bits of
10224;; reg, else if the insn is a shift right double, bits are taken from the
10225;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10226;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10227;;
10228;; Since sh[lr]d does not change the `reg' operand, that is done
10229;; separately, making all shifts emit pairs of shift double and normal
10230;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10231;; support a 63 bit shift, each shift where the count is in a reg expands
10232;; to a pair of shifts, a branch, a shift by 32 and a label.
10233;;
10234;; If the shift count is a constant, we need never emit more than one
10235;; shift pair, instead using moves and sign extension for counts greater
10236;; than 31.
10237
10238(define_expand "ashlti3"
10239  [(parallel [(set (match_operand:TI 0 "register_operand" "")
10240		   (ashift:TI (match_operand:TI 1 "register_operand" "")
10241			      (match_operand:QI 2 "nonmemory_operand" "")))
10242	      (clobber (reg:CC FLAGS_REG))])]
10243  "TARGET_64BIT"
10244{
10245  if (! immediate_operand (operands[2], QImode))
10246    {
10247      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10248      DONE;
10249    }
10250  ix86_expand_binary_operator (ASHIFT, TImode, operands);
10251  DONE;
10252})
10253
10254(define_insn "ashlti3_1"
10255  [(set (match_operand:TI 0 "register_operand" "=r")
10256	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10257		   (match_operand:QI 2 "register_operand" "c")))
10258   (clobber (match_scratch:DI 3 "=&r"))
10259   (clobber (reg:CC FLAGS_REG))]
10260  "TARGET_64BIT"
10261  "#"
10262  [(set_attr "type" "multi")])
10263
10264(define_insn "*ashlti3_2"
10265  [(set (match_operand:TI 0 "register_operand" "=r")
10266	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10267		   (match_operand:QI 2 "immediate_operand" "O")))
10268   (clobber (reg:CC FLAGS_REG))]
10269  "TARGET_64BIT"
10270  "#"
10271  [(set_attr "type" "multi")])
10272
10273(define_split
10274  [(set (match_operand:TI 0 "register_operand" "")
10275	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10276		   (match_operand:QI 2 "register_operand" "")))
10277   (clobber (match_scratch:DI 3 ""))
10278   (clobber (reg:CC FLAGS_REG))]
10279  "TARGET_64BIT && reload_completed"
10280  [(const_int 0)]
10281  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10282
10283(define_split
10284  [(set (match_operand:TI 0 "register_operand" "")
10285	(ashift:TI (match_operand:TI 1 "register_operand" "")
10286		   (match_operand:QI 2 "immediate_operand" "")))
10287   (clobber (reg:CC FLAGS_REG))]
10288  "TARGET_64BIT && reload_completed"
10289  [(const_int 0)]
10290  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10291
10292(define_insn "x86_64_shld"
10293  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10294        (ior:DI (ashift:DI (match_dup 0)
10295		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
10296		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10297		  (minus:QI (const_int 64) (match_dup 2)))))
10298   (clobber (reg:CC FLAGS_REG))]
10299  "TARGET_64BIT"
10300  "@
10301   shld{q}\t{%2, %1, %0|%0, %1, %2}
10302   shld{q}\t{%s2%1, %0|%0, %1, %2}"
10303  [(set_attr "type" "ishift")
10304   (set_attr "prefix_0f" "1")
10305   (set_attr "mode" "DI")
10306   (set_attr "athlon_decode" "vector")])
10307
10308(define_expand "x86_64_shift_adj"
10309  [(set (reg:CCZ FLAGS_REG)
10310	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10311			     (const_int 64))
10312		     (const_int 0)))
10313   (set (match_operand:DI 0 "register_operand" "")
10314        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315			 (match_operand:DI 1 "register_operand" "")
10316			 (match_dup 0)))
10317   (set (match_dup 1)
10318	(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10319			 (match_operand:DI 3 "register_operand" "r")
10320			 (match_dup 1)))]
10321  "TARGET_64BIT"
10322  "")
10323
10324(define_expand "ashldi3"
10325  [(set (match_operand:DI 0 "shiftdi_operand" "")
10326	(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10327		   (match_operand:QI 2 "nonmemory_operand" "")))]
10328  ""
10329  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10330
10331(define_insn "*ashldi3_1_rex64"
10332  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10333	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10334		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10335   (clobber (reg:CC FLAGS_REG))]
10336  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10337{
10338  switch (get_attr_type (insn))
10339    {
10340    case TYPE_ALU:
10341      gcc_assert (operands[2] == const1_rtx);
10342      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10343      return "add{q}\t{%0, %0|%0, %0}";
10344
10345    case TYPE_LEA:
10346      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10347      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10348      operands[1] = gen_rtx_MULT (DImode, operands[1],
10349				  GEN_INT (1 << INTVAL (operands[2])));
10350      return "lea{q}\t{%a1, %0|%0, %a1}";
10351
10352    default:
10353      if (REG_P (operands[2]))
10354	return "sal{q}\t{%b2, %0|%0, %b2}";
10355      else if (operands[2] == const1_rtx
10356	       && (TARGET_SHIFT1 || optimize_size))
10357	return "sal{q}\t%0";
10358      else
10359	return "sal{q}\t{%2, %0|%0, %2}";
10360    }
10361}
10362  [(set (attr "type")
10363     (cond [(eq_attr "alternative" "1")
10364	      (const_string "lea")
10365            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10366		          (const_int 0))
10367		      (match_operand 0 "register_operand" ""))
10368		 (match_operand 2 "const1_operand" ""))
10369	      (const_string "alu")
10370	   ]
10371	   (const_string "ishift")))
10372   (set_attr "mode" "DI")])
10373
10374;; Convert lea to the lea pattern to avoid flags dependency.
10375(define_split
10376  [(set (match_operand:DI 0 "register_operand" "")
10377	(ashift:DI (match_operand:DI 1 "index_register_operand" "")
10378		   (match_operand:QI 2 "immediate_operand" "")))
10379   (clobber (reg:CC FLAGS_REG))]
10380  "TARGET_64BIT && reload_completed
10381   && true_regnum (operands[0]) != true_regnum (operands[1])"
10382  [(set (match_dup 0)
10383	(mult:DI (match_dup 1)
10384		 (match_dup 2)))]
10385  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10386
10387;; This pattern can't accept a variable shift count, since shifts by
10388;; zero don't affect the flags.  We assume that shifts by constant
10389;; zero are optimized away.
10390(define_insn "*ashldi3_cmp_rex64"
10391  [(set (reg FLAGS_REG)
10392	(compare
10393	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10394		     (match_operand:QI 2 "immediate_operand" "e"))
10395	  (const_int 0)))
10396   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397	(ashift:DI (match_dup 1) (match_dup 2)))]
10398  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10399   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10400   && (optimize_size
10401       || !TARGET_PARTIAL_FLAG_REG_STALL
10402       || (operands[2] == const1_rtx
10403	   && (TARGET_SHIFT1
10404	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10405{
10406  switch (get_attr_type (insn))
10407    {
10408    case TYPE_ALU:
10409      gcc_assert (operands[2] == const1_rtx);
10410      return "add{q}\t{%0, %0|%0, %0}";
10411
10412    default:
10413      if (REG_P (operands[2]))
10414	return "sal{q}\t{%b2, %0|%0, %b2}";
10415      else if (operands[2] == const1_rtx
10416	       && (TARGET_SHIFT1 || optimize_size))
10417	return "sal{q}\t%0";
10418      else
10419	return "sal{q}\t{%2, %0|%0, %2}";
10420    }
10421}
10422  [(set (attr "type")
10423     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10424		          (const_int 0))
10425		      (match_operand 0 "register_operand" ""))
10426		 (match_operand 2 "const1_operand" ""))
10427	      (const_string "alu")
10428	   ]
10429	   (const_string "ishift")))
10430   (set_attr "mode" "DI")])
10431
10432(define_insn "*ashldi3_cconly_rex64"
10433  [(set (reg FLAGS_REG)
10434	(compare
10435	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10436		     (match_operand:QI 2 "immediate_operand" "e"))
10437	  (const_int 0)))
10438   (clobber (match_scratch:DI 0 "=r"))]
10439  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10440   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10441   && (optimize_size
10442       || !TARGET_PARTIAL_FLAG_REG_STALL
10443       || (operands[2] == const1_rtx
10444	   && (TARGET_SHIFT1
10445	       || TARGET_DOUBLE_WITH_ADD)))"
10446{
10447  switch (get_attr_type (insn))
10448    {
10449    case TYPE_ALU:
10450      gcc_assert (operands[2] == const1_rtx);
10451      return "add{q}\t{%0, %0|%0, %0}";
10452
10453    default:
10454      if (REG_P (operands[2]))
10455	return "sal{q}\t{%b2, %0|%0, %b2}";
10456      else if (operands[2] == const1_rtx
10457	       && (TARGET_SHIFT1 || optimize_size))
10458	return "sal{q}\t%0";
10459      else
10460	return "sal{q}\t{%2, %0|%0, %2}";
10461    }
10462}
10463  [(set (attr "type")
10464     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10465		          (const_int 0))
10466		      (match_operand 0 "register_operand" ""))
10467		 (match_operand 2 "const1_operand" ""))
10468	      (const_string "alu")
10469	   ]
10470	   (const_string "ishift")))
10471   (set_attr "mode" "DI")])
10472
10473(define_insn "*ashldi3_1"
10474  [(set (match_operand:DI 0 "register_operand" "=&r,r")
10475	(ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10476		   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10477   (clobber (reg:CC FLAGS_REG))]
10478  "!TARGET_64BIT"
10479  "#"
10480  [(set_attr "type" "multi")])
10481
10482;; By default we don't ask for a scratch register, because when DImode
10483;; values are manipulated, registers are already at a premium.  But if
10484;; we have one handy, we won't turn it away.
10485(define_peephole2
10486  [(match_scratch:SI 3 "r")
10487   (parallel [(set (match_operand:DI 0 "register_operand" "")
10488		   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10489			      (match_operand:QI 2 "nonmemory_operand" "")))
10490	      (clobber (reg:CC FLAGS_REG))])
10491   (match_dup 3)]
10492  "!TARGET_64BIT && TARGET_CMOVE"
10493  [(const_int 0)]
10494  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10495
10496(define_split
10497  [(set (match_operand:DI 0 "register_operand" "")
10498	(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10499		   (match_operand:QI 2 "nonmemory_operand" "")))
10500   (clobber (reg:CC FLAGS_REG))]
10501  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10502		     ? flow2_completed : reload_completed)"
10503  [(const_int 0)]
10504  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10505
10506(define_insn "x86_shld_1"
10507  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10508        (ior:SI (ashift:SI (match_dup 0)
10509		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10510		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10511		  (minus:QI (const_int 32) (match_dup 2)))))
10512   (clobber (reg:CC FLAGS_REG))]
10513  ""
10514  "@
10515   shld{l}\t{%2, %1, %0|%0, %1, %2}
10516   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10517  [(set_attr "type" "ishift")
10518   (set_attr "prefix_0f" "1")
10519   (set_attr "mode" "SI")
10520   (set_attr "pent_pair" "np")
10521   (set_attr "athlon_decode" "vector")])
10522
10523(define_expand "x86_shift_adj_1"
10524  [(set (reg:CCZ FLAGS_REG)
10525	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10526			     (const_int 32))
10527		     (const_int 0)))
10528   (set (match_operand:SI 0 "register_operand" "")
10529        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10530			 (match_operand:SI 1 "register_operand" "")
10531			 (match_dup 0)))
10532   (set (match_dup 1)
10533	(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10534			 (match_operand:SI 3 "register_operand" "r")
10535			 (match_dup 1)))]
10536  "TARGET_CMOVE"
10537  "")
10538
10539(define_expand "x86_shift_adj_2"
10540  [(use (match_operand:SI 0 "register_operand" ""))
10541   (use (match_operand:SI 1 "register_operand" ""))
10542   (use (match_operand:QI 2 "register_operand" ""))]
10543  ""
10544{
10545  rtx label = gen_label_rtx ();
10546  rtx tmp;
10547
10548  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10549
10550  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10551  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10552  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10553			      gen_rtx_LABEL_REF (VOIDmode, label),
10554			      pc_rtx);
10555  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10556  JUMP_LABEL (tmp) = label;
10557
10558  emit_move_insn (operands[0], operands[1]);
10559  ix86_expand_clear (operands[1]);
10560
10561  emit_label (label);
10562  LABEL_NUSES (label) = 1;
10563
10564  DONE;
10565})
10566
10567(define_expand "ashlsi3"
10568  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10569	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10570		   (match_operand:QI 2 "nonmemory_operand" "")))
10571   (clobber (reg:CC FLAGS_REG))]
10572  ""
10573  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10574
10575(define_insn "*ashlsi3_1"
10576  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10577	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10578		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10579   (clobber (reg:CC FLAGS_REG))]
10580  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10581{
10582  switch (get_attr_type (insn))
10583    {
10584    case TYPE_ALU:
10585      gcc_assert (operands[2] == const1_rtx);
10586      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10587      return "add{l}\t{%0, %0|%0, %0}";
10588
10589    case TYPE_LEA:
10590      return "#";
10591
10592    default:
10593      if (REG_P (operands[2]))
10594	return "sal{l}\t{%b2, %0|%0, %b2}";
10595      else if (operands[2] == const1_rtx
10596	       && (TARGET_SHIFT1 || optimize_size))
10597	return "sal{l}\t%0";
10598      else
10599	return "sal{l}\t{%2, %0|%0, %2}";
10600    }
10601}
10602  [(set (attr "type")
10603     (cond [(eq_attr "alternative" "1")
10604	      (const_string "lea")
10605            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10606		          (const_int 0))
10607		      (match_operand 0 "register_operand" ""))
10608		 (match_operand 2 "const1_operand" ""))
10609	      (const_string "alu")
10610	   ]
10611	   (const_string "ishift")))
10612   (set_attr "mode" "SI")])
10613
10614;; Convert lea to the lea pattern to avoid flags dependency.
10615(define_split
10616  [(set (match_operand 0 "register_operand" "")
10617	(ashift (match_operand 1 "index_register_operand" "")
10618                (match_operand:QI 2 "const_int_operand" "")))
10619   (clobber (reg:CC FLAGS_REG))]
10620  "reload_completed
10621   && true_regnum (operands[0]) != true_regnum (operands[1])
10622   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10623  [(const_int 0)]
10624{
10625  rtx pat;
10626  enum machine_mode mode = GET_MODE (operands[0]);
10627
10628  if (GET_MODE_SIZE (mode) < 4)
10629    operands[0] = gen_lowpart (SImode, operands[0]);
10630  if (mode != Pmode)
10631    operands[1] = gen_lowpart (Pmode, operands[1]);
10632  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10633
10634  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10635  if (Pmode != SImode)
10636    pat = gen_rtx_SUBREG (SImode, pat, 0);
10637  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10638  DONE;
10639})
10640
10641;; Rare case of shifting RSP is handled by generating move and shift
10642(define_split
10643  [(set (match_operand 0 "register_operand" "")
10644	(ashift (match_operand 1 "register_operand" "")
10645                (match_operand:QI 2 "const_int_operand" "")))
10646   (clobber (reg:CC FLAGS_REG))]
10647  "reload_completed
10648   && true_regnum (operands[0]) != true_regnum (operands[1])"
10649  [(const_int 0)]
10650{
10651  rtx pat, clob;
10652  emit_move_insn (operands[0], operands[1]);
10653  pat = gen_rtx_SET (VOIDmode, operands[0],
10654		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10655				     operands[0], operands[2]));
10656  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10657  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10658  DONE;
10659})
10660
10661(define_insn "*ashlsi3_1_zext"
10662  [(set (match_operand:DI 0 "register_operand" "=r,r")
10663	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10664			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10665   (clobber (reg:CC FLAGS_REG))]
10666  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10667{
10668  switch (get_attr_type (insn))
10669    {
10670    case TYPE_ALU:
10671      gcc_assert (operands[2] == const1_rtx);
10672      return "add{l}\t{%k0, %k0|%k0, %k0}";
10673
10674    case TYPE_LEA:
10675      return "#";
10676
10677    default:
10678      if (REG_P (operands[2]))
10679	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10680      else if (operands[2] == const1_rtx
10681	       && (TARGET_SHIFT1 || optimize_size))
10682	return "sal{l}\t%k0";
10683      else
10684	return "sal{l}\t{%2, %k0|%k0, %2}";
10685    }
10686}
10687  [(set (attr "type")
10688     (cond [(eq_attr "alternative" "1")
10689	      (const_string "lea")
10690            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10691		     (const_int 0))
10692		 (match_operand 2 "const1_operand" ""))
10693	      (const_string "alu")
10694	   ]
10695	   (const_string "ishift")))
10696   (set_attr "mode" "SI")])
10697
10698;; Convert lea to the lea pattern to avoid flags dependency.
10699(define_split
10700  [(set (match_operand:DI 0 "register_operand" "")
10701	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10702				(match_operand:QI 2 "const_int_operand" ""))))
10703   (clobber (reg:CC FLAGS_REG))]
10704  "TARGET_64BIT && reload_completed
10705   && true_regnum (operands[0]) != true_regnum (operands[1])"
10706  [(set (match_dup 0) (zero_extend:DI
10707			(subreg:SI (mult:SI (match_dup 1)
10708					    (match_dup 2)) 0)))]
10709{
10710  operands[1] = gen_lowpart (Pmode, operands[1]);
10711  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10712})
10713
10714;; This pattern can't accept a variable shift count, since shifts by
10715;; zero don't affect the flags.  We assume that shifts by constant
10716;; zero are optimized away.
10717(define_insn "*ashlsi3_cmp"
10718  [(set (reg FLAGS_REG)
10719	(compare
10720	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10721		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10722	  (const_int 0)))
10723   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10724	(ashift:SI (match_dup 1) (match_dup 2)))]
10725  "ix86_match_ccmode (insn, CCGOCmode)
10726   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10727   && (optimize_size
10728       || !TARGET_PARTIAL_FLAG_REG_STALL
10729       || (operands[2] == const1_rtx
10730	   && (TARGET_SHIFT1
10731	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10732{
10733  switch (get_attr_type (insn))
10734    {
10735    case TYPE_ALU:
10736      gcc_assert (operands[2] == const1_rtx);
10737      return "add{l}\t{%0, %0|%0, %0}";
10738
10739    default:
10740      if (REG_P (operands[2]))
10741	return "sal{l}\t{%b2, %0|%0, %b2}";
10742      else if (operands[2] == const1_rtx
10743	       && (TARGET_SHIFT1 || optimize_size))
10744	return "sal{l}\t%0";
10745      else
10746	return "sal{l}\t{%2, %0|%0, %2}";
10747    }
10748}
10749  [(set (attr "type")
10750     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10751		          (const_int 0))
10752		      (match_operand 0 "register_operand" ""))
10753		 (match_operand 2 "const1_operand" ""))
10754	      (const_string "alu")
10755	   ]
10756	   (const_string "ishift")))
10757   (set_attr "mode" "SI")])
10758
10759(define_insn "*ashlsi3_cconly"
10760  [(set (reg FLAGS_REG)
10761	(compare
10762	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10763		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10764	  (const_int 0)))
10765   (clobber (match_scratch:SI 0 "=r"))]
10766  "ix86_match_ccmode (insn, CCGOCmode)
10767   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10768   && (optimize_size
10769       || !TARGET_PARTIAL_FLAG_REG_STALL
10770       || (operands[2] == const1_rtx
10771	   && (TARGET_SHIFT1
10772	       || TARGET_DOUBLE_WITH_ADD)))"
10773{
10774  switch (get_attr_type (insn))
10775    {
10776    case TYPE_ALU:
10777      gcc_assert (operands[2] == const1_rtx);
10778      return "add{l}\t{%0, %0|%0, %0}";
10779
10780    default:
10781      if (REG_P (operands[2]))
10782	return "sal{l}\t{%b2, %0|%0, %b2}";
10783      else if (operands[2] == const1_rtx
10784	       && (TARGET_SHIFT1 || optimize_size))
10785	return "sal{l}\t%0";
10786      else
10787	return "sal{l}\t{%2, %0|%0, %2}";
10788    }
10789}
10790  [(set (attr "type")
10791     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10792		          (const_int 0))
10793		      (match_operand 0 "register_operand" ""))
10794		 (match_operand 2 "const1_operand" ""))
10795	      (const_string "alu")
10796	   ]
10797	   (const_string "ishift")))
10798   (set_attr "mode" "SI")])
10799
10800(define_insn "*ashlsi3_cmp_zext"
10801  [(set (reg FLAGS_REG)
10802	(compare
10803	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10804		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10805	  (const_int 0)))
10806   (set (match_operand:DI 0 "register_operand" "=r")
10807	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10808  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10809   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10810   && (optimize_size
10811       || !TARGET_PARTIAL_FLAG_REG_STALL
10812       || (operands[2] == const1_rtx
10813	   && (TARGET_SHIFT1
10814	       || TARGET_DOUBLE_WITH_ADD)))"
10815{
10816  switch (get_attr_type (insn))
10817    {
10818    case TYPE_ALU:
10819      gcc_assert (operands[2] == const1_rtx);
10820      return "add{l}\t{%k0, %k0|%k0, %k0}";
10821
10822    default:
10823      if (REG_P (operands[2]))
10824	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10825      else if (operands[2] == const1_rtx
10826	       && (TARGET_SHIFT1 || optimize_size))
10827	return "sal{l}\t%k0";
10828      else
10829	return "sal{l}\t{%2, %k0|%k0, %2}";
10830    }
10831}
10832  [(set (attr "type")
10833     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10834		     (const_int 0))
10835		 (match_operand 2 "const1_operand" ""))
10836	      (const_string "alu")
10837	   ]
10838	   (const_string "ishift")))
10839   (set_attr "mode" "SI")])
10840
10841(define_expand "ashlhi3"
10842  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10843	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10844		   (match_operand:QI 2 "nonmemory_operand" "")))
10845   (clobber (reg:CC FLAGS_REG))]
10846  "TARGET_HIMODE_MATH"
10847  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10848
10849(define_insn "*ashlhi3_1_lea"
10850  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10851	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10852		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10853   (clobber (reg:CC FLAGS_REG))]
10854  "!TARGET_PARTIAL_REG_STALL
10855   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10856{
10857  switch (get_attr_type (insn))
10858    {
10859    case TYPE_LEA:
10860      return "#";
10861    case TYPE_ALU:
10862      gcc_assert (operands[2] == const1_rtx);
10863      return "add{w}\t{%0, %0|%0, %0}";
10864
10865    default:
10866      if (REG_P (operands[2]))
10867	return "sal{w}\t{%b2, %0|%0, %b2}";
10868      else if (operands[2] == const1_rtx
10869	       && (TARGET_SHIFT1 || optimize_size))
10870	return "sal{w}\t%0";
10871      else
10872	return "sal{w}\t{%2, %0|%0, %2}";
10873    }
10874}
10875  [(set (attr "type")
10876     (cond [(eq_attr "alternative" "1")
10877	      (const_string "lea")
10878            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10879		          (const_int 0))
10880		      (match_operand 0 "register_operand" ""))
10881		 (match_operand 2 "const1_operand" ""))
10882	      (const_string "alu")
10883	   ]
10884	   (const_string "ishift")))
10885   (set_attr "mode" "HI,SI")])
10886
10887(define_insn "*ashlhi3_1"
10888  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10889	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10890		   (match_operand:QI 2 "nonmemory_operand" "cI")))
10891   (clobber (reg:CC FLAGS_REG))]
10892  "TARGET_PARTIAL_REG_STALL
10893   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10894{
10895  switch (get_attr_type (insn))
10896    {
10897    case TYPE_ALU:
10898      gcc_assert (operands[2] == const1_rtx);
10899      return "add{w}\t{%0, %0|%0, %0}";
10900
10901    default:
10902      if (REG_P (operands[2]))
10903	return "sal{w}\t{%b2, %0|%0, %b2}";
10904      else if (operands[2] == const1_rtx
10905	       && (TARGET_SHIFT1 || optimize_size))
10906	return "sal{w}\t%0";
10907      else
10908	return "sal{w}\t{%2, %0|%0, %2}";
10909    }
10910}
10911  [(set (attr "type")
10912     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10913		          (const_int 0))
10914		      (match_operand 0 "register_operand" ""))
10915		 (match_operand 2 "const1_operand" ""))
10916	      (const_string "alu")
10917	   ]
10918	   (const_string "ishift")))
10919   (set_attr "mode" "HI")])
10920
10921;; This pattern can't accept a variable shift count, since shifts by
10922;; zero don't affect the flags.  We assume that shifts by constant
10923;; zero are optimized away.
10924(define_insn "*ashlhi3_cmp"
10925  [(set (reg FLAGS_REG)
10926	(compare
10927	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10928		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10929	  (const_int 0)))
10930   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10931	(ashift:HI (match_dup 1) (match_dup 2)))]
10932  "ix86_match_ccmode (insn, CCGOCmode)
10933   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10934   && (optimize_size
10935       || !TARGET_PARTIAL_FLAG_REG_STALL
10936       || (operands[2] == const1_rtx
10937	   && (TARGET_SHIFT1
10938	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10939{
10940  switch (get_attr_type (insn))
10941    {
10942    case TYPE_ALU:
10943      gcc_assert (operands[2] == const1_rtx);
10944      return "add{w}\t{%0, %0|%0, %0}";
10945
10946    default:
10947      if (REG_P (operands[2]))
10948	return "sal{w}\t{%b2, %0|%0, %b2}";
10949      else if (operands[2] == const1_rtx
10950	       && (TARGET_SHIFT1 || optimize_size))
10951	return "sal{w}\t%0";
10952      else
10953	return "sal{w}\t{%2, %0|%0, %2}";
10954    }
10955}
10956  [(set (attr "type")
10957     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10958		          (const_int 0))
10959		      (match_operand 0 "register_operand" ""))
10960		 (match_operand 2 "const1_operand" ""))
10961	      (const_string "alu")
10962	   ]
10963	   (const_string "ishift")))
10964   (set_attr "mode" "HI")])
10965
10966(define_insn "*ashlhi3_cconly"
10967  [(set (reg FLAGS_REG)
10968	(compare
10969	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10970		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10971	  (const_int 0)))
10972   (clobber (match_scratch:HI 0 "=r"))]
10973  "ix86_match_ccmode (insn, CCGOCmode)
10974   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10975   && (optimize_size
10976       || !TARGET_PARTIAL_FLAG_REG_STALL
10977       || (operands[2] == const1_rtx
10978	   && (TARGET_SHIFT1
10979	       || TARGET_DOUBLE_WITH_ADD)))"
10980{
10981  switch (get_attr_type (insn))
10982    {
10983    case TYPE_ALU:
10984      gcc_assert (operands[2] == const1_rtx);
10985      return "add{w}\t{%0, %0|%0, %0}";
10986
10987    default:
10988      if (REG_P (operands[2]))
10989	return "sal{w}\t{%b2, %0|%0, %b2}";
10990      else if (operands[2] == const1_rtx
10991	       && (TARGET_SHIFT1 || optimize_size))
10992	return "sal{w}\t%0";
10993      else
10994	return "sal{w}\t{%2, %0|%0, %2}";
10995    }
10996}
10997  [(set (attr "type")
10998     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10999		          (const_int 0))
11000		      (match_operand 0 "register_operand" ""))
11001		 (match_operand 2 "const1_operand" ""))
11002	      (const_string "alu")
11003	   ]
11004	   (const_string "ishift")))
11005   (set_attr "mode" "HI")])
11006
11007(define_expand "ashlqi3"
11008  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11009	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11010		   (match_operand:QI 2 "nonmemory_operand" "")))
11011   (clobber (reg:CC FLAGS_REG))]
11012  "TARGET_QIMODE_MATH"
11013  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11014
11015;; %%% Potential partial reg stall on alternative 2.  What to do?
11016
11017(define_insn "*ashlqi3_1_lea"
11018  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11019	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11020		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11021   (clobber (reg:CC FLAGS_REG))]
11022  "!TARGET_PARTIAL_REG_STALL
11023   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11024{
11025  switch (get_attr_type (insn))
11026    {
11027    case TYPE_LEA:
11028      return "#";
11029    case TYPE_ALU:
11030      gcc_assert (operands[2] == const1_rtx);
11031      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11032        return "add{l}\t{%k0, %k0|%k0, %k0}";
11033      else
11034        return "add{b}\t{%0, %0|%0, %0}";
11035
11036    default:
11037      if (REG_P (operands[2]))
11038	{
11039	  if (get_attr_mode (insn) == MODE_SI)
11040	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11041	  else
11042	    return "sal{b}\t{%b2, %0|%0, %b2}";
11043	}
11044      else if (operands[2] == const1_rtx
11045	       && (TARGET_SHIFT1 || optimize_size))
11046	{
11047	  if (get_attr_mode (insn) == MODE_SI)
11048	    return "sal{l}\t%0";
11049	  else
11050	    return "sal{b}\t%0";
11051	}
11052      else
11053	{
11054	  if (get_attr_mode (insn) == MODE_SI)
11055	    return "sal{l}\t{%2, %k0|%k0, %2}";
11056	  else
11057	    return "sal{b}\t{%2, %0|%0, %2}";
11058	}
11059    }
11060}
11061  [(set (attr "type")
11062     (cond [(eq_attr "alternative" "2")
11063	      (const_string "lea")
11064            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11065		          (const_int 0))
11066		      (match_operand 0 "register_operand" ""))
11067		 (match_operand 2 "const1_operand" ""))
11068	      (const_string "alu")
11069	   ]
11070	   (const_string "ishift")))
11071   (set_attr "mode" "QI,SI,SI")])
11072
11073(define_insn "*ashlqi3_1"
11074  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11075	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11076		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11077   (clobber (reg:CC FLAGS_REG))]
11078  "TARGET_PARTIAL_REG_STALL
11079   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11080{
11081  switch (get_attr_type (insn))
11082    {
11083    case TYPE_ALU:
11084      gcc_assert (operands[2] == const1_rtx);
11085      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11086        return "add{l}\t{%k0, %k0|%k0, %k0}";
11087      else
11088        return "add{b}\t{%0, %0|%0, %0}";
11089
11090    default:
11091      if (REG_P (operands[2]))
11092	{
11093	  if (get_attr_mode (insn) == MODE_SI)
11094	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11095	  else
11096	    return "sal{b}\t{%b2, %0|%0, %b2}";
11097	}
11098      else if (operands[2] == const1_rtx
11099	       && (TARGET_SHIFT1 || optimize_size))
11100	{
11101	  if (get_attr_mode (insn) == MODE_SI)
11102	    return "sal{l}\t%0";
11103	  else
11104	    return "sal{b}\t%0";
11105	}
11106      else
11107	{
11108	  if (get_attr_mode (insn) == MODE_SI)
11109	    return "sal{l}\t{%2, %k0|%k0, %2}";
11110	  else
11111	    return "sal{b}\t{%2, %0|%0, %2}";
11112	}
11113    }
11114}
11115  [(set (attr "type")
11116     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11117		          (const_int 0))
11118		      (match_operand 0 "register_operand" ""))
11119		 (match_operand 2 "const1_operand" ""))
11120	      (const_string "alu")
11121	   ]
11122	   (const_string "ishift")))
11123   (set_attr "mode" "QI,SI")])
11124
11125;; This pattern can't accept a variable shift count, since shifts by
11126;; zero don't affect the flags.  We assume that shifts by constant
11127;; zero are optimized away.
11128(define_insn "*ashlqi3_cmp"
11129  [(set (reg FLAGS_REG)
11130	(compare
11131	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11132		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11133	  (const_int 0)))
11134   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11135	(ashift:QI (match_dup 1) (match_dup 2)))]
11136  "ix86_match_ccmode (insn, CCGOCmode)
11137   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11138   && (optimize_size
11139       || !TARGET_PARTIAL_FLAG_REG_STALL
11140       || (operands[2] == const1_rtx
11141	   && (TARGET_SHIFT1
11142	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11143{
11144  switch (get_attr_type (insn))
11145    {
11146    case TYPE_ALU:
11147      gcc_assert (operands[2] == const1_rtx);
11148      return "add{b}\t{%0, %0|%0, %0}";
11149
11150    default:
11151      if (REG_P (operands[2]))
11152	return "sal{b}\t{%b2, %0|%0, %b2}";
11153      else if (operands[2] == const1_rtx
11154	       && (TARGET_SHIFT1 || optimize_size))
11155	return "sal{b}\t%0";
11156      else
11157	return "sal{b}\t{%2, %0|%0, %2}";
11158    }
11159}
11160  [(set (attr "type")
11161     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11162		          (const_int 0))
11163		      (match_operand 0 "register_operand" ""))
11164		 (match_operand 2 "const1_operand" ""))
11165	      (const_string "alu")
11166	   ]
11167	   (const_string "ishift")))
11168   (set_attr "mode" "QI")])
11169
11170(define_insn "*ashlqi3_cconly"
11171  [(set (reg FLAGS_REG)
11172	(compare
11173	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11174		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11175	  (const_int 0)))
11176   (clobber (match_scratch:QI 0 "=q"))]
11177  "ix86_match_ccmode (insn, CCGOCmode)
11178   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11179   && (optimize_size
11180       || !TARGET_PARTIAL_FLAG_REG_STALL
11181       || (operands[2] == const1_rtx
11182	   && (TARGET_SHIFT1
11183	       || TARGET_DOUBLE_WITH_ADD)))"
11184{
11185  switch (get_attr_type (insn))
11186    {
11187    case TYPE_ALU:
11188      gcc_assert (operands[2] == const1_rtx);
11189      return "add{b}\t{%0, %0|%0, %0}";
11190
11191    default:
11192      if (REG_P (operands[2]))
11193	return "sal{b}\t{%b2, %0|%0, %b2}";
11194      else if (operands[2] == const1_rtx
11195	       && (TARGET_SHIFT1 || optimize_size))
11196	return "sal{b}\t%0";
11197      else
11198	return "sal{b}\t{%2, %0|%0, %2}";
11199    }
11200}
11201  [(set (attr "type")
11202     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11203		          (const_int 0))
11204		      (match_operand 0 "register_operand" ""))
11205		 (match_operand 2 "const1_operand" ""))
11206	      (const_string "alu")
11207	   ]
11208	   (const_string "ishift")))
11209   (set_attr "mode" "QI")])
11210
11211;; See comment above `ashldi3' about how this works.
11212
11213(define_expand "ashrti3"
11214  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11215		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11216				(match_operand:QI 2 "nonmemory_operand" "")))
11217	      (clobber (reg:CC FLAGS_REG))])]
11218  "TARGET_64BIT"
11219{
11220  if (! immediate_operand (operands[2], QImode))
11221    {
11222      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11223      DONE;
11224    }
11225  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11226  DONE;
11227})
11228
11229(define_insn "ashrti3_1"
11230  [(set (match_operand:TI 0 "register_operand" "=r")
11231	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11232		     (match_operand:QI 2 "register_operand" "c")))
11233   (clobber (match_scratch:DI 3 "=&r"))
11234   (clobber (reg:CC FLAGS_REG))]
11235  "TARGET_64BIT"
11236  "#"
11237  [(set_attr "type" "multi")])
11238
11239(define_insn "*ashrti3_2"
11240  [(set (match_operand:TI 0 "register_operand" "=r")
11241	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11242		     (match_operand:QI 2 "immediate_operand" "O")))
11243   (clobber (reg:CC FLAGS_REG))]
11244  "TARGET_64BIT"
11245  "#"
11246  [(set_attr "type" "multi")])
11247
11248(define_split
11249  [(set (match_operand:TI 0 "register_operand" "")
11250	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11251		     (match_operand:QI 2 "register_operand" "")))
11252   (clobber (match_scratch:DI 3 ""))
11253   (clobber (reg:CC FLAGS_REG))]
11254  "TARGET_64BIT && reload_completed"
11255  [(const_int 0)]
11256  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11257
11258(define_split
11259  [(set (match_operand:TI 0 "register_operand" "")
11260	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11261		     (match_operand:QI 2 "immediate_operand" "")))
11262   (clobber (reg:CC FLAGS_REG))]
11263  "TARGET_64BIT && reload_completed"
11264  [(const_int 0)]
11265  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11266
11267(define_insn "x86_64_shrd"
11268  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11269        (ior:DI (ashiftrt:DI (match_dup 0)
11270		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
11271		(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11272		  (minus:QI (const_int 64) (match_dup 2)))))
11273   (clobber (reg:CC FLAGS_REG))]
11274  "TARGET_64BIT"
11275  "@
11276   shrd{q}\t{%2, %1, %0|%0, %1, %2}
11277   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11278  [(set_attr "type" "ishift")
11279   (set_attr "prefix_0f" "1")
11280   (set_attr "mode" "DI")
11281   (set_attr "athlon_decode" "vector")])
11282
11283(define_expand "ashrdi3"
11284  [(set (match_operand:DI 0 "shiftdi_operand" "")
11285	(ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11286		     (match_operand:QI 2 "nonmemory_operand" "")))]
11287  ""
11288  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11289
11290(define_insn "*ashrdi3_63_rex64"
11291  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11292	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11293		     (match_operand:DI 2 "const_int_operand" "i,i")))
11294   (clobber (reg:CC FLAGS_REG))]
11295  "TARGET_64BIT && INTVAL (operands[2]) == 63
11296   && (TARGET_USE_CLTD || optimize_size)
11297   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11298  "@
11299   {cqto|cqo}
11300   sar{q}\t{%2, %0|%0, %2}"
11301  [(set_attr "type" "imovx,ishift")
11302   (set_attr "prefix_0f" "0,*")
11303   (set_attr "length_immediate" "0,*")
11304   (set_attr "modrm" "0,1")
11305   (set_attr "mode" "DI")])
11306
11307(define_insn "*ashrdi3_1_one_bit_rex64"
11308  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11309	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11310		     (match_operand:QI 2 "const1_operand" "")))
11311   (clobber (reg:CC FLAGS_REG))]
11312  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11313   && (TARGET_SHIFT1 || optimize_size)"
11314  "sar{q}\t%0"
11315  [(set_attr "type" "ishift")
11316   (set (attr "length") 
11317     (if_then_else (match_operand:DI 0 "register_operand" "") 
11318	(const_string "2")
11319	(const_string "*")))])
11320
11321(define_insn "*ashrdi3_1_rex64"
11322  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11323	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11324		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11325   (clobber (reg:CC FLAGS_REG))]
11326  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11327  "@
11328   sar{q}\t{%2, %0|%0, %2}
11329   sar{q}\t{%b2, %0|%0, %b2}"
11330  [(set_attr "type" "ishift")
11331   (set_attr "mode" "DI")])
11332
11333;; This pattern can't accept a variable shift count, since shifts by
11334;; zero don't affect the flags.  We assume that shifts by constant
11335;; zero are optimized away.
11336(define_insn "*ashrdi3_one_bit_cmp_rex64"
11337  [(set (reg FLAGS_REG)
11338	(compare
11339	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11340		       (match_operand:QI 2 "const1_operand" ""))
11341	  (const_int 0)))
11342   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11343	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11344  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11345   && (TARGET_SHIFT1 || optimize_size)
11346   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11347  "sar{q}\t%0"
11348  [(set_attr "type" "ishift")
11349   (set (attr "length") 
11350     (if_then_else (match_operand:DI 0 "register_operand" "") 
11351	(const_string "2")
11352	(const_string "*")))])
11353
11354(define_insn "*ashrdi3_one_bit_cconly_rex64"
11355  [(set (reg FLAGS_REG)
11356	(compare
11357	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11358		       (match_operand:QI 2 "const1_operand" ""))
11359	  (const_int 0)))
11360   (clobber (match_scratch:DI 0 "=r"))]
11361  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11362   && (TARGET_SHIFT1 || optimize_size)
11363   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11364  "sar{q}\t%0"
11365  [(set_attr "type" "ishift")
11366   (set_attr "length" "2")])
11367
11368;; This pattern can't accept a variable shift count, since shifts by
11369;; zero don't affect the flags.  We assume that shifts by constant
11370;; zero are optimized away.
11371(define_insn "*ashrdi3_cmp_rex64"
11372  [(set (reg FLAGS_REG)
11373	(compare
11374	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11375		       (match_operand:QI 2 "const_int_operand" "n"))
11376	  (const_int 0)))
11377   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11378	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11379  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11380   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11381   && (optimize_size
11382       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11383  "sar{q}\t{%2, %0|%0, %2}"
11384  [(set_attr "type" "ishift")
11385   (set_attr "mode" "DI")])
11386
11387(define_insn "*ashrdi3_cconly_rex64"
11388  [(set (reg FLAGS_REG)
11389	(compare
11390	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11391		       (match_operand:QI 2 "const_int_operand" "n"))
11392	  (const_int 0)))
11393   (clobber (match_scratch:DI 0 "=r"))]
11394  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11396   && (optimize_size
11397       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11398  "sar{q}\t{%2, %0|%0, %2}"
11399  [(set_attr "type" "ishift")
11400   (set_attr "mode" "DI")])
11401
11402(define_insn "*ashrdi3_1"
11403  [(set (match_operand:DI 0 "register_operand" "=r")
11404	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11405		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11406   (clobber (reg:CC FLAGS_REG))]
11407  "!TARGET_64BIT"
11408  "#"
11409  [(set_attr "type" "multi")])
11410
11411;; By default we don't ask for a scratch register, because when DImode
11412;; values are manipulated, registers are already at a premium.  But if
11413;; we have one handy, we won't turn it away.
11414(define_peephole2
11415  [(match_scratch:SI 3 "r")
11416   (parallel [(set (match_operand:DI 0 "register_operand" "")
11417		   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11418			        (match_operand:QI 2 "nonmemory_operand" "")))
11419	      (clobber (reg:CC FLAGS_REG))])
11420   (match_dup 3)]
11421  "!TARGET_64BIT && TARGET_CMOVE"
11422  [(const_int 0)]
11423  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11424
11425(define_split
11426  [(set (match_operand:DI 0 "register_operand" "")
11427	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11428		     (match_operand:QI 2 "nonmemory_operand" "")))
11429   (clobber (reg:CC FLAGS_REG))]
11430  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11431		     ? flow2_completed : reload_completed)"
11432  [(const_int 0)]
11433  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11434
11435(define_insn "x86_shrd_1"
11436  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11437        (ior:SI (ashiftrt:SI (match_dup 0)
11438		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11439		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11440		  (minus:QI (const_int 32) (match_dup 2)))))
11441   (clobber (reg:CC FLAGS_REG))]
11442  ""
11443  "@
11444   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11445   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11446  [(set_attr "type" "ishift")
11447   (set_attr "prefix_0f" "1")
11448   (set_attr "pent_pair" "np")
11449   (set_attr "mode" "SI")])
11450
11451(define_expand "x86_shift_adj_3"
11452  [(use (match_operand:SI 0 "register_operand" ""))
11453   (use (match_operand:SI 1 "register_operand" ""))
11454   (use (match_operand:QI 2 "register_operand" ""))]
11455  ""
11456{
11457  rtx label = gen_label_rtx ();
11458  rtx tmp;
11459
11460  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11461
11462  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11463  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11464  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11465			      gen_rtx_LABEL_REF (VOIDmode, label),
11466			      pc_rtx);
11467  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11468  JUMP_LABEL (tmp) = label;
11469
11470  emit_move_insn (operands[0], operands[1]);
11471  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11472
11473  emit_label (label);
11474  LABEL_NUSES (label) = 1;
11475
11476  DONE;
11477})
11478
11479(define_insn "ashrsi3_31"
11480  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11481	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11482		     (match_operand:SI 2 "const_int_operand" "i,i")))
11483   (clobber (reg:CC FLAGS_REG))]
11484  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11485   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11486  "@
11487   {cltd|cdq}
11488   sar{l}\t{%2, %0|%0, %2}"
11489  [(set_attr "type" "imovx,ishift")
11490   (set_attr "prefix_0f" "0,*")
11491   (set_attr "length_immediate" "0,*")
11492   (set_attr "modrm" "0,1")
11493   (set_attr "mode" "SI")])
11494
11495(define_insn "*ashrsi3_31_zext"
11496  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11497	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11498				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11499   (clobber (reg:CC FLAGS_REG))]
11500  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11501   && INTVAL (operands[2]) == 31
11502   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11503  "@
11504   {cltd|cdq}
11505   sar{l}\t{%2, %k0|%k0, %2}"
11506  [(set_attr "type" "imovx,ishift")
11507   (set_attr "prefix_0f" "0,*")
11508   (set_attr "length_immediate" "0,*")
11509   (set_attr "modrm" "0,1")
11510   (set_attr "mode" "SI")])
11511
11512(define_expand "ashrsi3"
11513  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11514	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11515		     (match_operand:QI 2 "nonmemory_operand" "")))
11516   (clobber (reg:CC FLAGS_REG))]
11517  ""
11518  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11519
11520(define_insn "*ashrsi3_1_one_bit"
11521  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11522	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11523		     (match_operand:QI 2 "const1_operand" "")))
11524   (clobber (reg:CC FLAGS_REG))]
11525  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11526   && (TARGET_SHIFT1 || optimize_size)"
11527  "sar{l}\t%0"
11528  [(set_attr "type" "ishift")
11529   (set (attr "length") 
11530     (if_then_else (match_operand:SI 0 "register_operand" "") 
11531	(const_string "2")
11532	(const_string "*")))])
11533
11534(define_insn "*ashrsi3_1_one_bit_zext"
11535  [(set (match_operand:DI 0 "register_operand" "=r")
11536	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11537				     (match_operand:QI 2 "const1_operand" ""))))
11538   (clobber (reg:CC FLAGS_REG))]
11539  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11540   && (TARGET_SHIFT1 || optimize_size)"
11541  "sar{l}\t%k0"
11542  [(set_attr "type" "ishift")
11543   (set_attr "length" "2")])
11544
11545(define_insn "*ashrsi3_1"
11546  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11547	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11548		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11549   (clobber (reg:CC FLAGS_REG))]
11550  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551  "@
11552   sar{l}\t{%2, %0|%0, %2}
11553   sar{l}\t{%b2, %0|%0, %b2}"
11554  [(set_attr "type" "ishift")
11555   (set_attr "mode" "SI")])
11556
11557(define_insn "*ashrsi3_1_zext"
11558  [(set (match_operand:DI 0 "register_operand" "=r,r")
11559	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11560				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11561   (clobber (reg:CC FLAGS_REG))]
11562  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11563  "@
11564   sar{l}\t{%2, %k0|%k0, %2}
11565   sar{l}\t{%b2, %k0|%k0, %b2}"
11566  [(set_attr "type" "ishift")
11567   (set_attr "mode" "SI")])
11568
11569;; This pattern can't accept a variable shift count, since shifts by
11570;; zero don't affect the flags.  We assume that shifts by constant
11571;; zero are optimized away.
11572(define_insn "*ashrsi3_one_bit_cmp"
11573  [(set (reg FLAGS_REG)
11574	(compare
11575	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11576		       (match_operand:QI 2 "const1_operand" ""))
11577	  (const_int 0)))
11578   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11579	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11580  "ix86_match_ccmode (insn, CCGOCmode)
11581   && (TARGET_SHIFT1 || optimize_size)
11582   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11583  "sar{l}\t%0"
11584  [(set_attr "type" "ishift")
11585   (set (attr "length") 
11586     (if_then_else (match_operand:SI 0 "register_operand" "") 
11587	(const_string "2")
11588	(const_string "*")))])
11589
11590(define_insn "*ashrsi3_one_bit_cconly"
11591  [(set (reg FLAGS_REG)
11592	(compare
11593	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11594		       (match_operand:QI 2 "const1_operand" ""))
11595	  (const_int 0)))
11596   (clobber (match_scratch:SI 0 "=r"))]
11597  "ix86_match_ccmode (insn, CCGOCmode)
11598   && (TARGET_SHIFT1 || optimize_size)
11599   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11600  "sar{l}\t%0"
11601  [(set_attr "type" "ishift")
11602   (set_attr "length" "2")])
11603
11604(define_insn "*ashrsi3_one_bit_cmp_zext"
11605  [(set (reg FLAGS_REG)
11606	(compare
11607	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11608		       (match_operand:QI 2 "const1_operand" ""))
11609	  (const_int 0)))
11610   (set (match_operand:DI 0 "register_operand" "=r")
11611	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11612  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11613   && (TARGET_SHIFT1 || optimize_size)
11614   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11615  "sar{l}\t%k0"
11616  [(set_attr "type" "ishift")
11617   (set_attr "length" "2")])
11618
11619;; This pattern can't accept a variable shift count, since shifts by
11620;; zero don't affect the flags.  We assume that shifts by constant
11621;; zero are optimized away.
11622(define_insn "*ashrsi3_cmp"
11623  [(set (reg FLAGS_REG)
11624	(compare
11625	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11626		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11627	  (const_int 0)))
11628   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11629	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11630  "ix86_match_ccmode (insn, CCGOCmode)
11631   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11632   && (optimize_size
11633       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11634  "sar{l}\t{%2, %0|%0, %2}"
11635  [(set_attr "type" "ishift")
11636   (set_attr "mode" "SI")])
11637
11638(define_insn "*ashrsi3_cconly"
11639  [(set (reg FLAGS_REG)
11640	(compare
11641	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11642		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11643	  (const_int 0)))
11644   (clobber (match_scratch:SI 0 "=r"))]
11645  "ix86_match_ccmode (insn, CCGOCmode)
11646   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11647   && (optimize_size
11648       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11649  "sar{l}\t{%2, %0|%0, %2}"
11650  [(set_attr "type" "ishift")
11651   (set_attr "mode" "SI")])
11652
11653(define_insn "*ashrsi3_cmp_zext"
11654  [(set (reg FLAGS_REG)
11655	(compare
11656	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11657		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11658	  (const_int 0)))
11659   (set (match_operand:DI 0 "register_operand" "=r")
11660	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11661  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11662   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11663   && (optimize_size
11664       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11665  "sar{l}\t{%2, %k0|%k0, %2}"
11666  [(set_attr "type" "ishift")
11667   (set_attr "mode" "SI")])
11668
11669(define_expand "ashrhi3"
11670  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11671	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11672		     (match_operand:QI 2 "nonmemory_operand" "")))
11673   (clobber (reg:CC FLAGS_REG))]
11674  "TARGET_HIMODE_MATH"
11675  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11676
11677(define_insn "*ashrhi3_1_one_bit"
11678  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11679	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11680		     (match_operand:QI 2 "const1_operand" "")))
11681   (clobber (reg:CC FLAGS_REG))]
11682  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11683   && (TARGET_SHIFT1 || optimize_size)"
11684  "sar{w}\t%0"
11685  [(set_attr "type" "ishift")
11686   (set (attr "length") 
11687     (if_then_else (match_operand 0 "register_operand" "") 
11688	(const_string "2")
11689	(const_string "*")))])
11690
11691(define_insn "*ashrhi3_1"
11692  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11693	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11694		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11695   (clobber (reg:CC FLAGS_REG))]
11696  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11697  "@
11698   sar{w}\t{%2, %0|%0, %2}
11699   sar{w}\t{%b2, %0|%0, %b2}"
11700  [(set_attr "type" "ishift")
11701   (set_attr "mode" "HI")])
11702
11703;; This pattern can't accept a variable shift count, since shifts by
11704;; zero don't affect the flags.  We assume that shifts by constant
11705;; zero are optimized away.
11706(define_insn "*ashrhi3_one_bit_cmp"
11707  [(set (reg FLAGS_REG)
11708	(compare
11709	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11710		       (match_operand:QI 2 "const1_operand" ""))
11711	  (const_int 0)))
11712   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11713	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11714  "ix86_match_ccmode (insn, CCGOCmode)
11715   && (TARGET_SHIFT1 || optimize_size)
11716   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11717  "sar{w}\t%0"
11718  [(set_attr "type" "ishift")
11719   (set (attr "length") 
11720     (if_then_else (match_operand 0 "register_operand" "") 
11721	(const_string "2")
11722	(const_string "*")))])
11723
11724(define_insn "*ashrhi3_one_bit_cconly"
11725  [(set (reg FLAGS_REG)
11726	(compare
11727	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11728		       (match_operand:QI 2 "const1_operand" ""))
11729	  (const_int 0)))
11730   (clobber (match_scratch:HI 0 "=r"))]
11731  "ix86_match_ccmode (insn, CCGOCmode)
11732   && (TARGET_SHIFT1 || optimize_size)
11733   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11734  "sar{w}\t%0"
11735  [(set_attr "type" "ishift")
11736   (set_attr "length" "2")])
11737
11738;; This pattern can't accept a variable shift count, since shifts by
11739;; zero don't affect the flags.  We assume that shifts by constant
11740;; zero are optimized away.
11741(define_insn "*ashrhi3_cmp"
11742  [(set (reg FLAGS_REG)
11743	(compare
11744	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11745		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11746	  (const_int 0)))
11747   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11748	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11749  "ix86_match_ccmode (insn, CCGOCmode)
11750   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11751   && (optimize_size
11752       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11753  "sar{w}\t{%2, %0|%0, %2}"
11754  [(set_attr "type" "ishift")
11755   (set_attr "mode" "HI")])
11756
11757(define_insn "*ashrhi3_cconly"
11758  [(set (reg FLAGS_REG)
11759	(compare
11760	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11761		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11762	  (const_int 0)))
11763   (clobber (match_scratch:HI 0 "=r"))]
11764  "ix86_match_ccmode (insn, CCGOCmode)
11765   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11766   && (optimize_size
11767       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11768  "sar{w}\t{%2, %0|%0, %2}"
11769  [(set_attr "type" "ishift")
11770   (set_attr "mode" "HI")])
11771
11772(define_expand "ashrqi3"
11773  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11774	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11775		     (match_operand:QI 2 "nonmemory_operand" "")))
11776   (clobber (reg:CC FLAGS_REG))]
11777  "TARGET_QIMODE_MATH"
11778  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11779
11780(define_insn "*ashrqi3_1_one_bit"
11781  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11782	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11783		     (match_operand:QI 2 "const1_operand" "")))
11784   (clobber (reg:CC FLAGS_REG))]
11785  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11786   && (TARGET_SHIFT1 || optimize_size)"
11787  "sar{b}\t%0"
11788  [(set_attr "type" "ishift")
11789   (set (attr "length") 
11790     (if_then_else (match_operand 0 "register_operand" "") 
11791	(const_string "2")
11792	(const_string "*")))])
11793
11794(define_insn "*ashrqi3_1_one_bit_slp"
11795  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11796	(ashiftrt:QI (match_dup 0)
11797		     (match_operand:QI 1 "const1_operand" "")))
11798   (clobber (reg:CC FLAGS_REG))]
11799  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11800   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11801   && (TARGET_SHIFT1 || optimize_size)"
11802  "sar{b}\t%0"
11803  [(set_attr "type" "ishift1")
11804   (set (attr "length") 
11805     (if_then_else (match_operand 0 "register_operand" "") 
11806	(const_string "2")
11807	(const_string "*")))])
11808
11809(define_insn "*ashrqi3_1"
11810  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11811	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11812		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11813   (clobber (reg:CC FLAGS_REG))]
11814  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11815  "@
11816   sar{b}\t{%2, %0|%0, %2}
11817   sar{b}\t{%b2, %0|%0, %b2}"
11818  [(set_attr "type" "ishift")
11819   (set_attr "mode" "QI")])
11820
11821(define_insn "*ashrqi3_1_slp"
11822  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11823	(ashiftrt:QI (match_dup 0)
11824		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11825   (clobber (reg:CC FLAGS_REG))]
11826  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11827   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11828  "@
11829   sar{b}\t{%1, %0|%0, %1}
11830   sar{b}\t{%b1, %0|%0, %b1}"
11831  [(set_attr "type" "ishift1")
11832   (set_attr "mode" "QI")])
11833
11834;; This pattern can't accept a variable shift count, since shifts by
11835;; zero don't affect the flags.  We assume that shifts by constant
11836;; zero are optimized away.
11837(define_insn "*ashrqi3_one_bit_cmp"
11838  [(set (reg FLAGS_REG)
11839	(compare
11840	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11841		       (match_operand:QI 2 "const1_operand" "I"))
11842	  (const_int 0)))
11843   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11844	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11845  "ix86_match_ccmode (insn, CCGOCmode)
11846   && (TARGET_SHIFT1 || optimize_size)
11847   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11848  "sar{b}\t%0"
11849  [(set_attr "type" "ishift")
11850   (set (attr "length") 
11851     (if_then_else (match_operand 0 "register_operand" "") 
11852	(const_string "2")
11853	(const_string "*")))])
11854
11855(define_insn "*ashrqi3_one_bit_cconly"
11856  [(set (reg FLAGS_REG)
11857	(compare
11858	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11859		       (match_operand:QI 2 "const1_operand" "I"))
11860	  (const_int 0)))
11861   (clobber (match_scratch:QI 0 "=q"))]
11862  "ix86_match_ccmode (insn, CCGOCmode)
11863   && (TARGET_SHIFT1 || optimize_size)
11864   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11865  "sar{b}\t%0"
11866  [(set_attr "type" "ishift")
11867   (set_attr "length" "2")])
11868
11869;; This pattern can't accept a variable shift count, since shifts by
11870;; zero don't affect the flags.  We assume that shifts by constant
11871;; zero are optimized away.
11872(define_insn "*ashrqi3_cmp"
11873  [(set (reg FLAGS_REG)
11874	(compare
11875	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11876		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11877	  (const_int 0)))
11878   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11879	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11880  "ix86_match_ccmode (insn, CCGOCmode)
11881   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11882   && (optimize_size
11883       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11884  "sar{b}\t{%2, %0|%0, %2}"
11885  [(set_attr "type" "ishift")
11886   (set_attr "mode" "QI")])
11887
11888(define_insn "*ashrqi3_cconly"
11889  [(set (reg FLAGS_REG)
11890	(compare
11891	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11892		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11893	  (const_int 0)))
11894   (clobber (match_scratch:QI 0 "=q"))]
11895  "ix86_match_ccmode (insn, CCGOCmode)
11896   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11897   && (optimize_size
11898       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11899  "sar{b}\t{%2, %0|%0, %2}"
11900  [(set_attr "type" "ishift")
11901   (set_attr "mode" "QI")])
11902
11903
11904;; Logical shift instructions
11905
11906;; See comment above `ashldi3' about how this works.
11907
11908(define_expand "lshrti3"
11909  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11910		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11911			        (match_operand:QI 2 "nonmemory_operand" "")))
11912	      (clobber (reg:CC FLAGS_REG))])]
11913  "TARGET_64BIT"
11914{
11915  if (! immediate_operand (operands[2], QImode))
11916    {
11917      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11918      DONE;
11919    }
11920  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11921  DONE;
11922})
11923
11924(define_insn "lshrti3_1"
11925  [(set (match_operand:TI 0 "register_operand" "=r")
11926	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11927		     (match_operand:QI 2 "register_operand" "c")))
11928   (clobber (match_scratch:DI 3 "=&r"))
11929   (clobber (reg:CC FLAGS_REG))]
11930  "TARGET_64BIT"
11931  "#"
11932  [(set_attr "type" "multi")])
11933
11934(define_insn "*lshrti3_2"
11935  [(set (match_operand:TI 0 "register_operand" "=r")
11936	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11937		     (match_operand:QI 2 "immediate_operand" "O")))
11938   (clobber (reg:CC FLAGS_REG))]
11939  "TARGET_64BIT"
11940  "#"
11941  [(set_attr "type" "multi")])
11942
11943(define_split 
11944  [(set (match_operand:TI 0 "register_operand" "")
11945	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11946		     (match_operand:QI 2 "register_operand" "")))
11947   (clobber (match_scratch:DI 3 ""))
11948   (clobber (reg:CC FLAGS_REG))]
11949  "TARGET_64BIT && reload_completed"
11950  [(const_int 0)]
11951  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11952
11953(define_split 
11954  [(set (match_operand:TI 0 "register_operand" "")
11955	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11956		     (match_operand:QI 2 "immediate_operand" "")))
11957   (clobber (reg:CC FLAGS_REG))]
11958  "TARGET_64BIT && reload_completed"
11959  [(const_int 0)]
11960  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11961
11962(define_expand "lshrdi3"
11963  [(set (match_operand:DI 0 "shiftdi_operand" "")
11964	(lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11965		     (match_operand:QI 2 "nonmemory_operand" "")))]
11966  ""
11967  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11968
11969(define_insn "*lshrdi3_1_one_bit_rex64"
11970  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11971	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11972		     (match_operand:QI 2 "const1_operand" "")))
11973   (clobber (reg:CC FLAGS_REG))]
11974  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11975   && (TARGET_SHIFT1 || optimize_size)"
11976  "shr{q}\t%0"
11977  [(set_attr "type" "ishift")
11978   (set (attr "length") 
11979     (if_then_else (match_operand:DI 0 "register_operand" "") 
11980	(const_string "2")
11981	(const_string "*")))])
11982
11983(define_insn "*lshrdi3_1_rex64"
11984  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11985	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11986		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11987   (clobber (reg:CC FLAGS_REG))]
11988  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11989  "@
11990   shr{q}\t{%2, %0|%0, %2}
11991   shr{q}\t{%b2, %0|%0, %b2}"
11992  [(set_attr "type" "ishift")
11993   (set_attr "mode" "DI")])
11994
11995;; This pattern can't accept a variable shift count, since shifts by
11996;; zero don't affect the flags.  We assume that shifts by constant
11997;; zero are optimized away.
11998(define_insn "*lshrdi3_cmp_one_bit_rex64"
11999  [(set (reg FLAGS_REG)
12000	(compare
12001	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12002		       (match_operand:QI 2 "const1_operand" ""))
12003	  (const_int 0)))
12004   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12005	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12006  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12007   && (TARGET_SHIFT1 || optimize_size)
12008   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12009  "shr{q}\t%0"
12010  [(set_attr "type" "ishift")
12011   (set (attr "length") 
12012     (if_then_else (match_operand:DI 0 "register_operand" "") 
12013	(const_string "2")
12014	(const_string "*")))])
12015
12016(define_insn "*lshrdi3_cconly_one_bit_rex64"
12017  [(set (reg FLAGS_REG)
12018	(compare
12019	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12020		       (match_operand:QI 2 "const1_operand" ""))
12021	  (const_int 0)))
12022   (clobber (match_scratch:DI 0 "=r"))]
12023  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12024   && (TARGET_SHIFT1 || optimize_size)
12025   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12026  "shr{q}\t%0"
12027  [(set_attr "type" "ishift")
12028   (set_attr "length" "2")])
12029
12030;; This pattern can't accept a variable shift count, since shifts by
12031;; zero don't affect the flags.  We assume that shifts by constant
12032;; zero are optimized away.
12033(define_insn "*lshrdi3_cmp_rex64"
12034  [(set (reg FLAGS_REG)
12035	(compare
12036	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12037		       (match_operand:QI 2 "const_int_operand" "e"))
12038	  (const_int 0)))
12039   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12040	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12041  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12042   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12043   && (optimize_size
12044       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12045  "shr{q}\t{%2, %0|%0, %2}"
12046  [(set_attr "type" "ishift")
12047   (set_attr "mode" "DI")])
12048
12049(define_insn "*lshrdi3_cconly_rex64"
12050  [(set (reg FLAGS_REG)
12051	(compare
12052	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12053		       (match_operand:QI 2 "const_int_operand" "e"))
12054	  (const_int 0)))
12055   (clobber (match_scratch:DI 0 "=r"))]
12056  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12057   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12058   && (optimize_size
12059       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12060  "shr{q}\t{%2, %0|%0, %2}"
12061  [(set_attr "type" "ishift")
12062   (set_attr "mode" "DI")])
12063
12064(define_insn "*lshrdi3_1"
12065  [(set (match_operand:DI 0 "register_operand" "=r")
12066	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12067		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
12068   (clobber (reg:CC FLAGS_REG))]
12069  "!TARGET_64BIT"
12070  "#"
12071  [(set_attr "type" "multi")])
12072
12073;; By default we don't ask for a scratch register, because when DImode
12074;; values are manipulated, registers are already at a premium.  But if
12075;; we have one handy, we won't turn it away.
12076(define_peephole2
12077  [(match_scratch:SI 3 "r")
12078   (parallel [(set (match_operand:DI 0 "register_operand" "")
12079		   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12080			        (match_operand:QI 2 "nonmemory_operand" "")))
12081	      (clobber (reg:CC FLAGS_REG))])
12082   (match_dup 3)]
12083  "!TARGET_64BIT && TARGET_CMOVE"
12084  [(const_int 0)]
12085  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12086
12087(define_split 
12088  [(set (match_operand:DI 0 "register_operand" "")
12089	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12090		     (match_operand:QI 2 "nonmemory_operand" "")))
12091   (clobber (reg:CC FLAGS_REG))]
12092  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12093		     ? flow2_completed : reload_completed)"
12094  [(const_int 0)]
12095  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12096
12097(define_expand "lshrsi3"
12098  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12099	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12100		     (match_operand:QI 2 "nonmemory_operand" "")))
12101   (clobber (reg:CC FLAGS_REG))]
12102  ""
12103  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12104
12105(define_insn "*lshrsi3_1_one_bit"
12106  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12107	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12108		     (match_operand:QI 2 "const1_operand" "")))
12109   (clobber (reg:CC FLAGS_REG))]
12110  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12111   && (TARGET_SHIFT1 || optimize_size)"
12112  "shr{l}\t%0"
12113  [(set_attr "type" "ishift")
12114   (set (attr "length") 
12115     (if_then_else (match_operand:SI 0 "register_operand" "") 
12116	(const_string "2")
12117	(const_string "*")))])
12118
12119(define_insn "*lshrsi3_1_one_bit_zext"
12120  [(set (match_operand:DI 0 "register_operand" "=r")
12121	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12122		     (match_operand:QI 2 "const1_operand" "")))
12123   (clobber (reg:CC FLAGS_REG))]
12124  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12125   && (TARGET_SHIFT1 || optimize_size)"
12126  "shr{l}\t%k0"
12127  [(set_attr "type" "ishift")
12128   (set_attr "length" "2")])
12129
12130(define_insn "*lshrsi3_1"
12131  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12132	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12133		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12134   (clobber (reg:CC FLAGS_REG))]
12135  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12136  "@
12137   shr{l}\t{%2, %0|%0, %2}
12138   shr{l}\t{%b2, %0|%0, %b2}"
12139  [(set_attr "type" "ishift")
12140   (set_attr "mode" "SI")])
12141
12142(define_insn "*lshrsi3_1_zext"
12143  [(set (match_operand:DI 0 "register_operand" "=r,r")
12144	(zero_extend:DI
12145	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12146		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12147   (clobber (reg:CC FLAGS_REG))]
12148  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12149  "@
12150   shr{l}\t{%2, %k0|%k0, %2}
12151   shr{l}\t{%b2, %k0|%k0, %b2}"
12152  [(set_attr "type" "ishift")
12153   (set_attr "mode" "SI")])
12154
12155;; This pattern can't accept a variable shift count, since shifts by
12156;; zero don't affect the flags.  We assume that shifts by constant
12157;; zero are optimized away.
12158(define_insn "*lshrsi3_one_bit_cmp"
12159  [(set (reg FLAGS_REG)
12160	(compare
12161	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162		       (match_operand:QI 2 "const1_operand" ""))
12163	  (const_int 0)))
12164   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12165	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12166  "ix86_match_ccmode (insn, CCGOCmode)
12167   && (TARGET_SHIFT1 || optimize_size)
12168   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12169  "shr{l}\t%0"
12170  [(set_attr "type" "ishift")
12171   (set (attr "length") 
12172     (if_then_else (match_operand:SI 0 "register_operand" "") 
12173	(const_string "2")
12174	(const_string "*")))])
12175
12176(define_insn "*lshrsi3_one_bit_cconly"
12177  [(set (reg FLAGS_REG)
12178	(compare
12179	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12180		       (match_operand:QI 2 "const1_operand" ""))
12181	  (const_int 0)))
12182   (clobber (match_scratch:SI 0 "=r"))]
12183  "ix86_match_ccmode (insn, CCGOCmode)
12184   && (TARGET_SHIFT1 || optimize_size)
12185   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12186  "shr{l}\t%0"
12187  [(set_attr "type" "ishift")
12188   (set_attr "length" "2")])
12189
12190(define_insn "*lshrsi3_cmp_one_bit_zext"
12191  [(set (reg FLAGS_REG)
12192	(compare
12193	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12194		       (match_operand:QI 2 "const1_operand" ""))
12195	  (const_int 0)))
12196   (set (match_operand:DI 0 "register_operand" "=r")
12197	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12198  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12199   && (TARGET_SHIFT1 || optimize_size)
12200   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12201  "shr{l}\t%k0"
12202  [(set_attr "type" "ishift")
12203   (set_attr "length" "2")])
12204
12205;; This pattern can't accept a variable shift count, since shifts by
12206;; zero don't affect the flags.  We assume that shifts by constant
12207;; zero are optimized away.
12208(define_insn "*lshrsi3_cmp"
12209  [(set (reg FLAGS_REG)
12210	(compare
12211	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12212		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12213	  (const_int 0)))
12214   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12215	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12216  "ix86_match_ccmode (insn, CCGOCmode)
12217   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12218   && (optimize_size
12219       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12220  "shr{l}\t{%2, %0|%0, %2}"
12221  [(set_attr "type" "ishift")
12222   (set_attr "mode" "SI")])
12223
12224(define_insn "*lshrsi3_cconly"
12225  [(set (reg FLAGS_REG)
12226      (compare
12227	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12228		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
12229        (const_int 0)))
12230   (clobber (match_scratch:SI 0 "=r"))]
12231  "ix86_match_ccmode (insn, CCGOCmode)
12232   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12233   && (optimize_size
12234       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12235  "shr{l}\t{%2, %0|%0, %2}"
12236  [(set_attr "type" "ishift")
12237   (set_attr "mode" "SI")])
12238
12239(define_insn "*lshrsi3_cmp_zext"
12240  [(set (reg FLAGS_REG)
12241	(compare
12242	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12243		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12244	  (const_int 0)))
12245   (set (match_operand:DI 0 "register_operand" "=r")
12246	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12247  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12248   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12249   && (optimize_size
12250       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12251  "shr{l}\t{%2, %k0|%k0, %2}"
12252  [(set_attr "type" "ishift")
12253   (set_attr "mode" "SI")])
12254
12255(define_expand "lshrhi3"
12256  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12257	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12258		     (match_operand:QI 2 "nonmemory_operand" "")))
12259   (clobber (reg:CC FLAGS_REG))]
12260  "TARGET_HIMODE_MATH"
12261  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12262
12263(define_insn "*lshrhi3_1_one_bit"
12264  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12265	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12266		     (match_operand:QI 2 "const1_operand" "")))
12267   (clobber (reg:CC FLAGS_REG))]
12268  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12269   && (TARGET_SHIFT1 || optimize_size)"
12270  "shr{w}\t%0"
12271  [(set_attr "type" "ishift")
12272   (set (attr "length") 
12273     (if_then_else (match_operand 0 "register_operand" "") 
12274	(const_string "2")
12275	(const_string "*")))])
12276
12277(define_insn "*lshrhi3_1"
12278  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12279	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12280		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12281   (clobber (reg:CC FLAGS_REG))]
12282  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12283  "@
12284   shr{w}\t{%2, %0|%0, %2}
12285   shr{w}\t{%b2, %0|%0, %b2}"
12286  [(set_attr "type" "ishift")
12287   (set_attr "mode" "HI")])
12288
12289;; This pattern can't accept a variable shift count, since shifts by
12290;; zero don't affect the flags.  We assume that shifts by constant
12291;; zero are optimized away.
12292(define_insn "*lshrhi3_one_bit_cmp"
12293  [(set (reg FLAGS_REG)
12294	(compare
12295	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12296		       (match_operand:QI 2 "const1_operand" ""))
12297	  (const_int 0)))
12298   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12299	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12300  "ix86_match_ccmode (insn, CCGOCmode)
12301   && (TARGET_SHIFT1 || optimize_size)
12302   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12303  "shr{w}\t%0"
12304  [(set_attr "type" "ishift")
12305   (set (attr "length") 
12306     (if_then_else (match_operand:SI 0 "register_operand" "") 
12307	(const_string "2")
12308	(const_string "*")))])
12309
12310(define_insn "*lshrhi3_one_bit_cconly"
12311  [(set (reg FLAGS_REG)
12312	(compare
12313	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12314		       (match_operand:QI 2 "const1_operand" ""))
12315	  (const_int 0)))
12316   (clobber (match_scratch:HI 0 "=r"))]
12317  "ix86_match_ccmode (insn, CCGOCmode)
12318   && (TARGET_SHIFT1 || optimize_size)
12319   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12320  "shr{w}\t%0"
12321  [(set_attr "type" "ishift")
12322   (set_attr "length" "2")])
12323
12324;; This pattern can't accept a variable shift count, since shifts by
12325;; zero don't affect the flags.  We assume that shifts by constant
12326;; zero are optimized away.
12327(define_insn "*lshrhi3_cmp"
12328  [(set (reg FLAGS_REG)
12329	(compare
12330	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12331		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12332	  (const_int 0)))
12333   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12334	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12335  "ix86_match_ccmode (insn, CCGOCmode)
12336   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12337   && (optimize_size
12338       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12339  "shr{w}\t{%2, %0|%0, %2}"
12340  [(set_attr "type" "ishift")
12341   (set_attr "mode" "HI")])
12342
12343(define_insn "*lshrhi3_cconly"
12344  [(set (reg FLAGS_REG)
12345	(compare
12346	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12347		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12348	  (const_int 0)))
12349   (clobber (match_scratch:HI 0 "=r"))]
12350  "ix86_match_ccmode (insn, CCGOCmode)
12351   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12352   && (optimize_size
12353       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12354  "shr{w}\t{%2, %0|%0, %2}"
12355  [(set_attr "type" "ishift")
12356   (set_attr "mode" "HI")])
12357
12358(define_expand "lshrqi3"
12359  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12360	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12361		     (match_operand:QI 2 "nonmemory_operand" "")))
12362   (clobber (reg:CC FLAGS_REG))]
12363  "TARGET_QIMODE_MATH"
12364  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12365
12366(define_insn "*lshrqi3_1_one_bit"
12367  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12368	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12369		     (match_operand:QI 2 "const1_operand" "")))
12370   (clobber (reg:CC FLAGS_REG))]
12371  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12372   && (TARGET_SHIFT1 || optimize_size)"
12373  "shr{b}\t%0"
12374  [(set_attr "type" "ishift")
12375   (set (attr "length") 
12376     (if_then_else (match_operand 0 "register_operand" "") 
12377	(const_string "2")
12378	(const_string "*")))])
12379
12380(define_insn "*lshrqi3_1_one_bit_slp"
12381  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12382	(lshiftrt:QI (match_dup 0)
12383		     (match_operand:QI 1 "const1_operand" "")))
12384   (clobber (reg:CC FLAGS_REG))]
12385  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12386   && (TARGET_SHIFT1 || optimize_size)"
12387  "shr{b}\t%0"
12388  [(set_attr "type" "ishift1")
12389   (set (attr "length") 
12390     (if_then_else (match_operand 0 "register_operand" "") 
12391	(const_string "2")
12392	(const_string "*")))])
12393
12394(define_insn "*lshrqi3_1"
12395  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12396	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12397		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12398   (clobber (reg:CC FLAGS_REG))]
12399  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12400  "@
12401   shr{b}\t{%2, %0|%0, %2}
12402   shr{b}\t{%b2, %0|%0, %b2}"
12403  [(set_attr "type" "ishift")
12404   (set_attr "mode" "QI")])
12405
12406(define_insn "*lshrqi3_1_slp"
12407  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12408	(lshiftrt:QI (match_dup 0)
12409		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12410   (clobber (reg:CC FLAGS_REG))]
12411  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12412   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12413  "@
12414   shr{b}\t{%1, %0|%0, %1}
12415   shr{b}\t{%b1, %0|%0, %b1}"
12416  [(set_attr "type" "ishift1")
12417   (set_attr "mode" "QI")])
12418
12419;; This pattern can't accept a variable shift count, since shifts by
12420;; zero don't affect the flags.  We assume that shifts by constant
12421;; zero are optimized away.
12422(define_insn "*lshrqi2_one_bit_cmp"
12423  [(set (reg FLAGS_REG)
12424	(compare
12425	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12426		       (match_operand:QI 2 "const1_operand" ""))
12427	  (const_int 0)))
12428   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12429	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12430  "ix86_match_ccmode (insn, CCGOCmode)
12431   && (TARGET_SHIFT1 || optimize_size)
12432   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12433  "shr{b}\t%0"
12434  [(set_attr "type" "ishift")
12435   (set (attr "length") 
12436     (if_then_else (match_operand:SI 0 "register_operand" "") 
12437	(const_string "2")
12438	(const_string "*")))])
12439
12440(define_insn "*lshrqi2_one_bit_cconly"
12441  [(set (reg FLAGS_REG)
12442	(compare
12443	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12444		       (match_operand:QI 2 "const1_operand" ""))
12445	  (const_int 0)))
12446   (clobber (match_scratch:QI 0 "=q"))]
12447  "ix86_match_ccmode (insn, CCGOCmode)
12448   && (TARGET_SHIFT1 || optimize_size)
12449   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12450  "shr{b}\t%0"
12451  [(set_attr "type" "ishift")
12452   (set_attr "length" "2")])
12453
12454;; This pattern can't accept a variable shift count, since shifts by
12455;; zero don't affect the flags.  We assume that shifts by constant
12456;; zero are optimized away.
12457(define_insn "*lshrqi2_cmp"
12458  [(set (reg FLAGS_REG)
12459	(compare
12460	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12461		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12462	  (const_int 0)))
12463   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12464	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12465  "ix86_match_ccmode (insn, CCGOCmode)
12466   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12467   && (optimize_size
12468       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12469  "shr{b}\t{%2, %0|%0, %2}"
12470  [(set_attr "type" "ishift")
12471   (set_attr "mode" "QI")])
12472
12473(define_insn "*lshrqi2_cconly"
12474  [(set (reg FLAGS_REG)
12475	(compare
12476	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12477		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12478	  (const_int 0)))
12479   (clobber (match_scratch:QI 0 "=q"))]
12480  "ix86_match_ccmode (insn, CCGOCmode)
12481   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12482   && (optimize_size
12483       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12484  "shr{b}\t{%2, %0|%0, %2}"
12485  [(set_attr "type" "ishift")
12486   (set_attr "mode" "QI")])
12487
12488;; Rotate instructions
12489
12490(define_expand "rotldi3"
12491  [(set (match_operand:DI 0 "shiftdi_operand" "")
12492	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12493		   (match_operand:QI 2 "nonmemory_operand" "")))
12494   (clobber (reg:CC FLAGS_REG))]
12495 ""
12496{
12497  if (TARGET_64BIT)
12498    {
12499      ix86_expand_binary_operator (ROTATE, DImode, operands);
12500      DONE;
12501    }
12502  if (!const_1_to_31_operand (operands[2], VOIDmode))
12503    FAIL;
12504  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12505  DONE;
12506})
12507
12508;; Implement rotation using two double-precision shift instructions
12509;; and a scratch register.   
12510(define_insn_and_split "ix86_rotldi3"
12511 [(set (match_operand:DI 0 "register_operand" "=r")
12512       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12513                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12514  (clobber (reg:CC FLAGS_REG))
12515  (clobber (match_scratch:SI 3 "=&r"))]
12516 "!TARGET_64BIT"
12517 "" 
12518 "&& reload_completed"
12519 [(set (match_dup 3) (match_dup 4))
12520  (parallel
12521   [(set (match_dup 4)
12522         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12523                 (lshiftrt:SI (match_dup 5)
12524                              (minus:QI (const_int 32) (match_dup 2)))))
12525    (clobber (reg:CC FLAGS_REG))])
12526  (parallel
12527   [(set (match_dup 5)
12528         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12529                 (lshiftrt:SI (match_dup 3)
12530                              (minus:QI (const_int 32) (match_dup 2)))))
12531    (clobber (reg:CC FLAGS_REG))])]
12532 "split_di (operands, 1, operands + 4, operands + 5);")
12533 
12534(define_insn "*rotlsi3_1_one_bit_rex64"
12535  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12536	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12537		   (match_operand:QI 2 "const1_operand" "")))
12538   (clobber (reg:CC FLAGS_REG))]
12539  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12540   && (TARGET_SHIFT1 || optimize_size)"
12541  "rol{q}\t%0"
12542  [(set_attr "type" "rotate")
12543   (set (attr "length") 
12544     (if_then_else (match_operand:DI 0 "register_operand" "") 
12545	(const_string "2")
12546	(const_string "*")))])
12547
12548(define_insn "*rotldi3_1_rex64"
12549  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12550	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12551		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12552   (clobber (reg:CC FLAGS_REG))]
12553  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12554  "@
12555   rol{q}\t{%2, %0|%0, %2}
12556   rol{q}\t{%b2, %0|%0, %b2}"
12557  [(set_attr "type" "rotate")
12558   (set_attr "mode" "DI")])
12559
12560(define_expand "rotlsi3"
12561  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12562	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12563		   (match_operand:QI 2 "nonmemory_operand" "")))
12564   (clobber (reg:CC FLAGS_REG))]
12565  ""
12566  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12567
12568(define_insn "*rotlsi3_1_one_bit"
12569  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12570	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12571		   (match_operand:QI 2 "const1_operand" "")))
12572   (clobber (reg:CC FLAGS_REG))]
12573  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12574   && (TARGET_SHIFT1 || optimize_size)"
12575  "rol{l}\t%0"
12576  [(set_attr "type" "rotate")
12577   (set (attr "length") 
12578     (if_then_else (match_operand:SI 0 "register_operand" "") 
12579	(const_string "2")
12580	(const_string "*")))])
12581
12582(define_insn "*rotlsi3_1_one_bit_zext"
12583  [(set (match_operand:DI 0 "register_operand" "=r")
12584	(zero_extend:DI
12585	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12586		     (match_operand:QI 2 "const1_operand" ""))))
12587   (clobber (reg:CC FLAGS_REG))]
12588  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12589   && (TARGET_SHIFT1 || optimize_size)"
12590  "rol{l}\t%k0"
12591  [(set_attr "type" "rotate")
12592   (set_attr "length" "2")])
12593
12594(define_insn "*rotlsi3_1"
12595  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12596	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12597		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12598   (clobber (reg:CC FLAGS_REG))]
12599  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12600  "@
12601   rol{l}\t{%2, %0|%0, %2}
12602   rol{l}\t{%b2, %0|%0, %b2}"
12603  [(set_attr "type" "rotate")
12604   (set_attr "mode" "SI")])
12605
12606(define_insn "*rotlsi3_1_zext"
12607  [(set (match_operand:DI 0 "register_operand" "=r,r")
12608	(zero_extend:DI
12609	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12610		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12611   (clobber (reg:CC FLAGS_REG))]
12612  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12613  "@
12614   rol{l}\t{%2, %k0|%k0, %2}
12615   rol{l}\t{%b2, %k0|%k0, %b2}"
12616  [(set_attr "type" "rotate")
12617   (set_attr "mode" "SI")])
12618
12619(define_expand "rotlhi3"
12620  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12621	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12622		   (match_operand:QI 2 "nonmemory_operand" "")))
12623   (clobber (reg:CC FLAGS_REG))]
12624  "TARGET_HIMODE_MATH"
12625  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12626
12627(define_insn "*rotlhi3_1_one_bit"
12628  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12629	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12630		   (match_operand:QI 2 "const1_operand" "")))
12631   (clobber (reg:CC FLAGS_REG))]
12632  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12633   && (TARGET_SHIFT1 || optimize_size)"
12634  "rol{w}\t%0"
12635  [(set_attr "type" "rotate")
12636   (set (attr "length") 
12637     (if_then_else (match_operand 0 "register_operand" "") 
12638	(const_string "2")
12639	(const_string "*")))])
12640
12641(define_insn "*rotlhi3_1"
12642  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12643	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12644		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12645   (clobber (reg:CC FLAGS_REG))]
12646  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12647  "@
12648   rol{w}\t{%2, %0|%0, %2}
12649   rol{w}\t{%b2, %0|%0, %b2}"
12650  [(set_attr "type" "rotate")
12651   (set_attr "mode" "HI")])
12652
12653(define_expand "rotlqi3"
12654  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12655	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12656		   (match_operand:QI 2 "nonmemory_operand" "")))
12657   (clobber (reg:CC FLAGS_REG))]
12658  "TARGET_QIMODE_MATH"
12659  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12660
12661(define_insn "*rotlqi3_1_one_bit_slp"
12662  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12663	(rotate:QI (match_dup 0)
12664		   (match_operand:QI 1 "const1_operand" "")))
12665   (clobber (reg:CC FLAGS_REG))]
12666  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12667   && (TARGET_SHIFT1 || optimize_size)"
12668  "rol{b}\t%0"
12669  [(set_attr "type" "rotate1")
12670   (set (attr "length") 
12671     (if_then_else (match_operand 0 "register_operand" "") 
12672	(const_string "2")
12673	(const_string "*")))])
12674
12675(define_insn "*rotlqi3_1_one_bit"
12676  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12677	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12678		   (match_operand:QI 2 "const1_operand" "")))
12679   (clobber (reg:CC FLAGS_REG))]
12680  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12681   && (TARGET_SHIFT1 || optimize_size)"
12682  "rol{b}\t%0"
12683  [(set_attr "type" "rotate")
12684   (set (attr "length") 
12685     (if_then_else (match_operand 0 "register_operand" "") 
12686	(const_string "2")
12687	(const_string "*")))])
12688
12689(define_insn "*rotlqi3_1_slp"
12690  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12691	(rotate:QI (match_dup 0)
12692		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12693   (clobber (reg:CC FLAGS_REG))]
12694  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12695   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12696  "@
12697   rol{b}\t{%1, %0|%0, %1}
12698   rol{b}\t{%b1, %0|%0, %b1}"
12699  [(set_attr "type" "rotate1")
12700   (set_attr "mode" "QI")])
12701
12702(define_insn "*rotlqi3_1"
12703  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12704	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12705		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12706   (clobber (reg:CC FLAGS_REG))]
12707  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12708  "@
12709   rol{b}\t{%2, %0|%0, %2}
12710   rol{b}\t{%b2, %0|%0, %b2}"
12711  [(set_attr "type" "rotate")
12712   (set_attr "mode" "QI")])
12713
12714(define_expand "rotrdi3"
12715  [(set (match_operand:DI 0 "shiftdi_operand" "")
12716	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12717		   (match_operand:QI 2 "nonmemory_operand" "")))
12718   (clobber (reg:CC FLAGS_REG))]
12719 ""
12720{
12721  if (TARGET_64BIT)
12722    {
12723      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12724      DONE;
12725    }
12726  if (!const_1_to_31_operand (operands[2], VOIDmode))
12727    FAIL;
12728  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12729  DONE;
12730})
12731  
12732;; Implement rotation using two double-precision shift instructions
12733;; and a scratch register.   
12734(define_insn_and_split "ix86_rotrdi3"
12735 [(set (match_operand:DI 0 "register_operand" "=r")
12736       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12737                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12738  (clobber (reg:CC FLAGS_REG))
12739  (clobber (match_scratch:SI 3 "=&r"))]
12740 "!TARGET_64BIT"
12741 ""
12742 "&& reload_completed"
12743 [(set (match_dup 3) (match_dup 4))
12744  (parallel
12745   [(set (match_dup 4)
12746         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12747                 (ashift:SI (match_dup 5)
12748                            (minus:QI (const_int 32) (match_dup 2)))))
12749    (clobber (reg:CC FLAGS_REG))])
12750  (parallel
12751   [(set (match_dup 5)
12752         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12753                 (ashift:SI (match_dup 3)
12754                            (minus:QI (const_int 32) (match_dup 2)))))
12755    (clobber (reg:CC FLAGS_REG))])]
12756 "split_di (operands, 1, operands + 4, operands + 5);")
12757
12758(define_insn "*rotrdi3_1_one_bit_rex64"
12759  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12760	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12761		     (match_operand:QI 2 "const1_operand" "")))
12762   (clobber (reg:CC FLAGS_REG))]
12763  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12764   && (TARGET_SHIFT1 || optimize_size)"
12765  "ror{q}\t%0"
12766  [(set_attr "type" "rotate")
12767   (set (attr "length") 
12768     (if_then_else (match_operand:DI 0 "register_operand" "") 
12769	(const_string "2")
12770	(const_string "*")))])
12771
12772(define_insn "*rotrdi3_1_rex64"
12773  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12774	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12775		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12776   (clobber (reg:CC FLAGS_REG))]
12777  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12778  "@
12779   ror{q}\t{%2, %0|%0, %2}
12780   ror{q}\t{%b2, %0|%0, %b2}"
12781  [(set_attr "type" "rotate")
12782   (set_attr "mode" "DI")])
12783
12784(define_expand "rotrsi3"
12785  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12786	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12787		     (match_operand:QI 2 "nonmemory_operand" "")))
12788   (clobber (reg:CC FLAGS_REG))]
12789  ""
12790  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12791
12792(define_insn "*rotrsi3_1_one_bit"
12793  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12794	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12795		     (match_operand:QI 2 "const1_operand" "")))
12796   (clobber (reg:CC FLAGS_REG))]
12797  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12798   && (TARGET_SHIFT1 || optimize_size)"
12799  "ror{l}\t%0"
12800  [(set_attr "type" "rotate")
12801   (set (attr "length") 
12802     (if_then_else (match_operand:SI 0 "register_operand" "") 
12803	(const_string "2")
12804	(const_string "*")))])
12805
12806(define_insn "*rotrsi3_1_one_bit_zext"
12807  [(set (match_operand:DI 0 "register_operand" "=r")
12808	(zero_extend:DI
12809	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12810		       (match_operand:QI 2 "const1_operand" ""))))
12811   (clobber (reg:CC FLAGS_REG))]
12812  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12813   && (TARGET_SHIFT1 || optimize_size)"
12814  "ror{l}\t%k0"
12815  [(set_attr "type" "rotate")
12816   (set (attr "length") 
12817     (if_then_else (match_operand:SI 0 "register_operand" "") 
12818	(const_string "2")
12819	(const_string "*")))])
12820
12821(define_insn "*rotrsi3_1"
12822  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12823	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12824		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12825   (clobber (reg:CC FLAGS_REG))]
12826  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12827  "@
12828   ror{l}\t{%2, %0|%0, %2}
12829   ror{l}\t{%b2, %0|%0, %b2}"
12830  [(set_attr "type" "rotate")
12831   (set_attr "mode" "SI")])
12832
12833(define_insn "*rotrsi3_1_zext"
12834  [(set (match_operand:DI 0 "register_operand" "=r,r")
12835	(zero_extend:DI
12836	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12837		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12838   (clobber (reg:CC FLAGS_REG))]
12839  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12840  "@
12841   ror{l}\t{%2, %k0|%k0, %2}
12842   ror{l}\t{%b2, %k0|%k0, %b2}"
12843  [(set_attr "type" "rotate")
12844   (set_attr "mode" "SI")])
12845
12846(define_expand "rotrhi3"
12847  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12848	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12849		     (match_operand:QI 2 "nonmemory_operand" "")))
12850   (clobber (reg:CC FLAGS_REG))]
12851  "TARGET_HIMODE_MATH"
12852  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12853
12854(define_insn "*rotrhi3_one_bit"
12855  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12856	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12857		     (match_operand:QI 2 "const1_operand" "")))
12858   (clobber (reg:CC FLAGS_REG))]
12859  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12860   && (TARGET_SHIFT1 || optimize_size)"
12861  "ror{w}\t%0"
12862  [(set_attr "type" "rotate")
12863   (set (attr "length") 
12864     (if_then_else (match_operand 0 "register_operand" "") 
12865	(const_string "2")
12866	(const_string "*")))])
12867
12868(define_insn "*rotrhi3"
12869  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12870	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12871		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12872   (clobber (reg:CC FLAGS_REG))]
12873  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12874  "@
12875   ror{w}\t{%2, %0|%0, %2}
12876   ror{w}\t{%b2, %0|%0, %b2}"
12877  [(set_attr "type" "rotate")
12878   (set_attr "mode" "HI")])
12879
12880(define_expand "rotrqi3"
12881  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12882	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12883		     (match_operand:QI 2 "nonmemory_operand" "")))
12884   (clobber (reg:CC FLAGS_REG))]
12885  "TARGET_QIMODE_MATH"
12886  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12887
12888(define_insn "*rotrqi3_1_one_bit"
12889  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12890	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12891		     (match_operand:QI 2 "const1_operand" "")))
12892   (clobber (reg:CC FLAGS_REG))]
12893  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12894   && (TARGET_SHIFT1 || optimize_size)"
12895  "ror{b}\t%0"
12896  [(set_attr "type" "rotate")
12897   (set (attr "length") 
12898     (if_then_else (match_operand 0 "register_operand" "") 
12899	(const_string "2")
12900	(const_string "*")))])
12901
12902(define_insn "*rotrqi3_1_one_bit_slp"
12903  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12904	(rotatert:QI (match_dup 0)
12905		     (match_operand:QI 1 "const1_operand" "")))
12906   (clobber (reg:CC FLAGS_REG))]
12907  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12908   && (TARGET_SHIFT1 || optimize_size)"
12909  "ror{b}\t%0"
12910  [(set_attr "type" "rotate1")
12911   (set (attr "length") 
12912     (if_then_else (match_operand 0 "register_operand" "") 
12913	(const_string "2")
12914	(const_string "*")))])
12915
12916(define_insn "*rotrqi3_1"
12917  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12918	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12919		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12920   (clobber (reg:CC FLAGS_REG))]
12921  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12922  "@
12923   ror{b}\t{%2, %0|%0, %2}
12924   ror{b}\t{%b2, %0|%0, %b2}"
12925  [(set_attr "type" "rotate")
12926   (set_attr "mode" "QI")])
12927
12928(define_insn "*rotrqi3_1_slp"
12929  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12930	(rotatert:QI (match_dup 0)
12931		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12932   (clobber (reg:CC FLAGS_REG))]
12933  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12934   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12935  "@
12936   ror{b}\t{%1, %0|%0, %1}
12937   ror{b}\t{%b1, %0|%0, %b1}"
12938  [(set_attr "type" "rotate1")
12939   (set_attr "mode" "QI")])
12940
12941;; Bit set / bit test instructions
12942
12943(define_expand "extv"
12944  [(set (match_operand:SI 0 "register_operand" "")
12945	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
12946			 (match_operand:SI 2 "const8_operand" "")
12947			 (match_operand:SI 3 "const8_operand" "")))]
12948  ""
12949{
12950  /* Handle extractions from %ah et al.  */
12951  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12952    FAIL;
12953
12954  /* From mips.md: extract_bit_field doesn't verify that our source
12955     matches the predicate, so check it again here.  */
12956  if (! ext_register_operand (operands[1], VOIDmode))
12957    FAIL;
12958})
12959
12960(define_expand "extzv"
12961  [(set (match_operand:SI 0 "register_operand" "")
12962	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
12963			 (match_operand:SI 2 "const8_operand" "")
12964			 (match_operand:SI 3 "const8_operand" "")))]
12965  ""
12966{
12967  /* Handle extractions from %ah et al.  */
12968  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12969    FAIL;
12970
12971  /* From mips.md: extract_bit_field doesn't verify that our source
12972     matches the predicate, so check it again here.  */
12973  if (! ext_register_operand (operands[1], VOIDmode))
12974    FAIL;
12975})
12976
12977(define_expand "insv"
12978  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12979		      (match_operand 1 "const8_operand" "")
12980		      (match_operand 2 "const8_operand" ""))
12981        (match_operand 3 "register_operand" ""))]
12982  ""
12983{
12984  /* Handle insertions to %ah et al.  */
12985  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12986    FAIL;
12987
12988  /* From mips.md: insert_bit_field doesn't verify that our source
12989     matches the predicate, so check it again here.  */
12990  if (! ext_register_operand (operands[0], VOIDmode))
12991    FAIL;
12992
12993  if (TARGET_64BIT)
12994    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12995  else
12996    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12997
12998  DONE;
12999})
13000
13001;; %%% bts, btr, btc, bt.
13002;; In general these instructions are *slow* when applied to memory,
13003;; since they enforce atomic operation.  When applied to registers,
13004;; it depends on the cpu implementation.  They're never faster than
13005;; the corresponding and/ior/xor operations, so with 32-bit there's
13006;; no point.  But in 64-bit, we can't hold the relevant immediates
13007;; within the instruction itself, so operating on bits in the high
13008;; 32-bits of a register becomes easier.
13009;;
13010;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13011;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13012;; negdf respectively, so they can never be disabled entirely.
13013
13014(define_insn "*btsq"
13015  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13016			 (const_int 1)
13017			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13018	(const_int 1))
13019   (clobber (reg:CC FLAGS_REG))]
13020  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13021  "bts{q} %1,%0"
13022  [(set_attr "type" "alu1")])
13023
13024(define_insn "*btrq"
13025  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13026			 (const_int 1)
13027			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13028	(const_int 0))
13029   (clobber (reg:CC FLAGS_REG))]
13030  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13031  "btr{q} %1,%0"
13032  [(set_attr "type" "alu1")])
13033
13034(define_insn "*btcq"
13035  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13036			 (const_int 1)
13037			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13038	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13039   (clobber (reg:CC FLAGS_REG))]
13040  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13041  "btc{q} %1,%0"
13042  [(set_attr "type" "alu1")])
13043
13044;; Allow Nocona to avoid these instructions if a register is available.
13045
13046(define_peephole2
13047  [(match_scratch:DI 2 "r")
13048   (parallel [(set (zero_extract:DI
13049		     (match_operand:DI 0 "register_operand" "")
13050		     (const_int 1)
13051		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13052		   (const_int 1))
13053	      (clobber (reg:CC FLAGS_REG))])]
13054  "TARGET_64BIT && !TARGET_USE_BT"
13055  [(const_int 0)]
13056{
13057  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13058  rtx op1;
13059
13060  if (HOST_BITS_PER_WIDE_INT >= 64)
13061    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13062  else if (i < HOST_BITS_PER_WIDE_INT)
13063    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13064  else
13065    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13066
13067  op1 = immed_double_const (lo, hi, DImode);
13068  if (i >= 31)
13069    {
13070      emit_move_insn (operands[2], op1);
13071      op1 = operands[2];
13072    }
13073
13074  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13075  DONE;
13076})
13077
13078(define_peephole2
13079  [(match_scratch:DI 2 "r")
13080   (parallel [(set (zero_extract:DI
13081		     (match_operand:DI 0 "register_operand" "")
13082		     (const_int 1)
13083		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13084		   (const_int 0))
13085	      (clobber (reg:CC FLAGS_REG))])]
13086  "TARGET_64BIT && !TARGET_USE_BT"
13087  [(const_int 0)]
13088{
13089  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13090  rtx op1;
13091
13092  if (HOST_BITS_PER_WIDE_INT >= 64)
13093    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13094  else if (i < HOST_BITS_PER_WIDE_INT)
13095    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13096  else
13097    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13098
13099  op1 = immed_double_const (~lo, ~hi, DImode);
13100  if (i >= 32)
13101    {
13102      emit_move_insn (operands[2], op1);
13103      op1 = operands[2];
13104    }
13105
13106  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13107  DONE;
13108})
13109
13110(define_peephole2
13111  [(match_scratch:DI 2 "r")
13112   (parallel [(set (zero_extract:DI
13113		     (match_operand:DI 0 "register_operand" "")
13114		     (const_int 1)
13115		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13116	      (not:DI (zero_extract:DI
13117			(match_dup 0) (const_int 1) (match_dup 1))))
13118	      (clobber (reg:CC FLAGS_REG))])]
13119  "TARGET_64BIT && !TARGET_USE_BT"
13120  [(const_int 0)]
13121{
13122  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13123  rtx op1;
13124
13125  if (HOST_BITS_PER_WIDE_INT >= 64)
13126    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13127  else if (i < HOST_BITS_PER_WIDE_INT)
13128    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13129  else
13130    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13131
13132  op1 = immed_double_const (lo, hi, DImode);
13133  if (i >= 31)
13134    {
13135      emit_move_insn (operands[2], op1);
13136      op1 = operands[2];
13137    }
13138
13139  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13140  DONE;
13141})
13142
13143;; Store-flag instructions.
13144
13145;; For all sCOND expanders, also expand the compare or test insn that
13146;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13147
13148;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13149;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13150;; way, which can later delete the movzx if only QImode is needed.
13151
13152(define_expand "seq"
13153  [(set (match_operand:QI 0 "register_operand" "")
13154        (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13155  ""
13156  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13157
13158(define_expand "sne"
13159  [(set (match_operand:QI 0 "register_operand" "")
13160        (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13161  ""
13162  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13163
13164(define_expand "sgt"
13165  [(set (match_operand:QI 0 "register_operand" "")
13166        (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13167  ""
13168  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13169
13170(define_expand "sgtu"
13171  [(set (match_operand:QI 0 "register_operand" "")
13172        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13173  ""
13174  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13175
13176(define_expand "slt"
13177  [(set (match_operand:QI 0 "register_operand" "")
13178        (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13179  ""
13180  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13181
13182(define_expand "sltu"
13183  [(set (match_operand:QI 0 "register_operand" "")
13184        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13185  ""
13186  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13187
13188(define_expand "sge"
13189  [(set (match_operand:QI 0 "register_operand" "")
13190        (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13191  ""
13192  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13193
13194(define_expand "sgeu"
13195  [(set (match_operand:QI 0 "register_operand" "")
13196        (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13197  ""
13198  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13199
13200(define_expand "sle"
13201  [(set (match_operand:QI 0 "register_operand" "")
13202        (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13203  ""
13204  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13205
13206(define_expand "sleu"
13207  [(set (match_operand:QI 0 "register_operand" "")
13208        (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209  ""
13210  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13211
13212(define_expand "sunordered"
13213  [(set (match_operand:QI 0 "register_operand" "")
13214        (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215  "TARGET_80387 || TARGET_SSE"
13216  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13217
13218(define_expand "sordered"
13219  [(set (match_operand:QI 0 "register_operand" "")
13220        (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221  "TARGET_80387"
13222  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13223
13224(define_expand "suneq"
13225  [(set (match_operand:QI 0 "register_operand" "")
13226        (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227  "TARGET_80387 || TARGET_SSE"
13228  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13229
13230(define_expand "sunge"
13231  [(set (match_operand:QI 0 "register_operand" "")
13232        (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233  "TARGET_80387 || TARGET_SSE"
13234  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13235
13236(define_expand "sungt"
13237  [(set (match_operand:QI 0 "register_operand" "")
13238        (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239  "TARGET_80387 || TARGET_SSE"
13240  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13241
13242(define_expand "sunle"
13243  [(set (match_operand:QI 0 "register_operand" "")
13244        (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245  "TARGET_80387 || TARGET_SSE"
13246  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13247
13248(define_expand "sunlt"
13249  [(set (match_operand:QI 0 "register_operand" "")
13250        (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251  "TARGET_80387 || TARGET_SSE"
13252  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13253
13254(define_expand "sltgt"
13255  [(set (match_operand:QI 0 "register_operand" "")
13256        (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257  "TARGET_80387 || TARGET_SSE"
13258  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13259
13260(define_insn "*setcc_1"
13261  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13262	(match_operator:QI 1 "ix86_comparison_operator"
13263	  [(reg FLAGS_REG) (const_int 0)]))]
13264  ""
13265  "set%C1\t%0"
13266  [(set_attr "type" "setcc")
13267   (set_attr "mode" "QI")])
13268
13269(define_insn "*setcc_2"
13270  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13271	(match_operator:QI 1 "ix86_comparison_operator"
13272	  [(reg FLAGS_REG) (const_int 0)]))]
13273  ""
13274  "set%C1\t%0"
13275  [(set_attr "type" "setcc")
13276   (set_attr "mode" "QI")])
13277
13278;; In general it is not safe to assume too much about CCmode registers,
13279;; so simplify-rtx stops when it sees a second one.  Under certain 
13280;; conditions this is safe on x86, so help combine not create
13281;;
13282;;	seta	%al
13283;;	testb	%al, %al
13284;;	sete	%al
13285
13286(define_split 
13287  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13288	(ne:QI (match_operator 1 "ix86_comparison_operator"
13289	         [(reg FLAGS_REG) (const_int 0)])
13290	    (const_int 0)))]
13291  ""
13292  [(set (match_dup 0) (match_dup 1))]
13293{
13294  PUT_MODE (operands[1], QImode);
13295})
13296
13297(define_split 
13298  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13299	(ne:QI (match_operator 1 "ix86_comparison_operator"
13300	         [(reg FLAGS_REG) (const_int 0)])
13301	    (const_int 0)))]
13302  ""
13303  [(set (match_dup 0) (match_dup 1))]
13304{
13305  PUT_MODE (operands[1], QImode);
13306})
13307
13308(define_split 
13309  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13310	(eq:QI (match_operator 1 "ix86_comparison_operator"
13311	         [(reg FLAGS_REG) (const_int 0)])
13312	    (const_int 0)))]
13313  ""
13314  [(set (match_dup 0) (match_dup 1))]
13315{
13316  rtx new_op1 = copy_rtx (operands[1]);
13317  operands[1] = new_op1;
13318  PUT_MODE (new_op1, QImode);
13319  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13320					     GET_MODE (XEXP (new_op1, 0))));
13321
13322  /* Make sure that (a) the CCmode we have for the flags is strong
13323     enough for the reversed compare or (b) we have a valid FP compare.  */
13324  if (! ix86_comparison_operator (new_op1, VOIDmode))
13325    FAIL;
13326})
13327
13328(define_split 
13329  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13330	(eq:QI (match_operator 1 "ix86_comparison_operator"
13331	         [(reg FLAGS_REG) (const_int 0)])
13332	    (const_int 0)))]
13333  ""
13334  [(set (match_dup 0) (match_dup 1))]
13335{
13336  rtx new_op1 = copy_rtx (operands[1]);
13337  operands[1] = new_op1;
13338  PUT_MODE (new_op1, QImode);
13339  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13340					     GET_MODE (XEXP (new_op1, 0))));
13341
13342  /* Make sure that (a) the CCmode we have for the flags is strong
13343     enough for the reversed compare or (b) we have a valid FP compare.  */
13344  if (! ix86_comparison_operator (new_op1, VOIDmode))
13345    FAIL;
13346})
13347
13348;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13349;; subsequent logical operations are used to imitate conditional moves.
13350;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13351;; it directly.
13352
13353(define_insn "*sse_setccsf"
13354  [(set (match_operand:SF 0 "register_operand" "=x")
13355	(match_operator:SF 1 "sse_comparison_operator"
13356	  [(match_operand:SF 2 "register_operand" "0")
13357	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13358  "TARGET_SSE"
13359  "cmp%D1ss\t{%3, %0|%0, %3}"
13360  [(set_attr "type" "ssecmp")
13361   (set_attr "mode" "SF")])
13362
13363(define_insn "*sse_setccdf"
13364  [(set (match_operand:DF 0 "register_operand" "=Y")
13365	(match_operator:DF 1 "sse_comparison_operator"
13366	  [(match_operand:DF 2 "register_operand" "0")
13367	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13368  "TARGET_SSE2"
13369  "cmp%D1sd\t{%3, %0|%0, %3}"
13370  [(set_attr "type" "ssecmp")
13371   (set_attr "mode" "DF")])
13372
13373;; Basic conditional jump instructions.
13374;; We ignore the overflow flag for signed branch instructions.
13375
13376;; For all bCOND expanders, also expand the compare or test insn that
13377;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13378
13379(define_expand "beq"
13380  [(set (pc)
13381	(if_then_else (match_dup 1)
13382		      (label_ref (match_operand 0 "" ""))
13383		      (pc)))]
13384  ""
13385  "ix86_expand_branch (EQ, operands[0]); DONE;")
13386
13387(define_expand "bne"
13388  [(set (pc)
13389	(if_then_else (match_dup 1)
13390		      (label_ref (match_operand 0 "" ""))
13391		      (pc)))]
13392  ""
13393  "ix86_expand_branch (NE, operands[0]); DONE;")
13394
13395(define_expand "bgt"
13396  [(set (pc)
13397	(if_then_else (match_dup 1)
13398		      (label_ref (match_operand 0 "" ""))
13399		      (pc)))]
13400  ""
13401  "ix86_expand_branch (GT, operands[0]); DONE;")
13402
13403(define_expand "bgtu"
13404  [(set (pc)
13405	(if_then_else (match_dup 1)
13406		      (label_ref (match_operand 0 "" ""))
13407		      (pc)))]
13408  ""
13409  "ix86_expand_branch (GTU, operands[0]); DONE;")
13410
13411(define_expand "blt"
13412  [(set (pc)
13413	(if_then_else (match_dup 1)
13414		      (label_ref (match_operand 0 "" ""))
13415		      (pc)))]
13416  ""
13417  "ix86_expand_branch (LT, operands[0]); DONE;")
13418
13419(define_expand "bltu"
13420  [(set (pc)
13421	(if_then_else (match_dup 1)
13422		      (label_ref (match_operand 0 "" ""))
13423		      (pc)))]
13424  ""
13425  "ix86_expand_branch (LTU, operands[0]); DONE;")
13426
13427(define_expand "bge"
13428  [(set (pc)
13429	(if_then_else (match_dup 1)
13430		      (label_ref (match_operand 0 "" ""))
13431		      (pc)))]
13432  ""
13433  "ix86_expand_branch (GE, operands[0]); DONE;")
13434
13435(define_expand "bgeu"
13436  [(set (pc)
13437	(if_then_else (match_dup 1)
13438		      (label_ref (match_operand 0 "" ""))
13439		      (pc)))]
13440  ""
13441  "ix86_expand_branch (GEU, operands[0]); DONE;")
13442
13443(define_expand "ble"
13444  [(set (pc)
13445	(if_then_else (match_dup 1)
13446		      (label_ref (match_operand 0 "" ""))
13447		      (pc)))]
13448  ""
13449  "ix86_expand_branch (LE, operands[0]); DONE;")
13450
13451(define_expand "bleu"
13452  [(set (pc)
13453	(if_then_else (match_dup 1)
13454		      (label_ref (match_operand 0 "" ""))
13455		      (pc)))]
13456  ""
13457  "ix86_expand_branch (LEU, operands[0]); DONE;")
13458
13459(define_expand "bunordered"
13460  [(set (pc)
13461	(if_then_else (match_dup 1)
13462		      (label_ref (match_operand 0 "" ""))
13463		      (pc)))]
13464  "TARGET_80387 || TARGET_SSE_MATH"
13465  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13466
13467(define_expand "bordered"
13468  [(set (pc)
13469	(if_then_else (match_dup 1)
13470		      (label_ref (match_operand 0 "" ""))
13471		      (pc)))]
13472  "TARGET_80387 || TARGET_SSE_MATH"
13473  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13474
13475(define_expand "buneq"
13476  [(set (pc)
13477	(if_then_else (match_dup 1)
13478		      (label_ref (match_operand 0 "" ""))
13479		      (pc)))]
13480  "TARGET_80387 || TARGET_SSE_MATH"
13481  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13482
13483(define_expand "bunge"
13484  [(set (pc)
13485	(if_then_else (match_dup 1)
13486		      (label_ref (match_operand 0 "" ""))
13487		      (pc)))]
13488  "TARGET_80387 || TARGET_SSE_MATH"
13489  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13490
13491(define_expand "bungt"
13492  [(set (pc)
13493	(if_then_else (match_dup 1)
13494		      (label_ref (match_operand 0 "" ""))
13495		      (pc)))]
13496  "TARGET_80387 || TARGET_SSE_MATH"
13497  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13498
13499(define_expand "bunle"
13500  [(set (pc)
13501	(if_then_else (match_dup 1)
13502		      (label_ref (match_operand 0 "" ""))
13503		      (pc)))]
13504  "TARGET_80387 || TARGET_SSE_MATH"
13505  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13506
13507(define_expand "bunlt"
13508  [(set (pc)
13509	(if_then_else (match_dup 1)
13510		      (label_ref (match_operand 0 "" ""))
13511		      (pc)))]
13512  "TARGET_80387 || TARGET_SSE_MATH"
13513  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13514
13515(define_expand "bltgt"
13516  [(set (pc)
13517	(if_then_else (match_dup 1)
13518		      (label_ref (match_operand 0 "" ""))
13519		      (pc)))]
13520  "TARGET_80387 || TARGET_SSE_MATH"
13521  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13522
13523(define_insn "*jcc_1"
13524  [(set (pc)
13525	(if_then_else (match_operator 1 "ix86_comparison_operator"
13526				      [(reg FLAGS_REG) (const_int 0)])
13527		      (label_ref (match_operand 0 "" ""))
13528		      (pc)))]
13529  ""
13530  "%+j%C1\t%l0"
13531  [(set_attr "type" "ibr")
13532   (set_attr "modrm" "0")
13533   (set (attr "length")
13534	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13535				  (const_int -126))
13536			      (lt (minus (match_dup 0) (pc))
13537				  (const_int 128)))
13538	     (const_int 2)
13539	     (const_int 6)))])
13540
13541(define_insn "*jcc_2"
13542  [(set (pc)
13543	(if_then_else (match_operator 1 "ix86_comparison_operator"
13544				      [(reg FLAGS_REG) (const_int 0)])
13545		      (pc)
13546		      (label_ref (match_operand 0 "" ""))))]
13547  ""
13548  "%+j%c1\t%l0"
13549  [(set_attr "type" "ibr")
13550   (set_attr "modrm" "0")
13551   (set (attr "length")
13552	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13553				  (const_int -126))
13554			      (lt (minus (match_dup 0) (pc))
13555				  (const_int 128)))
13556	     (const_int 2)
13557	     (const_int 6)))])
13558
13559;; In general it is not safe to assume too much about CCmode registers,
13560;; so simplify-rtx stops when it sees a second one.  Under certain 
13561;; conditions this is safe on x86, so help combine not create
13562;;
13563;;	seta	%al
13564;;	testb	%al, %al
13565;;	je	Lfoo
13566
13567(define_split 
13568  [(set (pc)
13569	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13570				      [(reg FLAGS_REG) (const_int 0)])
13571			  (const_int 0))
13572		      (label_ref (match_operand 1 "" ""))
13573		      (pc)))]
13574  ""
13575  [(set (pc)
13576	(if_then_else (match_dup 0)
13577		      (label_ref (match_dup 1))
13578		      (pc)))]
13579{
13580  PUT_MODE (operands[0], VOIDmode);
13581})
13582  
13583(define_split 
13584  [(set (pc)
13585	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13586				      [(reg FLAGS_REG) (const_int 0)])
13587			  (const_int 0))
13588		      (label_ref (match_operand 1 "" ""))
13589		      (pc)))]
13590  ""
13591  [(set (pc)
13592	(if_then_else (match_dup 0)
13593		      (label_ref (match_dup 1))
13594		      (pc)))]
13595{
13596  rtx new_op0 = copy_rtx (operands[0]);
13597  operands[0] = new_op0;
13598  PUT_MODE (new_op0, VOIDmode);
13599  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13600					     GET_MODE (XEXP (new_op0, 0))));
13601
13602  /* Make sure that (a) the CCmode we have for the flags is strong
13603     enough for the reversed compare or (b) we have a valid FP compare.  */
13604  if (! ix86_comparison_operator (new_op0, VOIDmode))
13605    FAIL;
13606})
13607
13608;; Define combination compare-and-branch fp compare instructions to use
13609;; during early optimization.  Splitting the operation apart early makes
13610;; for bad code when we want to reverse the operation.
13611
13612(define_insn "*fp_jcc_1_mixed"
13613  [(set (pc)
13614	(if_then_else (match_operator 0 "comparison_operator"
13615			[(match_operand 1 "register_operand" "f,x")
13616			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13617	  (label_ref (match_operand 3 "" ""))
13618	  (pc)))
13619   (clobber (reg:CCFP FPSR_REG))
13620   (clobber (reg:CCFP FLAGS_REG))]
13621  "TARGET_MIX_SSE_I387
13622   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13623   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13624   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13625  "#")
13626
13627(define_insn "*fp_jcc_1_sse"
13628  [(set (pc)
13629	(if_then_else (match_operator 0 "comparison_operator"
13630			[(match_operand 1 "register_operand" "x")
13631			 (match_operand 2 "nonimmediate_operand" "xm")])
13632	  (label_ref (match_operand 3 "" ""))
13633	  (pc)))
13634   (clobber (reg:CCFP FPSR_REG))
13635   (clobber (reg:CCFP FLAGS_REG))]
13636  "TARGET_SSE_MATH
13637   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13640  "#")
13641
13642(define_insn "*fp_jcc_1_387"
13643  [(set (pc)
13644	(if_then_else (match_operator 0 "comparison_operator"
13645			[(match_operand 1 "register_operand" "f")
13646			 (match_operand 2 "register_operand" "f")])
13647	  (label_ref (match_operand 3 "" ""))
13648	  (pc)))
13649   (clobber (reg:CCFP FPSR_REG))
13650   (clobber (reg:CCFP FLAGS_REG))]
13651  "TARGET_CMOVE && TARGET_80387
13652   && FLOAT_MODE_P (GET_MODE (operands[1]))
13653   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13654   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13655  "#")
13656
13657(define_insn "*fp_jcc_2_mixed"
13658  [(set (pc)
13659	(if_then_else (match_operator 0 "comparison_operator"
13660			[(match_operand 1 "register_operand" "f,x")
13661			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13662	  (pc)
13663	  (label_ref (match_operand 3 "" ""))))
13664   (clobber (reg:CCFP FPSR_REG))
13665   (clobber (reg:CCFP FLAGS_REG))]
13666  "TARGET_MIX_SSE_I387
13667   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13668   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13670  "#")
13671
13672(define_insn "*fp_jcc_2_sse"
13673  [(set (pc)
13674	(if_then_else (match_operator 0 "comparison_operator"
13675			[(match_operand 1 "register_operand" "x")
13676			 (match_operand 2 "nonimmediate_operand" "xm")])
13677	  (pc)
13678	  (label_ref (match_operand 3 "" ""))))
13679   (clobber (reg:CCFP FPSR_REG))
13680   (clobber (reg:CCFP FLAGS_REG))]
13681  "TARGET_SSE_MATH
13682   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13683   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13685  "#")
13686
13687(define_insn "*fp_jcc_2_387"
13688  [(set (pc)
13689	(if_then_else (match_operator 0 "comparison_operator"
13690			[(match_operand 1 "register_operand" "f")
13691			 (match_operand 2 "register_operand" "f")])
13692	  (pc)
13693	  (label_ref (match_operand 3 "" ""))))
13694   (clobber (reg:CCFP FPSR_REG))
13695   (clobber (reg:CCFP FLAGS_REG))]
13696  "TARGET_CMOVE && TARGET_80387
13697   && FLOAT_MODE_P (GET_MODE (operands[1]))
13698   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13699   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13700  "#")
13701
13702(define_insn "*fp_jcc_3_387"
13703  [(set (pc)
13704	(if_then_else (match_operator 0 "comparison_operator"
13705			[(match_operand 1 "register_operand" "f")
13706			 (match_operand 2 "nonimmediate_operand" "fm")])
13707	  (label_ref (match_operand 3 "" ""))
13708	  (pc)))
13709   (clobber (reg:CCFP FPSR_REG))
13710   (clobber (reg:CCFP FLAGS_REG))
13711   (clobber (match_scratch:HI 4 "=a"))]
13712  "TARGET_80387
13713   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13714   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13715   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13716   && SELECT_CC_MODE (GET_CODE (operands[0]),
13717		      operands[1], operands[2]) == CCFPmode
13718   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13719  "#")
13720
13721(define_insn "*fp_jcc_4_387"
13722  [(set (pc)
13723	(if_then_else (match_operator 0 "comparison_operator"
13724			[(match_operand 1 "register_operand" "f")
13725			 (match_operand 2 "nonimmediate_operand" "fm")])
13726	  (pc)
13727	  (label_ref (match_operand 3 "" ""))))
13728   (clobber (reg:CCFP FPSR_REG))
13729   (clobber (reg:CCFP FLAGS_REG))
13730   (clobber (match_scratch:HI 4 "=a"))]
13731  "TARGET_80387
13732   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13733   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13734   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13735   && SELECT_CC_MODE (GET_CODE (operands[0]),
13736		      operands[1], operands[2]) == CCFPmode
13737   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13738  "#")
13739
13740(define_insn "*fp_jcc_5_387"
13741  [(set (pc)
13742	(if_then_else (match_operator 0 "comparison_operator"
13743			[(match_operand 1 "register_operand" "f")
13744			 (match_operand 2 "register_operand" "f")])
13745	  (label_ref (match_operand 3 "" ""))
13746	  (pc)))
13747   (clobber (reg:CCFP FPSR_REG))
13748   (clobber (reg:CCFP FLAGS_REG))
13749   (clobber (match_scratch:HI 4 "=a"))]
13750  "TARGET_80387
13751   && FLOAT_MODE_P (GET_MODE (operands[1]))
13752   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13753   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13754  "#")
13755
13756(define_insn "*fp_jcc_6_387"
13757  [(set (pc)
13758	(if_then_else (match_operator 0 "comparison_operator"
13759			[(match_operand 1 "register_operand" "f")
13760			 (match_operand 2 "register_operand" "f")])
13761	  (pc)
13762	  (label_ref (match_operand 3 "" ""))))
13763   (clobber (reg:CCFP FPSR_REG))
13764   (clobber (reg:CCFP FLAGS_REG))
13765   (clobber (match_scratch:HI 4 "=a"))]
13766  "TARGET_80387
13767   && FLOAT_MODE_P (GET_MODE (operands[1]))
13768   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13769   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13770  "#")
13771
13772(define_insn "*fp_jcc_7_387"
13773  [(set (pc)
13774	(if_then_else (match_operator 0 "comparison_operator"
13775			[(match_operand 1 "register_operand" "f")
13776			 (match_operand 2 "const0_operand" "X")])
13777	  (label_ref (match_operand 3 "" ""))
13778	  (pc)))
13779   (clobber (reg:CCFP FPSR_REG))
13780   (clobber (reg:CCFP FLAGS_REG))
13781   (clobber (match_scratch:HI 4 "=a"))]
13782  "TARGET_80387
13783   && FLOAT_MODE_P (GET_MODE (operands[1]))
13784   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13785   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13786   && SELECT_CC_MODE (GET_CODE (operands[0]),
13787		      operands[1], operands[2]) == CCFPmode
13788   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13789  "#")
13790
13791;; The order of operands in *fp_jcc_8_387 is forced by combine in
13792;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13793;; with a precedence over other operators and is always put in the first
13794;; place. Swap condition and operands to match ficom instruction.
13795
13796(define_insn "*fp_jcc_8<mode>_387"
13797  [(set (pc)
13798	(if_then_else (match_operator 0 "comparison_operator"
13799			[(match_operator 1 "float_operator"
13800			   [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13801			   (match_operand 3 "register_operand" "f,f")])
13802	  (label_ref (match_operand 4 "" ""))
13803	  (pc)))
13804   (clobber (reg:CCFP FPSR_REG))
13805   (clobber (reg:CCFP FLAGS_REG))
13806   (clobber (match_scratch:HI 5 "=a,a"))]
13807  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13808   && FLOAT_MODE_P (GET_MODE (operands[3]))
13809   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13810   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13811   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13812   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13813  "#")
13814
13815(define_split
13816  [(set (pc)
13817	(if_then_else (match_operator 0 "comparison_operator"
13818			[(match_operand 1 "register_operand" "")
13819			 (match_operand 2 "nonimmediate_operand" "")])
13820	  (match_operand 3 "" "")
13821	  (match_operand 4 "" "")))
13822   (clobber (reg:CCFP FPSR_REG))
13823   (clobber (reg:CCFP FLAGS_REG))]
13824  "reload_completed"
13825  [(const_int 0)]
13826{
13827  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13828	                operands[3], operands[4], NULL_RTX, NULL_RTX);
13829  DONE;
13830})
13831
13832(define_split
13833  [(set (pc)
13834	(if_then_else (match_operator 0 "comparison_operator"
13835			[(match_operand 1 "register_operand" "")
13836			 (match_operand 2 "general_operand" "")])
13837	  (match_operand 3 "" "")
13838	  (match_operand 4 "" "")))
13839   (clobber (reg:CCFP FPSR_REG))
13840   (clobber (reg:CCFP FLAGS_REG))
13841   (clobber (match_scratch:HI 5 "=a"))]
13842  "reload_completed"
13843  [(const_int 0)]
13844{
13845  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13846	     		operands[3], operands[4], operands[5], NULL_RTX);
13847  DONE;
13848})
13849
13850(define_split
13851  [(set (pc)
13852	(if_then_else (match_operator 0 "comparison_operator"
13853			[(match_operator 1 "float_operator"
13854			   [(match_operand:X87MODEI12 2 "memory_operand" "")])
13855			   (match_operand 3 "register_operand" "")])
13856	  (match_operand 4 "" "")
13857	  (match_operand 5 "" "")))
13858   (clobber (reg:CCFP FPSR_REG))
13859   (clobber (reg:CCFP FLAGS_REG))
13860   (clobber (match_scratch:HI 6 "=a"))]
13861  "reload_completed"
13862  [(const_int 0)]
13863{
13864  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13865  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13866			operands[3], operands[7],
13867			operands[4], operands[5], operands[6], NULL_RTX);
13868  DONE;
13869})
13870
13871;; %%% Kill this when reload knows how to do it.
13872(define_split
13873  [(set (pc)
13874	(if_then_else (match_operator 0 "comparison_operator"
13875			[(match_operator 1 "float_operator"
13876			   [(match_operand:X87MODEI12 2 "register_operand" "")])
13877			   (match_operand 3 "register_operand" "")])
13878	  (match_operand 4 "" "")
13879	  (match_operand 5 "" "")))
13880   (clobber (reg:CCFP FPSR_REG))
13881   (clobber (reg:CCFP FLAGS_REG))
13882   (clobber (match_scratch:HI 6 "=a"))]
13883  "reload_completed"
13884  [(const_int 0)]
13885{
13886  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13887  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13888  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13889			operands[3], operands[7],
13890			operands[4], operands[5], operands[6], operands[2]);
13891  DONE;
13892})
13893
13894;; Unconditional and other jump instructions
13895
13896(define_insn "jump"
13897  [(set (pc)
13898	(label_ref (match_operand 0 "" "")))]
13899  ""
13900  "jmp\t%l0"
13901  [(set_attr "type" "ibr")
13902   (set (attr "length")
13903	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13904				  (const_int -126))
13905			      (lt (minus (match_dup 0) (pc))
13906				  (const_int 128)))
13907	     (const_int 2)
13908	     (const_int 5)))
13909   (set_attr "modrm" "0")])
13910
13911(define_expand "indirect_jump"
13912  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13913  ""
13914  "")
13915
13916(define_insn "*indirect_jump"
13917  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13918  "!TARGET_64BIT"
13919  "jmp\t%A0"
13920  [(set_attr "type" "ibr")
13921   (set_attr "length_immediate" "0")])
13922
13923(define_insn "*indirect_jump_rtx64"
13924  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13925  "TARGET_64BIT"
13926  "jmp\t%A0"
13927  [(set_attr "type" "ibr")
13928   (set_attr "length_immediate" "0")])
13929
13930(define_expand "tablejump"
13931  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13932	      (use (label_ref (match_operand 1 "" "")))])]
13933  ""
13934{
13935  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13936     relative.  Convert the relative address to an absolute address.  */
13937  if (flag_pic)
13938    {
13939      rtx op0, op1;
13940      enum rtx_code code;
13941
13942      if (TARGET_64BIT)
13943	{
13944	  code = PLUS;
13945	  op0 = operands[0];
13946	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13947	}
13948      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13949	{
13950	  code = PLUS;
13951	  op0 = operands[0];
13952	  op1 = pic_offset_table_rtx;
13953	}
13954      else
13955	{
13956	  code = MINUS;
13957	  op0 = pic_offset_table_rtx;
13958	  op1 = operands[0];
13959	}
13960
13961      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13962					 OPTAB_DIRECT);
13963    }
13964})
13965
13966(define_insn "*tablejump_1"
13967  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13968   (use (label_ref (match_operand 1 "" "")))]
13969  "!TARGET_64BIT"
13970  "jmp\t%A0"
13971  [(set_attr "type" "ibr")
13972   (set_attr "length_immediate" "0")])
13973
13974(define_insn "*tablejump_1_rtx64"
13975  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13976   (use (label_ref (match_operand 1 "" "")))]
13977  "TARGET_64BIT"
13978  "jmp\t%A0"
13979  [(set_attr "type" "ibr")
13980   (set_attr "length_immediate" "0")])
13981
13982;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13983
13984(define_peephole2
13985  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13986   (set (match_operand:QI 1 "register_operand" "")
13987	(match_operator:QI 2 "ix86_comparison_operator"
13988	  [(reg FLAGS_REG) (const_int 0)]))
13989   (set (match_operand 3 "q_regs_operand" "")
13990	(zero_extend (match_dup 1)))]
13991  "(peep2_reg_dead_p (3, operands[1])
13992    || operands_match_p (operands[1], operands[3]))
13993   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13994  [(set (match_dup 4) (match_dup 0))
13995   (set (strict_low_part (match_dup 5))
13996	(match_dup 2))]
13997{
13998  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13999  operands[5] = gen_lowpart (QImode, operands[3]);
14000  ix86_expand_clear (operands[3]);
14001})
14002
14003;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14004
14005(define_peephole2
14006  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14007   (set (match_operand:QI 1 "register_operand" "")
14008	(match_operator:QI 2 "ix86_comparison_operator"
14009	  [(reg FLAGS_REG) (const_int 0)]))
14010   (parallel [(set (match_operand 3 "q_regs_operand" "")
14011		   (zero_extend (match_dup 1)))
14012	      (clobber (reg:CC FLAGS_REG))])]
14013  "(peep2_reg_dead_p (3, operands[1])
14014    || operands_match_p (operands[1], operands[3]))
14015   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14016  [(set (match_dup 4) (match_dup 0))
14017   (set (strict_low_part (match_dup 5))
14018	(match_dup 2))]
14019{
14020  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14021  operands[5] = gen_lowpart (QImode, operands[3]);
14022  ix86_expand_clear (operands[3]);
14023})
14024
14025;; Call instructions.
14026
14027;; The predicates normally associated with named expanders are not properly
14028;; checked for calls.  This is a bug in the generic code, but it isn't that
14029;; easy to fix.  Ignore it for now and be prepared to fix things up.
14030
14031;; Call subroutine returning no value.
14032
14033(define_expand "call_pop"
14034  [(parallel [(call (match_operand:QI 0 "" "")
14035		    (match_operand:SI 1 "" ""))
14036	      (set (reg:SI SP_REG)
14037		   (plus:SI (reg:SI SP_REG)
14038			    (match_operand:SI 3 "" "")))])]
14039  "!TARGET_64BIT"
14040{
14041  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14042  DONE;
14043})
14044
14045(define_insn "*call_pop_0"
14046  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14047	 (match_operand:SI 1 "" ""))
14048   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14049			    (match_operand:SI 2 "immediate_operand" "")))]
14050  "!TARGET_64BIT"
14051{
14052  if (SIBLING_CALL_P (insn))
14053    return "jmp\t%P0";
14054  else
14055    return "call\t%P0";
14056}
14057  [(set_attr "type" "call")])
14058  
14059(define_insn "*call_pop_1"
14060  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14061	 (match_operand:SI 1 "" ""))
14062   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14063			    (match_operand:SI 2 "immediate_operand" "i")))]
14064  "!TARGET_64BIT"
14065{
14066  if (constant_call_address_operand (operands[0], Pmode))
14067    {
14068      if (SIBLING_CALL_P (insn))
14069	return "jmp\t%P0";
14070      else
14071	return "call\t%P0";
14072    }
14073  if (SIBLING_CALL_P (insn))
14074    return "jmp\t%A0";
14075  else
14076    return "call\t%A0";
14077}
14078  [(set_attr "type" "call")])
14079
14080(define_expand "call"
14081  [(call (match_operand:QI 0 "" "")
14082	 (match_operand 1 "" ""))
14083   (use (match_operand 2 "" ""))]
14084  ""
14085{
14086  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14087  DONE;
14088})
14089
14090(define_expand "sibcall"
14091  [(call (match_operand:QI 0 "" "")
14092	 (match_operand 1 "" ""))
14093   (use (match_operand 2 "" ""))]
14094  ""
14095{
14096  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14097  DONE;
14098})
14099
14100(define_insn "*call_0"
14101  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14102	 (match_operand 1 "" ""))]
14103  ""
14104{
14105  if (SIBLING_CALL_P (insn))
14106    return "jmp\t%P0";
14107  else
14108    return "call\t%P0";
14109}
14110  [(set_attr "type" "call")])
14111
14112(define_insn "*call_1"
14113  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14114	 (match_operand 1 "" ""))]
14115  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14116{
14117  if (constant_call_address_operand (operands[0], Pmode))
14118    return "call\t%P0";
14119  return "call\t%A0";
14120}
14121  [(set_attr "type" "call")])
14122
14123(define_insn "*sibcall_1"
14124  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14125	 (match_operand 1 "" ""))]
14126  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14127{
14128  if (constant_call_address_operand (operands[0], Pmode))
14129    return "jmp\t%P0";
14130  return "jmp\t%A0";
14131}
14132  [(set_attr "type" "call")])
14133
14134(define_insn "*call_1_rex64"
14135  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14136	 (match_operand 1 "" ""))]
14137  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14138{
14139  if (constant_call_address_operand (operands[0], Pmode))
14140    return "call\t%P0";
14141  return "call\t%A0";
14142}
14143  [(set_attr "type" "call")])
14144
14145(define_insn "*sibcall_1_rex64"
14146  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14147	 (match_operand 1 "" ""))]
14148  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14149  "jmp\t%P0"
14150  [(set_attr "type" "call")])
14151
14152(define_insn "*sibcall_1_rex64_v"
14153  [(call (mem:QI (reg:DI 40))
14154	 (match_operand 0 "" ""))]
14155  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14156  "jmp\t*%%r11"
14157  [(set_attr "type" "call")])
14158
14159
14160;; Call subroutine, returning value in operand 0
14161
14162(define_expand "call_value_pop"
14163  [(parallel [(set (match_operand 0 "" "")
14164		   (call (match_operand:QI 1 "" "")
14165			 (match_operand:SI 2 "" "")))
14166	      (set (reg:SI SP_REG)
14167		   (plus:SI (reg:SI SP_REG)
14168			    (match_operand:SI 4 "" "")))])]
14169  "!TARGET_64BIT"
14170{
14171  ix86_expand_call (operands[0], operands[1], operands[2],
14172		    operands[3], operands[4], 0);
14173  DONE;
14174})
14175
14176(define_expand "call_value"
14177  [(set (match_operand 0 "" "")
14178	(call (match_operand:QI 1 "" "")
14179	      (match_operand:SI 2 "" "")))
14180   (use (match_operand:SI 3 "" ""))]
14181  ;; Operand 2 not used on the i386.
14182  ""
14183{
14184  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14185  DONE;
14186})
14187
14188(define_expand "sibcall_value"
14189  [(set (match_operand 0 "" "")
14190	(call (match_operand:QI 1 "" "")
14191	      (match_operand:SI 2 "" "")))
14192   (use (match_operand:SI 3 "" ""))]
14193  ;; Operand 2 not used on the i386.
14194  ""
14195{
14196  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14197  DONE;
14198})
14199
14200;; Call subroutine returning any type.
14201
14202(define_expand "untyped_call"
14203  [(parallel [(call (match_operand 0 "" "")
14204		    (const_int 0))
14205	      (match_operand 1 "" "")
14206	      (match_operand 2 "" "")])]
14207  ""
14208{
14209  int i;
14210
14211  /* In order to give reg-stack an easier job in validating two
14212     coprocessor registers as containing a possible return value,
14213     simply pretend the untyped call returns a complex long double
14214     value.  */
14215
14216  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14217		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14218		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14219		    NULL, 0);
14220
14221  for (i = 0; i < XVECLEN (operands[2], 0); i++)
14222    {
14223      rtx set = XVECEXP (operands[2], 0, i);
14224      emit_move_insn (SET_DEST (set), SET_SRC (set));
14225    }
14226
14227  /* The optimizer does not know that the call sets the function value
14228     registers we stored in the result block.  We avoid problems by
14229     claiming that all hard registers are used and clobbered at this
14230     point.  */
14231  emit_insn (gen_blockage (const0_rtx));
14232
14233  DONE;
14234})
14235
14236;; Prologue and epilogue instructions
14237
14238;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14239;; all of memory.  This blocks insns from being moved across this point.
14240
14241(define_insn "blockage"
14242  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14243  ""
14244  ""
14245  [(set_attr "length" "0")])
14246
14247;; Insn emitted into the body of a function to return from a function.
14248;; This is only done if the function's epilogue is known to be simple.
14249;; See comments for ix86_can_use_return_insn_p in i386.c.
14250
14251(define_expand "return"
14252  [(return)]
14253  "ix86_can_use_return_insn_p ()"
14254{
14255  if (current_function_pops_args)
14256    {
14257      rtx popc = GEN_INT (current_function_pops_args);
14258      emit_jump_insn (gen_return_pop_internal (popc));
14259      DONE;
14260    }
14261})
14262
14263(define_insn "return_internal"
14264  [(return)]
14265  "reload_completed"
14266  "ret"
14267  [(set_attr "length" "1")
14268   (set_attr "length_immediate" "0")
14269   (set_attr "modrm" "0")])
14270
14271;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14272;; instruction Athlon and K8 have.
14273
14274(define_insn "return_internal_long"
14275  [(return)
14276   (unspec [(const_int 0)] UNSPEC_REP)]
14277  "reload_completed"
14278  "rep {;} ret"
14279  [(set_attr "length" "1")
14280   (set_attr "length_immediate" "0")
14281   (set_attr "prefix_rep" "1")
14282   (set_attr "modrm" "0")])
14283
14284(define_insn "return_pop_internal"
14285  [(return)
14286   (use (match_operand:SI 0 "const_int_operand" ""))]
14287  "reload_completed"
14288  "ret\t%0"
14289  [(set_attr "length" "3")
14290   (set_attr "length_immediate" "2")
14291   (set_attr "modrm" "0")])
14292
14293(define_insn "return_indirect_internal"
14294  [(return)
14295   (use (match_operand:SI 0 "register_operand" "r"))]
14296  "reload_completed"
14297  "jmp\t%A0"
14298  [(set_attr "type" "ibr")
14299   (set_attr "length_immediate" "0")])
14300
14301(define_insn "nop"
14302  [(const_int 0)]
14303  ""
14304  "nop"
14305  [(set_attr "length" "1")
14306   (set_attr "length_immediate" "0")
14307   (set_attr "modrm" "0")])
14308
14309;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14310;; branch prediction penalty for the third jump in a 16-byte
14311;; block on K8.
14312
14313(define_insn "align"
14314  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14315  ""
14316{
14317#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14318  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14319#else
14320  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14321     The align insn is used to avoid 3 jump instructions in the row to improve
14322     branch prediction and the benefits hardly outweigh the cost of extra 8
14323     nops on the average inserted by full alignment pseudo operation.  */
14324#endif
14325  return "";
14326}
14327  [(set_attr "length" "16")])
14328
14329(define_expand "prologue"
14330  [(const_int 1)]
14331  ""
14332  "ix86_expand_prologue (); DONE;")
14333
14334(define_insn "set_got"
14335  [(set (match_operand:SI 0 "register_operand" "=r")
14336	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14337   (clobber (reg:CC FLAGS_REG))]
14338  "!TARGET_64BIT"
14339  { return output_set_got (operands[0], NULL_RTX); }
14340  [(set_attr "type" "multi")
14341   (set_attr "length" "12")])
14342
14343(define_insn "set_got_labelled"
14344  [(set (match_operand:SI 0 "register_operand" "=r")
14345	(unspec:SI [(label_ref (match_operand 1 "" ""))]
14346	 UNSPEC_SET_GOT))
14347   (clobber (reg:CC FLAGS_REG))]
14348  "!TARGET_64BIT"
14349  { return output_set_got (operands[0], operands[1]); }
14350  [(set_attr "type" "multi")
14351   (set_attr "length" "12")])
14352
14353(define_insn "set_got_rex64"
14354  [(set (match_operand:DI 0 "register_operand" "=r")
14355	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14356  "TARGET_64BIT"
14357  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14358  [(set_attr "type" "lea")
14359   (set_attr "length" "6")])
14360
14361(define_expand "epilogue"
14362  [(const_int 1)]
14363  ""
14364  "ix86_expand_epilogue (1); DONE;")
14365
14366(define_expand "sibcall_epilogue"
14367  [(const_int 1)]
14368  ""
14369  "ix86_expand_epilogue (0); DONE;")
14370
14371(define_expand "eh_return"
14372  [(use (match_operand 0 "register_operand" ""))]
14373  ""
14374{
14375  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14376
14377  /* Tricky bit: we write the address of the handler to which we will
14378     be returning into someone else's stack frame, one word below the
14379     stack address we wish to restore.  */
14380  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14381  tmp = plus_constant (tmp, -UNITS_PER_WORD);
14382  tmp = gen_rtx_MEM (Pmode, tmp);
14383  emit_move_insn (tmp, ra);
14384
14385  if (Pmode == SImode)
14386    emit_jump_insn (gen_eh_return_si (sa));
14387  else
14388    emit_jump_insn (gen_eh_return_di (sa));
14389  emit_barrier ();
14390  DONE;
14391})
14392
14393(define_insn_and_split "eh_return_si"
14394  [(set (pc) 
14395        (unspec [(match_operand:SI 0 "register_operand" "c")]
14396	         UNSPEC_EH_RETURN))]
14397  "!TARGET_64BIT"
14398  "#"
14399  "reload_completed"
14400  [(const_int 1)]
14401  "ix86_expand_epilogue (2); DONE;")
14402
14403(define_insn_and_split "eh_return_di"
14404  [(set (pc) 
14405        (unspec [(match_operand:DI 0 "register_operand" "c")]
14406	         UNSPEC_EH_RETURN))]
14407  "TARGET_64BIT"
14408  "#"
14409  "reload_completed"
14410  [(const_int 1)]
14411  "ix86_expand_epilogue (2); DONE;")
14412
14413(define_insn "leave"
14414  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14415   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14416   (clobber (mem:BLK (scratch)))]
14417  "!TARGET_64BIT"
14418  "leave"
14419  [(set_attr "type" "leave")])
14420
14421(define_insn "leave_rex64"
14422  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14423   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14424   (clobber (mem:BLK (scratch)))]
14425  "TARGET_64BIT"
14426  "leave"
14427  [(set_attr "type" "leave")])
14428
14429(define_expand "ffssi2"
14430  [(parallel
14431     [(set (match_operand:SI 0 "register_operand" "") 
14432	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14433      (clobber (match_scratch:SI 2 ""))
14434      (clobber (reg:CC FLAGS_REG))])]
14435  ""
14436  "")
14437
14438(define_insn_and_split "*ffs_cmove"
14439  [(set (match_operand:SI 0 "register_operand" "=r") 
14440	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14441   (clobber (match_scratch:SI 2 "=&r"))
14442   (clobber (reg:CC FLAGS_REG))]
14443  "TARGET_CMOVE"
14444  "#"
14445  "&& reload_completed"
14446  [(set (match_dup 2) (const_int -1))
14447   (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14448	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14449   (set (match_dup 0) (if_then_else:SI
14450			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14451			(match_dup 2)
14452			(match_dup 0)))
14453   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14454	      (clobber (reg:CC FLAGS_REG))])]
14455  "")
14456
14457(define_insn_and_split "*ffs_no_cmove"
14458  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14459	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14460   (clobber (match_scratch:SI 2 "=&q"))
14461   (clobber (reg:CC FLAGS_REG))]
14462  ""
14463  "#"
14464  "reload_completed"
14465  [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14466	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14467   (set (strict_low_part (match_dup 3))
14468	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14469   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14470	      (clobber (reg:CC FLAGS_REG))])
14471   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14472	      (clobber (reg:CC FLAGS_REG))])
14473   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14474	      (clobber (reg:CC FLAGS_REG))])]
14475{
14476  operands[3] = gen_lowpart (QImode, operands[2]);
14477  ix86_expand_clear (operands[2]);
14478})
14479
14480(define_insn "*ffssi_1"
14481  [(set (reg:CCZ FLAGS_REG)
14482	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14483		     (const_int 0)))
14484   (set (match_operand:SI 0 "register_operand" "=r")
14485	(ctz:SI (match_dup 1)))]
14486  ""
14487  "bsf{l}\t{%1, %0|%0, %1}"
14488  [(set_attr "prefix_0f" "1")])
14489
14490(define_expand "ffsdi2"
14491  [(parallel
14492     [(set (match_operand:DI 0 "register_operand" "") 
14493	   (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14494      (clobber (match_scratch:DI 2 ""))
14495      (clobber (reg:CC FLAGS_REG))])]
14496  "TARGET_64BIT && TARGET_CMOVE"
14497  "")
14498
14499(define_insn_and_split "*ffs_rex64"
14500  [(set (match_operand:DI 0 "register_operand" "=r") 
14501	(ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14502   (clobber (match_scratch:DI 2 "=&r"))
14503   (clobber (reg:CC FLAGS_REG))]
14504  "TARGET_64BIT && TARGET_CMOVE"
14505  "#"
14506  "&& reload_completed"
14507  [(set (match_dup 2) (const_int -1))
14508   (parallel [(set (reg:CCZ FLAGS_REG)
14509		   (compare:CCZ (match_dup 1) (const_int 0)))
14510	      (set (match_dup 0) (ctz:DI (match_dup 1)))])
14511   (set (match_dup 0) (if_then_else:DI
14512			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14513			(match_dup 2)
14514			(match_dup 0)))
14515   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14516	      (clobber (reg:CC FLAGS_REG))])]
14517  "")
14518
14519(define_insn "*ffsdi_1"
14520  [(set (reg:CCZ FLAGS_REG)
14521	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14522		     (const_int 0)))
14523   (set (match_operand:DI 0 "register_operand" "=r")
14524	(ctz:DI (match_dup 1)))]
14525  "TARGET_64BIT"
14526  "bsf{q}\t{%1, %0|%0, %1}"
14527  [(set_attr "prefix_0f" "1")])
14528
14529(define_insn "ctzsi2"
14530  [(set (match_operand:SI 0 "register_operand" "=r")
14531	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14532   (clobber (reg:CC FLAGS_REG))]
14533  ""
14534  "bsf{l}\t{%1, %0|%0, %1}"
14535  [(set_attr "prefix_0f" "1")])
14536
14537(define_insn "ctzdi2"
14538  [(set (match_operand:DI 0 "register_operand" "=r")
14539	(ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14540   (clobber (reg:CC FLAGS_REG))]
14541  "TARGET_64BIT"
14542  "bsf{q}\t{%1, %0|%0, %1}"
14543  [(set_attr "prefix_0f" "1")])
14544
14545(define_expand "clzsi2"
14546  [(parallel
14547     [(set (match_operand:SI 0 "register_operand" "")
14548	   (minus:SI (const_int 31)
14549		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14550      (clobber (reg:CC FLAGS_REG))])
14551   (parallel
14552     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14553      (clobber (reg:CC FLAGS_REG))])]
14554  ""
14555  "")
14556
14557(define_insn "*bsr"
14558  [(set (match_operand:SI 0 "register_operand" "=r")
14559	(minus:SI (const_int 31)
14560		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14561   (clobber (reg:CC FLAGS_REG))]
14562  ""
14563  "bsr{l}\t{%1, %0|%0, %1}"
14564  [(set_attr "prefix_0f" "1")])
14565
14566(define_expand "clzdi2"
14567  [(parallel
14568     [(set (match_operand:DI 0 "register_operand" "")
14569	   (minus:DI (const_int 63)
14570		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14571      (clobber (reg:CC FLAGS_REG))])
14572   (parallel
14573     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14574      (clobber (reg:CC FLAGS_REG))])]
14575  "TARGET_64BIT"
14576  "")
14577
14578(define_insn "*bsr_rex64"
14579  [(set (match_operand:DI 0 "register_operand" "=r")
14580	(minus:DI (const_int 63)
14581		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14582   (clobber (reg:CC FLAGS_REG))]
14583  "TARGET_64BIT"
14584  "bsr{q}\t{%1, %0|%0, %1}"
14585  [(set_attr "prefix_0f" "1")])
14586
14587;; Thread-local storage patterns for ELF.
14588;;
14589;; Note that these code sequences must appear exactly as shown
14590;; in order to allow linker relaxation.
14591
14592(define_insn "*tls_global_dynamic_32_gnu"
14593  [(set (match_operand:SI 0 "register_operand" "=a")
14594	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14595		    (match_operand:SI 2 "tls_symbolic_operand" "")
14596		    (match_operand:SI 3 "call_insn_operand" "")]
14597		    UNSPEC_TLS_GD))
14598   (clobber (match_scratch:SI 4 "=d"))
14599   (clobber (match_scratch:SI 5 "=c"))
14600   (clobber (reg:CC FLAGS_REG))]
14601  "!TARGET_64BIT && TARGET_GNU_TLS"
14602  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14603  [(set_attr "type" "multi")
14604   (set_attr "length" "12")])
14605
14606(define_insn "*tls_global_dynamic_32_sun"
14607  [(set (match_operand:SI 0 "register_operand" "=a")
14608	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14609		    (match_operand:SI 2 "tls_symbolic_operand" "")
14610		    (match_operand:SI 3 "call_insn_operand" "")]
14611		    UNSPEC_TLS_GD))
14612   (clobber (match_scratch:SI 4 "=d"))
14613   (clobber (match_scratch:SI 5 "=c"))
14614   (clobber (reg:CC FLAGS_REG))]
14615  "!TARGET_64BIT && TARGET_SUN_TLS"
14616  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14617	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14618  [(set_attr "type" "multi")
14619   (set_attr "length" "14")])
14620
14621(define_expand "tls_global_dynamic_32"
14622  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14623		   (unspec:SI
14624		    [(match_dup 2)
14625		     (match_operand:SI 1 "tls_symbolic_operand" "")
14626		     (match_dup 3)]
14627		    UNSPEC_TLS_GD))
14628	      (clobber (match_scratch:SI 4 ""))
14629	      (clobber (match_scratch:SI 5 ""))
14630	      (clobber (reg:CC FLAGS_REG))])]
14631  ""
14632{
14633  if (flag_pic)
14634    operands[2] = pic_offset_table_rtx;
14635  else
14636    {
14637      operands[2] = gen_reg_rtx (Pmode);
14638      emit_insn (gen_set_got (operands[2]));
14639    }
14640  if (TARGET_GNU2_TLS)
14641    {
14642       emit_insn (gen_tls_dynamic_gnu2_32
14643		  (operands[0], operands[1], operands[2]));
14644       DONE;
14645    }
14646  operands[3] = ix86_tls_get_addr ();
14647})
14648
14649(define_insn "*tls_global_dynamic_64"
14650  [(set (match_operand:DI 0 "register_operand" "=a")
14651	(call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14652		 (match_operand:DI 3 "" "")))
14653   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14654	      UNSPEC_TLS_GD)]
14655  "TARGET_64BIT"
14656  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14657  [(set_attr "type" "multi")
14658   (set_attr "length" "16")])
14659
14660(define_expand "tls_global_dynamic_64"
14661  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14662		   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14663	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14664			 UNSPEC_TLS_GD)])]
14665  ""
14666{
14667  if (TARGET_GNU2_TLS)
14668    {
14669       emit_insn (gen_tls_dynamic_gnu2_64
14670		  (operands[0], operands[1]));
14671       DONE;
14672    }
14673  operands[2] = ix86_tls_get_addr ();
14674})
14675
14676(define_insn "*tls_local_dynamic_base_32_gnu"
14677  [(set (match_operand:SI 0 "register_operand" "=a")
14678	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14679                    (match_operand:SI 2 "call_insn_operand" "")]
14680		   UNSPEC_TLS_LD_BASE))
14681   (clobber (match_scratch:SI 3 "=d"))
14682   (clobber (match_scratch:SI 4 "=c"))
14683   (clobber (reg:CC FLAGS_REG))]
14684  "!TARGET_64BIT && TARGET_GNU_TLS"
14685  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14686  [(set_attr "type" "multi")
14687   (set_attr "length" "11")])
14688
14689(define_insn "*tls_local_dynamic_base_32_sun"
14690  [(set (match_operand:SI 0 "register_operand" "=a")
14691	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14692                    (match_operand:SI 2 "call_insn_operand" "")]
14693		   UNSPEC_TLS_LD_BASE))
14694   (clobber (match_scratch:SI 3 "=d"))
14695   (clobber (match_scratch:SI 4 "=c"))
14696   (clobber (reg:CC FLAGS_REG))]
14697  "!TARGET_64BIT && TARGET_SUN_TLS"
14698  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14699	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14700  [(set_attr "type" "multi")
14701   (set_attr "length" "13")])
14702
14703(define_expand "tls_local_dynamic_base_32"
14704  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14705		   (unspec:SI [(match_dup 1) (match_dup 2)]
14706			      UNSPEC_TLS_LD_BASE))
14707	      (clobber (match_scratch:SI 3 ""))
14708	      (clobber (match_scratch:SI 4 ""))
14709	      (clobber (reg:CC FLAGS_REG))])]
14710  ""
14711{
14712  if (flag_pic)
14713    operands[1] = pic_offset_table_rtx;
14714  else
14715    {
14716      operands[1] = gen_reg_rtx (Pmode);
14717      emit_insn (gen_set_got (operands[1]));
14718    }
14719  if (TARGET_GNU2_TLS)
14720    {
14721       emit_insn (gen_tls_dynamic_gnu2_32
14722		  (operands[0], ix86_tls_module_base (), operands[1]));
14723       DONE;
14724    }
14725  operands[2] = ix86_tls_get_addr ();
14726})
14727
14728(define_insn "*tls_local_dynamic_base_64"
14729  [(set (match_operand:DI 0 "register_operand" "=a")
14730	(call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14731		 (match_operand:DI 2 "" "")))
14732   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14733  "TARGET_64BIT"
14734  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14735  [(set_attr "type" "multi")
14736   (set_attr "length" "12")])
14737
14738(define_expand "tls_local_dynamic_base_64"
14739  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14740		   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14741	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14742  ""
14743{
14744  if (TARGET_GNU2_TLS)
14745    {
14746       emit_insn (gen_tls_dynamic_gnu2_64
14747		  (operands[0], ix86_tls_module_base ()));
14748       DONE;
14749    }
14750  operands[1] = ix86_tls_get_addr ();
14751})
14752
14753;; Local dynamic of a single variable is a lose.  Show combine how
14754;; to convert that back to global dynamic.
14755
14756(define_insn_and_split "*tls_local_dynamic_32_once"
14757  [(set (match_operand:SI 0 "register_operand" "=a")
14758	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14759			     (match_operand:SI 2 "call_insn_operand" "")]
14760			    UNSPEC_TLS_LD_BASE)
14761		 (const:SI (unspec:SI
14762			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
14763			    UNSPEC_DTPOFF))))
14764   (clobber (match_scratch:SI 4 "=d"))
14765   (clobber (match_scratch:SI 5 "=c"))
14766   (clobber (reg:CC FLAGS_REG))]
14767  ""
14768  "#"
14769  ""
14770  [(parallel [(set (match_dup 0)
14771		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14772			      UNSPEC_TLS_GD))
14773	      (clobber (match_dup 4))
14774	      (clobber (match_dup 5))
14775	      (clobber (reg:CC FLAGS_REG))])]
14776  "")
14777
14778;; Load and add the thread base pointer from %gs:0.
14779
14780(define_insn "*load_tp_si"
14781  [(set (match_operand:SI 0 "register_operand" "=r")
14782	(unspec:SI [(const_int 0)] UNSPEC_TP))]
14783  "!TARGET_64BIT"
14784  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14785  [(set_attr "type" "imov")
14786   (set_attr "modrm" "0")
14787   (set_attr "length" "7")
14788   (set_attr "memory" "load")
14789   (set_attr "imm_disp" "false")])
14790
14791(define_insn "*add_tp_si"
14792  [(set (match_operand:SI 0 "register_operand" "=r")
14793	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14794		 (match_operand:SI 1 "register_operand" "0")))
14795   (clobber (reg:CC FLAGS_REG))]
14796  "!TARGET_64BIT"
14797  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14798  [(set_attr "type" "alu")
14799   (set_attr "modrm" "0")
14800   (set_attr "length" "7")
14801   (set_attr "memory" "load")
14802   (set_attr "imm_disp" "false")])
14803
14804(define_insn "*load_tp_di"
14805  [(set (match_operand:DI 0 "register_operand" "=r")
14806	(unspec:DI [(const_int 0)] UNSPEC_TP))]
14807  "TARGET_64BIT"
14808  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14809  [(set_attr "type" "imov")
14810   (set_attr "modrm" "0")
14811   (set_attr "length" "7")
14812   (set_attr "memory" "load")
14813   (set_attr "imm_disp" "false")])
14814
14815(define_insn "*add_tp_di"
14816  [(set (match_operand:DI 0 "register_operand" "=r")
14817	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14818		 (match_operand:DI 1 "register_operand" "0")))
14819   (clobber (reg:CC FLAGS_REG))]
14820  "TARGET_64BIT"
14821  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14822  [(set_attr "type" "alu")
14823   (set_attr "modrm" "0")
14824   (set_attr "length" "7")
14825   (set_attr "memory" "load")
14826   (set_attr "imm_disp" "false")])
14827
14828;; GNU2 TLS patterns can be split.
14829
14830(define_expand "tls_dynamic_gnu2_32"
14831  [(set (match_dup 3)
14832	(plus:SI (match_operand:SI 2 "register_operand" "")
14833		 (const:SI
14834		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14835			     UNSPEC_TLSDESC))))
14836   (parallel
14837    [(set (match_operand:SI 0 "register_operand" "")
14838	  (unspec:SI [(match_dup 1) (match_dup 3)
14839		      (match_dup 2) (reg:SI SP_REG)]
14840		      UNSPEC_TLSDESC))
14841     (clobber (reg:CC FLAGS_REG))])]
14842  "!TARGET_64BIT && TARGET_GNU2_TLS"
14843{
14844  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14845  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14846})
14847
14848(define_insn "*tls_dynamic_lea_32"
14849  [(set (match_operand:SI 0 "register_operand" "=r")
14850	(plus:SI (match_operand:SI 1 "register_operand" "b")
14851		 (const:SI
14852		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14853			      UNSPEC_TLSDESC))))]
14854  "!TARGET_64BIT && TARGET_GNU2_TLS"
14855  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14856  [(set_attr "type" "lea")
14857   (set_attr "mode" "SI")
14858   (set_attr "length" "6")
14859   (set_attr "length_address" "4")])
14860
14861(define_insn "*tls_dynamic_call_32"
14862  [(set (match_operand:SI 0 "register_operand" "=a")
14863	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14864		    (match_operand:SI 2 "register_operand" "0")
14865		    ;; we have to make sure %ebx still points to the GOT
14866		    (match_operand:SI 3 "register_operand" "b")
14867		    (reg:SI SP_REG)]
14868		   UNSPEC_TLSDESC))
14869   (clobber (reg:CC FLAGS_REG))]
14870  "!TARGET_64BIT && TARGET_GNU2_TLS"
14871  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14872  [(set_attr "type" "call")
14873   (set_attr "length" "2")
14874   (set_attr "length_address" "0")])
14875
14876(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14877  [(set (match_operand:SI 0 "register_operand" "=&a")
14878	(plus:SI
14879	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14880		     (match_operand:SI 4 "" "")
14881		     (match_operand:SI 2 "register_operand" "b")
14882		     (reg:SI SP_REG)]
14883		    UNSPEC_TLSDESC)
14884	 (const:SI (unspec:SI
14885		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
14886		    UNSPEC_DTPOFF))))
14887   (clobber (reg:CC FLAGS_REG))]
14888  "!TARGET_64BIT && TARGET_GNU2_TLS"
14889  "#"
14890  ""
14891  [(set (match_dup 0) (match_dup 5))]
14892{
14893  operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14894  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14895})
14896
14897(define_expand "tls_dynamic_gnu2_64"
14898  [(set (match_dup 2)
14899	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14900		   UNSPEC_TLSDESC))
14901   (parallel
14902    [(set (match_operand:DI 0 "register_operand" "")
14903	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14904		     UNSPEC_TLSDESC))
14905     (clobber (reg:CC FLAGS_REG))])]
14906  "TARGET_64BIT && TARGET_GNU2_TLS"
14907{
14908  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14909  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14910})
14911
14912(define_insn "*tls_dynamic_lea_64"
14913  [(set (match_operand:DI 0 "register_operand" "=r")
14914	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14915		   UNSPEC_TLSDESC))]
14916  "TARGET_64BIT && TARGET_GNU2_TLS"
14917  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14918  [(set_attr "type" "lea")
14919   (set_attr "mode" "DI")
14920   (set_attr "length" "7")
14921   (set_attr "length_address" "4")])
14922
14923(define_insn "*tls_dynamic_call_64"
14924  [(set (match_operand:DI 0 "register_operand" "=a")
14925	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14926		    (match_operand:DI 2 "register_operand" "0")
14927		    (reg:DI SP_REG)]
14928		   UNSPEC_TLSDESC))
14929   (clobber (reg:CC FLAGS_REG))]
14930  "TARGET_64BIT && TARGET_GNU2_TLS"
14931  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14932  [(set_attr "type" "call")
14933   (set_attr "length" "2")
14934   (set_attr "length_address" "0")])
14935
14936(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14937  [(set (match_operand:DI 0 "register_operand" "=&a")
14938	(plus:DI
14939	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14940		     (match_operand:DI 3 "" "")
14941		     (reg:DI SP_REG)]
14942		    UNSPEC_TLSDESC)
14943	 (const:DI (unspec:DI
14944		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
14945		    UNSPEC_DTPOFF))))
14946   (clobber (reg:CC FLAGS_REG))]
14947  "TARGET_64BIT && TARGET_GNU2_TLS"
14948  "#"
14949  ""
14950  [(set (match_dup 0) (match_dup 4))]
14951{
14952  operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14953  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14954})
14955
14956;;
14957
14958;; These patterns match the binary 387 instructions for addM3, subM3,
14959;; mulM3 and divM3.  There are three patterns for each of DFmode and
14960;; SFmode.  The first is the normal insn, the second the same insn but
14961;; with one operand a conversion, and the third the same insn but with
14962;; the other operand a conversion.  The conversion may be SFmode or
14963;; SImode if the target mode DFmode, but only SImode if the target mode
14964;; is SFmode.
14965
14966;; Gcc is slightly more smart about handling normal two address instructions
14967;; so use special patterns for add and mull.
14968
14969(define_insn "*fop_sf_comm_mixed"
14970  [(set (match_operand:SF 0 "register_operand" "=f,x")
14971	(match_operator:SF 3 "binary_fp_operator"
14972			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14973			 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14974  "TARGET_MIX_SSE_I387
14975   && COMMUTATIVE_ARITH_P (operands[3])
14976   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14977  "* return output_387_binary_op (insn, operands);"
14978  [(set (attr "type") 
14979	(if_then_else (eq_attr "alternative" "1")
14980	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14981	      (const_string "ssemul")
14982	      (const_string "sseadd"))
14983	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14984	      (const_string "fmul")
14985	      (const_string "fop"))))
14986   (set_attr "mode" "SF")])
14987
14988(define_insn "*fop_sf_comm_sse"
14989  [(set (match_operand:SF 0 "register_operand" "=x")
14990	(match_operator:SF 3 "binary_fp_operator"
14991			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14992			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14993  "TARGET_SSE_MATH
14994   && COMMUTATIVE_ARITH_P (operands[3])
14995   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14996  "* return output_387_binary_op (insn, operands);"
14997  [(set (attr "type") 
14998        (if_then_else (match_operand:SF 3 "mult_operator" "") 
14999	   (const_string "ssemul")
15000	   (const_string "sseadd")))
15001   (set_attr "mode" "SF")])
15002
15003(define_insn "*fop_sf_comm_i387"
15004  [(set (match_operand:SF 0 "register_operand" "=f")
15005	(match_operator:SF 3 "binary_fp_operator"
15006			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15007			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15008  "TARGET_80387
15009   && COMMUTATIVE_ARITH_P (operands[3])
15010   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15011  "* return output_387_binary_op (insn, operands);"
15012  [(set (attr "type") 
15013	(if_then_else (match_operand:SF 3 "mult_operator" "") 
15014	   (const_string "fmul")
15015	   (const_string "fop")))
15016   (set_attr "mode" "SF")])
15017
15018(define_insn "*fop_sf_1_mixed"
15019  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15020	(match_operator:SF 3 "binary_fp_operator"
15021			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15022			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15023  "TARGET_MIX_SSE_I387
15024   && !COMMUTATIVE_ARITH_P (operands[3])
15025   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15026  "* return output_387_binary_op (insn, operands);"
15027  [(set (attr "type") 
15028        (cond [(and (eq_attr "alternative" "2")
15029	            (match_operand:SF 3 "mult_operator" ""))
15030                 (const_string "ssemul")
15031	       (and (eq_attr "alternative" "2")
15032	            (match_operand:SF 3 "div_operator" ""))
15033                 (const_string "ssediv")
15034	       (eq_attr "alternative" "2")
15035                 (const_string "sseadd")
15036	       (match_operand:SF 3 "mult_operator" "") 
15037                 (const_string "fmul")
15038               (match_operand:SF 3 "div_operator" "") 
15039                 (const_string "fdiv")
15040              ]
15041              (const_string "fop")))
15042   (set_attr "mode" "SF")])
15043
15044(define_insn "*fop_sf_1_sse"
15045  [(set (match_operand:SF 0 "register_operand" "=x")
15046	(match_operator:SF 3 "binary_fp_operator"
15047			[(match_operand:SF 1 "register_operand" "0")
15048			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15049  "TARGET_SSE_MATH
15050   && !COMMUTATIVE_ARITH_P (operands[3])"
15051  "* return output_387_binary_op (insn, operands);"
15052  [(set (attr "type") 
15053        (cond [(match_operand:SF 3 "mult_operator" "")
15054                 (const_string "ssemul")
15055	       (match_operand:SF 3 "div_operator" "")
15056                 (const_string "ssediv")
15057              ]
15058              (const_string "sseadd")))
15059   (set_attr "mode" "SF")])
15060
15061;; This pattern is not fully shadowed by the pattern above.
15062(define_insn "*fop_sf_1_i387"
15063  [(set (match_operand:SF 0 "register_operand" "=f,f")
15064	(match_operator:SF 3 "binary_fp_operator"
15065			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15066			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15067  "TARGET_80387 && !TARGET_SSE_MATH
15068   && !COMMUTATIVE_ARITH_P (operands[3])
15069   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15070  "* return output_387_binary_op (insn, operands);"
15071  [(set (attr "type") 
15072        (cond [(match_operand:SF 3 "mult_operator" "") 
15073                 (const_string "fmul")
15074               (match_operand:SF 3 "div_operator" "") 
15075                 (const_string "fdiv")
15076              ]
15077              (const_string "fop")))
15078   (set_attr "mode" "SF")])
15079
15080;; ??? Add SSE splitters for these!
15081(define_insn "*fop_sf_2<mode>_i387"
15082  [(set (match_operand:SF 0 "register_operand" "=f,f")
15083	(match_operator:SF 3 "binary_fp_operator"
15084	  [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15085	   (match_operand:SF 2 "register_operand" "0,0")]))]
15086  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15087  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15088  [(set (attr "type") 
15089        (cond [(match_operand:SF 3 "mult_operator" "") 
15090                 (const_string "fmul")
15091               (match_operand:SF 3 "div_operator" "") 
15092                 (const_string "fdiv")
15093              ]
15094              (const_string "fop")))
15095   (set_attr "fp_int_src" "true")
15096   (set_attr "mode" "<MODE>")])
15097
15098(define_insn "*fop_sf_3<mode>_i387"
15099  [(set (match_operand:SF 0 "register_operand" "=f,f")
15100	(match_operator:SF 3 "binary_fp_operator"
15101	  [(match_operand:SF 1 "register_operand" "0,0")
15102	   (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15103  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15104  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15105  [(set (attr "type") 
15106        (cond [(match_operand:SF 3 "mult_operator" "") 
15107                 (const_string "fmul")
15108               (match_operand:SF 3 "div_operator" "") 
15109                 (const_string "fdiv")
15110              ]
15111              (const_string "fop")))
15112   (set_attr "fp_int_src" "true")
15113   (set_attr "mode" "<MODE>")])
15114
15115(define_insn "*fop_df_comm_mixed"
15116  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15117	(match_operator:DF 3 "binary_fp_operator"
15118			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15119			 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15120  "TARGET_SSE2 && TARGET_MIX_SSE_I387
15121   && COMMUTATIVE_ARITH_P (operands[3])
15122   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15123  "* return output_387_binary_op (insn, operands);"
15124  [(set (attr "type") 
15125	(if_then_else (eq_attr "alternative" "1")
15126	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15127	      (const_string "ssemul")
15128	      (const_string "sseadd"))
15129	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15130	      (const_string "fmul")
15131	      (const_string "fop"))))
15132   (set_attr "mode" "DF")])
15133
15134(define_insn "*fop_df_comm_sse"
15135  [(set (match_operand:DF 0 "register_operand" "=Y")
15136	(match_operator:DF 3 "binary_fp_operator"
15137			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15138			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15139  "TARGET_SSE2 && TARGET_SSE_MATH
15140   && COMMUTATIVE_ARITH_P (operands[3])
15141   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15142  "* return output_387_binary_op (insn, operands);"
15143  [(set (attr "type") 
15144        (if_then_else (match_operand:DF 3 "mult_operator" "") 
15145	   (const_string "ssemul")
15146	   (const_string "sseadd")))
15147   (set_attr "mode" "DF")])
15148
15149(define_insn "*fop_df_comm_i387"
15150  [(set (match_operand:DF 0 "register_operand" "=f")
15151	(match_operator:DF 3 "binary_fp_operator"
15152			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15153			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15154  "TARGET_80387
15155   && COMMUTATIVE_ARITH_P (operands[3])
15156   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15157  "* return output_387_binary_op (insn, operands);"
15158  [(set (attr "type") 
15159	(if_then_else (match_operand:DF 3 "mult_operator" "") 
15160	   (const_string "fmul")
15161	   (const_string "fop")))
15162   (set_attr "mode" "DF")])
15163
15164(define_insn "*fop_df_1_mixed"
15165  [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15166	(match_operator:DF 3 "binary_fp_operator"
15167			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15168			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15169  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15170   && !COMMUTATIVE_ARITH_P (operands[3])
15171   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15172  "* return output_387_binary_op (insn, operands);"
15173  [(set (attr "type") 
15174        (cond [(and (eq_attr "alternative" "2")
15175	            (match_operand:DF 3 "mult_operator" ""))
15176                 (const_string "ssemul")
15177	       (and (eq_attr "alternative" "2")
15178	            (match_operand:DF 3 "div_operator" ""))
15179                 (const_string "ssediv")
15180	       (eq_attr "alternative" "2")
15181                 (const_string "sseadd")
15182	       (match_operand:DF 3 "mult_operator" "") 
15183                 (const_string "fmul")
15184               (match_operand:DF 3 "div_operator" "") 
15185                 (const_string "fdiv")
15186              ]
15187              (const_string "fop")))
15188   (set_attr "mode" "DF")])
15189
15190(define_insn "*fop_df_1_sse"
15191  [(set (match_operand:DF 0 "register_operand" "=Y")
15192	(match_operator:DF 3 "binary_fp_operator"
15193			[(match_operand:DF 1 "register_operand" "0")
15194			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15195  "TARGET_SSE2 && TARGET_SSE_MATH
15196   && !COMMUTATIVE_ARITH_P (operands[3])"
15197  "* return output_387_binary_op (insn, operands);"
15198  [(set_attr "mode" "DF")
15199   (set (attr "type") 
15200        (cond [(match_operand:DF 3 "mult_operator" "")
15201                 (const_string "ssemul")
15202	       (match_operand:DF 3 "div_operator" "")
15203                 (const_string "ssediv")
15204              ]
15205              (const_string "sseadd")))])
15206
15207;; This pattern is not fully shadowed by the pattern above.
15208(define_insn "*fop_df_1_i387"
15209  [(set (match_operand:DF 0 "register_operand" "=f,f")
15210	(match_operator:DF 3 "binary_fp_operator"
15211			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15212			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15213  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15214   && !COMMUTATIVE_ARITH_P (operands[3])
15215   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15216  "* return output_387_binary_op (insn, operands);"
15217  [(set (attr "type") 
15218        (cond [(match_operand:DF 3 "mult_operator" "") 
15219                 (const_string "fmul")
15220               (match_operand:DF 3 "div_operator" "")
15221                 (const_string "fdiv")
15222              ]
15223              (const_string "fop")))
15224   (set_attr "mode" "DF")])
15225
15226;; ??? Add SSE splitters for these!
15227(define_insn "*fop_df_2<mode>_i387"
15228  [(set (match_operand:DF 0 "register_operand" "=f,f")
15229	(match_operator:DF 3 "binary_fp_operator"
15230	   [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15231	    (match_operand:DF 2 "register_operand" "0,0")]))]
15232  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15233   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15234  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15235  [(set (attr "type") 
15236        (cond [(match_operand:DF 3 "mult_operator" "") 
15237                 (const_string "fmul")
15238               (match_operand:DF 3 "div_operator" "") 
15239                 (const_string "fdiv")
15240              ]
15241              (const_string "fop")))
15242   (set_attr "fp_int_src" "true")
15243   (set_attr "mode" "<MODE>")])
15244
15245(define_insn "*fop_df_3<mode>_i387"
15246  [(set (match_operand:DF 0 "register_operand" "=f,f")
15247	(match_operator:DF 3 "binary_fp_operator"
15248	   [(match_operand:DF 1 "register_operand" "0,0")
15249	    (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15250  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15251   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15252  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15253  [(set (attr "type") 
15254        (cond [(match_operand:DF 3 "mult_operator" "") 
15255                 (const_string "fmul")
15256               (match_operand:DF 3 "div_operator" "") 
15257                 (const_string "fdiv")
15258              ]
15259              (const_string "fop")))
15260   (set_attr "fp_int_src" "true")
15261   (set_attr "mode" "<MODE>")])
15262
15263(define_insn "*fop_df_4_i387"
15264  [(set (match_operand:DF 0 "register_operand" "=f,f")
15265	(match_operator:DF 3 "binary_fp_operator"
15266	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15267	    (match_operand:DF 2 "register_operand" "0,f")]))]
15268  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15269   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15270  "* return output_387_binary_op (insn, operands);"
15271  [(set (attr "type") 
15272        (cond [(match_operand:DF 3 "mult_operator" "") 
15273                 (const_string "fmul")
15274               (match_operand:DF 3 "div_operator" "") 
15275                 (const_string "fdiv")
15276              ]
15277              (const_string "fop")))
15278   (set_attr "mode" "SF")])
15279
15280(define_insn "*fop_df_5_i387"
15281  [(set (match_operand:DF 0 "register_operand" "=f,f")
15282	(match_operator:DF 3 "binary_fp_operator"
15283	  [(match_operand:DF 1 "register_operand" "0,f")
15284	   (float_extend:DF
15285	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15286  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15287  "* return output_387_binary_op (insn, operands);"
15288  [(set (attr "type") 
15289        (cond [(match_operand:DF 3 "mult_operator" "") 
15290                 (const_string "fmul")
15291               (match_operand:DF 3 "div_operator" "") 
15292                 (const_string "fdiv")
15293              ]
15294              (const_string "fop")))
15295   (set_attr "mode" "SF")])
15296
15297(define_insn "*fop_df_6_i387"
15298  [(set (match_operand:DF 0 "register_operand" "=f,f")
15299	(match_operator:DF 3 "binary_fp_operator"
15300	  [(float_extend:DF
15301	    (match_operand:SF 1 "register_operand" "0,f"))
15302	   (float_extend:DF
15303	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15304  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15305  "* return output_387_binary_op (insn, operands);"
15306  [(set (attr "type") 
15307        (cond [(match_operand:DF 3 "mult_operator" "") 
15308                 (const_string "fmul")
15309               (match_operand:DF 3 "div_operator" "") 
15310                 (const_string "fdiv")
15311              ]
15312              (const_string "fop")))
15313   (set_attr "mode" "SF")])
15314
15315(define_insn "*fop_xf_comm_i387"
15316  [(set (match_operand:XF 0 "register_operand" "=f")
15317	(match_operator:XF 3 "binary_fp_operator"
15318			[(match_operand:XF 1 "register_operand" "%0")
15319			 (match_operand:XF 2 "register_operand" "f")]))]
15320  "TARGET_80387
15321   && COMMUTATIVE_ARITH_P (operands[3])"
15322  "* return output_387_binary_op (insn, operands);"
15323  [(set (attr "type") 
15324        (if_then_else (match_operand:XF 3 "mult_operator" "") 
15325           (const_string "fmul")
15326           (const_string "fop")))
15327   (set_attr "mode" "XF")])
15328
15329(define_insn "*fop_xf_1_i387"
15330  [(set (match_operand:XF 0 "register_operand" "=f,f")
15331	(match_operator:XF 3 "binary_fp_operator"
15332			[(match_operand:XF 1 "register_operand" "0,f")
15333			 (match_operand:XF 2 "register_operand" "f,0")]))]
15334  "TARGET_80387
15335   && !COMMUTATIVE_ARITH_P (operands[3])"
15336  "* return output_387_binary_op (insn, operands);"
15337  [(set (attr "type") 
15338        (cond [(match_operand:XF 3 "mult_operator" "") 
15339                 (const_string "fmul")
15340               (match_operand:XF 3 "div_operator" "") 
15341                 (const_string "fdiv")
15342              ]
15343              (const_string "fop")))
15344   (set_attr "mode" "XF")])
15345
15346(define_insn "*fop_xf_2<mode>_i387"
15347  [(set (match_operand:XF 0 "register_operand" "=f,f")
15348	(match_operator:XF 3 "binary_fp_operator"
15349	   [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15350	    (match_operand:XF 2 "register_operand" "0,0")]))]
15351  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15352  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15353  [(set (attr "type") 
15354        (cond [(match_operand:XF 3 "mult_operator" "") 
15355                 (const_string "fmul")
15356               (match_operand:XF 3 "div_operator" "") 
15357                 (const_string "fdiv")
15358              ]
15359              (const_string "fop")))
15360   (set_attr "fp_int_src" "true")
15361   (set_attr "mode" "<MODE>")])
15362
15363(define_insn "*fop_xf_3<mode>_i387"
15364  [(set (match_operand:XF 0 "register_operand" "=f,f")
15365	(match_operator:XF 3 "binary_fp_operator"
15366	  [(match_operand:XF 1 "register_operand" "0,0")
15367	   (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15368  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15369  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15370  [(set (attr "type") 
15371        (cond [(match_operand:XF 3 "mult_operator" "") 
15372                 (const_string "fmul")
15373               (match_operand:XF 3 "div_operator" "") 
15374                 (const_string "fdiv")
15375              ]
15376              (const_string "fop")))
15377   (set_attr "fp_int_src" "true")
15378   (set_attr "mode" "<MODE>")])
15379
15380(define_insn "*fop_xf_4_i387"
15381  [(set (match_operand:XF 0 "register_operand" "=f,f")
15382	(match_operator:XF 3 "binary_fp_operator"
15383	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15384	    (match_operand:XF 2 "register_operand" "0,f")]))]
15385  "TARGET_80387"
15386  "* return output_387_binary_op (insn, operands);"
15387  [(set (attr "type") 
15388        (cond [(match_operand:XF 3 "mult_operator" "") 
15389                 (const_string "fmul")
15390               (match_operand:XF 3 "div_operator" "") 
15391                 (const_string "fdiv")
15392              ]
15393              (const_string "fop")))
15394   (set_attr "mode" "SF")])
15395
15396(define_insn "*fop_xf_5_i387"
15397  [(set (match_operand:XF 0 "register_operand" "=f,f")
15398	(match_operator:XF 3 "binary_fp_operator"
15399	  [(match_operand:XF 1 "register_operand" "0,f")
15400	   (float_extend:XF
15401	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15402  "TARGET_80387"
15403  "* return output_387_binary_op (insn, operands);"
15404  [(set (attr "type") 
15405        (cond [(match_operand:XF 3 "mult_operator" "") 
15406                 (const_string "fmul")
15407               (match_operand:XF 3 "div_operator" "") 
15408                 (const_string "fdiv")
15409              ]
15410              (const_string "fop")))
15411   (set_attr "mode" "SF")])
15412
15413(define_insn "*fop_xf_6_i387"
15414  [(set (match_operand:XF 0 "register_operand" "=f,f")
15415	(match_operator:XF 3 "binary_fp_operator"
15416	  [(float_extend:XF
15417	    (match_operand 1 "register_operand" "0,f"))
15418	   (float_extend:XF
15419	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15420  "TARGET_80387"
15421  "* return output_387_binary_op (insn, operands);"
15422  [(set (attr "type") 
15423        (cond [(match_operand:XF 3 "mult_operator" "") 
15424                 (const_string "fmul")
15425               (match_operand:XF 3 "div_operator" "") 
15426                 (const_string "fdiv")
15427              ]
15428              (const_string "fop")))
15429   (set_attr "mode" "SF")])
15430
15431(define_split
15432  [(set (match_operand 0 "register_operand" "")
15433	(match_operator 3 "binary_fp_operator"
15434	   [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15435	    (match_operand 2 "register_operand" "")]))]
15436  "TARGET_80387 && reload_completed
15437   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15438  [(const_int 0)]
15439{ 
15440  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15441  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15442  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15443			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15444					  GET_MODE (operands[3]),
15445					  operands[4],
15446					  operands[2])));
15447  ix86_free_from_memory (GET_MODE (operands[1]));
15448  DONE;
15449})
15450
15451(define_split
15452  [(set (match_operand 0 "register_operand" "")
15453	(match_operator 3 "binary_fp_operator"
15454	   [(match_operand 1 "register_operand" "")
15455	    (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15456  "TARGET_80387 && reload_completed
15457   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15458  [(const_int 0)]
15459{
15460  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15461  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15462  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15463			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15464					  GET_MODE (operands[3]),
15465					  operands[1],
15466					  operands[4])));
15467  ix86_free_from_memory (GET_MODE (operands[2]));
15468  DONE;
15469})
15470
15471;; FPU special functions.
15472
15473(define_expand "sqrtsf2"
15474  [(set (match_operand:SF 0 "register_operand" "")
15475	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15476  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15477{
15478  if (!TARGET_SSE_MATH)
15479    operands[1] = force_reg (SFmode, operands[1]);
15480})
15481
15482(define_insn "*sqrtsf2_mixed"
15483  [(set (match_operand:SF 0 "register_operand" "=f,x")
15484	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15485  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15486  "@
15487   fsqrt
15488   sqrtss\t{%1, %0|%0, %1}"
15489  [(set_attr "type" "fpspc,sse")
15490   (set_attr "mode" "SF,SF")
15491   (set_attr "athlon_decode" "direct,*")])
15492
15493(define_insn "*sqrtsf2_sse"
15494  [(set (match_operand:SF 0 "register_operand" "=x")
15495	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15496  "TARGET_SSE_MATH"
15497  "sqrtss\t{%1, %0|%0, %1}"
15498  [(set_attr "type" "sse")
15499   (set_attr "mode" "SF")
15500   (set_attr "athlon_decode" "*")])
15501
15502(define_insn "*sqrtsf2_i387"
15503  [(set (match_operand:SF 0 "register_operand" "=f")
15504	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15505  "TARGET_USE_FANCY_MATH_387"
15506  "fsqrt"
15507  [(set_attr "type" "fpspc")
15508   (set_attr "mode" "SF")
15509   (set_attr "athlon_decode" "direct")])
15510
15511(define_expand "sqrtdf2"
15512  [(set (match_operand:DF 0 "register_operand" "")
15513	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15514  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15515{
15516  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15517    operands[1] = force_reg (DFmode, operands[1]);
15518})
15519
15520(define_insn "*sqrtdf2_mixed"
15521  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15522	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15523  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15524  "@
15525   fsqrt
15526   sqrtsd\t{%1, %0|%0, %1}"
15527  [(set_attr "type" "fpspc,sse")
15528   (set_attr "mode" "DF,DF")
15529   (set_attr "athlon_decode" "direct,*")])
15530
15531(define_insn "*sqrtdf2_sse"
15532  [(set (match_operand:DF 0 "register_operand" "=Y")
15533	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15534  "TARGET_SSE2 && TARGET_SSE_MATH"
15535  "sqrtsd\t{%1, %0|%0, %1}"
15536  [(set_attr "type" "sse")
15537   (set_attr "mode" "DF")
15538   (set_attr "athlon_decode" "*")])
15539
15540(define_insn "*sqrtdf2_i387"
15541  [(set (match_operand:DF 0 "register_operand" "=f")
15542	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15543  "TARGET_USE_FANCY_MATH_387"
15544  "fsqrt"
15545  [(set_attr "type" "fpspc")
15546   (set_attr "mode" "DF")
15547   (set_attr "athlon_decode" "direct")])
15548
15549(define_insn "*sqrtextendsfdf2_i387"
15550  [(set (match_operand:DF 0 "register_operand" "=f")
15551	(sqrt:DF (float_extend:DF
15552		  (match_operand:SF 1 "register_operand" "0"))))]
15553  "TARGET_USE_FANCY_MATH_387
15554   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15555  "fsqrt"
15556  [(set_attr "type" "fpspc")
15557   (set_attr "mode" "DF")
15558   (set_attr "athlon_decode" "direct")])
15559
15560(define_insn "sqrtxf2"
15561  [(set (match_operand:XF 0 "register_operand" "=f")
15562	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15563  "TARGET_USE_FANCY_MATH_387"
15564  "fsqrt"
15565  [(set_attr "type" "fpspc")
15566   (set_attr "mode" "XF")
15567   (set_attr "athlon_decode" "direct")])
15568
15569(define_insn "*sqrtextendsfxf2_i387"
15570  [(set (match_operand:XF 0 "register_operand" "=f")
15571	(sqrt:XF (float_extend:XF
15572		  (match_operand:SF 1 "register_operand" "0"))))]
15573  "TARGET_USE_FANCY_MATH_387"
15574  "fsqrt"
15575  [(set_attr "type" "fpspc")
15576   (set_attr "mode" "XF")
15577   (set_attr "athlon_decode" "direct")])
15578
15579(define_insn "*sqrtextenddfxf2_i387"
15580  [(set (match_operand:XF 0 "register_operand" "=f")
15581	(sqrt:XF (float_extend:XF
15582		  (match_operand:DF 1 "register_operand" "0"))))]
15583  "TARGET_USE_FANCY_MATH_387"
15584  "fsqrt"
15585  [(set_attr "type" "fpspc")
15586   (set_attr "mode" "XF")
15587   (set_attr "athlon_decode" "direct")])
15588
15589(define_insn "fpremxf4"
15590  [(set (match_operand:XF 0 "register_operand" "=f")
15591	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15592		    (match_operand:XF 3 "register_operand" "1")]
15593		   UNSPEC_FPREM_F))
15594   (set (match_operand:XF 1 "register_operand" "=u")
15595	(unspec:XF [(match_dup 2) (match_dup 3)]
15596		   UNSPEC_FPREM_U))
15597   (set (reg:CCFP FPSR_REG)
15598	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15599  "TARGET_USE_FANCY_MATH_387
15600   && flag_unsafe_math_optimizations"
15601  "fprem"
15602  [(set_attr "type" "fpspc")
15603   (set_attr "mode" "XF")])
15604
15605(define_expand "fmodsf3"
15606  [(use (match_operand:SF 0 "register_operand" ""))
15607   (use (match_operand:SF 1 "register_operand" ""))
15608   (use (match_operand:SF 2 "register_operand" ""))]
15609  "TARGET_USE_FANCY_MATH_387
15610   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15611   && flag_unsafe_math_optimizations"
15612{
15613  rtx label = gen_label_rtx ();
15614
15615  rtx op1 = gen_reg_rtx (XFmode);
15616  rtx op2 = gen_reg_rtx (XFmode);
15617
15618  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15619  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15620
15621  emit_label (label);
15622
15623  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15624  ix86_emit_fp_unordered_jump (label);
15625
15626  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15627  DONE;
15628})
15629
15630(define_expand "fmoddf3"
15631  [(use (match_operand:DF 0 "register_operand" ""))
15632   (use (match_operand:DF 1 "register_operand" ""))
15633   (use (match_operand:DF 2 "register_operand" ""))]
15634  "TARGET_USE_FANCY_MATH_387
15635   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15636   && flag_unsafe_math_optimizations"
15637{
15638  rtx label = gen_label_rtx ();
15639
15640  rtx op1 = gen_reg_rtx (XFmode);
15641  rtx op2 = gen_reg_rtx (XFmode);
15642
15643  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15644  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15645
15646  emit_label (label);
15647
15648  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15649  ix86_emit_fp_unordered_jump (label);
15650
15651  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15652  DONE;
15653})
15654
15655(define_expand "fmodxf3"
15656  [(use (match_operand:XF 0 "register_operand" ""))
15657   (use (match_operand:XF 1 "register_operand" ""))
15658   (use (match_operand:XF 2 "register_operand" ""))]
15659  "TARGET_USE_FANCY_MATH_387
15660   && flag_unsafe_math_optimizations"
15661{
15662  rtx label = gen_label_rtx ();
15663
15664  emit_label (label);
15665
15666  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15667			   operands[1], operands[2]));
15668  ix86_emit_fp_unordered_jump (label);
15669
15670  emit_move_insn (operands[0], operands[1]);
15671  DONE;
15672})
15673
15674(define_insn "fprem1xf4"
15675  [(set (match_operand:XF 0 "register_operand" "=f")
15676	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15677		    (match_operand:XF 3 "register_operand" "1")]
15678		   UNSPEC_FPREM1_F))
15679   (set (match_operand:XF 1 "register_operand" "=u")
15680	(unspec:XF [(match_dup 2) (match_dup 3)]
15681		   UNSPEC_FPREM1_U))
15682   (set (reg:CCFP FPSR_REG)
15683	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15684  "TARGET_USE_FANCY_MATH_387
15685   && flag_unsafe_math_optimizations"
15686  "fprem1"
15687  [(set_attr "type" "fpspc")
15688   (set_attr "mode" "XF")])
15689
15690(define_expand "dremsf3"
15691  [(use (match_operand:SF 0 "register_operand" ""))
15692   (use (match_operand:SF 1 "register_operand" ""))
15693   (use (match_operand:SF 2 "register_operand" ""))]
15694  "TARGET_USE_FANCY_MATH_387
15695   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15696   && flag_unsafe_math_optimizations"
15697{
15698  rtx label = gen_label_rtx ();
15699
15700  rtx op1 = gen_reg_rtx (XFmode);
15701  rtx op2 = gen_reg_rtx (XFmode);
15702
15703  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15704  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15705
15706  emit_label (label);
15707
15708  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15709  ix86_emit_fp_unordered_jump (label);
15710
15711  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15712  DONE;
15713})
15714
15715(define_expand "dremdf3"
15716  [(use (match_operand:DF 0 "register_operand" ""))
15717   (use (match_operand:DF 1 "register_operand" ""))
15718   (use (match_operand:DF 2 "register_operand" ""))]
15719  "TARGET_USE_FANCY_MATH_387
15720   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15721   && flag_unsafe_math_optimizations"
15722{
15723  rtx label = gen_label_rtx ();
15724
15725  rtx op1 = gen_reg_rtx (XFmode);
15726  rtx op2 = gen_reg_rtx (XFmode);
15727
15728  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15729  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15730
15731  emit_label (label);
15732
15733  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15734  ix86_emit_fp_unordered_jump (label);
15735
15736  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15737  DONE;
15738})
15739
15740(define_expand "dremxf3"
15741  [(use (match_operand:XF 0 "register_operand" ""))
15742   (use (match_operand:XF 1 "register_operand" ""))
15743   (use (match_operand:XF 2 "register_operand" ""))]
15744  "TARGET_USE_FANCY_MATH_387
15745   && flag_unsafe_math_optimizations"
15746{
15747  rtx label = gen_label_rtx ();
15748
15749  emit_label (label);
15750
15751  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15752			    operands[1], operands[2]));
15753  ix86_emit_fp_unordered_jump (label);
15754
15755  emit_move_insn (operands[0], operands[1]);
15756  DONE;
15757})
15758
15759(define_insn "*sindf2"
15760  [(set (match_operand:DF 0 "register_operand" "=f")
15761	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15762  "TARGET_USE_FANCY_MATH_387
15763   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15764   && flag_unsafe_math_optimizations"
15765  "fsin"
15766  [(set_attr "type" "fpspc")
15767   (set_attr "mode" "DF")])
15768
15769(define_insn "*sinsf2"
15770  [(set (match_operand:SF 0 "register_operand" "=f")
15771	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15772  "TARGET_USE_FANCY_MATH_387
15773   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15774   && flag_unsafe_math_optimizations"
15775  "fsin"
15776  [(set_attr "type" "fpspc")
15777   (set_attr "mode" "SF")])
15778
15779(define_insn "*sinextendsfdf2"
15780  [(set (match_operand:DF 0 "register_operand" "=f")
15781	(unspec:DF [(float_extend:DF
15782		     (match_operand:SF 1 "register_operand" "0"))]
15783		   UNSPEC_SIN))]
15784  "TARGET_USE_FANCY_MATH_387
15785   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15786   && flag_unsafe_math_optimizations"
15787  "fsin"
15788  [(set_attr "type" "fpspc")
15789   (set_attr "mode" "DF")])
15790
15791(define_insn "*sinxf2"
15792  [(set (match_operand:XF 0 "register_operand" "=f")
15793	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15794  "TARGET_USE_FANCY_MATH_387
15795   && flag_unsafe_math_optimizations"
15796  "fsin"
15797  [(set_attr "type" "fpspc")
15798   (set_attr "mode" "XF")])
15799
15800(define_insn "*cosdf2"
15801  [(set (match_operand:DF 0 "register_operand" "=f")
15802	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15803  "TARGET_USE_FANCY_MATH_387
15804   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15805   && flag_unsafe_math_optimizations"
15806  "fcos"
15807  [(set_attr "type" "fpspc")
15808   (set_attr "mode" "DF")])
15809
15810(define_insn "*cossf2"
15811  [(set (match_operand:SF 0 "register_operand" "=f")
15812	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15813  "TARGET_USE_FANCY_MATH_387
15814   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15815   && flag_unsafe_math_optimizations"
15816  "fcos"
15817  [(set_attr "type" "fpspc")
15818   (set_attr "mode" "SF")])
15819
15820(define_insn "*cosextendsfdf2"
15821  [(set (match_operand:DF 0 "register_operand" "=f")
15822	(unspec:DF [(float_extend:DF
15823		     (match_operand:SF 1 "register_operand" "0"))]
15824		   UNSPEC_COS))]
15825  "TARGET_USE_FANCY_MATH_387
15826   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15827   && flag_unsafe_math_optimizations"
15828  "fcos"
15829  [(set_attr "type" "fpspc")
15830   (set_attr "mode" "DF")])
15831
15832(define_insn "*cosxf2"
15833  [(set (match_operand:XF 0 "register_operand" "=f")
15834	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15835  "TARGET_USE_FANCY_MATH_387
15836   && flag_unsafe_math_optimizations"
15837  "fcos"
15838  [(set_attr "type" "fpspc")
15839   (set_attr "mode" "XF")])
15840
15841;; With sincos pattern defined, sin and cos builtin function will be
15842;; expanded to sincos pattern with one of its outputs left unused. 
15843;; Cse pass  will detected, if two sincos patterns can be combined,
15844;; otherwise sincos pattern will be split back to sin or cos pattern,
15845;; depending on the unused output.
15846
15847(define_insn "sincosdf3"
15848  [(set (match_operand:DF 0 "register_operand" "=f")
15849	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15850		   UNSPEC_SINCOS_COS))
15851   (set (match_operand:DF 1 "register_operand" "=u")
15852        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15853  "TARGET_USE_FANCY_MATH_387
15854   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15855   && flag_unsafe_math_optimizations"
15856  "fsincos"
15857  [(set_attr "type" "fpspc")
15858   (set_attr "mode" "DF")])
15859
15860(define_split
15861  [(set (match_operand:DF 0 "register_operand" "")
15862	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15863		   UNSPEC_SINCOS_COS))
15864   (set (match_operand:DF 1 "register_operand" "")
15865	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15866  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15867   && !reload_completed && !reload_in_progress"
15868  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15869  "")
15870
15871(define_split
15872  [(set (match_operand:DF 0 "register_operand" "")
15873	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15874		   UNSPEC_SINCOS_COS))
15875   (set (match_operand:DF 1 "register_operand" "")
15876	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15877  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15878   && !reload_completed && !reload_in_progress"
15879  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15880  "")
15881
15882(define_insn "sincossf3"
15883  [(set (match_operand:SF 0 "register_operand" "=f")
15884	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15885		   UNSPEC_SINCOS_COS))
15886   (set (match_operand:SF 1 "register_operand" "=u")
15887        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15888  "TARGET_USE_FANCY_MATH_387
15889   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15890   && flag_unsafe_math_optimizations"
15891  "fsincos"
15892  [(set_attr "type" "fpspc")
15893   (set_attr "mode" "SF")])
15894
15895(define_split
15896  [(set (match_operand:SF 0 "register_operand" "")
15897	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15898		   UNSPEC_SINCOS_COS))
15899   (set (match_operand:SF 1 "register_operand" "")
15900	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15901  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15902   && !reload_completed && !reload_in_progress"
15903  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15904  "")
15905
15906(define_split
15907  [(set (match_operand:SF 0 "register_operand" "")
15908	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15909		   UNSPEC_SINCOS_COS))
15910   (set (match_operand:SF 1 "register_operand" "")
15911	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15912  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15913   && !reload_completed && !reload_in_progress"
15914  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15915  "")
15916
15917(define_insn "*sincosextendsfdf3"
15918  [(set (match_operand:DF 0 "register_operand" "=f")
15919	(unspec:DF [(float_extend:DF
15920		     (match_operand:SF 2 "register_operand" "0"))]
15921		   UNSPEC_SINCOS_COS))
15922   (set (match_operand:DF 1 "register_operand" "=u")
15923        (unspec:DF [(float_extend:DF
15924		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15925  "TARGET_USE_FANCY_MATH_387
15926   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15927   && flag_unsafe_math_optimizations"
15928  "fsincos"
15929  [(set_attr "type" "fpspc")
15930   (set_attr "mode" "DF")])
15931
15932(define_split
15933  [(set (match_operand:DF 0 "register_operand" "")
15934	(unspec:DF [(float_extend:DF
15935		     (match_operand:SF 2 "register_operand" ""))]
15936		   UNSPEC_SINCOS_COS))
15937   (set (match_operand:DF 1 "register_operand" "")
15938        (unspec:DF [(float_extend:DF
15939		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15940  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15941   && !reload_completed && !reload_in_progress"
15942  [(set (match_dup 1) (unspec:DF [(float_extend:DF
15943				   (match_dup 2))] UNSPEC_SIN))]
15944  "")
15945
15946(define_split
15947  [(set (match_operand:DF 0 "register_operand" "")
15948	(unspec:DF [(float_extend:DF
15949		     (match_operand:SF 2 "register_operand" ""))]
15950		   UNSPEC_SINCOS_COS))
15951   (set (match_operand:DF 1 "register_operand" "")
15952        (unspec:DF [(float_extend:DF
15953		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15954  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15955   && !reload_completed && !reload_in_progress"
15956  [(set (match_dup 0) (unspec:DF [(float_extend:DF
15957				   (match_dup 2))] UNSPEC_COS))]
15958  "")
15959
15960(define_insn "sincosxf3"
15961  [(set (match_operand:XF 0 "register_operand" "=f")
15962	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15963		   UNSPEC_SINCOS_COS))
15964   (set (match_operand:XF 1 "register_operand" "=u")
15965        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15966  "TARGET_USE_FANCY_MATH_387
15967   && flag_unsafe_math_optimizations"
15968  "fsincos"
15969  [(set_attr "type" "fpspc")
15970   (set_attr "mode" "XF")])
15971
15972(define_split
15973  [(set (match_operand:XF 0 "register_operand" "")
15974	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15975		   UNSPEC_SINCOS_COS))
15976   (set (match_operand:XF 1 "register_operand" "")
15977	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15978  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15979   && !reload_completed && !reload_in_progress"
15980  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15981  "")
15982
15983(define_split
15984  [(set (match_operand:XF 0 "register_operand" "")
15985	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15986		   UNSPEC_SINCOS_COS))
15987   (set (match_operand:XF 1 "register_operand" "")
15988	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15989  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15990   && !reload_completed && !reload_in_progress"
15991  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15992  "")
15993
15994(define_insn "*tandf3_1"
15995  [(set (match_operand:DF 0 "register_operand" "=f")
15996	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15997		   UNSPEC_TAN_ONE))
15998   (set (match_operand:DF 1 "register_operand" "=u")
15999        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16000  "TARGET_USE_FANCY_MATH_387
16001   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16002   && flag_unsafe_math_optimizations"
16003  "fptan"
16004  [(set_attr "type" "fpspc")
16005   (set_attr "mode" "DF")])
16006
16007;; optimize sequence: fptan
16008;;		      fstp    %st(0)
16009;;		      fld1
16010;; into fptan insn.
16011
16012(define_peephole2
16013  [(parallel[(set (match_operand:DF 0 "register_operand" "")
16014		  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16015			     UNSPEC_TAN_ONE))
16016	     (set (match_operand:DF 1 "register_operand" "")
16017		  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16018   (set (match_dup 0)
16019        (match_operand:DF 3 "immediate_operand" ""))]
16020  "standard_80387_constant_p (operands[3]) == 2"
16021  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16022   	     (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16023  "")
16024
16025(define_expand "tandf2"
16026  [(parallel [(set (match_dup 2)
16027		   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16028			      UNSPEC_TAN_ONE))
16029	      (set (match_operand:DF 0 "register_operand" "")
16030		   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16031  "TARGET_USE_FANCY_MATH_387
16032   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16033   && flag_unsafe_math_optimizations"
16034{
16035  operands[2] = gen_reg_rtx (DFmode);
16036})
16037
16038(define_insn "*tansf3_1"
16039  [(set (match_operand:SF 0 "register_operand" "=f")
16040	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16041		   UNSPEC_TAN_ONE))
16042   (set (match_operand:SF 1 "register_operand" "=u")
16043        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16044  "TARGET_USE_FANCY_MATH_387
16045   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16046   && flag_unsafe_math_optimizations"
16047  "fptan"
16048  [(set_attr "type" "fpspc")
16049   (set_attr "mode" "SF")])
16050
16051;; optimize sequence: fptan
16052;;		      fstp    %st(0)
16053;;		      fld1
16054;; into fptan insn.
16055
16056(define_peephole2
16057  [(parallel[(set (match_operand:SF 0 "register_operand" "")
16058		  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16059			     UNSPEC_TAN_ONE))
16060	     (set (match_operand:SF 1 "register_operand" "")
16061		  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16062   (set (match_dup 0)
16063        (match_operand:SF 3 "immediate_operand" ""))]
16064  "standard_80387_constant_p (operands[3]) == 2"
16065  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16066   	     (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16067  "")
16068
16069(define_expand "tansf2"
16070  [(parallel [(set (match_dup 2)
16071		   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16072			      UNSPEC_TAN_ONE))
16073	      (set (match_operand:SF 0 "register_operand" "")
16074		   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16075  "TARGET_USE_FANCY_MATH_387
16076   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16077   && flag_unsafe_math_optimizations"
16078{
16079  operands[2] = gen_reg_rtx (SFmode);
16080})
16081
16082(define_insn "*tanxf3_1"
16083  [(set (match_operand:XF 0 "register_operand" "=f")
16084	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16085		   UNSPEC_TAN_ONE))
16086   (set (match_operand:XF 1 "register_operand" "=u")
16087        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16088  "TARGET_USE_FANCY_MATH_387
16089   && flag_unsafe_math_optimizations"
16090  "fptan"
16091  [(set_attr "type" "fpspc")
16092   (set_attr "mode" "XF")])
16093
16094;; optimize sequence: fptan
16095;;		      fstp    %st(0)
16096;;		      fld1
16097;; into fptan insn.
16098
16099(define_peephole2
16100  [(parallel[(set (match_operand:XF 0 "register_operand" "")
16101		  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16102			     UNSPEC_TAN_ONE))
16103	     (set (match_operand:XF 1 "register_operand" "")
16104		  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16105   (set (match_dup 0)
16106        (match_operand:XF 3 "immediate_operand" ""))]
16107  "standard_80387_constant_p (operands[3]) == 2"
16108  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16109   	     (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16110  "")
16111
16112(define_expand "tanxf2"
16113  [(parallel [(set (match_dup 2)
16114		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16115			      UNSPEC_TAN_ONE))
16116	      (set (match_operand:XF 0 "register_operand" "")
16117		   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16118  "TARGET_USE_FANCY_MATH_387
16119   && flag_unsafe_math_optimizations"
16120{
16121  operands[2] = gen_reg_rtx (XFmode);
16122})
16123
16124(define_insn "atan2df3_1"
16125  [(set (match_operand:DF 0 "register_operand" "=f")
16126	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
16127		    (match_operand:DF 1 "register_operand" "u")]
16128		   UNSPEC_FPATAN))
16129   (clobber (match_scratch:DF 3 "=1"))]
16130  "TARGET_USE_FANCY_MATH_387
16131   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16132   && flag_unsafe_math_optimizations"
16133  "fpatan"
16134  [(set_attr "type" "fpspc")
16135   (set_attr "mode" "DF")])
16136
16137(define_expand "atan2df3"
16138  [(use (match_operand:DF 0 "register_operand" ""))
16139   (use (match_operand:DF 2 "register_operand" ""))
16140   (use (match_operand:DF 1 "register_operand" ""))]
16141  "TARGET_USE_FANCY_MATH_387
16142   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16143   && flag_unsafe_math_optimizations"
16144{
16145  rtx copy = gen_reg_rtx (DFmode);
16146  emit_move_insn (copy, operands[1]);
16147  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16148  DONE;
16149})
16150
16151(define_expand "atandf2"
16152  [(parallel [(set (match_operand:DF 0 "register_operand" "")
16153		   (unspec:DF [(match_dup 2)
16154			       (match_operand:DF 1 "register_operand" "")]
16155		    UNSPEC_FPATAN))
16156	      (clobber (match_scratch:DF 3 ""))])]
16157  "TARGET_USE_FANCY_MATH_387
16158   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16159   && flag_unsafe_math_optimizations"
16160{
16161  operands[2] = gen_reg_rtx (DFmode);
16162  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16163})
16164
16165(define_insn "atan2sf3_1"
16166  [(set (match_operand:SF 0 "register_operand" "=f")
16167        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16168		    (match_operand:SF 1 "register_operand" "u")]
16169		   UNSPEC_FPATAN))
16170   (clobber (match_scratch:SF 3 "=1"))]
16171  "TARGET_USE_FANCY_MATH_387
16172   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16173   && flag_unsafe_math_optimizations"
16174  "fpatan"
16175  [(set_attr "type" "fpspc")
16176   (set_attr "mode" "SF")])
16177
16178(define_expand "atan2sf3"
16179  [(use (match_operand:SF 0 "register_operand" ""))
16180   (use (match_operand:SF 2 "register_operand" ""))
16181   (use (match_operand:SF 1 "register_operand" ""))]
16182  "TARGET_USE_FANCY_MATH_387
16183   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16184   && flag_unsafe_math_optimizations"
16185{
16186  rtx copy = gen_reg_rtx (SFmode);
16187  emit_move_insn (copy, operands[1]);
16188  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16189  DONE;
16190})
16191
16192(define_expand "atansf2"
16193  [(parallel [(set (match_operand:SF 0 "register_operand" "")
16194		   (unspec:SF [(match_dup 2)
16195			       (match_operand:SF 1 "register_operand" "")]
16196		    UNSPEC_FPATAN))
16197	      (clobber (match_scratch:SF 3 ""))])]
16198  "TARGET_USE_FANCY_MATH_387
16199   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16200   && flag_unsafe_math_optimizations"
16201{
16202  operands[2] = gen_reg_rtx (SFmode);
16203  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16204})
16205
16206(define_insn "atan2xf3_1"
16207  [(set (match_operand:XF 0 "register_operand" "=f")
16208        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16209	            (match_operand:XF 1 "register_operand" "u")]
16210	           UNSPEC_FPATAN))
16211   (clobber (match_scratch:XF 3 "=1"))]
16212  "TARGET_USE_FANCY_MATH_387
16213   && flag_unsafe_math_optimizations"
16214  "fpatan"
16215  [(set_attr "type" "fpspc")
16216   (set_attr "mode" "XF")])
16217
16218(define_expand "atan2xf3"
16219  [(use (match_operand:XF 0 "register_operand" ""))
16220   (use (match_operand:XF 2 "register_operand" ""))
16221   (use (match_operand:XF 1 "register_operand" ""))]
16222  "TARGET_USE_FANCY_MATH_387
16223   && flag_unsafe_math_optimizations"
16224{
16225  rtx copy = gen_reg_rtx (XFmode);
16226  emit_move_insn (copy, operands[1]);
16227  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16228  DONE;
16229})
16230
16231(define_expand "atanxf2"
16232  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16233		   (unspec:XF [(match_dup 2)
16234			       (match_operand:XF 1 "register_operand" "")]
16235		    UNSPEC_FPATAN))
16236	      (clobber (match_scratch:XF 3 ""))])]
16237  "TARGET_USE_FANCY_MATH_387
16238   && flag_unsafe_math_optimizations"
16239{
16240  operands[2] = gen_reg_rtx (XFmode);
16241  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16242})
16243
16244(define_expand "asindf2"
16245  [(set (match_dup 2)
16246	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16247   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16248   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16249   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16250   (parallel [(set (match_dup 7)
16251        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16252			      UNSPEC_FPATAN))
16253   	      (clobber (match_scratch:XF 8 ""))])
16254   (set (match_operand:DF 0 "register_operand" "")
16255	(float_truncate:DF (match_dup 7)))]
16256  "TARGET_USE_FANCY_MATH_387
16257   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16258   && flag_unsafe_math_optimizations"
16259{
16260  int i;
16261
16262  for (i=2; i<8; i++)
16263    operands[i] = gen_reg_rtx (XFmode);
16264
16265  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16266})
16267
16268(define_expand "asinsf2"
16269  [(set (match_dup 2)
16270	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16271   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16272   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16273   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16274   (parallel [(set (match_dup 7)
16275        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16276			      UNSPEC_FPATAN))
16277   	      (clobber (match_scratch:XF 8 ""))])
16278   (set (match_operand:SF 0 "register_operand" "")
16279	(float_truncate:SF (match_dup 7)))]
16280  "TARGET_USE_FANCY_MATH_387
16281   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16282   && flag_unsafe_math_optimizations"
16283{
16284  int i;
16285
16286  for (i=2; i<8; i++)
16287    operands[i] = gen_reg_rtx (XFmode);
16288
16289  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16290})
16291
16292(define_expand "asinxf2"
16293  [(set (match_dup 2)
16294	(mult:XF (match_operand:XF 1 "register_operand" "")
16295		 (match_dup 1)))
16296   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16297   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16298   (parallel [(set (match_operand:XF 0 "register_operand" "")
16299        	   (unspec:XF [(match_dup 5) (match_dup 1)]
16300			      UNSPEC_FPATAN))
16301   	      (clobber (match_scratch:XF 6 ""))])]
16302  "TARGET_USE_FANCY_MATH_387
16303   && flag_unsafe_math_optimizations"
16304{
16305  int i;
16306
16307  for (i=2; i<6; i++)
16308    operands[i] = gen_reg_rtx (XFmode);
16309
16310  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16311})
16312
16313(define_expand "acosdf2"
16314  [(set (match_dup 2)
16315	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16316   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16317   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16318   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16319   (parallel [(set (match_dup 7)
16320        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16321			      UNSPEC_FPATAN))
16322   	      (clobber (match_scratch:XF 8 ""))])
16323   (set (match_operand:DF 0 "register_operand" "")
16324	(float_truncate:DF (match_dup 7)))]
16325  "TARGET_USE_FANCY_MATH_387
16326   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16327   && flag_unsafe_math_optimizations"
16328{
16329  int i;
16330
16331  for (i=2; i<8; i++)
16332    operands[i] = gen_reg_rtx (XFmode);
16333
16334  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16335})
16336
16337(define_expand "acossf2"
16338  [(set (match_dup 2)
16339	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16340   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16341   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16342   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16343   (parallel [(set (match_dup 7)
16344        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16345			      UNSPEC_FPATAN))
16346   	      (clobber (match_scratch:XF 8 ""))])
16347   (set (match_operand:SF 0 "register_operand" "")
16348	(float_truncate:SF (match_dup 7)))]
16349  "TARGET_USE_FANCY_MATH_387
16350   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16351   && flag_unsafe_math_optimizations"
16352{
16353  int i;
16354
16355  for (i=2; i<8; i++)
16356    operands[i] = gen_reg_rtx (XFmode);
16357
16358  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16359})
16360
16361(define_expand "acosxf2"
16362  [(set (match_dup 2)
16363	(mult:XF (match_operand:XF 1 "register_operand" "")
16364		 (match_dup 1)))
16365   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16366   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16367   (parallel [(set (match_operand:XF 0 "register_operand" "")
16368        	   (unspec:XF [(match_dup 1) (match_dup 5)]
16369			      UNSPEC_FPATAN))
16370   	      (clobber (match_scratch:XF 6 ""))])]
16371  "TARGET_USE_FANCY_MATH_387
16372   && flag_unsafe_math_optimizations"
16373{
16374  int i;
16375
16376  for (i=2; i<6; i++)
16377    operands[i] = gen_reg_rtx (XFmode);
16378
16379  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16380})
16381
16382(define_insn "fyl2x_xf3"
16383  [(set (match_operand:XF 0 "register_operand" "=f")
16384        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16385		    (match_operand:XF 1 "register_operand" "u")]
16386	           UNSPEC_FYL2X))
16387   (clobber (match_scratch:XF 3 "=1"))]
16388  "TARGET_USE_FANCY_MATH_387
16389   && flag_unsafe_math_optimizations"
16390  "fyl2x"
16391  [(set_attr "type" "fpspc")
16392   (set_attr "mode" "XF")])
16393
16394(define_expand "logsf2"
16395  [(set (match_dup 2)
16396	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16397   (parallel [(set (match_dup 4)
16398		   (unspec:XF [(match_dup 2)
16399			       (match_dup 3)] UNSPEC_FYL2X))
16400	      (clobber (match_scratch:XF 5 ""))])
16401   (set (match_operand:SF 0 "register_operand" "")
16402	(float_truncate:SF (match_dup 4)))]
16403  "TARGET_USE_FANCY_MATH_387
16404   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16405   && flag_unsafe_math_optimizations"
16406{
16407  rtx temp;
16408
16409  operands[2] = gen_reg_rtx (XFmode);
16410  operands[3] = gen_reg_rtx (XFmode);
16411  operands[4] = gen_reg_rtx (XFmode);
16412
16413  temp = standard_80387_constant_rtx (4); /* fldln2 */
16414  emit_move_insn (operands[3], temp);
16415})
16416
16417(define_expand "logdf2"
16418  [(set (match_dup 2)
16419	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16420   (parallel [(set (match_dup 4)
16421		   (unspec:XF [(match_dup 2)
16422			       (match_dup 3)] UNSPEC_FYL2X))
16423	      (clobber (match_scratch:XF 5 ""))])
16424   (set (match_operand:DF 0 "register_operand" "")
16425	(float_truncate:DF (match_dup 4)))]
16426  "TARGET_USE_FANCY_MATH_387
16427   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16428   && flag_unsafe_math_optimizations"
16429{
16430  rtx temp;
16431
16432  operands[2] = gen_reg_rtx (XFmode);
16433  operands[3] = gen_reg_rtx (XFmode);
16434  operands[4] = gen_reg_rtx (XFmode);
16435
16436  temp = standard_80387_constant_rtx (4); /* fldln2 */
16437  emit_move_insn (operands[3], temp);
16438})
16439
16440(define_expand "logxf2"
16441  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16442		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16443			       (match_dup 2)] UNSPEC_FYL2X))
16444	      (clobber (match_scratch:XF 3 ""))])]
16445  "TARGET_USE_FANCY_MATH_387
16446   && flag_unsafe_math_optimizations"
16447{
16448  rtx temp;
16449
16450  operands[2] = gen_reg_rtx (XFmode);
16451  temp = standard_80387_constant_rtx (4); /* fldln2 */
16452  emit_move_insn (operands[2], temp);
16453})
16454
16455(define_expand "log10sf2"
16456  [(set (match_dup 2)
16457	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16458   (parallel [(set (match_dup 4)
16459		   (unspec:XF [(match_dup 2)
16460			       (match_dup 3)] UNSPEC_FYL2X))
16461	      (clobber (match_scratch:XF 5 ""))])
16462   (set (match_operand:SF 0 "register_operand" "")
16463	(float_truncate:SF (match_dup 4)))]
16464  "TARGET_USE_FANCY_MATH_387
16465   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16466   && flag_unsafe_math_optimizations"
16467{
16468  rtx temp;
16469
16470  operands[2] = gen_reg_rtx (XFmode);
16471  operands[3] = gen_reg_rtx (XFmode);
16472  operands[4] = gen_reg_rtx (XFmode);
16473
16474  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16475  emit_move_insn (operands[3], temp);
16476})
16477
16478(define_expand "log10df2"
16479  [(set (match_dup 2)
16480	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16481   (parallel [(set (match_dup 4)
16482		   (unspec:XF [(match_dup 2)
16483			       (match_dup 3)] UNSPEC_FYL2X))
16484	      (clobber (match_scratch:XF 5 ""))])
16485   (set (match_operand:DF 0 "register_operand" "")
16486	(float_truncate:DF (match_dup 4)))]
16487  "TARGET_USE_FANCY_MATH_387
16488   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16489   && flag_unsafe_math_optimizations"
16490{
16491  rtx temp;
16492
16493  operands[2] = gen_reg_rtx (XFmode);
16494  operands[3] = gen_reg_rtx (XFmode);
16495  operands[4] = gen_reg_rtx (XFmode);
16496
16497  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16498  emit_move_insn (operands[3], temp);
16499})
16500
16501(define_expand "log10xf2"
16502  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16503		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16504			       (match_dup 2)] UNSPEC_FYL2X))
16505	      (clobber (match_scratch:XF 3 ""))])]
16506  "TARGET_USE_FANCY_MATH_387
16507   && flag_unsafe_math_optimizations"
16508{
16509  rtx temp;
16510
16511  operands[2] = gen_reg_rtx (XFmode);
16512  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16513  emit_move_insn (operands[2], temp);
16514})
16515
16516(define_expand "log2sf2"
16517  [(set (match_dup 2)
16518	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16519   (parallel [(set (match_dup 4)
16520		   (unspec:XF [(match_dup 2)
16521			       (match_dup 3)] UNSPEC_FYL2X))
16522	      (clobber (match_scratch:XF 5 ""))])
16523   (set (match_operand:SF 0 "register_operand" "")
16524	(float_truncate:SF (match_dup 4)))]
16525  "TARGET_USE_FANCY_MATH_387
16526   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16527   && flag_unsafe_math_optimizations"
16528{
16529  operands[2] = gen_reg_rtx (XFmode);
16530  operands[3] = gen_reg_rtx (XFmode);
16531  operands[4] = gen_reg_rtx (XFmode);
16532
16533  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16534})
16535
16536(define_expand "log2df2"
16537  [(set (match_dup 2)
16538	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16539   (parallel [(set (match_dup 4)
16540		   (unspec:XF [(match_dup 2)
16541			       (match_dup 3)] UNSPEC_FYL2X))
16542	      (clobber (match_scratch:XF 5 ""))])
16543   (set (match_operand:DF 0 "register_operand" "")
16544	(float_truncate:DF (match_dup 4)))]
16545  "TARGET_USE_FANCY_MATH_387
16546   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16547   && flag_unsafe_math_optimizations"
16548{
16549  operands[2] = gen_reg_rtx (XFmode);
16550  operands[3] = gen_reg_rtx (XFmode);
16551  operands[4] = gen_reg_rtx (XFmode);
16552
16553  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16554})
16555
16556(define_expand "log2xf2"
16557  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16558		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16559			       (match_dup 2)] UNSPEC_FYL2X))
16560	      (clobber (match_scratch:XF 3 ""))])]
16561  "TARGET_USE_FANCY_MATH_387
16562   && flag_unsafe_math_optimizations"
16563{
16564  operands[2] = gen_reg_rtx (XFmode);
16565  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16566})
16567
16568(define_insn "fyl2xp1_xf3"
16569  [(set (match_operand:XF 0 "register_operand" "=f")
16570        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16571		    (match_operand:XF 1 "register_operand" "u")]
16572	           UNSPEC_FYL2XP1))
16573   (clobber (match_scratch:XF 3 "=1"))]
16574  "TARGET_USE_FANCY_MATH_387
16575   && flag_unsafe_math_optimizations"
16576  "fyl2xp1"
16577  [(set_attr "type" "fpspc")
16578   (set_attr "mode" "XF")])
16579
16580(define_expand "log1psf2"
16581  [(use (match_operand:SF 0 "register_operand" ""))
16582   (use (match_operand:SF 1 "register_operand" ""))]
16583  "TARGET_USE_FANCY_MATH_387
16584   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16585   && flag_unsafe_math_optimizations"
16586{
16587  rtx op0 = gen_reg_rtx (XFmode);
16588  rtx op1 = gen_reg_rtx (XFmode);
16589
16590  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16591  ix86_emit_i387_log1p (op0, op1);
16592  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16593  DONE;
16594})
16595
16596(define_expand "log1pdf2"
16597  [(use (match_operand:DF 0 "register_operand" ""))
16598   (use (match_operand:DF 1 "register_operand" ""))]
16599  "TARGET_USE_FANCY_MATH_387
16600   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16601   && flag_unsafe_math_optimizations"
16602{
16603  rtx op0 = gen_reg_rtx (XFmode);
16604  rtx op1 = gen_reg_rtx (XFmode);
16605
16606  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16607  ix86_emit_i387_log1p (op0, op1);
16608  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16609  DONE;
16610})
16611
16612(define_expand "log1pxf2"
16613  [(use (match_operand:XF 0 "register_operand" ""))
16614   (use (match_operand:XF 1 "register_operand" ""))]
16615  "TARGET_USE_FANCY_MATH_387
16616   && flag_unsafe_math_optimizations"
16617{
16618  ix86_emit_i387_log1p (operands[0], operands[1]);
16619  DONE;
16620})
16621
16622(define_insn "*fxtractxf3"
16623  [(set (match_operand:XF 0 "register_operand" "=f")
16624	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16625		   UNSPEC_XTRACT_FRACT))
16626   (set (match_operand:XF 1 "register_operand" "=u")
16627        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16628  "TARGET_USE_FANCY_MATH_387
16629   && flag_unsafe_math_optimizations"
16630  "fxtract"
16631  [(set_attr "type" "fpspc")
16632   (set_attr "mode" "XF")])
16633
16634(define_expand "logbsf2"
16635  [(set (match_dup 2)
16636	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16637   (parallel [(set (match_dup 3)
16638		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16639	      (set (match_dup 4)
16640		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16641   (set (match_operand:SF 0 "register_operand" "")
16642	(float_truncate:SF (match_dup 4)))]
16643  "TARGET_USE_FANCY_MATH_387
16644   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16645   && flag_unsafe_math_optimizations"
16646{
16647  operands[2] = gen_reg_rtx (XFmode);
16648  operands[3] = gen_reg_rtx (XFmode);
16649  operands[4] = gen_reg_rtx (XFmode);
16650})
16651
16652(define_expand "logbdf2"
16653  [(set (match_dup 2)
16654	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16655   (parallel [(set (match_dup 3)
16656		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16657	      (set (match_dup 4)
16658		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16659   (set (match_operand:DF 0 "register_operand" "")
16660	(float_truncate:DF (match_dup 4)))]
16661  "TARGET_USE_FANCY_MATH_387
16662   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16663   && flag_unsafe_math_optimizations"
16664{
16665  operands[2] = gen_reg_rtx (XFmode);
16666  operands[3] = gen_reg_rtx (XFmode);
16667  operands[4] = gen_reg_rtx (XFmode);
16668})
16669
16670(define_expand "logbxf2"
16671  [(parallel [(set (match_dup 2)
16672		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16673			      UNSPEC_XTRACT_FRACT))
16674	      (set (match_operand:XF 0 "register_operand" "")
16675		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16676  "TARGET_USE_FANCY_MATH_387
16677   && flag_unsafe_math_optimizations"
16678{
16679  operands[2] = gen_reg_rtx (XFmode);
16680})
16681
16682(define_expand "ilogbsi2"
16683  [(parallel [(set (match_dup 2)
16684		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16685			      UNSPEC_XTRACT_FRACT))
16686	      (set (match_operand:XF 3 "register_operand" "")
16687		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16688   (parallel [(set (match_operand:SI 0 "register_operand" "")
16689	           (fix:SI (match_dup 3)))
16690	      (clobber (reg:CC FLAGS_REG))])]
16691  "TARGET_USE_FANCY_MATH_387
16692   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16693   && flag_unsafe_math_optimizations"
16694{
16695  operands[2] = gen_reg_rtx (XFmode);
16696  operands[3] = gen_reg_rtx (XFmode);
16697})
16698
16699(define_insn "*f2xm1xf2"
16700  [(set (match_operand:XF 0 "register_operand" "=f")
16701	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16702	 UNSPEC_F2XM1))]
16703  "TARGET_USE_FANCY_MATH_387
16704   && flag_unsafe_math_optimizations"
16705  "f2xm1"
16706  [(set_attr "type" "fpspc")
16707   (set_attr "mode" "XF")])
16708
16709(define_insn "*fscalexf4"
16710  [(set (match_operand:XF 0 "register_operand" "=f")
16711	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16712		    (match_operand:XF 3 "register_operand" "1")]
16713		   UNSPEC_FSCALE_FRACT))
16714   (set (match_operand:XF 1 "register_operand" "=u")
16715	(unspec:XF [(match_dup 2) (match_dup 3)]
16716		   UNSPEC_FSCALE_EXP))]
16717  "TARGET_USE_FANCY_MATH_387
16718   && flag_unsafe_math_optimizations"
16719  "fscale"
16720  [(set_attr "type" "fpspc")
16721   (set_attr "mode" "XF")])
16722
16723(define_expand "expsf2"
16724  [(set (match_dup 2)
16725	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16726   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16727   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16728   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16729   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16730   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16731   (parallel [(set (match_dup 10)
16732		   (unspec:XF [(match_dup 9) (match_dup 5)]
16733			      UNSPEC_FSCALE_FRACT))
16734	      (set (match_dup 11)
16735		   (unspec:XF [(match_dup 9) (match_dup 5)]
16736			      UNSPEC_FSCALE_EXP))])
16737   (set (match_operand:SF 0 "register_operand" "")
16738	(float_truncate:SF (match_dup 10)))]
16739  "TARGET_USE_FANCY_MATH_387
16740   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16741   && flag_unsafe_math_optimizations"
16742{
16743  rtx temp;
16744  int i;
16745
16746  for (i=2; i<12; i++)
16747    operands[i] = gen_reg_rtx (XFmode);
16748  temp = standard_80387_constant_rtx (5); /* fldl2e */
16749  emit_move_insn (operands[3], temp);
16750  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16751})
16752
16753(define_expand "expdf2"
16754  [(set (match_dup 2)
16755	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16756   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16757   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16758   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16759   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16760   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16761   (parallel [(set (match_dup 10)
16762		   (unspec:XF [(match_dup 9) (match_dup 5)]
16763			      UNSPEC_FSCALE_FRACT))
16764	      (set (match_dup 11)
16765		   (unspec:XF [(match_dup 9) (match_dup 5)]
16766			      UNSPEC_FSCALE_EXP))])
16767   (set (match_operand:DF 0 "register_operand" "")
16768	(float_truncate:DF (match_dup 10)))]
16769  "TARGET_USE_FANCY_MATH_387
16770   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16771   && flag_unsafe_math_optimizations"
16772{
16773  rtx temp;
16774  int i;
16775
16776  for (i=2; i<12; i++)
16777    operands[i] = gen_reg_rtx (XFmode);
16778  temp = standard_80387_constant_rtx (5); /* fldl2e */
16779  emit_move_insn (operands[3], temp);
16780  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16781})
16782
16783(define_expand "expxf2"
16784  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16785			       (match_dup 2)))
16786   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16787   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16788   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16789   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16790   (parallel [(set (match_operand:XF 0 "register_operand" "")
16791		   (unspec:XF [(match_dup 8) (match_dup 4)]
16792			      UNSPEC_FSCALE_FRACT))
16793	      (set (match_dup 9)
16794		   (unspec:XF [(match_dup 8) (match_dup 4)]
16795			      UNSPEC_FSCALE_EXP))])]
16796  "TARGET_USE_FANCY_MATH_387
16797   && flag_unsafe_math_optimizations"
16798{
16799  rtx temp;
16800  int i;
16801
16802  for (i=2; i<10; i++)
16803    operands[i] = gen_reg_rtx (XFmode);
16804  temp = standard_80387_constant_rtx (5); /* fldl2e */
16805  emit_move_insn (operands[2], temp);
16806  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16807})
16808
16809(define_expand "exp10sf2"
16810  [(set (match_dup 2)
16811	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16812   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16813   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16814   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16815   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16816   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16817   (parallel [(set (match_dup 10)
16818		   (unspec:XF [(match_dup 9) (match_dup 5)]
16819			      UNSPEC_FSCALE_FRACT))
16820	      (set (match_dup 11)
16821		   (unspec:XF [(match_dup 9) (match_dup 5)]
16822			      UNSPEC_FSCALE_EXP))])
16823   (set (match_operand:SF 0 "register_operand" "")
16824	(float_truncate:SF (match_dup 10)))]
16825  "TARGET_USE_FANCY_MATH_387
16826   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16827   && flag_unsafe_math_optimizations"
16828{
16829  rtx temp;
16830  int i;
16831
16832  for (i=2; i<12; i++)
16833    operands[i] = gen_reg_rtx (XFmode);
16834  temp = standard_80387_constant_rtx (6); /* fldl2t */
16835  emit_move_insn (operands[3], temp);
16836  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16837})
16838
16839(define_expand "exp10df2"
16840  [(set (match_dup 2)
16841	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16842   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16843   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16844   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16845   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16846   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16847   (parallel [(set (match_dup 10)
16848		   (unspec:XF [(match_dup 9) (match_dup 5)]
16849			      UNSPEC_FSCALE_FRACT))
16850	      (set (match_dup 11)
16851		   (unspec:XF [(match_dup 9) (match_dup 5)]
16852			      UNSPEC_FSCALE_EXP))])
16853   (set (match_operand:DF 0 "register_operand" "")
16854	(float_truncate:DF (match_dup 10)))]
16855  "TARGET_USE_FANCY_MATH_387
16856   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16857   && flag_unsafe_math_optimizations"
16858{
16859  rtx temp;
16860  int i;
16861
16862  for (i=2; i<12; i++)
16863    operands[i] = gen_reg_rtx (XFmode);
16864  temp = standard_80387_constant_rtx (6); /* fldl2t */
16865  emit_move_insn (operands[3], temp);
16866  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16867})
16868
16869(define_expand "exp10xf2"
16870  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16871			       (match_dup 2)))
16872   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16873   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16874   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16875   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16876   (parallel [(set (match_operand:XF 0 "register_operand" "")
16877		   (unspec:XF [(match_dup 8) (match_dup 4)]
16878			      UNSPEC_FSCALE_FRACT))
16879	      (set (match_dup 9)
16880		   (unspec:XF [(match_dup 8) (match_dup 4)]
16881			      UNSPEC_FSCALE_EXP))])]
16882  "TARGET_USE_FANCY_MATH_387
16883   && flag_unsafe_math_optimizations"
16884{
16885  rtx temp;
16886  int i;
16887
16888  for (i=2; i<10; i++)
16889    operands[i] = gen_reg_rtx (XFmode);
16890  temp = standard_80387_constant_rtx (6); /* fldl2t */
16891  emit_move_insn (operands[2], temp);
16892  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16893})
16894
16895(define_expand "exp2sf2"
16896  [(set (match_dup 2)
16897	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16898   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16899   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16900   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16901   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16902   (parallel [(set (match_dup 8)
16903		   (unspec:XF [(match_dup 7) (match_dup 3)]
16904			      UNSPEC_FSCALE_FRACT))
16905	      (set (match_dup 9)
16906		   (unspec:XF [(match_dup 7) (match_dup 3)]
16907			      UNSPEC_FSCALE_EXP))])
16908   (set (match_operand:SF 0 "register_operand" "")
16909	(float_truncate:SF (match_dup 8)))]
16910  "TARGET_USE_FANCY_MATH_387
16911   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16912   && flag_unsafe_math_optimizations"
16913{
16914  int i;
16915
16916  for (i=2; i<10; i++)
16917    operands[i] = gen_reg_rtx (XFmode);
16918  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16919})
16920
16921(define_expand "exp2df2"
16922  [(set (match_dup 2)
16923	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16924   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16925   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16926   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16927   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16928   (parallel [(set (match_dup 8)
16929		   (unspec:XF [(match_dup 7) (match_dup 3)]
16930			      UNSPEC_FSCALE_FRACT))
16931	      (set (match_dup 9)
16932		   (unspec:XF [(match_dup 7) (match_dup 3)]
16933			      UNSPEC_FSCALE_EXP))])
16934   (set (match_operand:DF 0 "register_operand" "")
16935	(float_truncate:DF (match_dup 8)))]
16936  "TARGET_USE_FANCY_MATH_387
16937   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16938   && flag_unsafe_math_optimizations"
16939{
16940  int i;
16941
16942  for (i=2; i<10; i++)
16943    operands[i] = gen_reg_rtx (XFmode);
16944  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16945})
16946
16947(define_expand "exp2xf2"
16948  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16949   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16950   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16951   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16952   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16953   (parallel [(set (match_operand:XF 0 "register_operand" "")
16954		   (unspec:XF [(match_dup 7) (match_dup 3)]
16955			      UNSPEC_FSCALE_FRACT))
16956	      (set (match_dup 8)
16957		   (unspec:XF [(match_dup 7) (match_dup 3)]
16958			      UNSPEC_FSCALE_EXP))])]
16959  "TARGET_USE_FANCY_MATH_387
16960   && flag_unsafe_math_optimizations"
16961{
16962  int i;
16963
16964  for (i=2; i<9; i++)
16965    operands[i] = gen_reg_rtx (XFmode);
16966  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16967})
16968
16969(define_expand "expm1df2"
16970  [(set (match_dup 2)
16971	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16972   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16973   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16974   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16975   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16976   (parallel [(set (match_dup 8)
16977		   (unspec:XF [(match_dup 7) (match_dup 5)]
16978			      UNSPEC_FSCALE_FRACT))
16979		   (set (match_dup 9)
16980		   (unspec:XF [(match_dup 7) (match_dup 5)]
16981			      UNSPEC_FSCALE_EXP))])
16982   (parallel [(set (match_dup 11)
16983		   (unspec:XF [(match_dup 10) (match_dup 9)]
16984			      UNSPEC_FSCALE_FRACT))
16985	      (set (match_dup 12)
16986		   (unspec:XF [(match_dup 10) (match_dup 9)]
16987			      UNSPEC_FSCALE_EXP))])
16988   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16989   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16990   (set (match_operand:DF 0 "register_operand" "")
16991	(float_truncate:DF (match_dup 14)))]
16992  "TARGET_USE_FANCY_MATH_387
16993   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16994   && flag_unsafe_math_optimizations"
16995{
16996  rtx temp;
16997  int i;
16998
16999  for (i=2; i<15; i++)
17000    operands[i] = gen_reg_rtx (XFmode);
17001  temp = standard_80387_constant_rtx (5); /* fldl2e */
17002  emit_move_insn (operands[3], temp);
17003  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17004})
17005
17006(define_expand "expm1sf2"
17007  [(set (match_dup 2)
17008	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17009   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17010   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17011   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17012   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17013   (parallel [(set (match_dup 8)
17014		   (unspec:XF [(match_dup 7) (match_dup 5)]
17015			      UNSPEC_FSCALE_FRACT))
17016		   (set (match_dup 9)
17017		   (unspec:XF [(match_dup 7) (match_dup 5)]
17018			      UNSPEC_FSCALE_EXP))])
17019   (parallel [(set (match_dup 11)
17020		   (unspec:XF [(match_dup 10) (match_dup 9)]
17021			      UNSPEC_FSCALE_FRACT))
17022	      (set (match_dup 12)
17023		   (unspec:XF [(match_dup 10) (match_dup 9)]
17024			      UNSPEC_FSCALE_EXP))])
17025   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17026   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17027   (set (match_operand:SF 0 "register_operand" "")
17028	(float_truncate:SF (match_dup 14)))]
17029  "TARGET_USE_FANCY_MATH_387
17030   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17031   && flag_unsafe_math_optimizations"
17032{
17033  rtx temp;
17034  int i;
17035
17036  for (i=2; i<15; i++)
17037    operands[i] = gen_reg_rtx (XFmode);
17038  temp = standard_80387_constant_rtx (5); /* fldl2e */
17039  emit_move_insn (operands[3], temp);
17040  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17041})
17042
17043(define_expand "expm1xf2"
17044  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17045			       (match_dup 2)))
17046   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17047   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17048   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17049   (parallel [(set (match_dup 7)
17050		   (unspec:XF [(match_dup 6) (match_dup 4)]
17051			      UNSPEC_FSCALE_FRACT))
17052		   (set (match_dup 8)
17053		   (unspec:XF [(match_dup 6) (match_dup 4)]
17054			      UNSPEC_FSCALE_EXP))])
17055   (parallel [(set (match_dup 10)
17056		   (unspec:XF [(match_dup 9) (match_dup 8)]
17057			      UNSPEC_FSCALE_FRACT))
17058	      (set (match_dup 11)
17059		   (unspec:XF [(match_dup 9) (match_dup 8)]
17060			      UNSPEC_FSCALE_EXP))])
17061   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17062   (set (match_operand:XF 0 "register_operand" "")
17063	(plus:XF (match_dup 12) (match_dup 7)))]
17064  "TARGET_USE_FANCY_MATH_387
17065   && flag_unsafe_math_optimizations"
17066{
17067  rtx temp;
17068  int i;
17069
17070  for (i=2; i<13; i++)
17071    operands[i] = gen_reg_rtx (XFmode);
17072  temp = standard_80387_constant_rtx (5); /* fldl2e */
17073  emit_move_insn (operands[2], temp);
17074  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17075})
17076
17077(define_expand "ldexpdf3"
17078  [(set (match_dup 3)
17079	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17080   (set (match_dup 4)
17081	(float:XF (match_operand:SI 2 "register_operand" "")))
17082   (parallel [(set (match_dup 5)
17083		   (unspec:XF [(match_dup 3) (match_dup 4)]
17084			      UNSPEC_FSCALE_FRACT))
17085	      (set (match_dup 6)
17086		   (unspec:XF [(match_dup 3) (match_dup 4)]
17087			      UNSPEC_FSCALE_EXP))])
17088   (set (match_operand:DF 0 "register_operand" "")
17089	(float_truncate:DF (match_dup 5)))]
17090  "TARGET_USE_FANCY_MATH_387
17091   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17092   && flag_unsafe_math_optimizations"
17093{
17094  int i;
17095
17096  for (i=3; i<7; i++)
17097    operands[i] = gen_reg_rtx (XFmode);
17098})
17099
17100(define_expand "ldexpsf3"
17101  [(set (match_dup 3)
17102	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17103   (set (match_dup 4)
17104	(float:XF (match_operand:SI 2 "register_operand" "")))
17105   (parallel [(set (match_dup 5)
17106		   (unspec:XF [(match_dup 3) (match_dup 4)]
17107			      UNSPEC_FSCALE_FRACT))
17108	      (set (match_dup 6)
17109		   (unspec:XF [(match_dup 3) (match_dup 4)]
17110			      UNSPEC_FSCALE_EXP))])
17111   (set (match_operand:SF 0 "register_operand" "")
17112	(float_truncate:SF (match_dup 5)))]
17113  "TARGET_USE_FANCY_MATH_387
17114   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17115   && flag_unsafe_math_optimizations"
17116{
17117  int i;
17118
17119  for (i=3; i<7; i++)
17120    operands[i] = gen_reg_rtx (XFmode);
17121})
17122
17123(define_expand "ldexpxf3"
17124  [(set (match_dup 3)
17125	(float:XF (match_operand:SI 2 "register_operand" "")))
17126   (parallel [(set (match_operand:XF 0 " register_operand" "")
17127		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
17128			       (match_dup 3)]
17129			      UNSPEC_FSCALE_FRACT))
17130	      (set (match_dup 4)
17131		   (unspec:XF [(match_dup 1) (match_dup 3)]
17132			      UNSPEC_FSCALE_EXP))])]
17133  "TARGET_USE_FANCY_MATH_387
17134   && flag_unsafe_math_optimizations"
17135{
17136  int i;
17137
17138  for (i=3; i<5; i++)
17139    operands[i] = gen_reg_rtx (XFmode);
17140})
17141
17142
17143(define_insn "frndintxf2"
17144  [(set (match_operand:XF 0 "register_operand" "=f")
17145	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17146	 UNSPEC_FRNDINT))]
17147  "TARGET_USE_FANCY_MATH_387
17148   && flag_unsafe_math_optimizations"
17149  "frndint"
17150  [(set_attr "type" "fpspc")
17151   (set_attr "mode" "XF")])
17152
17153(define_expand "rintdf2"
17154  [(use (match_operand:DF 0 "register_operand" ""))
17155   (use (match_operand:DF 1 "register_operand" ""))]
17156  "TARGET_USE_FANCY_MATH_387
17157   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17158   && flag_unsafe_math_optimizations"
17159{
17160  rtx op0 = gen_reg_rtx (XFmode);
17161  rtx op1 = gen_reg_rtx (XFmode);
17162
17163  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17164  emit_insn (gen_frndintxf2 (op0, op1));
17165
17166  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17167  DONE;
17168})
17169
17170(define_expand "rintsf2"
17171  [(use (match_operand:SF 0 "register_operand" ""))
17172   (use (match_operand:SF 1 "register_operand" ""))]
17173  "TARGET_USE_FANCY_MATH_387
17174   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17175   && flag_unsafe_math_optimizations"
17176{
17177  rtx op0 = gen_reg_rtx (XFmode);
17178  rtx op1 = gen_reg_rtx (XFmode);
17179
17180  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17181  emit_insn (gen_frndintxf2 (op0, op1));
17182
17183  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17184  DONE;
17185})
17186
17187(define_expand "rintxf2"
17188  [(use (match_operand:XF 0 "register_operand" ""))
17189   (use (match_operand:XF 1 "register_operand" ""))]
17190  "TARGET_USE_FANCY_MATH_387
17191   && flag_unsafe_math_optimizations"
17192{
17193  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17194  DONE;
17195})
17196
17197(define_insn_and_split "*fistdi2_1"
17198  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17199	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17200	 UNSPEC_FIST))]
17201  "TARGET_USE_FANCY_MATH_387
17202   && flag_unsafe_math_optimizations
17203   && !(reload_completed || reload_in_progress)"
17204  "#"
17205  "&& 1"
17206  [(const_int 0)]
17207{
17208  if (memory_operand (operands[0], VOIDmode))
17209    emit_insn (gen_fistdi2 (operands[0], operands[1]));
17210  else
17211    {
17212      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17213      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17214					 operands[2]));
17215    }
17216  DONE;
17217}
17218  [(set_attr "type" "fpspc")
17219   (set_attr "mode" "DI")])
17220
17221(define_insn "fistdi2"
17222  [(set (match_operand:DI 0 "memory_operand" "=m")
17223	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17224	 UNSPEC_FIST))
17225   (clobber (match_scratch:XF 2 "=&1f"))]
17226  "TARGET_USE_FANCY_MATH_387
17227   && flag_unsafe_math_optimizations"
17228  "* return output_fix_trunc (insn, operands, 0);"
17229  [(set_attr "type" "fpspc")
17230   (set_attr "mode" "DI")])
17231
17232(define_insn "fistdi2_with_temp"
17233  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17234	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17235	 UNSPEC_FIST))
17236   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17237   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17238  "TARGET_USE_FANCY_MATH_387
17239   && flag_unsafe_math_optimizations"
17240  "#"
17241  [(set_attr "type" "fpspc")
17242   (set_attr "mode" "DI")])
17243
17244(define_split 
17245  [(set (match_operand:DI 0 "register_operand" "")
17246	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17247	 UNSPEC_FIST))
17248   (clobber (match_operand:DI 2 "memory_operand" ""))
17249   (clobber (match_scratch 3 ""))]
17250  "reload_completed"
17251  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17252	      (clobber (match_dup 3))])
17253   (set (match_dup 0) (match_dup 2))]
17254  "")
17255
17256(define_split 
17257  [(set (match_operand:DI 0 "memory_operand" "")
17258	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17259	 UNSPEC_FIST))
17260   (clobber (match_operand:DI 2 "memory_operand" ""))
17261   (clobber (match_scratch 3 ""))]
17262  "reload_completed"
17263  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17264	      (clobber (match_dup 3))])]
17265  "")
17266
17267(define_insn_and_split "*fist<mode>2_1"
17268  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17269	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17270	 UNSPEC_FIST))]
17271  "TARGET_USE_FANCY_MATH_387
17272   && flag_unsafe_math_optimizations
17273   && !(reload_completed || reload_in_progress)"
17274  "#"
17275  "&& 1"
17276  [(const_int 0)]
17277{
17278  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17279  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17280					operands[2]));
17281  DONE;
17282}
17283  [(set_attr "type" "fpspc")
17284   (set_attr "mode" "<MODE>")])
17285
17286(define_insn "fist<mode>2"
17287  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17288	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17289	 UNSPEC_FIST))]
17290  "TARGET_USE_FANCY_MATH_387
17291   && flag_unsafe_math_optimizations"
17292  "* return output_fix_trunc (insn, operands, 0);"
17293  [(set_attr "type" "fpspc")
17294   (set_attr "mode" "<MODE>")])
17295
17296(define_insn "fist<mode>2_with_temp"
17297  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17298	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17299	 UNSPEC_FIST))
17300   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17301  "TARGET_USE_FANCY_MATH_387
17302   && flag_unsafe_math_optimizations"
17303  "#"
17304  [(set_attr "type" "fpspc")
17305   (set_attr "mode" "<MODE>")])
17306
17307(define_split 
17308  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17309	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17310	 UNSPEC_FIST))
17311   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17312  "reload_completed"
17313  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17314		       UNSPEC_FIST))
17315   (set (match_dup 0) (match_dup 2))]
17316  "")
17317
17318(define_split 
17319  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17320	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17321	 UNSPEC_FIST))
17322   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17323  "reload_completed"
17324  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17325		       UNSPEC_FIST))]
17326  "")
17327
17328(define_expand "lrint<mode>2"
17329  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17330	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17331	 UNSPEC_FIST))]
17332  "TARGET_USE_FANCY_MATH_387
17333   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17334   && flag_unsafe_math_optimizations"
17335  "")
17336
17337;; Rounding mode control word calculation could clobber FLAGS_REG.
17338(define_insn_and_split "frndintxf2_floor"
17339  [(set (match_operand:XF 0 "register_operand" "=f")
17340	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17341	 UNSPEC_FRNDINT_FLOOR))
17342   (clobber (reg:CC FLAGS_REG))]
17343  "TARGET_USE_FANCY_MATH_387
17344   && flag_unsafe_math_optimizations
17345   && !(reload_completed || reload_in_progress)"
17346  "#"
17347  "&& 1"
17348  [(const_int 0)]
17349{
17350  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17351
17352  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17353  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17354
17355  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17356					operands[2], operands[3]));
17357  DONE;
17358}
17359  [(set_attr "type" "frndint")
17360   (set_attr "i387_cw" "floor")
17361   (set_attr "mode" "XF")])
17362
17363(define_insn "frndintxf2_floor_i387"
17364  [(set (match_operand:XF 0 "register_operand" "=f")
17365	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17366	 UNSPEC_FRNDINT_FLOOR))
17367   (use (match_operand:HI 2 "memory_operand" "m"))
17368   (use (match_operand:HI 3 "memory_operand" "m"))]
17369  "TARGET_USE_FANCY_MATH_387
17370   && flag_unsafe_math_optimizations"
17371  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17372  [(set_attr "type" "frndint")
17373   (set_attr "i387_cw" "floor")
17374   (set_attr "mode" "XF")])
17375
17376(define_expand "floorxf2"
17377  [(use (match_operand:XF 0 "register_operand" ""))
17378   (use (match_operand:XF 1 "register_operand" ""))]
17379  "TARGET_USE_FANCY_MATH_387
17380   && flag_unsafe_math_optimizations"
17381{
17382  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17383  DONE;
17384})
17385
17386(define_expand "floordf2"
17387  [(use (match_operand:DF 0 "register_operand" ""))
17388   (use (match_operand:DF 1 "register_operand" ""))]
17389  "TARGET_USE_FANCY_MATH_387
17390   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17391   && flag_unsafe_math_optimizations"
17392{
17393  rtx op0 = gen_reg_rtx (XFmode);
17394  rtx op1 = gen_reg_rtx (XFmode);
17395
17396  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17397  emit_insn (gen_frndintxf2_floor (op0, op1));
17398
17399  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17400  DONE;
17401})
17402
17403(define_expand "floorsf2"
17404  [(use (match_operand:SF 0 "register_operand" ""))
17405   (use (match_operand:SF 1 "register_operand" ""))]
17406  "TARGET_USE_FANCY_MATH_387
17407   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17408   && flag_unsafe_math_optimizations"
17409{
17410  rtx op0 = gen_reg_rtx (XFmode);
17411  rtx op1 = gen_reg_rtx (XFmode);
17412
17413  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17414  emit_insn (gen_frndintxf2_floor (op0, op1));
17415
17416  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17417  DONE;
17418})
17419
17420(define_insn_and_split "*fist<mode>2_floor_1"
17421  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17422	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17423	 UNSPEC_FIST_FLOOR))
17424   (clobber (reg:CC FLAGS_REG))]
17425  "TARGET_USE_FANCY_MATH_387
17426   && flag_unsafe_math_optimizations
17427   && !(reload_completed || reload_in_progress)"
17428  "#"
17429  "&& 1"
17430  [(const_int 0)]
17431{
17432  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17433
17434  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17435  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17436  if (memory_operand (operands[0], VOIDmode))
17437    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17438				      operands[2], operands[3]));
17439  else
17440    {
17441      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17442      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17443						  operands[2], operands[3],
17444						  operands[4]));
17445    }
17446  DONE;
17447}
17448  [(set_attr "type" "fistp")
17449   (set_attr "i387_cw" "floor")
17450   (set_attr "mode" "<MODE>")])
17451
17452(define_insn "fistdi2_floor"
17453  [(set (match_operand:DI 0 "memory_operand" "=m")
17454	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17455	 UNSPEC_FIST_FLOOR))
17456   (use (match_operand:HI 2 "memory_operand" "m"))
17457   (use (match_operand:HI 3 "memory_operand" "m"))
17458   (clobber (match_scratch:XF 4 "=&1f"))]
17459  "TARGET_USE_FANCY_MATH_387
17460   && flag_unsafe_math_optimizations"
17461  "* return output_fix_trunc (insn, operands, 0);"
17462  [(set_attr "type" "fistp")
17463   (set_attr "i387_cw" "floor")
17464   (set_attr "mode" "DI")])
17465
17466(define_insn "fistdi2_floor_with_temp"
17467  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17468	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17469	 UNSPEC_FIST_FLOOR))
17470   (use (match_operand:HI 2 "memory_operand" "m,m"))
17471   (use (match_operand:HI 3 "memory_operand" "m,m"))
17472   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17473   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17474  "TARGET_USE_FANCY_MATH_387
17475   && flag_unsafe_math_optimizations"
17476  "#"
17477  [(set_attr "type" "fistp")
17478   (set_attr "i387_cw" "floor")
17479   (set_attr "mode" "DI")])
17480
17481(define_split 
17482  [(set (match_operand:DI 0 "register_operand" "")
17483	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17484	 UNSPEC_FIST_FLOOR))
17485   (use (match_operand:HI 2 "memory_operand" ""))
17486   (use (match_operand:HI 3 "memory_operand" ""))
17487   (clobber (match_operand:DI 4 "memory_operand" ""))
17488   (clobber (match_scratch 5 ""))]
17489  "reload_completed"
17490  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17491	      (use (match_dup 2))
17492	      (use (match_dup 3))
17493	      (clobber (match_dup 5))])
17494   (set (match_dup 0) (match_dup 4))]
17495  "")
17496
17497(define_split 
17498  [(set (match_operand:DI 0 "memory_operand" "")
17499	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17500	 UNSPEC_FIST_FLOOR))
17501   (use (match_operand:HI 2 "memory_operand" ""))
17502   (use (match_operand:HI 3 "memory_operand" ""))
17503   (clobber (match_operand:DI 4 "memory_operand" ""))
17504   (clobber (match_scratch 5 ""))]
17505  "reload_completed"
17506  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17507	      (use (match_dup 2))
17508	      (use (match_dup 3))
17509	      (clobber (match_dup 5))])]
17510  "")
17511
17512(define_insn "fist<mode>2_floor"
17513  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17514	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17515	 UNSPEC_FIST_FLOOR))
17516   (use (match_operand:HI 2 "memory_operand" "m"))
17517   (use (match_operand:HI 3 "memory_operand" "m"))]
17518  "TARGET_USE_FANCY_MATH_387
17519   && flag_unsafe_math_optimizations"
17520  "* return output_fix_trunc (insn, operands, 0);"
17521  [(set_attr "type" "fistp")
17522   (set_attr "i387_cw" "floor")
17523   (set_attr "mode" "<MODE>")])
17524
17525(define_insn "fist<mode>2_floor_with_temp"
17526  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17527	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17528	 UNSPEC_FIST_FLOOR))
17529   (use (match_operand:HI 2 "memory_operand" "m,m"))
17530   (use (match_operand:HI 3 "memory_operand" "m,m"))
17531   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17532  "TARGET_USE_FANCY_MATH_387
17533   && flag_unsafe_math_optimizations"
17534  "#"
17535  [(set_attr "type" "fistp")
17536   (set_attr "i387_cw" "floor")
17537   (set_attr "mode" "<MODE>")])
17538
17539(define_split 
17540  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17541	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17542	 UNSPEC_FIST_FLOOR))
17543   (use (match_operand:HI 2 "memory_operand" ""))
17544   (use (match_operand:HI 3 "memory_operand" ""))
17545   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17546  "reload_completed"
17547  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17548				  UNSPEC_FIST_FLOOR))
17549	      (use (match_dup 2))
17550	      (use (match_dup 3))])
17551   (set (match_dup 0) (match_dup 4))]
17552  "")
17553
17554(define_split 
17555  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17556	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17557	 UNSPEC_FIST_FLOOR))
17558   (use (match_operand:HI 2 "memory_operand" ""))
17559   (use (match_operand:HI 3 "memory_operand" ""))
17560   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17561  "reload_completed"
17562  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17563				  UNSPEC_FIST_FLOOR))
17564	      (use (match_dup 2))
17565	      (use (match_dup 3))])]
17566  "")
17567
17568(define_expand "lfloor<mode>2"
17569  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17570		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17571		    UNSPEC_FIST_FLOOR))
17572	      (clobber (reg:CC FLAGS_REG))])]
17573  "TARGET_USE_FANCY_MATH_387
17574   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17575   && flag_unsafe_math_optimizations"
17576  "")
17577
17578;; Rounding mode control word calculation could clobber FLAGS_REG.
17579(define_insn_and_split "frndintxf2_ceil"
17580  [(set (match_operand:XF 0 "register_operand" "=f")
17581	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17582	 UNSPEC_FRNDINT_CEIL))
17583   (clobber (reg:CC FLAGS_REG))]
17584  "TARGET_USE_FANCY_MATH_387
17585   && flag_unsafe_math_optimizations
17586   && !(reload_completed || reload_in_progress)"
17587  "#"
17588  "&& 1"
17589  [(const_int 0)]
17590{
17591  ix86_optimize_mode_switching[I387_CEIL] = 1;
17592
17593  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17594  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17595
17596  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17597				       operands[2], operands[3]));
17598  DONE;
17599}
17600  [(set_attr "type" "frndint")
17601   (set_attr "i387_cw" "ceil")
17602   (set_attr "mode" "XF")])
17603
17604(define_insn "frndintxf2_ceil_i387"
17605  [(set (match_operand:XF 0 "register_operand" "=f")
17606	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17607	 UNSPEC_FRNDINT_CEIL))
17608   (use (match_operand:HI 2 "memory_operand" "m"))
17609   (use (match_operand:HI 3 "memory_operand" "m"))]
17610  "TARGET_USE_FANCY_MATH_387
17611   && flag_unsafe_math_optimizations"
17612  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17613  [(set_attr "type" "frndint")
17614   (set_attr "i387_cw" "ceil")
17615   (set_attr "mode" "XF")])
17616
17617(define_expand "ceilxf2"
17618  [(use (match_operand:XF 0 "register_operand" ""))
17619   (use (match_operand:XF 1 "register_operand" ""))]
17620  "TARGET_USE_FANCY_MATH_387
17621   && flag_unsafe_math_optimizations"
17622{
17623  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17624  DONE;
17625})
17626
17627(define_expand "ceildf2"
17628  [(use (match_operand:DF 0 "register_operand" ""))
17629   (use (match_operand:DF 1 "register_operand" ""))]
17630  "TARGET_USE_FANCY_MATH_387
17631   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17632   && flag_unsafe_math_optimizations"
17633{
17634  rtx op0 = gen_reg_rtx (XFmode);
17635  rtx op1 = gen_reg_rtx (XFmode);
17636
17637  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17638  emit_insn (gen_frndintxf2_ceil (op0, op1));
17639
17640  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17641  DONE;
17642})
17643
17644(define_expand "ceilsf2"
17645  [(use (match_operand:SF 0 "register_operand" ""))
17646   (use (match_operand:SF 1 "register_operand" ""))]
17647  "TARGET_USE_FANCY_MATH_387
17648   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17649   && flag_unsafe_math_optimizations"
17650{
17651  rtx op0 = gen_reg_rtx (XFmode);
17652  rtx op1 = gen_reg_rtx (XFmode);
17653
17654  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17655  emit_insn (gen_frndintxf2_ceil (op0, op1));
17656
17657  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17658  DONE;
17659})
17660
17661(define_insn_and_split "*fist<mode>2_ceil_1"
17662  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17663	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17664	 UNSPEC_FIST_CEIL))
17665   (clobber (reg:CC FLAGS_REG))]
17666  "TARGET_USE_FANCY_MATH_387
17667   && flag_unsafe_math_optimizations
17668   && !(reload_completed || reload_in_progress)"
17669  "#"
17670  "&& 1"
17671  [(const_int 0)]
17672{
17673  ix86_optimize_mode_switching[I387_CEIL] = 1;
17674
17675  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17676  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17677  if (memory_operand (operands[0], VOIDmode))
17678    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17679				     operands[2], operands[3]));
17680  else
17681    {
17682      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17683      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17684						 operands[2], operands[3],
17685						 operands[4]));
17686    }
17687  DONE;
17688}
17689  [(set_attr "type" "fistp")
17690   (set_attr "i387_cw" "ceil")
17691   (set_attr "mode" "<MODE>")])
17692
17693(define_insn "fistdi2_ceil"
17694  [(set (match_operand:DI 0 "memory_operand" "=m")
17695	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17696	 UNSPEC_FIST_CEIL))
17697   (use (match_operand:HI 2 "memory_operand" "m"))
17698   (use (match_operand:HI 3 "memory_operand" "m"))
17699   (clobber (match_scratch:XF 4 "=&1f"))]
17700  "TARGET_USE_FANCY_MATH_387
17701   && flag_unsafe_math_optimizations"
17702  "* return output_fix_trunc (insn, operands, 0);"
17703  [(set_attr "type" "fistp")
17704   (set_attr "i387_cw" "ceil")
17705   (set_attr "mode" "DI")])
17706
17707(define_insn "fistdi2_ceil_with_temp"
17708  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17709	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17710	 UNSPEC_FIST_CEIL))
17711   (use (match_operand:HI 2 "memory_operand" "m,m"))
17712   (use (match_operand:HI 3 "memory_operand" "m,m"))
17713   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17714   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17715  "TARGET_USE_FANCY_MATH_387
17716   && flag_unsafe_math_optimizations"
17717  "#"
17718  [(set_attr "type" "fistp")
17719   (set_attr "i387_cw" "ceil")
17720   (set_attr "mode" "DI")])
17721
17722(define_split 
17723  [(set (match_operand:DI 0 "register_operand" "")
17724	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17725	 UNSPEC_FIST_CEIL))
17726   (use (match_operand:HI 2 "memory_operand" ""))
17727   (use (match_operand:HI 3 "memory_operand" ""))
17728   (clobber (match_operand:DI 4 "memory_operand" ""))
17729   (clobber (match_scratch 5 ""))]
17730  "reload_completed"
17731  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17732	      (use (match_dup 2))
17733	      (use (match_dup 3))
17734	      (clobber (match_dup 5))])
17735   (set (match_dup 0) (match_dup 4))]
17736  "")
17737
17738(define_split 
17739  [(set (match_operand:DI 0 "memory_operand" "")
17740	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17741	 UNSPEC_FIST_CEIL))
17742   (use (match_operand:HI 2 "memory_operand" ""))
17743   (use (match_operand:HI 3 "memory_operand" ""))
17744   (clobber (match_operand:DI 4 "memory_operand" ""))
17745   (clobber (match_scratch 5 ""))]
17746  "reload_completed"
17747  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17748	      (use (match_dup 2))
17749	      (use (match_dup 3))
17750	      (clobber (match_dup 5))])]
17751  "")
17752
17753(define_insn "fist<mode>2_ceil"
17754  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17755	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17756	 UNSPEC_FIST_CEIL))
17757   (use (match_operand:HI 2 "memory_operand" "m"))
17758   (use (match_operand:HI 3 "memory_operand" "m"))]
17759  "TARGET_USE_FANCY_MATH_387
17760   && flag_unsafe_math_optimizations"
17761  "* return output_fix_trunc (insn, operands, 0);"
17762  [(set_attr "type" "fistp")
17763   (set_attr "i387_cw" "ceil")
17764   (set_attr "mode" "<MODE>")])
17765
17766(define_insn "fist<mode>2_ceil_with_temp"
17767  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17768	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17769	 UNSPEC_FIST_CEIL))
17770   (use (match_operand:HI 2 "memory_operand" "m,m"))
17771   (use (match_operand:HI 3 "memory_operand" "m,m"))
17772   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17773  "TARGET_USE_FANCY_MATH_387
17774   && flag_unsafe_math_optimizations"
17775  "#"
17776  [(set_attr "type" "fistp")
17777   (set_attr "i387_cw" "ceil")
17778   (set_attr "mode" "<MODE>")])
17779
17780(define_split 
17781  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17782	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17783	 UNSPEC_FIST_CEIL))
17784   (use (match_operand:HI 2 "memory_operand" ""))
17785   (use (match_operand:HI 3 "memory_operand" ""))
17786   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17787  "reload_completed"
17788  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17789				  UNSPEC_FIST_CEIL))
17790	      (use (match_dup 2))
17791	      (use (match_dup 3))])
17792   (set (match_dup 0) (match_dup 4))]
17793  "")
17794
17795(define_split 
17796  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17797	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17798	 UNSPEC_FIST_CEIL))
17799   (use (match_operand:HI 2 "memory_operand" ""))
17800   (use (match_operand:HI 3 "memory_operand" ""))
17801   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17802  "reload_completed"
17803  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17804				  UNSPEC_FIST_CEIL))
17805	      (use (match_dup 2))
17806	      (use (match_dup 3))])]
17807  "")
17808
17809(define_expand "lceil<mode>2"
17810  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17811		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17812		    UNSPEC_FIST_CEIL))
17813	      (clobber (reg:CC FLAGS_REG))])]
17814  "TARGET_USE_FANCY_MATH_387
17815   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17816   && flag_unsafe_math_optimizations"
17817  "")
17818
17819;; Rounding mode control word calculation could clobber FLAGS_REG.
17820(define_insn_and_split "frndintxf2_trunc"
17821  [(set (match_operand:XF 0 "register_operand" "=f")
17822	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17823	 UNSPEC_FRNDINT_TRUNC))
17824   (clobber (reg:CC FLAGS_REG))]
17825  "TARGET_USE_FANCY_MATH_387
17826   && flag_unsafe_math_optimizations
17827   && !(reload_completed || reload_in_progress)"
17828  "#"
17829  "&& 1"
17830  [(const_int 0)]
17831{
17832  ix86_optimize_mode_switching[I387_TRUNC] = 1;
17833
17834  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17835  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17836
17837  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17838					operands[2], operands[3]));
17839  DONE;
17840}
17841  [(set_attr "type" "frndint")
17842   (set_attr "i387_cw" "trunc")
17843   (set_attr "mode" "XF")])
17844
17845(define_insn "frndintxf2_trunc_i387"
17846  [(set (match_operand:XF 0 "register_operand" "=f")
17847	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848	 UNSPEC_FRNDINT_TRUNC))
17849   (use (match_operand:HI 2 "memory_operand" "m"))
17850   (use (match_operand:HI 3 "memory_operand" "m"))]
17851  "TARGET_USE_FANCY_MATH_387
17852   && flag_unsafe_math_optimizations"
17853  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17854  [(set_attr "type" "frndint")
17855   (set_attr "i387_cw" "trunc")
17856   (set_attr "mode" "XF")])
17857
17858(define_expand "btruncxf2"
17859  [(use (match_operand:XF 0 "register_operand" ""))
17860   (use (match_operand:XF 1 "register_operand" ""))]
17861  "TARGET_USE_FANCY_MATH_387
17862   && flag_unsafe_math_optimizations"
17863{
17864  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17865  DONE;
17866})
17867
17868(define_expand "btruncdf2"
17869  [(use (match_operand:DF 0 "register_operand" ""))
17870   (use (match_operand:DF 1 "register_operand" ""))]
17871  "TARGET_USE_FANCY_MATH_387
17872   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17873   && flag_unsafe_math_optimizations"
17874{
17875  rtx op0 = gen_reg_rtx (XFmode);
17876  rtx op1 = gen_reg_rtx (XFmode);
17877
17878  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17879  emit_insn (gen_frndintxf2_trunc (op0, op1));
17880
17881  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17882  DONE;
17883})
17884
17885(define_expand "btruncsf2"
17886  [(use (match_operand:SF 0 "register_operand" ""))
17887   (use (match_operand:SF 1 "register_operand" ""))]
17888  "TARGET_USE_FANCY_MATH_387
17889   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17890   && flag_unsafe_math_optimizations"
17891{
17892  rtx op0 = gen_reg_rtx (XFmode);
17893  rtx op1 = gen_reg_rtx (XFmode);
17894
17895  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17896  emit_insn (gen_frndintxf2_trunc (op0, op1));
17897
17898  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17899  DONE;
17900})
17901
17902;; Rounding mode control word calculation could clobber FLAGS_REG.
17903(define_insn_and_split "frndintxf2_mask_pm"
17904  [(set (match_operand:XF 0 "register_operand" "=f")
17905	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17906	 UNSPEC_FRNDINT_MASK_PM))
17907   (clobber (reg:CC FLAGS_REG))]
17908  "TARGET_USE_FANCY_MATH_387
17909   && flag_unsafe_math_optimizations
17910   && !(reload_completed || reload_in_progress)"
17911  "#"
17912  "&& 1"
17913  [(const_int 0)]
17914{
17915  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17916
17917  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17918  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17919
17920  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17921					  operands[2], operands[3]));
17922  DONE;
17923}
17924  [(set_attr "type" "frndint")
17925   (set_attr "i387_cw" "mask_pm")
17926   (set_attr "mode" "XF")])
17927
17928(define_insn "frndintxf2_mask_pm_i387"
17929  [(set (match_operand:XF 0 "register_operand" "=f")
17930	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17931	 UNSPEC_FRNDINT_MASK_PM))
17932   (use (match_operand:HI 2 "memory_operand" "m"))
17933   (use (match_operand:HI 3 "memory_operand" "m"))]
17934  "TARGET_USE_FANCY_MATH_387
17935   && flag_unsafe_math_optimizations"
17936  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17937  [(set_attr "type" "frndint")
17938   (set_attr "i387_cw" "mask_pm")
17939   (set_attr "mode" "XF")])
17940
17941(define_expand "nearbyintxf2"
17942  [(use (match_operand:XF 0 "register_operand" ""))
17943   (use (match_operand:XF 1 "register_operand" ""))]
17944  "TARGET_USE_FANCY_MATH_387
17945   && flag_unsafe_math_optimizations"
17946{
17947  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17948
17949  DONE;
17950})
17951
17952(define_expand "nearbyintdf2"
17953  [(use (match_operand:DF 0 "register_operand" ""))
17954   (use (match_operand:DF 1 "register_operand" ""))]
17955  "TARGET_USE_FANCY_MATH_387
17956   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17957   && flag_unsafe_math_optimizations"
17958{
17959  rtx op0 = gen_reg_rtx (XFmode);
17960  rtx op1 = gen_reg_rtx (XFmode);
17961
17962  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17963  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17964
17965  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17966  DONE;
17967})
17968
17969(define_expand "nearbyintsf2"
17970  [(use (match_operand:SF 0 "register_operand" ""))
17971   (use (match_operand:SF 1 "register_operand" ""))]
17972  "TARGET_USE_FANCY_MATH_387
17973   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17974   && flag_unsafe_math_optimizations"
17975{
17976  rtx op0 = gen_reg_rtx (XFmode);
17977  rtx op1 = gen_reg_rtx (XFmode);
17978
17979  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17980  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17981
17982  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17983  DONE;
17984})
17985
17986
17987;; Block operation instructions
17988
17989(define_insn "cld"
17990 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17991 ""
17992 "cld"
17993  [(set_attr "type" "cld")])
17994
17995(define_expand "movmemsi"
17996  [(use (match_operand:BLK 0 "memory_operand" ""))
17997   (use (match_operand:BLK 1 "memory_operand" ""))
17998   (use (match_operand:SI 2 "nonmemory_operand" ""))
17999   (use (match_operand:SI 3 "const_int_operand" ""))]
18000  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18001{
18002 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18003   DONE;
18004 else
18005   FAIL;
18006})
18007
18008(define_expand "movmemdi"
18009  [(use (match_operand:BLK 0 "memory_operand" ""))
18010   (use (match_operand:BLK 1 "memory_operand" ""))
18011   (use (match_operand:DI 2 "nonmemory_operand" ""))
18012   (use (match_operand:DI 3 "const_int_operand" ""))]
18013  "TARGET_64BIT"
18014{
18015 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18016   DONE;
18017 else
18018   FAIL;
18019})
18020
18021;; Most CPUs don't like single string operations
18022;; Handle this case here to simplify previous expander.
18023
18024(define_expand "strmov"
18025  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18026   (set (match_operand 1 "memory_operand" "") (match_dup 4))
18027   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18028	      (clobber (reg:CC FLAGS_REG))])
18029   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18030	      (clobber (reg:CC FLAGS_REG))])]
18031  ""
18032{
18033  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18034
18035  /* If .md ever supports :P for Pmode, these can be directly
18036     in the pattern above.  */
18037  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18038  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18039
18040  if (TARGET_SINGLE_STRINGOP || optimize_size)
18041    {
18042      emit_insn (gen_strmov_singleop (operands[0], operands[1],
18043				      operands[2], operands[3],
18044				      operands[5], operands[6]));
18045      DONE;
18046    }
18047
18048  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18049})
18050
18051(define_expand "strmov_singleop"
18052  [(parallel [(set (match_operand 1 "memory_operand" "")
18053		   (match_operand 3 "memory_operand" ""))
18054	      (set (match_operand 0 "register_operand" "")
18055		   (match_operand 4 "" ""))
18056	      (set (match_operand 2 "register_operand" "")
18057		   (match_operand 5 "" ""))
18058	      (use (reg:SI DIRFLAG_REG))])]
18059  "TARGET_SINGLE_STRINGOP || optimize_size"
18060  "")
18061
18062(define_insn "*strmovdi_rex_1"
18063  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18064	(mem:DI (match_operand:DI 3 "register_operand" "1")))
18065   (set (match_operand:DI 0 "register_operand" "=D")
18066	(plus:DI (match_dup 2)
18067		 (const_int 8)))
18068   (set (match_operand:DI 1 "register_operand" "=S")
18069	(plus:DI (match_dup 3)
18070		 (const_int 8)))
18071   (use (reg:SI DIRFLAG_REG))]
18072  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18073  "movsq"
18074  [(set_attr "type" "str")
18075   (set_attr "mode" "DI")
18076   (set_attr "memory" "both")])
18077
18078(define_insn "*strmovsi_1"
18079  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18080	(mem:SI (match_operand:SI 3 "register_operand" "1")))
18081   (set (match_operand:SI 0 "register_operand" "=D")
18082	(plus:SI (match_dup 2)
18083		 (const_int 4)))
18084   (set (match_operand:SI 1 "register_operand" "=S")
18085	(plus:SI (match_dup 3)
18086		 (const_int 4)))
18087   (use (reg:SI DIRFLAG_REG))]
18088  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18089  "{movsl|movsd}"
18090  [(set_attr "type" "str")
18091   (set_attr "mode" "SI")
18092   (set_attr "memory" "both")])
18093
18094(define_insn "*strmovsi_rex_1"
18095  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18096	(mem:SI (match_operand:DI 3 "register_operand" "1")))
18097   (set (match_operand:DI 0 "register_operand" "=D")
18098	(plus:DI (match_dup 2)
18099		 (const_int 4)))
18100   (set (match_operand:DI 1 "register_operand" "=S")
18101	(plus:DI (match_dup 3)
18102		 (const_int 4)))
18103   (use (reg:SI DIRFLAG_REG))]
18104  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18105  "{movsl|movsd}"
18106  [(set_attr "type" "str")
18107   (set_attr "mode" "SI")
18108   (set_attr "memory" "both")])
18109
18110(define_insn "*strmovhi_1"
18111  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18112	(mem:HI (match_operand:SI 3 "register_operand" "1")))
18113   (set (match_operand:SI 0 "register_operand" "=D")
18114	(plus:SI (match_dup 2)
18115		 (const_int 2)))
18116   (set (match_operand:SI 1 "register_operand" "=S")
18117	(plus:SI (match_dup 3)
18118		 (const_int 2)))
18119   (use (reg:SI DIRFLAG_REG))]
18120  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18121  "movsw"
18122  [(set_attr "type" "str")
18123   (set_attr "memory" "both")
18124   (set_attr "mode" "HI")])
18125
18126(define_insn "*strmovhi_rex_1"
18127  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18128	(mem:HI (match_operand:DI 3 "register_operand" "1")))
18129   (set (match_operand:DI 0 "register_operand" "=D")
18130	(plus:DI (match_dup 2)
18131		 (const_int 2)))
18132   (set (match_operand:DI 1 "register_operand" "=S")
18133	(plus:DI (match_dup 3)
18134		 (const_int 2)))
18135   (use (reg:SI DIRFLAG_REG))]
18136  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18137  "movsw"
18138  [(set_attr "type" "str")
18139   (set_attr "memory" "both")
18140   (set_attr "mode" "HI")])
18141
18142(define_insn "*strmovqi_1"
18143  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18144	(mem:QI (match_operand:SI 3 "register_operand" "1")))
18145   (set (match_operand:SI 0 "register_operand" "=D")
18146	(plus:SI (match_dup 2)
18147		 (const_int 1)))
18148   (set (match_operand:SI 1 "register_operand" "=S")
18149	(plus:SI (match_dup 3)
18150		 (const_int 1)))
18151   (use (reg:SI DIRFLAG_REG))]
18152  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18153  "movsb"
18154  [(set_attr "type" "str")
18155   (set_attr "memory" "both")
18156   (set_attr "mode" "QI")])
18157
18158(define_insn "*strmovqi_rex_1"
18159  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18160	(mem:QI (match_operand:DI 3 "register_operand" "1")))
18161   (set (match_operand:DI 0 "register_operand" "=D")
18162	(plus:DI (match_dup 2)
18163		 (const_int 1)))
18164   (set (match_operand:DI 1 "register_operand" "=S")
18165	(plus:DI (match_dup 3)
18166		 (const_int 1)))
18167   (use (reg:SI DIRFLAG_REG))]
18168  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18169  "movsb"
18170  [(set_attr "type" "str")
18171   (set_attr "memory" "both")
18172   (set_attr "mode" "QI")])
18173
18174(define_expand "rep_mov"
18175  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18176	      (set (match_operand 0 "register_operand" "")
18177		   (match_operand 5 "" ""))
18178	      (set (match_operand 2 "register_operand" "")
18179		   (match_operand 6 "" ""))
18180	      (set (match_operand 1 "memory_operand" "")
18181		   (match_operand 3 "memory_operand" ""))
18182	      (use (match_dup 4))
18183	      (use (reg:SI DIRFLAG_REG))])]
18184  ""
18185  "")
18186
18187(define_insn "*rep_movdi_rex64"
18188  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18189   (set (match_operand:DI 0 "register_operand" "=D") 
18190        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18191			    (const_int 3))
18192		 (match_operand:DI 3 "register_operand" "0")))
18193   (set (match_operand:DI 1 "register_operand" "=S") 
18194        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18195		 (match_operand:DI 4 "register_operand" "1")))
18196   (set (mem:BLK (match_dup 3))
18197	(mem:BLK (match_dup 4)))
18198   (use (match_dup 5))
18199   (use (reg:SI DIRFLAG_REG))]
18200  "TARGET_64BIT"
18201  "{rep\;movsq|rep movsq}"
18202  [(set_attr "type" "str")
18203   (set_attr "prefix_rep" "1")
18204   (set_attr "memory" "both")
18205   (set_attr "mode" "DI")])
18206
18207(define_insn "*rep_movsi"
18208  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18209   (set (match_operand:SI 0 "register_operand" "=D") 
18210        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18211			    (const_int 2))
18212		 (match_operand:SI 3 "register_operand" "0")))
18213   (set (match_operand:SI 1 "register_operand" "=S") 
18214        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18215		 (match_operand:SI 4 "register_operand" "1")))
18216   (set (mem:BLK (match_dup 3))
18217	(mem:BLK (match_dup 4)))
18218   (use (match_dup 5))
18219   (use (reg:SI DIRFLAG_REG))]
18220  "!TARGET_64BIT"
18221  "{rep\;movsl|rep movsd}"
18222  [(set_attr "type" "str")
18223   (set_attr "prefix_rep" "1")
18224   (set_attr "memory" "both")
18225   (set_attr "mode" "SI")])
18226
18227(define_insn "*rep_movsi_rex64"
18228  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18229   (set (match_operand:DI 0 "register_operand" "=D") 
18230        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18231			    (const_int 2))
18232		 (match_operand:DI 3 "register_operand" "0")))
18233   (set (match_operand:DI 1 "register_operand" "=S") 
18234        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18235		 (match_operand:DI 4 "register_operand" "1")))
18236   (set (mem:BLK (match_dup 3))
18237	(mem:BLK (match_dup 4)))
18238   (use (match_dup 5))
18239   (use (reg:SI DIRFLAG_REG))]
18240  "TARGET_64BIT"
18241  "{rep\;movsl|rep movsd}"
18242  [(set_attr "type" "str")
18243   (set_attr "prefix_rep" "1")
18244   (set_attr "memory" "both")
18245   (set_attr "mode" "SI")])
18246
18247(define_insn "*rep_movqi"
18248  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18249   (set (match_operand:SI 0 "register_operand" "=D") 
18250        (plus:SI (match_operand:SI 3 "register_operand" "0")
18251		 (match_operand:SI 5 "register_operand" "2")))
18252   (set (match_operand:SI 1 "register_operand" "=S") 
18253        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18254   (set (mem:BLK (match_dup 3))
18255	(mem:BLK (match_dup 4)))
18256   (use (match_dup 5))
18257   (use (reg:SI DIRFLAG_REG))]
18258  "!TARGET_64BIT"
18259  "{rep\;movsb|rep movsb}"
18260  [(set_attr "type" "str")
18261   (set_attr "prefix_rep" "1")
18262   (set_attr "memory" "both")
18263   (set_attr "mode" "SI")])
18264
18265(define_insn "*rep_movqi_rex64"
18266  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18267   (set (match_operand:DI 0 "register_operand" "=D") 
18268        (plus:DI (match_operand:DI 3 "register_operand" "0")
18269		 (match_operand:DI 5 "register_operand" "2")))
18270   (set (match_operand:DI 1 "register_operand" "=S") 
18271        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18272   (set (mem:BLK (match_dup 3))
18273	(mem:BLK (match_dup 4)))
18274   (use (match_dup 5))
18275   (use (reg:SI DIRFLAG_REG))]
18276  "TARGET_64BIT"
18277  "{rep\;movsb|rep movsb}"
18278  [(set_attr "type" "str")
18279   (set_attr "prefix_rep" "1")
18280   (set_attr "memory" "both")
18281   (set_attr "mode" "SI")])
18282
18283(define_expand "setmemsi"
18284   [(use (match_operand:BLK 0 "memory_operand" ""))
18285    (use (match_operand:SI 1 "nonmemory_operand" ""))
18286    (use (match_operand 2 "const_int_operand" ""))
18287    (use (match_operand 3 "const_int_operand" ""))]
18288  ""
18289{
18290 /* If value to set is not zero, use the library routine.  */
18291 if (operands[2] != const0_rtx)
18292   FAIL;
18293
18294 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18295   DONE;
18296 else
18297   FAIL;
18298})
18299
18300(define_expand "setmemdi"
18301   [(use (match_operand:BLK 0 "memory_operand" ""))
18302    (use (match_operand:DI 1 "nonmemory_operand" ""))
18303    (use (match_operand 2 "const_int_operand" ""))
18304    (use (match_operand 3 "const_int_operand" ""))]
18305  "TARGET_64BIT"
18306{
18307 /* If value to set is not zero, use the library routine.  */
18308 if (operands[2] != const0_rtx)
18309   FAIL;
18310
18311 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18312   DONE;
18313 else
18314   FAIL;
18315})
18316
18317;; Most CPUs don't like single string operations
18318;; Handle this case here to simplify previous expander.
18319
18320(define_expand "strset"
18321  [(set (match_operand 1 "memory_operand" "")
18322	(match_operand 2 "register_operand" ""))
18323   (parallel [(set (match_operand 0 "register_operand" "")
18324		   (match_dup 3))
18325	      (clobber (reg:CC FLAGS_REG))])]
18326  ""
18327{
18328  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18329    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18330
18331  /* If .md ever supports :P for Pmode, this can be directly
18332     in the pattern above.  */
18333  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18334			      GEN_INT (GET_MODE_SIZE (GET_MODE
18335						      (operands[2]))));
18336  if (TARGET_SINGLE_STRINGOP || optimize_size)
18337    {
18338      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18339				      operands[3]));
18340      DONE;
18341    }
18342})
18343
18344(define_expand "strset_singleop"
18345  [(parallel [(set (match_operand 1 "memory_operand" "")
18346		   (match_operand 2 "register_operand" ""))
18347	      (set (match_operand 0 "register_operand" "")
18348		   (match_operand 3 "" ""))
18349	      (use (reg:SI DIRFLAG_REG))])]
18350  "TARGET_SINGLE_STRINGOP || optimize_size"
18351  "")
18352
18353(define_insn "*strsetdi_rex_1"
18354  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18355	(match_operand:DI 2 "register_operand" "a"))
18356   (set (match_operand:DI 0 "register_operand" "=D")
18357	(plus:DI (match_dup 1)
18358		 (const_int 8)))
18359   (use (reg:SI DIRFLAG_REG))]
18360  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18361  "stosq"
18362  [(set_attr "type" "str")
18363   (set_attr "memory" "store")
18364   (set_attr "mode" "DI")])
18365
18366(define_insn "*strsetsi_1"
18367  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18368	(match_operand:SI 2 "register_operand" "a"))
18369   (set (match_operand:SI 0 "register_operand" "=D")
18370	(plus:SI (match_dup 1)
18371		 (const_int 4)))
18372   (use (reg:SI DIRFLAG_REG))]
18373  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18374  "{stosl|stosd}"
18375  [(set_attr "type" "str")
18376   (set_attr "memory" "store")
18377   (set_attr "mode" "SI")])
18378
18379(define_insn "*strsetsi_rex_1"
18380  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18381	(match_operand:SI 2 "register_operand" "a"))
18382   (set (match_operand:DI 0 "register_operand" "=D")
18383	(plus:DI (match_dup 1)
18384		 (const_int 4)))
18385   (use (reg:SI DIRFLAG_REG))]
18386  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18387  "{stosl|stosd}"
18388  [(set_attr "type" "str")
18389   (set_attr "memory" "store")
18390   (set_attr "mode" "SI")])
18391
18392(define_insn "*strsethi_1"
18393  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18394	(match_operand:HI 2 "register_operand" "a"))
18395   (set (match_operand:SI 0 "register_operand" "=D")
18396	(plus:SI (match_dup 1)
18397		 (const_int 2)))
18398   (use (reg:SI DIRFLAG_REG))]
18399  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18400  "stosw"
18401  [(set_attr "type" "str")
18402   (set_attr "memory" "store")
18403   (set_attr "mode" "HI")])
18404
18405(define_insn "*strsethi_rex_1"
18406  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18407	(match_operand:HI 2 "register_operand" "a"))
18408   (set (match_operand:DI 0 "register_operand" "=D")
18409	(plus:DI (match_dup 1)
18410		 (const_int 2)))
18411   (use (reg:SI DIRFLAG_REG))]
18412  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18413  "stosw"
18414  [(set_attr "type" "str")
18415   (set_attr "memory" "store")
18416   (set_attr "mode" "HI")])
18417
18418(define_insn "*strsetqi_1"
18419  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18420	(match_operand:QI 2 "register_operand" "a"))
18421   (set (match_operand:SI 0 "register_operand" "=D")
18422	(plus:SI (match_dup 1)
18423		 (const_int 1)))
18424   (use (reg:SI DIRFLAG_REG))]
18425  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18426  "stosb"
18427  [(set_attr "type" "str")
18428   (set_attr "memory" "store")
18429   (set_attr "mode" "QI")])
18430
18431(define_insn "*strsetqi_rex_1"
18432  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18433	(match_operand:QI 2 "register_operand" "a"))
18434   (set (match_operand:DI 0 "register_operand" "=D")
18435	(plus:DI (match_dup 1)
18436		 (const_int 1)))
18437   (use (reg:SI DIRFLAG_REG))]
18438  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18439  "stosb"
18440  [(set_attr "type" "str")
18441   (set_attr "memory" "store")
18442   (set_attr "mode" "QI")])
18443
18444(define_expand "rep_stos"
18445  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18446	      (set (match_operand 0 "register_operand" "")
18447		   (match_operand 4 "" ""))
18448	      (set (match_operand 2 "memory_operand" "") (const_int 0))
18449	      (use (match_operand 3 "register_operand" ""))
18450	      (use (match_dup 1))
18451	      (use (reg:SI DIRFLAG_REG))])]
18452  ""
18453  "")
18454
18455(define_insn "*rep_stosdi_rex64"
18456  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18457   (set (match_operand:DI 0 "register_operand" "=D") 
18458        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18459			    (const_int 3))
18460		 (match_operand:DI 3 "register_operand" "0")))
18461   (set (mem:BLK (match_dup 3))
18462	(const_int 0))
18463   (use (match_operand:DI 2 "register_operand" "a"))
18464   (use (match_dup 4))
18465   (use (reg:SI DIRFLAG_REG))]
18466  "TARGET_64BIT"
18467  "{rep\;stosq|rep stosq}"
18468  [(set_attr "type" "str")
18469   (set_attr "prefix_rep" "1")
18470   (set_attr "memory" "store")
18471   (set_attr "mode" "DI")])
18472
18473(define_insn "*rep_stossi"
18474  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18475   (set (match_operand:SI 0 "register_operand" "=D") 
18476        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18477			    (const_int 2))
18478		 (match_operand:SI 3 "register_operand" "0")))
18479   (set (mem:BLK (match_dup 3))
18480	(const_int 0))
18481   (use (match_operand:SI 2 "register_operand" "a"))
18482   (use (match_dup 4))
18483   (use (reg:SI DIRFLAG_REG))]
18484  "!TARGET_64BIT"
18485  "{rep\;stosl|rep stosd}"
18486  [(set_attr "type" "str")
18487   (set_attr "prefix_rep" "1")
18488   (set_attr "memory" "store")
18489   (set_attr "mode" "SI")])
18490
18491(define_insn "*rep_stossi_rex64"
18492  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18493   (set (match_operand:DI 0 "register_operand" "=D") 
18494        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18495			    (const_int 2))
18496		 (match_operand:DI 3 "register_operand" "0")))
18497   (set (mem:BLK (match_dup 3))
18498	(const_int 0))
18499   (use (match_operand:SI 2 "register_operand" "a"))
18500   (use (match_dup 4))
18501   (use (reg:SI DIRFLAG_REG))]
18502  "TARGET_64BIT"
18503  "{rep\;stosl|rep stosd}"
18504  [(set_attr "type" "str")
18505   (set_attr "prefix_rep" "1")
18506   (set_attr "memory" "store")
18507   (set_attr "mode" "SI")])
18508
18509(define_insn "*rep_stosqi"
18510  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18511   (set (match_operand:SI 0 "register_operand" "=D") 
18512        (plus:SI (match_operand:SI 3 "register_operand" "0")
18513		 (match_operand:SI 4 "register_operand" "1")))
18514   (set (mem:BLK (match_dup 3))
18515	(const_int 0))
18516   (use (match_operand:QI 2 "register_operand" "a"))
18517   (use (match_dup 4))
18518   (use (reg:SI DIRFLAG_REG))]
18519  "!TARGET_64BIT"
18520  "{rep\;stosb|rep stosb}"
18521  [(set_attr "type" "str")
18522   (set_attr "prefix_rep" "1")
18523   (set_attr "memory" "store")
18524   (set_attr "mode" "QI")])
18525
18526(define_insn "*rep_stosqi_rex64"
18527  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18528   (set (match_operand:DI 0 "register_operand" "=D") 
18529        (plus:DI (match_operand:DI 3 "register_operand" "0")
18530		 (match_operand:DI 4 "register_operand" "1")))
18531   (set (mem:BLK (match_dup 3))
18532	(const_int 0))
18533   (use (match_operand:QI 2 "register_operand" "a"))
18534   (use (match_dup 4))
18535   (use (reg:SI DIRFLAG_REG))]
18536  "TARGET_64BIT"
18537  "{rep\;stosb|rep stosb}"
18538  [(set_attr "type" "str")
18539   (set_attr "prefix_rep" "1")
18540   (set_attr "memory" "store")
18541   (set_attr "mode" "QI")])
18542
18543(define_expand "cmpstrnsi"
18544  [(set (match_operand:SI 0 "register_operand" "")
18545	(compare:SI (match_operand:BLK 1 "general_operand" "")
18546		    (match_operand:BLK 2 "general_operand" "")))
18547   (use (match_operand 3 "general_operand" ""))
18548   (use (match_operand 4 "immediate_operand" ""))]
18549  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18550{
18551  rtx addr1, addr2, out, outlow, count, countreg, align;
18552
18553  /* Can't use this if the user has appropriated esi or edi.  */
18554  if (global_regs[4] || global_regs[5])
18555    FAIL;
18556
18557  out = operands[0];
18558  if (GET_CODE (out) != REG)
18559    out = gen_reg_rtx (SImode);
18560
18561  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18562  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18563  if (addr1 != XEXP (operands[1], 0))
18564    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18565  if (addr2 != XEXP (operands[2], 0))
18566    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18567
18568  count = operands[3];
18569  countreg = ix86_zero_extend_to_Pmode (count);
18570
18571  /* %%% Iff we are testing strict equality, we can use known alignment
18572     to good advantage.  This may be possible with combine, particularly
18573     once cc0 is dead.  */
18574  align = operands[4];
18575
18576  emit_insn (gen_cld ());
18577  if (GET_CODE (count) == CONST_INT)
18578    {
18579      if (INTVAL (count) == 0)
18580	{
18581	  emit_move_insn (operands[0], const0_rtx);
18582	  DONE;
18583	}
18584      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18585				     operands[1], operands[2]));
18586    }
18587  else
18588    {
18589      if (TARGET_64BIT)
18590	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18591      else
18592	emit_insn (gen_cmpsi_1 (countreg, countreg));
18593      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18594				  operands[1], operands[2]));
18595    }
18596
18597  outlow = gen_lowpart (QImode, out);
18598  emit_insn (gen_cmpintqi (outlow));
18599  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18600
18601  if (operands[0] != out)
18602    emit_move_insn (operands[0], out);
18603
18604  DONE;
18605})
18606
18607;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18608
18609(define_expand "cmpintqi"
18610  [(set (match_dup 1)
18611	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18612   (set (match_dup 2)
18613	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18614   (parallel [(set (match_operand:QI 0 "register_operand" "")
18615		   (minus:QI (match_dup 1)
18616			     (match_dup 2)))
18617	      (clobber (reg:CC FLAGS_REG))])]
18618  ""
18619  "operands[1] = gen_reg_rtx (QImode);
18620   operands[2] = gen_reg_rtx (QImode);")
18621
18622;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18623;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18624
18625(define_expand "cmpstrnqi_nz_1"
18626  [(parallel [(set (reg:CC FLAGS_REG)
18627		   (compare:CC (match_operand 4 "memory_operand" "")
18628			       (match_operand 5 "memory_operand" "")))
18629	      (use (match_operand 2 "register_operand" ""))
18630	      (use (match_operand:SI 3 "immediate_operand" ""))
18631	      (use (reg:SI DIRFLAG_REG))
18632	      (clobber (match_operand 0 "register_operand" ""))
18633	      (clobber (match_operand 1 "register_operand" ""))
18634	      (clobber (match_dup 2))])]
18635  ""
18636  "")
18637
18638(define_insn "*cmpstrnqi_nz_1"
18639  [(set (reg:CC FLAGS_REG)
18640	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18641		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18642   (use (match_operand:SI 6 "register_operand" "2"))
18643   (use (match_operand:SI 3 "immediate_operand" "i"))
18644   (use (reg:SI DIRFLAG_REG))
18645   (clobber (match_operand:SI 0 "register_operand" "=S"))
18646   (clobber (match_operand:SI 1 "register_operand" "=D"))
18647   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18648  "!TARGET_64BIT"
18649  "repz{\;| }cmpsb"
18650  [(set_attr "type" "str")
18651   (set_attr "mode" "QI")
18652   (set_attr "prefix_rep" "1")])
18653
18654(define_insn "*cmpstrnqi_nz_rex_1"
18655  [(set (reg:CC FLAGS_REG)
18656	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18657		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18658   (use (match_operand:DI 6 "register_operand" "2"))
18659   (use (match_operand:SI 3 "immediate_operand" "i"))
18660   (use (reg:SI DIRFLAG_REG))
18661   (clobber (match_operand:DI 0 "register_operand" "=S"))
18662   (clobber (match_operand:DI 1 "register_operand" "=D"))
18663   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18664  "TARGET_64BIT"
18665  "repz{\;| }cmpsb"
18666  [(set_attr "type" "str")
18667   (set_attr "mode" "QI")
18668   (set_attr "prefix_rep" "1")])
18669
18670;; The same, but the count is not known to not be zero.
18671
18672(define_expand "cmpstrnqi_1"
18673  [(parallel [(set (reg:CC FLAGS_REG)
18674		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
18675				     (const_int 0))
18676		  (compare:CC (match_operand 4 "memory_operand" "")
18677			      (match_operand 5 "memory_operand" ""))
18678		  (const_int 0)))
18679	      (use (match_operand:SI 3 "immediate_operand" ""))
18680	      (use (reg:CC FLAGS_REG))
18681	      (use (reg:SI DIRFLAG_REG))
18682	      (clobber (match_operand 0 "register_operand" ""))
18683	      (clobber (match_operand 1 "register_operand" ""))
18684	      (clobber (match_dup 2))])]
18685  ""
18686  "")
18687
18688(define_insn "*cmpstrnqi_1"
18689  [(set (reg:CC FLAGS_REG)
18690	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18691			     (const_int 0))
18692	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18693		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18694	  (const_int 0)))
18695   (use (match_operand:SI 3 "immediate_operand" "i"))
18696   (use (reg:CC FLAGS_REG))
18697   (use (reg:SI DIRFLAG_REG))
18698   (clobber (match_operand:SI 0 "register_operand" "=S"))
18699   (clobber (match_operand:SI 1 "register_operand" "=D"))
18700   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18701  "!TARGET_64BIT"
18702  "repz{\;| }cmpsb"
18703  [(set_attr "type" "str")
18704   (set_attr "mode" "QI")
18705   (set_attr "prefix_rep" "1")])
18706
18707(define_insn "*cmpstrnqi_rex_1"
18708  [(set (reg:CC FLAGS_REG)
18709	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18710			     (const_int 0))
18711	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18712		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18713	  (const_int 0)))
18714   (use (match_operand:SI 3 "immediate_operand" "i"))
18715   (use (reg:CC FLAGS_REG))
18716   (use (reg:SI DIRFLAG_REG))
18717   (clobber (match_operand:DI 0 "register_operand" "=S"))
18718   (clobber (match_operand:DI 1 "register_operand" "=D"))
18719   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18720  "TARGET_64BIT"
18721  "repz{\;| }cmpsb"
18722  [(set_attr "type" "str")
18723   (set_attr "mode" "QI")
18724   (set_attr "prefix_rep" "1")])
18725
18726(define_expand "strlensi"
18727  [(set (match_operand:SI 0 "register_operand" "")
18728	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
18729		    (match_operand:QI 2 "immediate_operand" "")
18730		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18731  ""
18732{
18733 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18734   DONE;
18735 else
18736   FAIL;
18737})
18738
18739(define_expand "strlendi"
18740  [(set (match_operand:DI 0 "register_operand" "")
18741	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
18742		    (match_operand:QI 2 "immediate_operand" "")
18743		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18744  ""
18745{
18746 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18747   DONE;
18748 else
18749   FAIL;
18750})
18751
18752(define_expand "strlenqi_1"
18753  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18754	      (use (reg:SI DIRFLAG_REG))
18755	      (clobber (match_operand 1 "register_operand" ""))
18756	      (clobber (reg:CC FLAGS_REG))])]
18757  ""
18758  "")
18759
18760(define_insn "*strlenqi_1"
18761  [(set (match_operand:SI 0 "register_operand" "=&c")
18762	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18763		    (match_operand:QI 2 "register_operand" "a")
18764		    (match_operand:SI 3 "immediate_operand" "i")
18765		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18766   (use (reg:SI DIRFLAG_REG))
18767   (clobber (match_operand:SI 1 "register_operand" "=D"))
18768   (clobber (reg:CC FLAGS_REG))]
18769  "!TARGET_64BIT"
18770  "repnz{\;| }scasb"
18771  [(set_attr "type" "str")
18772   (set_attr "mode" "QI")
18773   (set_attr "prefix_rep" "1")])
18774
18775(define_insn "*strlenqi_rex_1"
18776  [(set (match_operand:DI 0 "register_operand" "=&c")
18777	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18778		    (match_operand:QI 2 "register_operand" "a")
18779		    (match_operand:DI 3 "immediate_operand" "i")
18780		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18781   (use (reg:SI DIRFLAG_REG))
18782   (clobber (match_operand:DI 1 "register_operand" "=D"))
18783   (clobber (reg:CC FLAGS_REG))]
18784  "TARGET_64BIT"
18785  "repnz{\;| }scasb"
18786  [(set_attr "type" "str")
18787   (set_attr "mode" "QI")
18788   (set_attr "prefix_rep" "1")])
18789
18790;; Peephole optimizations to clean up after cmpstrn*.  This should be
18791;; handled in combine, but it is not currently up to the task.
18792;; When used for their truth value, the cmpstrn* expanders generate
18793;; code like this:
18794;;
18795;;   repz cmpsb
18796;;   seta 	%al
18797;;   setb 	%dl
18798;;   cmpb 	%al, %dl
18799;;   jcc	label
18800;;
18801;; The intermediate three instructions are unnecessary.
18802
18803;; This one handles cmpstrn*_nz_1...
18804(define_peephole2
18805  [(parallel[
18806     (set (reg:CC FLAGS_REG)
18807	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18808		      (mem:BLK (match_operand 5 "register_operand" ""))))
18809     (use (match_operand 6 "register_operand" ""))
18810     (use (match_operand:SI 3 "immediate_operand" ""))
18811     (use (reg:SI DIRFLAG_REG))
18812     (clobber (match_operand 0 "register_operand" ""))
18813     (clobber (match_operand 1 "register_operand" ""))
18814     (clobber (match_operand 2 "register_operand" ""))])
18815   (set (match_operand:QI 7 "register_operand" "")
18816	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18817   (set (match_operand:QI 8 "register_operand" "")
18818	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18819   (set (reg FLAGS_REG)
18820	(compare (match_dup 7) (match_dup 8)))
18821  ]
18822  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18823  [(parallel[
18824     (set (reg:CC FLAGS_REG)
18825	  (compare:CC (mem:BLK (match_dup 4))
18826		      (mem:BLK (match_dup 5))))
18827     (use (match_dup 6))
18828     (use (match_dup 3))
18829     (use (reg:SI DIRFLAG_REG))
18830     (clobber (match_dup 0))
18831     (clobber (match_dup 1))
18832     (clobber (match_dup 2))])]
18833  "")
18834
18835;; ...and this one handles cmpstrn*_1.
18836(define_peephole2
18837  [(parallel[
18838     (set (reg:CC FLAGS_REG)
18839	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18840			       (const_int 0))
18841	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18842		        (mem:BLK (match_operand 5 "register_operand" "")))
18843	    (const_int 0)))
18844     (use (match_operand:SI 3 "immediate_operand" ""))
18845     (use (reg:CC FLAGS_REG))
18846     (use (reg:SI DIRFLAG_REG))
18847     (clobber (match_operand 0 "register_operand" ""))
18848     (clobber (match_operand 1 "register_operand" ""))
18849     (clobber (match_operand 2 "register_operand" ""))])
18850   (set (match_operand:QI 7 "register_operand" "")
18851	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18852   (set (match_operand:QI 8 "register_operand" "")
18853	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18854   (set (reg FLAGS_REG)
18855	(compare (match_dup 7) (match_dup 8)))
18856  ]
18857  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18858  [(parallel[
18859     (set (reg:CC FLAGS_REG)
18860	  (if_then_else:CC (ne (match_dup 6)
18861			       (const_int 0))
18862	    (compare:CC (mem:BLK (match_dup 4))
18863			(mem:BLK (match_dup 5)))
18864	    (const_int 0)))
18865     (use (match_dup 3))
18866     (use (reg:CC FLAGS_REG))
18867     (use (reg:SI DIRFLAG_REG))
18868     (clobber (match_dup 0))
18869     (clobber (match_dup 1))
18870     (clobber (match_dup 2))])]
18871  "")
18872
18873
18874
18875;; Conditional move instructions.
18876
18877(define_expand "movdicc"
18878  [(set (match_operand:DI 0 "register_operand" "")
18879	(if_then_else:DI (match_operand 1 "comparison_operator" "")
18880			 (match_operand:DI 2 "general_operand" "")
18881			 (match_operand:DI 3 "general_operand" "")))]
18882  "TARGET_64BIT"
18883  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18884
18885(define_insn "x86_movdicc_0_m1_rex64"
18886  [(set (match_operand:DI 0 "register_operand" "=r")
18887	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18888	  (const_int -1)
18889	  (const_int 0)))
18890   (clobber (reg:CC FLAGS_REG))]
18891  "TARGET_64BIT"
18892  "sbb{q}\t%0, %0"
18893  ; Since we don't have the proper number of operands for an alu insn,
18894  ; fill in all the blanks.
18895  [(set_attr "type" "alu")
18896   (set_attr "pent_pair" "pu")
18897   (set_attr "memory" "none")
18898   (set_attr "imm_disp" "false")
18899   (set_attr "mode" "DI")
18900   (set_attr "length_immediate" "0")])
18901
18902(define_insn "*movdicc_c_rex64"
18903  [(set (match_operand:DI 0 "register_operand" "=r,r")
18904	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18905				[(reg FLAGS_REG) (const_int 0)])
18906		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18907		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18908  "TARGET_64BIT && TARGET_CMOVE
18909   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18910  "@
18911   cmov%O2%C1\t{%2, %0|%0, %2}
18912   cmov%O2%c1\t{%3, %0|%0, %3}"
18913  [(set_attr "type" "icmov")
18914   (set_attr "mode" "DI")])
18915
18916(define_expand "movsicc"
18917  [(set (match_operand:SI 0 "register_operand" "")
18918	(if_then_else:SI (match_operand 1 "comparison_operator" "")
18919			 (match_operand:SI 2 "general_operand" "")
18920			 (match_operand:SI 3 "general_operand" "")))]
18921  ""
18922  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18923
18924;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18925;; the register first winds up with `sbbl $0,reg', which is also weird.
18926;; So just document what we're doing explicitly.
18927
18928(define_insn "x86_movsicc_0_m1"
18929  [(set (match_operand:SI 0 "register_operand" "=r")
18930	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18931	  (const_int -1)
18932	  (const_int 0)))
18933   (clobber (reg:CC FLAGS_REG))]
18934  ""
18935  "sbb{l}\t%0, %0"
18936  ; Since we don't have the proper number of operands for an alu insn,
18937  ; fill in all the blanks.
18938  [(set_attr "type" "alu")
18939   (set_attr "pent_pair" "pu")
18940   (set_attr "memory" "none")
18941   (set_attr "imm_disp" "false")
18942   (set_attr "mode" "SI")
18943   (set_attr "length_immediate" "0")])
18944
18945(define_insn "*movsicc_noc"
18946  [(set (match_operand:SI 0 "register_operand" "=r,r")
18947	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18948				[(reg FLAGS_REG) (const_int 0)])
18949		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18950		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18951  "TARGET_CMOVE
18952   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18953  "@
18954   cmov%O2%C1\t{%2, %0|%0, %2}
18955   cmov%O2%c1\t{%3, %0|%0, %3}"
18956  [(set_attr "type" "icmov")
18957   (set_attr "mode" "SI")])
18958
18959(define_expand "movhicc"
18960  [(set (match_operand:HI 0 "register_operand" "")
18961	(if_then_else:HI (match_operand 1 "comparison_operator" "")
18962			 (match_operand:HI 2 "general_operand" "")
18963			 (match_operand:HI 3 "general_operand" "")))]
18964  "TARGET_HIMODE_MATH"
18965  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18966
18967(define_insn "*movhicc_noc"
18968  [(set (match_operand:HI 0 "register_operand" "=r,r")
18969	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18970				[(reg FLAGS_REG) (const_int 0)])
18971		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18972		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18973  "TARGET_CMOVE
18974   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18975  "@
18976   cmov%O2%C1\t{%2, %0|%0, %2}
18977   cmov%O2%c1\t{%3, %0|%0, %3}"
18978  [(set_attr "type" "icmov")
18979   (set_attr "mode" "HI")])
18980
18981(define_expand "movqicc"
18982  [(set (match_operand:QI 0 "register_operand" "")
18983	(if_then_else:QI (match_operand 1 "comparison_operator" "")
18984			 (match_operand:QI 2 "general_operand" "")
18985			 (match_operand:QI 3 "general_operand" "")))]
18986  "TARGET_QIMODE_MATH"
18987  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18988
18989(define_insn_and_split "*movqicc_noc"
18990  [(set (match_operand:QI 0 "register_operand" "=r,r")
18991	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18992				[(match_operand 4 "flags_reg_operand" "")
18993				 (const_int 0)])
18994		      (match_operand:QI 2 "register_operand" "r,0")
18995		      (match_operand:QI 3 "register_operand" "0,r")))]
18996  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18997  "#"
18998  "&& reload_completed"
18999  [(set (match_dup 0)
19000	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19001		      (match_dup 2)
19002		      (match_dup 3)))]
19003  "operands[0] = gen_lowpart (SImode, operands[0]);
19004   operands[2] = gen_lowpart (SImode, operands[2]);
19005   operands[3] = gen_lowpart (SImode, operands[3]);"
19006  [(set_attr "type" "icmov")
19007   (set_attr "mode" "SI")])
19008
19009(define_expand "movsfcc"
19010  [(set (match_operand:SF 0 "register_operand" "")
19011	(if_then_else:SF (match_operand 1 "comparison_operator" "")
19012			 (match_operand:SF 2 "register_operand" "")
19013			 (match_operand:SF 3 "register_operand" "")))]
19014  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19015  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19016
19017(define_insn "*movsfcc_1_387"
19018  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19019	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19020				[(reg FLAGS_REG) (const_int 0)])
19021		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19022		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19023  "TARGET_80387 && TARGET_CMOVE
19024   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19025  "@
19026   fcmov%F1\t{%2, %0|%0, %2}
19027   fcmov%f1\t{%3, %0|%0, %3}
19028   cmov%O2%C1\t{%2, %0|%0, %2}
19029   cmov%O2%c1\t{%3, %0|%0, %3}"
19030  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19031   (set_attr "mode" "SF,SF,SI,SI")])
19032
19033(define_expand "movdfcc"
19034  [(set (match_operand:DF 0 "register_operand" "")
19035	(if_then_else:DF (match_operand 1 "comparison_operator" "")
19036			 (match_operand:DF 2 "register_operand" "")
19037			 (match_operand:DF 3 "register_operand" "")))]
19038  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19039  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19040
19041(define_insn "*movdfcc_1"
19042  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19043	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19044				[(reg FLAGS_REG) (const_int 0)])
19045		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19046		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19047  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19048   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19049  "@
19050   fcmov%F1\t{%2, %0|%0, %2}
19051   fcmov%f1\t{%3, %0|%0, %3}
19052   #
19053   #"
19054  [(set_attr "type" "fcmov,fcmov,multi,multi")
19055   (set_attr "mode" "DF")])
19056
19057(define_insn "*movdfcc_1_rex64"
19058  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19059	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19060				[(reg FLAGS_REG) (const_int 0)])
19061		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19062		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19063  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19064   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19065  "@
19066   fcmov%F1\t{%2, %0|%0, %2}
19067   fcmov%f1\t{%3, %0|%0, %3}
19068   cmov%O2%C1\t{%2, %0|%0, %2}
19069   cmov%O2%c1\t{%3, %0|%0, %3}"
19070  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19071   (set_attr "mode" "DF")])
19072
19073(define_split
19074  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19075	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19076				[(match_operand 4 "flags_reg_operand" "")
19077				 (const_int 0)])
19078		      (match_operand:DF 2 "nonimmediate_operand" "")
19079		      (match_operand:DF 3 "nonimmediate_operand" "")))]
19080  "!TARGET_64BIT && reload_completed"
19081  [(set (match_dup 2)
19082	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19083		      (match_dup 5)
19084		      (match_dup 7)))
19085   (set (match_dup 3)
19086	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19087		      (match_dup 6)
19088		      (match_dup 8)))]
19089  "split_di (operands+2, 1, operands+5, operands+6);
19090   split_di (operands+3, 1, operands+7, operands+8);
19091   split_di (operands, 1, operands+2, operands+3);")
19092
19093(define_expand "movxfcc"
19094  [(set (match_operand:XF 0 "register_operand" "")
19095	(if_then_else:XF (match_operand 1 "comparison_operator" "")
19096			 (match_operand:XF 2 "register_operand" "")
19097			 (match_operand:XF 3 "register_operand" "")))]
19098  "TARGET_80387 && TARGET_CMOVE"
19099  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19100
19101(define_insn "*movxfcc_1"
19102  [(set (match_operand:XF 0 "register_operand" "=f,f")
19103	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19104				[(reg FLAGS_REG) (const_int 0)])
19105		      (match_operand:XF 2 "register_operand" "f,0")
19106		      (match_operand:XF 3 "register_operand" "0,f")))]
19107  "TARGET_80387 && TARGET_CMOVE"
19108  "@
19109   fcmov%F1\t{%2, %0|%0, %2}
19110   fcmov%f1\t{%3, %0|%0, %3}"
19111  [(set_attr "type" "fcmov")
19112   (set_attr "mode" "XF")])
19113
19114;; These versions of the min/max patterns are intentionally ignorant of
19115;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19116;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19117;; are undefined in this condition, we're certain this is correct.
19118
19119(define_insn "sminsf3"
19120  [(set (match_operand:SF 0 "register_operand" "=x")
19121	(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19122		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19123  "TARGET_SSE_MATH"
19124  "minss\t{%2, %0|%0, %2}"
19125  [(set_attr "type" "sseadd")
19126   (set_attr "mode" "SF")])
19127
19128(define_insn "smaxsf3"
19129  [(set (match_operand:SF 0 "register_operand" "=x")
19130	(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19131		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19132  "TARGET_SSE_MATH"
19133  "maxss\t{%2, %0|%0, %2}"
19134  [(set_attr "type" "sseadd")
19135   (set_attr "mode" "SF")])
19136
19137(define_insn "smindf3"
19138  [(set (match_operand:DF 0 "register_operand" "=x")
19139	(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19140		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19141  "TARGET_SSE2 && TARGET_SSE_MATH"
19142  "minsd\t{%2, %0|%0, %2}"
19143  [(set_attr "type" "sseadd")
19144   (set_attr "mode" "DF")])
19145
19146(define_insn "smaxdf3"
19147  [(set (match_operand:DF 0 "register_operand" "=x")
19148	(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19149		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19150  "TARGET_SSE2 && TARGET_SSE_MATH"
19151  "maxsd\t{%2, %0|%0, %2}"
19152  [(set_attr "type" "sseadd")
19153   (set_attr "mode" "DF")])
19154
19155;; These versions of the min/max patterns implement exactly the operations
19156;;   min = (op1 < op2 ? op1 : op2)
19157;;   max = (!(op1 < op2) ? op1 : op2)
19158;; Their operands are not commutative, and thus they may be used in the
19159;; presence of -0.0 and NaN.
19160
19161(define_insn "*ieee_sminsf3"
19162  [(set (match_operand:SF 0 "register_operand" "=x")
19163	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19164		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19165		   UNSPEC_IEEE_MIN))]
19166  "TARGET_SSE_MATH"
19167  "minss\t{%2, %0|%0, %2}"
19168  [(set_attr "type" "sseadd")
19169   (set_attr "mode" "SF")])
19170
19171(define_insn "*ieee_smaxsf3"
19172  [(set (match_operand:SF 0 "register_operand" "=x")
19173	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19174		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19175		   UNSPEC_IEEE_MAX))]
19176  "TARGET_SSE_MATH"
19177  "maxss\t{%2, %0|%0, %2}"
19178  [(set_attr "type" "sseadd")
19179   (set_attr "mode" "SF")])
19180
19181(define_insn "*ieee_smindf3"
19182  [(set (match_operand:DF 0 "register_operand" "=x")
19183	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19184		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19185		   UNSPEC_IEEE_MIN))]
19186  "TARGET_SSE2 && TARGET_SSE_MATH"
19187  "minsd\t{%2, %0|%0, %2}"
19188  [(set_attr "type" "sseadd")
19189   (set_attr "mode" "DF")])
19190
19191(define_insn "*ieee_smaxdf3"
19192  [(set (match_operand:DF 0 "register_operand" "=x")
19193	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19194		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19195		   UNSPEC_IEEE_MAX))]
19196  "TARGET_SSE2 && TARGET_SSE_MATH"
19197  "maxsd\t{%2, %0|%0, %2}"
19198  [(set_attr "type" "sseadd")
19199   (set_attr "mode" "DF")])
19200
19201;; Make two stack loads independent:
19202;;   fld aa              fld aa
19203;;   fld %st(0)     ->   fld bb
19204;;   fmul bb             fmul %st(1), %st
19205;;
19206;; Actually we only match the last two instructions for simplicity.
19207(define_peephole2
19208  [(set (match_operand 0 "fp_register_operand" "")
19209	(match_operand 1 "fp_register_operand" ""))
19210   (set (match_dup 0)
19211	(match_operator 2 "binary_fp_operator"
19212	   [(match_dup 0)
19213	    (match_operand 3 "memory_operand" "")]))]
19214  "REGNO (operands[0]) != REGNO (operands[1])"
19215  [(set (match_dup 0) (match_dup 3))
19216   (set (match_dup 0) (match_dup 4))]
19217
19218  ;; The % modifier is not operational anymore in peephole2's, so we have to
19219  ;; swap the operands manually in the case of addition and multiplication.
19220  "if (COMMUTATIVE_ARITH_P (operands[2]))
19221     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19222				 operands[0], operands[1]);
19223   else
19224     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19225				 operands[1], operands[0]);")
19226
19227;; Conditional addition patterns
19228(define_expand "addqicc"
19229  [(match_operand:QI 0 "register_operand" "")
19230   (match_operand 1 "comparison_operator" "")
19231   (match_operand:QI 2 "register_operand" "")
19232   (match_operand:QI 3 "const_int_operand" "")]
19233  ""
19234  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19235
19236(define_expand "addhicc"
19237  [(match_operand:HI 0 "register_operand" "")
19238   (match_operand 1 "comparison_operator" "")
19239   (match_operand:HI 2 "register_operand" "")
19240   (match_operand:HI 3 "const_int_operand" "")]
19241  ""
19242  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19243
19244(define_expand "addsicc"
19245  [(match_operand:SI 0 "register_operand" "")
19246   (match_operand 1 "comparison_operator" "")
19247   (match_operand:SI 2 "register_operand" "")
19248   (match_operand:SI 3 "const_int_operand" "")]
19249  ""
19250  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19251
19252(define_expand "adddicc"
19253  [(match_operand:DI 0 "register_operand" "")
19254   (match_operand 1 "comparison_operator" "")
19255   (match_operand:DI 2 "register_operand" "")
19256   (match_operand:DI 3 "const_int_operand" "")]
19257  "TARGET_64BIT"
19258  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19259
19260
19261;; Misc patterns (?)
19262
19263;; This pattern exists to put a dependency on all ebp-based memory accesses.
19264;; Otherwise there will be nothing to keep
19265;; 
19266;; [(set (reg ebp) (reg esp))]
19267;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19268;;  (clobber (eflags)]
19269;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19270;;
19271;; in proper program order.
19272(define_insn "pro_epilogue_adjust_stack_1"
19273  [(set (match_operand:SI 0 "register_operand" "=r,r")
19274	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
19275	         (match_operand:SI 2 "immediate_operand" "i,i")))
19276   (clobber (reg:CC FLAGS_REG))
19277   (clobber (mem:BLK (scratch)))]
19278  "!TARGET_64BIT"
19279{
19280  switch (get_attr_type (insn))
19281    {
19282    case TYPE_IMOV:
19283      return "mov{l}\t{%1, %0|%0, %1}";
19284
19285    case TYPE_ALU:
19286      if (GET_CODE (operands[2]) == CONST_INT
19287          && (INTVAL (operands[2]) == 128
19288	      || (INTVAL (operands[2]) < 0
19289	          && INTVAL (operands[2]) != -128)))
19290	{
19291	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19292	  return "sub{l}\t{%2, %0|%0, %2}";
19293	}
19294      return "add{l}\t{%2, %0|%0, %2}";
19295
19296    case TYPE_LEA:
19297      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19298      return "lea{l}\t{%a2, %0|%0, %a2}";
19299
19300    default:
19301      gcc_unreachable ();
19302    }
19303}
19304  [(set (attr "type")
19305	(cond [(eq_attr "alternative" "0")
19306		 (const_string "alu")
19307	       (match_operand:SI 2 "const0_operand" "")
19308		 (const_string "imov")
19309	      ]
19310	      (const_string "lea")))
19311   (set_attr "mode" "SI")])
19312
19313(define_insn "pro_epilogue_adjust_stack_rex64"
19314  [(set (match_operand:DI 0 "register_operand" "=r,r")
19315	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19316		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19317   (clobber (reg:CC FLAGS_REG))
19318   (clobber (mem:BLK (scratch)))]
19319  "TARGET_64BIT"
19320{
19321  switch (get_attr_type (insn))
19322    {
19323    case TYPE_IMOV:
19324      return "mov{q}\t{%1, %0|%0, %1}";
19325
19326    case TYPE_ALU:
19327      if (GET_CODE (operands[2]) == CONST_INT
19328	  /* Avoid overflows.  */
19329	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19330          && (INTVAL (operands[2]) == 128
19331	      || (INTVAL (operands[2]) < 0
19332	          && INTVAL (operands[2]) != -128)))
19333	{
19334	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19335	  return "sub{q}\t{%2, %0|%0, %2}";
19336	}
19337      return "add{q}\t{%2, %0|%0, %2}";
19338
19339    case TYPE_LEA:
19340      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19341      return "lea{q}\t{%a2, %0|%0, %a2}";
19342
19343    default:
19344      gcc_unreachable ();
19345    }
19346}
19347  [(set (attr "type")
19348	(cond [(eq_attr "alternative" "0")
19349		 (const_string "alu")
19350	       (match_operand:DI 2 "const0_operand" "")
19351		 (const_string "imov")
19352	      ]
19353	      (const_string "lea")))
19354   (set_attr "mode" "DI")])
19355
19356(define_insn "pro_epilogue_adjust_stack_rex64_2"
19357  [(set (match_operand:DI 0 "register_operand" "=r,r")
19358	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19359		 (match_operand:DI 3 "immediate_operand" "i,i")))
19360   (use (match_operand:DI 2 "register_operand" "r,r"))
19361   (clobber (reg:CC FLAGS_REG))
19362   (clobber (mem:BLK (scratch)))]
19363  "TARGET_64BIT"
19364{
19365  switch (get_attr_type (insn))
19366    {
19367    case TYPE_ALU:
19368      return "add{q}\t{%2, %0|%0, %2}";
19369
19370    case TYPE_LEA:
19371      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19372      return "lea{q}\t{%a2, %0|%0, %a2}";
19373
19374    default:
19375      gcc_unreachable ();
19376    }
19377}
19378  [(set_attr "type" "alu,lea")
19379   (set_attr "mode" "DI")])
19380
19381(define_expand "allocate_stack_worker"
19382  [(match_operand:SI 0 "register_operand" "")]
19383  "TARGET_STACK_PROBE"
19384{
19385  if (reload_completed)
19386    {
19387      if (TARGET_64BIT)
19388	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19389      else
19390	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19391    }
19392  else
19393    {
19394      if (TARGET_64BIT)
19395	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19396      else
19397	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19398    }
19399  DONE;
19400})
19401
19402(define_insn "allocate_stack_worker_1"
19403  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19404    UNSPECV_STACK_PROBE)
19405   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19406   (clobber (match_scratch:SI 1 "=0"))
19407   (clobber (reg:CC FLAGS_REG))]
19408  "!TARGET_64BIT && TARGET_STACK_PROBE"
19409  "call\t__alloca"
19410  [(set_attr "type" "multi")
19411   (set_attr "length" "5")])
19412
19413(define_expand "allocate_stack_worker_postreload"
19414  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19415				    UNSPECV_STACK_PROBE)
19416	      (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19417	      (clobber (match_dup 0))
19418	      (clobber (reg:CC FLAGS_REG))])]
19419  ""
19420  "")
19421
19422(define_insn "allocate_stack_worker_rex64"
19423  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19424    UNSPECV_STACK_PROBE)
19425   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19426   (clobber (match_scratch:DI 1 "=0"))
19427   (clobber (reg:CC FLAGS_REG))]
19428  "TARGET_64BIT && TARGET_STACK_PROBE"
19429  "call\t__alloca"
19430  [(set_attr "type" "multi")
19431   (set_attr "length" "5")])
19432
19433(define_expand "allocate_stack_worker_rex64_postreload"
19434  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19435				    UNSPECV_STACK_PROBE)
19436	      (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19437	      (clobber (match_dup 0))
19438	      (clobber (reg:CC FLAGS_REG))])]
19439  ""
19440  "")
19441
19442(define_expand "allocate_stack"
19443  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19444		   (minus:SI (reg:SI SP_REG)
19445			     (match_operand:SI 1 "general_operand" "")))
19446	      (clobber (reg:CC FLAGS_REG))])
19447   (parallel [(set (reg:SI SP_REG)
19448		   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19449	      (clobber (reg:CC FLAGS_REG))])]
19450  "TARGET_STACK_PROBE"
19451{
19452#ifdef CHECK_STACK_LIMIT
19453  if (GET_CODE (operands[1]) == CONST_INT
19454      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19455    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19456			   operands[1]));
19457  else 
19458#endif
19459    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19460							    operands[1])));
19461
19462  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19463  DONE;
19464})
19465
19466(define_expand "builtin_setjmp_receiver"
19467  [(label_ref (match_operand 0 "" ""))]
19468  "!TARGET_64BIT && flag_pic"
19469{
19470  if (TARGET_MACHO)
19471    {
19472      rtx xops[3];
19473      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19474      rtx label_rtx = gen_label_rtx ();
19475      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19476      xops[0] = xops[1] = picreg;
19477      xops[2] = gen_rtx_CONST (SImode,
19478	          gen_rtx_MINUS (SImode,
19479		    gen_rtx_LABEL_REF (SImode, label_rtx),
19480		    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19481      ix86_expand_binary_operator (MINUS, SImode, xops);
19482    }
19483  else
19484    emit_insn (gen_set_got (pic_offset_table_rtx));
19485  DONE;
19486})
19487
19488;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19489
19490(define_split
19491  [(set (match_operand 0 "register_operand" "")
19492	(match_operator 3 "promotable_binary_operator"
19493	   [(match_operand 1 "register_operand" "")
19494	    (match_operand 2 "aligned_operand" "")]))
19495   (clobber (reg:CC FLAGS_REG))]
19496  "! TARGET_PARTIAL_REG_STALL && reload_completed
19497   && ((GET_MODE (operands[0]) == HImode 
19498	&& ((!optimize_size && !TARGET_FAST_PREFIX)
19499            /* ??? next two lines just !satisfies_constraint_K (...) */
19500	    || GET_CODE (operands[2]) != CONST_INT
19501	    || satisfies_constraint_K (operands[2])))
19502       || (GET_MODE (operands[0]) == QImode 
19503	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19504  [(parallel [(set (match_dup 0)
19505		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19506	      (clobber (reg:CC FLAGS_REG))])]
19507  "operands[0] = gen_lowpart (SImode, operands[0]);
19508   operands[1] = gen_lowpart (SImode, operands[1]);
19509   if (GET_CODE (operands[3]) != ASHIFT)
19510     operands[2] = gen_lowpart (SImode, operands[2]);
19511   PUT_MODE (operands[3], SImode);")
19512
19513; Promote the QImode tests, as i386 has encoding of the AND
19514; instruction with 32-bit sign-extended immediate and thus the
19515; instruction size is unchanged, except in the %eax case for
19516; which it is increased by one byte, hence the ! optimize_size.
19517(define_split
19518  [(set (match_operand 0 "flags_reg_operand" "")
19519	(match_operator 2 "compare_operator"
19520	  [(and (match_operand 3 "aligned_operand" "")
19521		(match_operand 4 "const_int_operand" ""))
19522	   (const_int 0)]))
19523   (set (match_operand 1 "register_operand" "")
19524	(and (match_dup 3) (match_dup 4)))]
19525  "! TARGET_PARTIAL_REG_STALL && reload_completed
19526   /* Ensure that the operand will remain sign-extended immediate.  */
19527   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19528   && ! optimize_size
19529   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19530       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19531  [(parallel [(set (match_dup 0)
19532		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19533			            (const_int 0)]))
19534	      (set (match_dup 1)
19535		   (and:SI (match_dup 3) (match_dup 4)))])]
19536{
19537  operands[4]
19538    = gen_int_mode (INTVAL (operands[4])
19539		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19540  operands[1] = gen_lowpart (SImode, operands[1]);
19541  operands[3] = gen_lowpart (SImode, operands[3]);
19542})
19543
19544; Don't promote the QImode tests, as i386 doesn't have encoding of
19545; the TEST instruction with 32-bit sign-extended immediate and thus
19546; the instruction size would at least double, which is not what we
19547; want even with ! optimize_size.
19548(define_split
19549  [(set (match_operand 0 "flags_reg_operand" "")
19550	(match_operator 1 "compare_operator"
19551	  [(and (match_operand:HI 2 "aligned_operand" "")
19552		(match_operand:HI 3 "const_int_operand" ""))
19553	   (const_int 0)]))]
19554  "! TARGET_PARTIAL_REG_STALL && reload_completed
19555   /* Ensure that the operand will remain sign-extended immediate.  */
19556   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19557   && ! TARGET_FAST_PREFIX
19558   && ! optimize_size"
19559  [(set (match_dup 0)
19560	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19561		         (const_int 0)]))]
19562{
19563  operands[3]
19564    = gen_int_mode (INTVAL (operands[3])
19565		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19566  operands[2] = gen_lowpart (SImode, operands[2]);
19567})
19568
19569(define_split
19570  [(set (match_operand 0 "register_operand" "")
19571	(neg (match_operand 1 "register_operand" "")))
19572   (clobber (reg:CC FLAGS_REG))]
19573  "! TARGET_PARTIAL_REG_STALL && reload_completed
19574   && (GET_MODE (operands[0]) == HImode
19575       || (GET_MODE (operands[0]) == QImode 
19576	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19577  [(parallel [(set (match_dup 0)
19578		   (neg:SI (match_dup 1)))
19579	      (clobber (reg:CC FLAGS_REG))])]
19580  "operands[0] = gen_lowpart (SImode, operands[0]);
19581   operands[1] = gen_lowpart (SImode, operands[1]);")
19582
19583(define_split
19584  [(set (match_operand 0 "register_operand" "")
19585	(not (match_operand 1 "register_operand" "")))]
19586  "! TARGET_PARTIAL_REG_STALL && reload_completed
19587   && (GET_MODE (operands[0]) == HImode
19588       || (GET_MODE (operands[0]) == QImode 
19589	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19590  [(set (match_dup 0)
19591	(not:SI (match_dup 1)))]
19592  "operands[0] = gen_lowpart (SImode, operands[0]);
19593   operands[1] = gen_lowpart (SImode, operands[1]);")
19594
19595(define_split 
19596  [(set (match_operand 0 "register_operand" "")
19597	(if_then_else (match_operator 1 "comparison_operator" 
19598				[(reg FLAGS_REG) (const_int 0)])
19599		      (match_operand 2 "register_operand" "")
19600		      (match_operand 3 "register_operand" "")))]
19601  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19602   && (GET_MODE (operands[0]) == HImode
19603       || (GET_MODE (operands[0]) == QImode 
19604	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19605  [(set (match_dup 0)
19606	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19607  "operands[0] = gen_lowpart (SImode, operands[0]);
19608   operands[2] = gen_lowpart (SImode, operands[2]);
19609   operands[3] = gen_lowpart (SImode, operands[3]);")
19610			
19611
19612;; RTL Peephole optimizations, run before sched2.  These primarily look to
19613;; transform a complex memory operation into two memory to register operations.
19614
19615;; Don't push memory operands
19616(define_peephole2
19617  [(set (match_operand:SI 0 "push_operand" "")
19618	(match_operand:SI 1 "memory_operand" ""))
19619   (match_scratch:SI 2 "r")]
19620  "!optimize_size && !TARGET_PUSH_MEMORY
19621   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19622  [(set (match_dup 2) (match_dup 1))
19623   (set (match_dup 0) (match_dup 2))]
19624  "")
19625
19626(define_peephole2
19627  [(set (match_operand:DI 0 "push_operand" "")
19628	(match_operand:DI 1 "memory_operand" ""))
19629   (match_scratch:DI 2 "r")]
19630  "!optimize_size && !TARGET_PUSH_MEMORY
19631   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19632  [(set (match_dup 2) (match_dup 1))
19633   (set (match_dup 0) (match_dup 2))]
19634  "")
19635
19636;; We need to handle SFmode only, because DFmode and XFmode is split to
19637;; SImode pushes.
19638(define_peephole2
19639  [(set (match_operand:SF 0 "push_operand" "")
19640	(match_operand:SF 1 "memory_operand" ""))
19641   (match_scratch:SF 2 "r")]
19642  "!optimize_size && !TARGET_PUSH_MEMORY
19643   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19644  [(set (match_dup 2) (match_dup 1))
19645   (set (match_dup 0) (match_dup 2))]
19646  "")
19647
19648(define_peephole2
19649  [(set (match_operand:HI 0 "push_operand" "")
19650	(match_operand:HI 1 "memory_operand" ""))
19651   (match_scratch:HI 2 "r")]
19652  "!optimize_size && !TARGET_PUSH_MEMORY
19653   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19654  [(set (match_dup 2) (match_dup 1))
19655   (set (match_dup 0) (match_dup 2))]
19656  "")
19657
19658(define_peephole2
19659  [(set (match_operand:QI 0 "push_operand" "")
19660	(match_operand:QI 1 "memory_operand" ""))
19661   (match_scratch:QI 2 "q")]
19662  "!optimize_size && !TARGET_PUSH_MEMORY
19663   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19664  [(set (match_dup 2) (match_dup 1))
19665   (set (match_dup 0) (match_dup 2))]
19666  "")
19667
19668;; Don't move an immediate directly to memory when the instruction
19669;; gets too big.
19670(define_peephole2
19671  [(match_scratch:SI 1 "r")
19672   (set (match_operand:SI 0 "memory_operand" "")
19673        (const_int 0))]
19674  "! optimize_size
19675   && ! TARGET_USE_MOV0
19676   && TARGET_SPLIT_LONG_MOVES
19677   && get_attr_length (insn) >= ix86_cost->large_insn
19678   && peep2_regno_dead_p (0, FLAGS_REG)"
19679  [(parallel [(set (match_dup 1) (const_int 0))
19680	      (clobber (reg:CC FLAGS_REG))])
19681   (set (match_dup 0) (match_dup 1))]
19682  "")
19683
19684(define_peephole2
19685  [(match_scratch:HI 1 "r")
19686   (set (match_operand:HI 0 "memory_operand" "")
19687        (const_int 0))]
19688  "! optimize_size
19689   && ! TARGET_USE_MOV0
19690   && TARGET_SPLIT_LONG_MOVES
19691   && get_attr_length (insn) >= ix86_cost->large_insn
19692   && peep2_regno_dead_p (0, FLAGS_REG)"
19693  [(parallel [(set (match_dup 2) (const_int 0))
19694	      (clobber (reg:CC FLAGS_REG))])
19695   (set (match_dup 0) (match_dup 1))]
19696  "operands[2] = gen_lowpart (SImode, operands[1]);")
19697
19698(define_peephole2
19699  [(match_scratch:QI 1 "q")
19700   (set (match_operand:QI 0 "memory_operand" "")
19701        (const_int 0))]
19702  "! optimize_size
19703   && ! TARGET_USE_MOV0
19704   && TARGET_SPLIT_LONG_MOVES
19705   && get_attr_length (insn) >= ix86_cost->large_insn
19706   && peep2_regno_dead_p (0, FLAGS_REG)"
19707  [(parallel [(set (match_dup 2) (const_int 0))
19708	      (clobber (reg:CC FLAGS_REG))])
19709   (set (match_dup 0) (match_dup 1))]
19710  "operands[2] = gen_lowpart (SImode, operands[1]);")
19711
19712(define_peephole2
19713  [(match_scratch:SI 2 "r")
19714   (set (match_operand:SI 0 "memory_operand" "")
19715        (match_operand:SI 1 "immediate_operand" ""))]
19716  "! optimize_size
19717   && get_attr_length (insn) >= ix86_cost->large_insn
19718   && TARGET_SPLIT_LONG_MOVES"
19719  [(set (match_dup 2) (match_dup 1))
19720   (set (match_dup 0) (match_dup 2))]
19721  "")
19722
19723(define_peephole2
19724  [(match_scratch:HI 2 "r")
19725   (set (match_operand:HI 0 "memory_operand" "")
19726        (match_operand:HI 1 "immediate_operand" ""))]
19727  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19728  && TARGET_SPLIT_LONG_MOVES"
19729  [(set (match_dup 2) (match_dup 1))
19730   (set (match_dup 0) (match_dup 2))]
19731  "")
19732
19733(define_peephole2
19734  [(match_scratch:QI 2 "q")
19735   (set (match_operand:QI 0 "memory_operand" "")
19736        (match_operand:QI 1 "immediate_operand" ""))]
19737  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19738  && TARGET_SPLIT_LONG_MOVES"
19739  [(set (match_dup 2) (match_dup 1))
19740   (set (match_dup 0) (match_dup 2))]
19741  "")
19742
19743;; Don't compare memory with zero, load and use a test instead.
19744(define_peephole2
19745  [(set (match_operand 0 "flags_reg_operand" "")
19746 	(match_operator 1 "compare_operator"
19747	  [(match_operand:SI 2 "memory_operand" "")
19748	   (const_int 0)]))
19749   (match_scratch:SI 3 "r")]
19750  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19751  [(set (match_dup 3) (match_dup 2))
19752   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19753  "")
19754
19755;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19756;; Don't split NOTs with a displacement operand, because resulting XOR
19757;; will not be pairable anyway.
19758;;
19759;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19760;; represented using a modRM byte.  The XOR replacement is long decoded,
19761;; so this split helps here as well.
19762;;
19763;; Note: Can't do this as a regular split because we can't get proper
19764;; lifetime information then.
19765
19766(define_peephole2
19767  [(set (match_operand:SI 0 "nonimmediate_operand" "")
19768	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19769  "!optimize_size
19770   && peep2_regno_dead_p (0, FLAGS_REG)
19771   && ((TARGET_PENTIUM 
19772        && (GET_CODE (operands[0]) != MEM
19773            || !memory_displacement_operand (operands[0], SImode)))
19774       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19775  [(parallel [(set (match_dup 0)
19776		   (xor:SI (match_dup 1) (const_int -1)))
19777	      (clobber (reg:CC FLAGS_REG))])]
19778  "")
19779
19780(define_peephole2
19781  [(set (match_operand:HI 0 "nonimmediate_operand" "")
19782	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19783  "!optimize_size
19784   && peep2_regno_dead_p (0, FLAGS_REG)
19785   && ((TARGET_PENTIUM 
19786        && (GET_CODE (operands[0]) != MEM
19787            || !memory_displacement_operand (operands[0], HImode)))
19788       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19789  [(parallel [(set (match_dup 0)
19790		   (xor:HI (match_dup 1) (const_int -1)))
19791	      (clobber (reg:CC FLAGS_REG))])]
19792  "")
19793
19794(define_peephole2
19795  [(set (match_operand:QI 0 "nonimmediate_operand" "")
19796	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19797  "!optimize_size
19798   && peep2_regno_dead_p (0, FLAGS_REG)
19799   && ((TARGET_PENTIUM 
19800        && (GET_CODE (operands[0]) != MEM
19801            || !memory_displacement_operand (operands[0], QImode)))
19802       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19803  [(parallel [(set (match_dup 0)
19804		   (xor:QI (match_dup 1) (const_int -1)))
19805	      (clobber (reg:CC FLAGS_REG))])]
19806  "")
19807
19808;; Non pairable "test imm, reg" instructions can be translated to
19809;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19810;; byte opcode instead of two, have a short form for byte operands),
19811;; so do it for other CPUs as well.  Given that the value was dead,
19812;; this should not create any new dependencies.  Pass on the sub-word
19813;; versions if we're concerned about partial register stalls.
19814
19815(define_peephole2
19816  [(set (match_operand 0 "flags_reg_operand" "")
19817	(match_operator 1 "compare_operator"
19818	  [(and:SI (match_operand:SI 2 "register_operand" "")
19819		   (match_operand:SI 3 "immediate_operand" ""))
19820	   (const_int 0)]))]
19821  "ix86_match_ccmode (insn, CCNOmode)
19822   && (true_regnum (operands[2]) != 0
19823       || satisfies_constraint_K (operands[3]))
19824   && peep2_reg_dead_p (1, operands[2])"
19825  [(parallel
19826     [(set (match_dup 0)
19827	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19828		            (const_int 0)]))
19829      (set (match_dup 2)
19830	   (and:SI (match_dup 2) (match_dup 3)))])]
19831  "")
19832
19833;; We don't need to handle HImode case, because it will be promoted to SImode
19834;; on ! TARGET_PARTIAL_REG_STALL
19835
19836(define_peephole2
19837  [(set (match_operand 0 "flags_reg_operand" "")
19838	(match_operator 1 "compare_operator"
19839	  [(and:QI (match_operand:QI 2 "register_operand" "")
19840		   (match_operand:QI 3 "immediate_operand" ""))
19841	   (const_int 0)]))]
19842  "! TARGET_PARTIAL_REG_STALL
19843   && ix86_match_ccmode (insn, CCNOmode)
19844   && true_regnum (operands[2]) != 0
19845   && peep2_reg_dead_p (1, operands[2])"
19846  [(parallel
19847     [(set (match_dup 0)
19848	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19849		            (const_int 0)]))
19850      (set (match_dup 2)
19851	   (and:QI (match_dup 2) (match_dup 3)))])]
19852  "")
19853
19854(define_peephole2
19855  [(set (match_operand 0 "flags_reg_operand" "")
19856	(match_operator 1 "compare_operator"
19857	  [(and:SI
19858	     (zero_extract:SI
19859	       (match_operand 2 "ext_register_operand" "")
19860	       (const_int 8)
19861	       (const_int 8))
19862	     (match_operand 3 "const_int_operand" ""))
19863	   (const_int 0)]))]
19864  "! TARGET_PARTIAL_REG_STALL
19865   && ix86_match_ccmode (insn, CCNOmode)
19866   && true_regnum (operands[2]) != 0
19867   && peep2_reg_dead_p (1, operands[2])"
19868  [(parallel [(set (match_dup 0)
19869		   (match_op_dup 1
19870		     [(and:SI
19871			(zero_extract:SI
19872			  (match_dup 2)
19873			  (const_int 8)
19874			  (const_int 8))
19875			(match_dup 3))
19876		      (const_int 0)]))
19877	      (set (zero_extract:SI (match_dup 2)
19878				    (const_int 8)
19879				    (const_int 8))
19880		   (and:SI 
19881		     (zero_extract:SI
19882		       (match_dup 2)
19883		       (const_int 8)
19884		       (const_int 8))
19885		     (match_dup 3)))])]
19886  "")
19887
19888;; Don't do logical operations with memory inputs.
19889(define_peephole2
19890  [(match_scratch:SI 2 "r")
19891   (parallel [(set (match_operand:SI 0 "register_operand" "")
19892                   (match_operator:SI 3 "arith_or_logical_operator"
19893                     [(match_dup 0)
19894                      (match_operand:SI 1 "memory_operand" "")]))
19895              (clobber (reg:CC FLAGS_REG))])]
19896  "! optimize_size && ! TARGET_READ_MODIFY"
19897  [(set (match_dup 2) (match_dup 1))
19898   (parallel [(set (match_dup 0)
19899                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19900              (clobber (reg:CC FLAGS_REG))])]
19901  "")
19902
19903(define_peephole2
19904  [(match_scratch:SI 2 "r")
19905   (parallel [(set (match_operand:SI 0 "register_operand" "")
19906                   (match_operator:SI 3 "arith_or_logical_operator"
19907                     [(match_operand:SI 1 "memory_operand" "")
19908                      (match_dup 0)]))
19909              (clobber (reg:CC FLAGS_REG))])]
19910  "! optimize_size && ! TARGET_READ_MODIFY"
19911  [(set (match_dup 2) (match_dup 1))
19912   (parallel [(set (match_dup 0)
19913                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19914              (clobber (reg:CC FLAGS_REG))])]
19915  "")
19916
19917; Don't do logical operations with memory outputs
19918;
19919; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19920; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19921; the same decoder scheduling characteristics as the original.
19922
19923(define_peephole2
19924  [(match_scratch:SI 2 "r")
19925   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19926                   (match_operator:SI 3 "arith_or_logical_operator"
19927                     [(match_dup 0)
19928                      (match_operand:SI 1 "nonmemory_operand" "")]))
19929              (clobber (reg:CC FLAGS_REG))])]
19930  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19931  [(set (match_dup 2) (match_dup 0))
19932   (parallel [(set (match_dup 2)
19933                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19934              (clobber (reg:CC FLAGS_REG))])
19935   (set (match_dup 0) (match_dup 2))]
19936  "")
19937
19938(define_peephole2
19939  [(match_scratch:SI 2 "r")
19940   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19941                   (match_operator:SI 3 "arith_or_logical_operator"
19942                     [(match_operand:SI 1 "nonmemory_operand" "")
19943                      (match_dup 0)]))
19944              (clobber (reg:CC FLAGS_REG))])]
19945  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19946  [(set (match_dup 2) (match_dup 0))
19947   (parallel [(set (match_dup 2)
19948                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19949              (clobber (reg:CC FLAGS_REG))])
19950   (set (match_dup 0) (match_dup 2))]
19951  "")
19952
19953;; Attempt to always use XOR for zeroing registers.
19954(define_peephole2
19955  [(set (match_operand 0 "register_operand" "")
19956	(match_operand 1 "const0_operand" ""))]
19957  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19958   && (! TARGET_USE_MOV0 || optimize_size)
19959   && GENERAL_REG_P (operands[0])
19960   && peep2_regno_dead_p (0, FLAGS_REG)"
19961  [(parallel [(set (match_dup 0) (const_int 0))
19962	      (clobber (reg:CC FLAGS_REG))])]
19963{
19964  operands[0] = gen_lowpart (word_mode, operands[0]);
19965})
19966
19967(define_peephole2
19968  [(set (strict_low_part (match_operand 0 "register_operand" ""))
19969	(const_int 0))]
19970  "(GET_MODE (operands[0]) == QImode
19971    || GET_MODE (operands[0]) == HImode)
19972   && (! TARGET_USE_MOV0 || optimize_size)
19973   && peep2_regno_dead_p (0, FLAGS_REG)"
19974  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19975	      (clobber (reg:CC FLAGS_REG))])])
19976
19977;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19978(define_peephole2
19979  [(set (match_operand 0 "register_operand" "")
19980	(const_int -1))]
19981  "(GET_MODE (operands[0]) == HImode
19982    || GET_MODE (operands[0]) == SImode 
19983    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19984   && (optimize_size || TARGET_PENTIUM)
19985   && peep2_regno_dead_p (0, FLAGS_REG)"
19986  [(parallel [(set (match_dup 0) (const_int -1))
19987	      (clobber (reg:CC FLAGS_REG))])]
19988  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19989			      operands[0]);")
19990
19991;; Attempt to convert simple leas to adds. These can be created by
19992;; move expanders.
19993(define_peephole2
19994  [(set (match_operand:SI 0 "register_operand" "")
19995  	(plus:SI (match_dup 0)
19996		 (match_operand:SI 1 "nonmemory_operand" "")))]
19997  "peep2_regno_dead_p (0, FLAGS_REG)"
19998  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19999	      (clobber (reg:CC FLAGS_REG))])]
20000  "")
20001
20002(define_peephole2
20003  [(set (match_operand:SI 0 "register_operand" "")
20004  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20005			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20006  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20007  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20008	      (clobber (reg:CC FLAGS_REG))])]
20009  "operands[2] = gen_lowpart (SImode, operands[2]);")
20010
20011(define_peephole2
20012  [(set (match_operand:DI 0 "register_operand" "")
20013  	(plus:DI (match_dup 0)
20014		 (match_operand:DI 1 "x86_64_general_operand" "")))]
20015  "peep2_regno_dead_p (0, FLAGS_REG)"
20016  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20017	      (clobber (reg:CC FLAGS_REG))])]
20018  "")
20019
20020(define_peephole2
20021  [(set (match_operand:SI 0 "register_operand" "")
20022  	(mult:SI (match_dup 0)
20023		 (match_operand:SI 1 "const_int_operand" "")))]
20024  "exact_log2 (INTVAL (operands[1])) >= 0
20025   && peep2_regno_dead_p (0, FLAGS_REG)"
20026  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20027	      (clobber (reg:CC FLAGS_REG))])]
20028  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20029
20030(define_peephole2
20031  [(set (match_operand:DI 0 "register_operand" "")
20032  	(mult:DI (match_dup 0)
20033		 (match_operand:DI 1 "const_int_operand" "")))]
20034  "exact_log2 (INTVAL (operands[1])) >= 0
20035   && peep2_regno_dead_p (0, FLAGS_REG)"
20036  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20037	      (clobber (reg:CC FLAGS_REG))])]
20038  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20039
20040(define_peephole2
20041  [(set (match_operand:SI 0 "register_operand" "")
20042  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20043		   (match_operand:DI 2 "const_int_operand" "")) 0))]
20044  "exact_log2 (INTVAL (operands[2])) >= 0
20045   && REGNO (operands[0]) == REGNO (operands[1])
20046   && peep2_regno_dead_p (0, FLAGS_REG)"
20047  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20048	      (clobber (reg:CC FLAGS_REG))])]
20049  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20050
20051;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20052;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20053;; many CPUs it is also faster, since special hardware to avoid esp
20054;; dependencies is present.
20055
20056;; While some of these conversions may be done using splitters, we use peepholes
20057;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20058
20059;; Convert prologue esp subtractions to push.
20060;; We need register to push.  In order to keep verify_flow_info happy we have
20061;; two choices
20062;; - use scratch and clobber it in order to avoid dependencies
20063;; - use already live register
20064;; We can't use the second way right now, since there is no reliable way how to
20065;; verify that given register is live.  First choice will also most likely in
20066;; fewer dependencies.  On the place of esp adjustments it is very likely that
20067;; call clobbered registers are dead.  We may want to use base pointer as an
20068;; alternative when no register is available later.
20069
20070(define_peephole2
20071  [(match_scratch:SI 0 "r")
20072   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20073	      (clobber (reg:CC FLAGS_REG))
20074	      (clobber (mem:BLK (scratch)))])]
20075  "optimize_size || !TARGET_SUB_ESP_4"
20076  [(clobber (match_dup 0))
20077   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20078	      (clobber (mem:BLK (scratch)))])])
20079
20080(define_peephole2
20081  [(match_scratch:SI 0 "r")
20082   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20083	      (clobber (reg:CC FLAGS_REG))
20084	      (clobber (mem:BLK (scratch)))])]
20085  "optimize_size || !TARGET_SUB_ESP_8"
20086  [(clobber (match_dup 0))
20087   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20088   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20089	      (clobber (mem:BLK (scratch)))])])
20090
20091;; Convert esp subtractions to push.
20092(define_peephole2
20093  [(match_scratch:SI 0 "r")
20094   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20095	      (clobber (reg:CC FLAGS_REG))])]
20096  "optimize_size || !TARGET_SUB_ESP_4"
20097  [(clobber (match_dup 0))
20098   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20099
20100(define_peephole2
20101  [(match_scratch:SI 0 "r")
20102   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20103	      (clobber (reg:CC FLAGS_REG))])]
20104  "optimize_size || !TARGET_SUB_ESP_8"
20105  [(clobber (match_dup 0))
20106   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20107   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20108
20109;; Convert epilogue deallocator to pop.
20110(define_peephole2
20111  [(match_scratch:SI 0 "r")
20112   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20113	      (clobber (reg:CC FLAGS_REG))
20114	      (clobber (mem:BLK (scratch)))])]
20115  "optimize_size || !TARGET_ADD_ESP_4"
20116  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20117	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20118	      (clobber (mem:BLK (scratch)))])]
20119  "")
20120
20121;; Two pops case is tricky, since pop causes dependency on destination register.
20122;; We use two registers if available.
20123(define_peephole2
20124  [(match_scratch:SI 0 "r")
20125   (match_scratch:SI 1 "r")
20126   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20127	      (clobber (reg:CC FLAGS_REG))
20128	      (clobber (mem:BLK (scratch)))])]
20129  "optimize_size || !TARGET_ADD_ESP_8"
20130  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20131	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20132	      (clobber (mem:BLK (scratch)))])
20133   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20134	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20135  "")
20136
20137(define_peephole2
20138  [(match_scratch:SI 0 "r")
20139   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20140	      (clobber (reg:CC FLAGS_REG))
20141	      (clobber (mem:BLK (scratch)))])]
20142  "optimize_size"
20143  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20144	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20145	      (clobber (mem:BLK (scratch)))])
20146   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20147	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20148  "")
20149
20150;; Convert esp additions to pop.
20151(define_peephole2
20152  [(match_scratch:SI 0 "r")
20153   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20154	      (clobber (reg:CC FLAGS_REG))])]
20155  ""
20156  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20157	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20158  "")
20159
20160;; Two pops case is tricky, since pop causes dependency on destination register.
20161;; We use two registers if available.
20162(define_peephole2
20163  [(match_scratch:SI 0 "r")
20164   (match_scratch:SI 1 "r")
20165   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20166	      (clobber (reg:CC FLAGS_REG))])]
20167  ""
20168  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20169	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20170   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20171	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20172  "")
20173
20174(define_peephole2
20175  [(match_scratch:SI 0 "r")
20176   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20177	      (clobber (reg:CC FLAGS_REG))])]
20178  "optimize_size"
20179  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20180	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20181   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20182	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20183  "")
20184
20185;; Convert compares with 1 to shorter inc/dec operations when CF is not
20186;; required and register dies.  Similarly for 128 to plus -128.
20187(define_peephole2
20188  [(set (match_operand 0 "flags_reg_operand" "")
20189	(match_operator 1 "compare_operator"
20190	  [(match_operand 2 "register_operand" "")
20191	   (match_operand 3 "const_int_operand" "")]))]
20192  "(INTVAL (operands[3]) == -1
20193    || INTVAL (operands[3]) == 1
20194    || INTVAL (operands[3]) == 128)
20195   && ix86_match_ccmode (insn, CCGCmode)
20196   && peep2_reg_dead_p (1, operands[2])"
20197  [(parallel [(set (match_dup 0)
20198		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20199	      (clobber (match_dup 2))])]
20200  "")
20201
20202(define_peephole2
20203  [(match_scratch:DI 0 "r")
20204   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20205	      (clobber (reg:CC FLAGS_REG))
20206	      (clobber (mem:BLK (scratch)))])]
20207  "optimize_size || !TARGET_SUB_ESP_4"
20208  [(clobber (match_dup 0))
20209   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20210	      (clobber (mem:BLK (scratch)))])])
20211
20212(define_peephole2
20213  [(match_scratch:DI 0 "r")
20214   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20215	      (clobber (reg:CC FLAGS_REG))
20216	      (clobber (mem:BLK (scratch)))])]
20217  "optimize_size || !TARGET_SUB_ESP_8"
20218  [(clobber (match_dup 0))
20219   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20220   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20221	      (clobber (mem:BLK (scratch)))])])
20222
20223;; Convert esp subtractions to push.
20224(define_peephole2
20225  [(match_scratch:DI 0 "r")
20226   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20227	      (clobber (reg:CC FLAGS_REG))])]
20228  "optimize_size || !TARGET_SUB_ESP_4"
20229  [(clobber (match_dup 0))
20230   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20231
20232(define_peephole2
20233  [(match_scratch:DI 0 "r")
20234   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20235	      (clobber (reg:CC FLAGS_REG))])]
20236  "optimize_size || !TARGET_SUB_ESP_8"
20237  [(clobber (match_dup 0))
20238   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20239   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20240
20241;; Convert epilogue deallocator to pop.
20242(define_peephole2
20243  [(match_scratch:DI 0 "r")
20244   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20245	      (clobber (reg:CC FLAGS_REG))
20246	      (clobber (mem:BLK (scratch)))])]
20247  "optimize_size || !TARGET_ADD_ESP_4"
20248  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20249	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20250	      (clobber (mem:BLK (scratch)))])]
20251  "")
20252
20253;; Two pops case is tricky, since pop causes dependency on destination register.
20254;; We use two registers if available.
20255(define_peephole2
20256  [(match_scratch:DI 0 "r")
20257   (match_scratch:DI 1 "r")
20258   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20259	      (clobber (reg:CC FLAGS_REG))
20260	      (clobber (mem:BLK (scratch)))])]
20261  "optimize_size || !TARGET_ADD_ESP_8"
20262  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20263	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20264	      (clobber (mem:BLK (scratch)))])
20265   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20266	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20267  "")
20268
20269(define_peephole2
20270  [(match_scratch:DI 0 "r")
20271   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20272	      (clobber (reg:CC FLAGS_REG))
20273	      (clobber (mem:BLK (scratch)))])]
20274  "optimize_size"
20275  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20276	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20277	      (clobber (mem:BLK (scratch)))])
20278   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20279	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20280  "")
20281
20282;; Convert esp additions to pop.
20283(define_peephole2
20284  [(match_scratch:DI 0 "r")
20285   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20286	      (clobber (reg:CC FLAGS_REG))])]
20287  ""
20288  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20289	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20290  "")
20291
20292;; Two pops case is tricky, since pop causes dependency on destination register.
20293;; We use two registers if available.
20294(define_peephole2
20295  [(match_scratch:DI 0 "r")
20296   (match_scratch:DI 1 "r")
20297   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20298	      (clobber (reg:CC FLAGS_REG))])]
20299  ""
20300  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20301	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20302   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20303	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20304  "")
20305
20306(define_peephole2
20307  [(match_scratch:DI 0 "r")
20308   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20309	      (clobber (reg:CC FLAGS_REG))])]
20310  "optimize_size"
20311  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20312	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20313   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20314	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20315  "")
20316
20317;; Convert imul by three, five and nine into lea
20318(define_peephole2
20319  [(parallel
20320    [(set (match_operand:SI 0 "register_operand" "")
20321	  (mult:SI (match_operand:SI 1 "register_operand" "")
20322		   (match_operand:SI 2 "const_int_operand" "")))
20323     (clobber (reg:CC FLAGS_REG))])]
20324  "INTVAL (operands[2]) == 3
20325   || INTVAL (operands[2]) == 5
20326   || INTVAL (operands[2]) == 9"
20327  [(set (match_dup 0)
20328        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20329                 (match_dup 1)))]
20330  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20331
20332(define_peephole2
20333  [(parallel
20334    [(set (match_operand:SI 0 "register_operand" "")
20335          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20336                   (match_operand:SI 2 "const_int_operand" "")))
20337     (clobber (reg:CC FLAGS_REG))])]
20338  "!optimize_size 
20339   && (INTVAL (operands[2]) == 3
20340       || INTVAL (operands[2]) == 5
20341       || INTVAL (operands[2]) == 9)"
20342  [(set (match_dup 0) (match_dup 1))
20343   (set (match_dup 0)
20344        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20345                 (match_dup 0)))]
20346  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20347
20348(define_peephole2
20349  [(parallel
20350    [(set (match_operand:DI 0 "register_operand" "")
20351	  (mult:DI (match_operand:DI 1 "register_operand" "")
20352		   (match_operand:DI 2 "const_int_operand" "")))
20353     (clobber (reg:CC FLAGS_REG))])]
20354  "TARGET_64BIT
20355   && (INTVAL (operands[2]) == 3
20356       || INTVAL (operands[2]) == 5
20357       || INTVAL (operands[2]) == 9)"
20358  [(set (match_dup 0)
20359        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20360                 (match_dup 1)))]
20361  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20362
20363(define_peephole2
20364  [(parallel
20365    [(set (match_operand:DI 0 "register_operand" "")
20366          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20367                   (match_operand:DI 2 "const_int_operand" "")))
20368     (clobber (reg:CC FLAGS_REG))])]
20369  "TARGET_64BIT
20370   && !optimize_size 
20371   && (INTVAL (operands[2]) == 3
20372       || INTVAL (operands[2]) == 5
20373       || INTVAL (operands[2]) == 9)"
20374  [(set (match_dup 0) (match_dup 1))
20375   (set (match_dup 0)
20376        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20377                 (match_dup 0)))]
20378  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20379
20380;; Imul $32bit_imm, mem, reg is vector decoded, while
20381;; imul $32bit_imm, reg, reg is direct decoded.
20382(define_peephole2
20383  [(match_scratch:DI 3 "r")
20384   (parallel [(set (match_operand:DI 0 "register_operand" "")
20385		   (mult:DI (match_operand:DI 1 "memory_operand" "")
20386			    (match_operand:DI 2 "immediate_operand" "")))
20387	      (clobber (reg:CC FLAGS_REG))])]
20388  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20389   && !satisfies_constraint_K (operands[2])"
20390  [(set (match_dup 3) (match_dup 1))
20391   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20392	      (clobber (reg:CC FLAGS_REG))])]
20393"")
20394
20395(define_peephole2
20396  [(match_scratch:SI 3 "r")
20397   (parallel [(set (match_operand:SI 0 "register_operand" "")
20398		   (mult:SI (match_operand:SI 1 "memory_operand" "")
20399			    (match_operand:SI 2 "immediate_operand" "")))
20400	      (clobber (reg:CC FLAGS_REG))])]
20401  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20402   && !satisfies_constraint_K (operands[2])"
20403  [(set (match_dup 3) (match_dup 1))
20404   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20405	      (clobber (reg:CC FLAGS_REG))])]
20406"")
20407
20408(define_peephole2
20409  [(match_scratch:SI 3 "r")
20410   (parallel [(set (match_operand:DI 0 "register_operand" "")
20411		   (zero_extend:DI
20412		     (mult:SI (match_operand:SI 1 "memory_operand" "")
20413			      (match_operand:SI 2 "immediate_operand" ""))))
20414	      (clobber (reg:CC FLAGS_REG))])]
20415  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20416   && !satisfies_constraint_K (operands[2])"
20417  [(set (match_dup 3) (match_dup 1))
20418   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20419	      (clobber (reg:CC FLAGS_REG))])]
20420"")
20421
20422;; imul $8/16bit_imm, regmem, reg is vector decoded.
20423;; Convert it into imul reg, reg
20424;; It would be better to force assembler to encode instruction using long
20425;; immediate, but there is apparently no way to do so.
20426(define_peephole2
20427  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20428		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20429			    (match_operand:DI 2 "const_int_operand" "")))
20430	      (clobber (reg:CC FLAGS_REG))])
20431   (match_scratch:DI 3 "r")]
20432  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20433   && satisfies_constraint_K (operands[2])"
20434  [(set (match_dup 3) (match_dup 2))
20435   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20436	      (clobber (reg:CC FLAGS_REG))])]
20437{
20438  if (!rtx_equal_p (operands[0], operands[1]))
20439    emit_move_insn (operands[0], operands[1]);
20440})
20441
20442(define_peephole2
20443  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20444		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20445			    (match_operand:SI 2 "const_int_operand" "")))
20446	      (clobber (reg:CC FLAGS_REG))])
20447   (match_scratch:SI 3 "r")]
20448  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20449   && satisfies_constraint_K (operands[2])"
20450  [(set (match_dup 3) (match_dup 2))
20451   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20452	      (clobber (reg:CC FLAGS_REG))])]
20453{
20454  if (!rtx_equal_p (operands[0], operands[1]))
20455    emit_move_insn (operands[0], operands[1]);
20456})
20457
20458(define_peephole2
20459  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20460		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20461			    (match_operand:HI 2 "immediate_operand" "")))
20462	      (clobber (reg:CC FLAGS_REG))])
20463   (match_scratch:HI 3 "r")]
20464  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20465  [(set (match_dup 3) (match_dup 2))
20466   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20467	      (clobber (reg:CC FLAGS_REG))])]
20468{
20469  if (!rtx_equal_p (operands[0], operands[1]))
20470    emit_move_insn (operands[0], operands[1]);
20471})
20472
20473;; After splitting up read-modify operations, array accesses with memory
20474;; operands might end up in form:
20475;;  sall    $2, %eax
20476;;  movl    4(%esp), %edx
20477;;  addl    %edx, %eax
20478;; instead of pre-splitting:
20479;;  sall    $2, %eax
20480;;  addl    4(%esp), %eax
20481;; Turn it into:
20482;;  movl    4(%esp), %edx
20483;;  leal    (%edx,%eax,4), %eax
20484
20485(define_peephole2
20486  [(parallel [(set (match_operand 0 "register_operand" "")
20487		   (ashift (match_operand 1 "register_operand" "")
20488			   (match_operand 2 "const_int_operand" "")))
20489	       (clobber (reg:CC FLAGS_REG))])
20490   (set (match_operand 3 "register_operand")
20491        (match_operand 4 "x86_64_general_operand" ""))
20492   (parallel [(set (match_operand 5 "register_operand" "")
20493		   (plus (match_operand 6 "register_operand" "")
20494			 (match_operand 7 "register_operand" "")))
20495		   (clobber (reg:CC FLAGS_REG))])]
20496  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20497   /* Validate MODE for lea.  */
20498   && ((!TARGET_PARTIAL_REG_STALL
20499	&& (GET_MODE (operands[0]) == QImode
20500	    || GET_MODE (operands[0]) == HImode))
20501       || GET_MODE (operands[0]) == SImode 
20502       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20503   /* We reorder load and the shift.  */
20504   && !rtx_equal_p (operands[1], operands[3])
20505   && !reg_overlap_mentioned_p (operands[0], operands[4])
20506   /* Last PLUS must consist of operand 0 and 3.  */
20507   && !rtx_equal_p (operands[0], operands[3])
20508   && (rtx_equal_p (operands[3], operands[6])
20509       || rtx_equal_p (operands[3], operands[7]))
20510   && (rtx_equal_p (operands[0], operands[6])
20511       || rtx_equal_p (operands[0], operands[7]))
20512   /* The intermediate operand 0 must die or be same as output.  */
20513   && (rtx_equal_p (operands[0], operands[5])
20514       || peep2_reg_dead_p (3, operands[0]))"
20515  [(set (match_dup 3) (match_dup 4))
20516   (set (match_dup 0) (match_dup 1))]
20517{
20518  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20519  int scale = 1 << INTVAL (operands[2]);
20520  rtx index = gen_lowpart (Pmode, operands[1]);
20521  rtx base = gen_lowpart (Pmode, operands[3]);
20522  rtx dest = gen_lowpart (mode, operands[5]);
20523
20524  operands[1] = gen_rtx_PLUS (Pmode, base,
20525  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20526  if (mode != Pmode)
20527    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20528  operands[0] = dest;
20529})
20530
20531;; Call-value patterns last so that the wildcard operand does not
20532;; disrupt insn-recog's switch tables.
20533
20534(define_insn "*call_value_pop_0"
20535  [(set (match_operand 0 "" "")
20536	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20537	      (match_operand:SI 2 "" "")))
20538   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20539			    (match_operand:SI 3 "immediate_operand" "")))]
20540  "!TARGET_64BIT"
20541{
20542  if (SIBLING_CALL_P (insn))
20543    return "jmp\t%P1";
20544  else
20545    return "call\t%P1";
20546}
20547  [(set_attr "type" "callv")])
20548
20549(define_insn "*call_value_pop_1"
20550  [(set (match_operand 0 "" "")
20551	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20552	      (match_operand:SI 2 "" "")))
20553   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20554			    (match_operand:SI 3 "immediate_operand" "i")))]
20555  "!TARGET_64BIT"
20556{
20557  if (constant_call_address_operand (operands[1], Pmode))
20558    {
20559      if (SIBLING_CALL_P (insn))
20560	return "jmp\t%P1";
20561      else
20562	return "call\t%P1";
20563    }
20564  if (SIBLING_CALL_P (insn))
20565    return "jmp\t%A1";
20566  else
20567    return "call\t%A1";
20568}
20569  [(set_attr "type" "callv")])
20570
20571(define_insn "*call_value_0"
20572  [(set (match_operand 0 "" "")
20573	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20574	      (match_operand:SI 2 "" "")))]
20575  "!TARGET_64BIT"
20576{
20577  if (SIBLING_CALL_P (insn))
20578    return "jmp\t%P1";
20579  else
20580    return "call\t%P1";
20581}
20582  [(set_attr "type" "callv")])
20583
20584(define_insn "*call_value_0_rex64"
20585  [(set (match_operand 0 "" "")
20586	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20587	      (match_operand:DI 2 "const_int_operand" "")))]
20588  "TARGET_64BIT"
20589{
20590  if (SIBLING_CALL_P (insn))
20591    return "jmp\t%P1";
20592  else
20593    return "call\t%P1";
20594}
20595  [(set_attr "type" "callv")])
20596
20597(define_insn "*call_value_1"
20598  [(set (match_operand 0 "" "")
20599	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20600	      (match_operand:SI 2 "" "")))]
20601  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20602{
20603  if (constant_call_address_operand (operands[1], Pmode))
20604    return "call\t%P1";
20605  return "call\t%A1";
20606}
20607  [(set_attr "type" "callv")])
20608
20609(define_insn "*sibcall_value_1"
20610  [(set (match_operand 0 "" "")
20611	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20612	      (match_operand:SI 2 "" "")))]
20613  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20614{
20615  if (constant_call_address_operand (operands[1], Pmode))
20616    return "jmp\t%P1";
20617  return "jmp\t%A1";
20618}
20619  [(set_attr "type" "callv")])
20620
20621(define_insn "*call_value_1_rex64"
20622  [(set (match_operand 0 "" "")
20623	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20624	      (match_operand:DI 2 "" "")))]
20625  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20626{
20627  if (constant_call_address_operand (operands[1], Pmode))
20628    return "call\t%P1";
20629  return "call\t%A1";
20630}
20631  [(set_attr "type" "callv")])
20632
20633(define_insn "*sibcall_value_1_rex64"
20634  [(set (match_operand 0 "" "")
20635	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20636	      (match_operand:DI 2 "" "")))]
20637  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20638  "jmp\t%P1"
20639  [(set_attr "type" "callv")])
20640
20641(define_insn "*sibcall_value_1_rex64_v"
20642  [(set (match_operand 0 "" "")
20643	(call (mem:QI (reg:DI 40))
20644	      (match_operand:DI 1 "" "")))]
20645  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20646  "jmp\t*%%r11"
20647  [(set_attr "type" "callv")])
20648
20649;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20650;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20651;; caught for use by garbage collectors and the like.  Using an insn that
20652;; maps to SIGILL makes it more likely the program will rightfully die.
20653;; Keeping with tradition, "6" is in honor of #UD.
20654(define_insn "trap"
20655  [(trap_if (const_int 1) (const_int 6))]
20656  ""
20657  { return ASM_SHORT "0x0b0f"; }
20658  [(set_attr "length" "2")])
20659
20660(define_expand "sse_prologue_save"
20661  [(parallel [(set (match_operand:BLK 0 "" "")
20662		   (unspec:BLK [(reg:DI 21)
20663				(reg:DI 22)
20664				(reg:DI 23)
20665				(reg:DI 24)
20666				(reg:DI 25)
20667				(reg:DI 26)
20668				(reg:DI 27)
20669				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20670	      (use (match_operand:DI 1 "register_operand" ""))
20671	      (use (match_operand:DI 2 "immediate_operand" ""))
20672	      (use (label_ref:DI (match_operand 3 "" "")))])]
20673  "TARGET_64BIT"
20674  "")
20675
20676(define_insn "*sse_prologue_save_insn"
20677  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20678			  (match_operand:DI 4 "const_int_operand" "n")))
20679	(unspec:BLK [(reg:DI 21)
20680		     (reg:DI 22)
20681		     (reg:DI 23)
20682		     (reg:DI 24)
20683		     (reg:DI 25)
20684		     (reg:DI 26)
20685		     (reg:DI 27)
20686		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20687   (use (match_operand:DI 1 "register_operand" "r"))
20688   (use (match_operand:DI 2 "const_int_operand" "i"))
20689   (use (label_ref:DI (match_operand 3 "" "X")))]
20690  "TARGET_64BIT
20691   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20692   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20693  "*
20694{
20695  int i;
20696  operands[0] = gen_rtx_MEM (Pmode,
20697			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20698  output_asm_insn (\"jmp\\t%A1\", operands);
20699  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20700    {
20701      operands[4] = adjust_address (operands[0], DImode, i*16);
20702      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20703      PUT_MODE (operands[4], TImode);
20704      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20705        output_asm_insn (\"rex\", operands);
20706      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20707    }
20708  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20709			     CODE_LABEL_NUMBER (operands[3]));
20710  RET;
20711}
20712  "
20713  [(set_attr "type" "other")
20714   (set_attr "length_immediate" "0")
20715   (set_attr "length_address" "0")
20716   (set_attr "length" "135")
20717   (set_attr "memory" "store")
20718   (set_attr "modrm" "0")
20719   (set_attr "mode" "DI")])
20720
20721(define_expand "prefetch"
20722  [(prefetch (match_operand 0 "address_operand" "")
20723	     (match_operand:SI 1 "const_int_operand" "")
20724	     (match_operand:SI 2 "const_int_operand" ""))]
20725  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20726{
20727  int rw = INTVAL (operands[1]);
20728  int locality = INTVAL (operands[2]);
20729
20730  gcc_assert (rw == 0 || rw == 1);
20731  gcc_assert (locality >= 0 && locality <= 3);
20732  gcc_assert (GET_MODE (operands[0]) == Pmode
20733	      || GET_MODE (operands[0]) == VOIDmode);
20734
20735  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20736     supported by SSE counterpart or the SSE prefetch is not available
20737     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20738     of locality.  */
20739  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20740    operands[2] = GEN_INT (3);
20741  else
20742    operands[1] = const0_rtx;
20743})
20744
20745(define_insn "*prefetch_sse"
20746  [(prefetch (match_operand:SI 0 "address_operand" "p")
20747	     (const_int 0)
20748	     (match_operand:SI 1 "const_int_operand" ""))]
20749  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20750{
20751  static const char * const patterns[4] = {
20752   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20753  };
20754
20755  int locality = INTVAL (operands[1]);
20756  gcc_assert (locality >= 0 && locality <= 3);
20757
20758  return patterns[locality];  
20759}
20760  [(set_attr "type" "sse")
20761   (set_attr "memory" "none")])
20762
20763(define_insn "*prefetch_sse_rex"
20764  [(prefetch (match_operand:DI 0 "address_operand" "p")
20765	     (const_int 0)
20766	     (match_operand:SI 1 "const_int_operand" ""))]
20767  "TARGET_PREFETCH_SSE && TARGET_64BIT"
20768{
20769  static const char * const patterns[4] = {
20770   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20771  };
20772
20773  int locality = INTVAL (operands[1]);
20774  gcc_assert (locality >= 0 && locality <= 3);
20775
20776  return patterns[locality];  
20777}
20778  [(set_attr "type" "sse")
20779   (set_attr "memory" "none")])
20780
20781(define_insn "*prefetch_3dnow"
20782  [(prefetch (match_operand:SI 0 "address_operand" "p")
20783	     (match_operand:SI 1 "const_int_operand" "n")
20784	     (const_int 3))]
20785  "TARGET_3DNOW && !TARGET_64BIT"
20786{
20787  if (INTVAL (operands[1]) == 0)
20788    return "prefetch\t%a0";
20789  else
20790    return "prefetchw\t%a0";
20791}
20792  [(set_attr "type" "mmx")
20793   (set_attr "memory" "none")])
20794
20795(define_insn "*prefetch_3dnow_rex"
20796  [(prefetch (match_operand:DI 0 "address_operand" "p")
20797	     (match_operand:SI 1 "const_int_operand" "n")
20798	     (const_int 3))]
20799  "TARGET_3DNOW && TARGET_64BIT"
20800{
20801  if (INTVAL (operands[1]) == 0)
20802    return "prefetch\t%a0";
20803  else
20804    return "prefetchw\t%a0";
20805}
20806  [(set_attr "type" "mmx")
20807   (set_attr "memory" "none")])
20808
20809(define_expand "stack_protect_set"
20810  [(match_operand 0 "memory_operand" "")
20811   (match_operand 1 "memory_operand" "")]
20812  ""
20813{
20814#ifdef TARGET_THREAD_SSP_OFFSET
20815  if (TARGET_64BIT)
20816    emit_insn (gen_stack_tls_protect_set_di (operands[0],
20817					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20818  else
20819    emit_insn (gen_stack_tls_protect_set_si (operands[0],
20820					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20821#else
20822  if (TARGET_64BIT)
20823    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20824  else
20825    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20826#endif
20827  DONE;
20828})
20829
20830(define_insn "stack_protect_set_si"
20831  [(set (match_operand:SI 0 "memory_operand" "=m")
20832	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20833   (set (match_scratch:SI 2 "=&r") (const_int 0))
20834   (clobber (reg:CC FLAGS_REG))]
20835  ""
20836  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20837  [(set_attr "type" "multi")])
20838
20839(define_insn "stack_protect_set_di"
20840  [(set (match_operand:DI 0 "memory_operand" "=m")
20841	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20842   (set (match_scratch:DI 2 "=&r") (const_int 0))
20843   (clobber (reg:CC FLAGS_REG))]
20844  "TARGET_64BIT"
20845  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20846  [(set_attr "type" "multi")])
20847
20848(define_insn "stack_tls_protect_set_si"
20849  [(set (match_operand:SI 0 "memory_operand" "=m")
20850	(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20851   (set (match_scratch:SI 2 "=&r") (const_int 0))
20852   (clobber (reg:CC FLAGS_REG))]
20853  ""
20854  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20855  [(set_attr "type" "multi")])
20856
20857(define_insn "stack_tls_protect_set_di"
20858  [(set (match_operand:DI 0 "memory_operand" "=m")
20859	(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20860   (set (match_scratch:DI 2 "=&r") (const_int 0))
20861   (clobber (reg:CC FLAGS_REG))]
20862  "TARGET_64BIT"
20863  {
20864     /* The kernel uses a different segment register for performance reasons; a
20865        system call would not have to trash the userspace segment register,
20866        which would be expensive */
20867     if (ix86_cmodel != CM_KERNEL)
20868        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20869     else
20870        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20871  }
20872  [(set_attr "type" "multi")])
20873
20874(define_expand "stack_protect_test"
20875  [(match_operand 0 "memory_operand" "")
20876   (match_operand 1 "memory_operand" "")
20877   (match_operand 2 "" "")]
20878  ""
20879{
20880  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20881  ix86_compare_op0 = operands[0];
20882  ix86_compare_op1 = operands[1];
20883  ix86_compare_emitted = flags;
20884
20885#ifdef TARGET_THREAD_SSP_OFFSET
20886  if (TARGET_64BIT)
20887    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20888					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20889  else
20890    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20891					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20892#else
20893  if (TARGET_64BIT)
20894    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20895  else
20896    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20897#endif
20898  emit_jump_insn (gen_beq (operands[2]));
20899  DONE;
20900})
20901
20902(define_insn "stack_protect_test_si"
20903  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20904	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20905		     (match_operand:SI 2 "memory_operand" "m")]
20906		    UNSPEC_SP_TEST))
20907   (clobber (match_scratch:SI 3 "=&r"))]
20908  ""
20909  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20910  [(set_attr "type" "multi")])
20911
20912(define_insn "stack_protect_test_di"
20913  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20914	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20915		     (match_operand:DI 2 "memory_operand" "m")]
20916		    UNSPEC_SP_TEST))
20917   (clobber (match_scratch:DI 3 "=&r"))]
20918  "TARGET_64BIT"
20919  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20920  [(set_attr "type" "multi")])
20921
20922(define_insn "stack_tls_protect_test_si"
20923  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20924	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20925		     (match_operand:SI 2 "const_int_operand" "i")]
20926		    UNSPEC_SP_TLS_TEST))
20927   (clobber (match_scratch:SI 3 "=r"))]
20928  ""
20929  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20930  [(set_attr "type" "multi")])
20931
20932(define_insn "stack_tls_protect_test_di"
20933  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20934	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20935		     (match_operand:DI 2 "const_int_operand" "i")]
20936		    UNSPEC_SP_TLS_TEST))
20937   (clobber (match_scratch:DI 3 "=r"))]
20938  "TARGET_64BIT"
20939  {
20940     /* The kernel uses a different segment register for performance reasons; a
20941        system call would not have to trash the userspace segment register,
20942        which would be expensive */
20943     if (ix86_cmodel != CM_KERNEL)
20944        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20945     else
20946        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20947  }
20948  [(set_attr "type" "multi")])
20949
20950(include "sse.md")
20951(include "mmx.md")
20952(include "sync.md")
20953